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:
Benjamin Tissoires
2015-11-25 18:20:10 +01:00
parent 9cc323d80f
commit 0ab1c5c234
2 changed files with 36 additions and 7 deletions

View File

@@ -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) */
/* -------------------------------------------------------------------------- */

View File

@@ -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) */
/* -------------------------------------------------------------------------- */