forked from drath/libratbag
hidpp10: check crc when reading a page
If the crc is wrong, the device will ignore the page. This technically multiply by 6 the time to access the device, but this is because we do not cache anything currently in hidpp10. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
This commit is contained in:
@@ -629,19 +629,19 @@ hidpp10_get_profile_directory(struct hidpp10_device *dev,
|
||||
{
|
||||
unsigned int i;
|
||||
int res;
|
||||
struct hidpp10_directory directory[16]; /* assume 16 profiles max */
|
||||
uint8_t bytes[HIDPP10_PAGE_SIZE] = { 0 };
|
||||
struct hidpp10_directory *directory = (struct hidpp10_directory *)bytes;
|
||||
size_t count;
|
||||
|
||||
hidpp_log_raw(&dev->base, "Fetching the profiles' directory\n");
|
||||
|
||||
for (i = 0; i < sizeof(directory); i += 16) {
|
||||
res = hidpp10_read_memory(dev, 0x01, i, (uint8_t *)directory + i);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
res = hidpp10_read_page(dev, 0x01, bytes);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < ARRAY_LENGTH(directory); i++) {
|
||||
/* assume 16 profiles max */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (directory[i].page == 0xFF)
|
||||
break;
|
||||
count++;
|
||||
@@ -1242,6 +1242,29 @@ hidpp10_read_memory(struct hidpp10_device *dev, uint8_t page, uint16_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp10_read_page(struct hidpp10_device *dev, uint8_t page,
|
||||
uint8_t bytes[HIDPP10_PAGE_SIZE])
|
||||
{
|
||||
unsigned int i;
|
||||
int res;
|
||||
uint16_t crc, read_crc;
|
||||
|
||||
for (i = 0; i < HIDPP10_PAGE_SIZE; i += 16) {
|
||||
res = hidpp10_read_memory(dev, page, i, bytes + i);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
crc = hidpp_crc_ccitt(bytes, HIDPP10_PAGE_SIZE - 2);
|
||||
read_crc = hidpp_get_unaligned_be_u16(&bytes[HIDPP10_PAGE_SIZE - 2]);
|
||||
|
||||
if (crc != read_crc)
|
||||
return -EILSEQ; /* return illegal sequence */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0xB2: Device Connection and Disconnection (Pairing) */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -503,12 +503,18 @@ hidpp10_set_usb_refresh_rate(struct hidpp10_device *dev,
|
||||
/* 0xA2: Read Sector */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP10_PAGE_SIZE (16 * 2 * 16)
|
||||
|
||||
int
|
||||
hidpp10_read_memory(struct hidpp10_device *dev,
|
||||
uint8_t page,
|
||||
uint16_t offset,
|
||||
uint8_t bytes[16]);
|
||||
|
||||
int
|
||||
hidpp10_read_page(struct hidpp10_device *dev, uint8_t page,
|
||||
uint8_t bytes[HIDPP10_PAGE_SIZE]);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0xB2: Device Connection and Disconnection (Pairing) */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user