From 0ab1c5c234767fda76429478af7cebec5e43fb32 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 25 Nov 2015 18:20:10 +0100 Subject: [PATCH] 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 --- src/hidpp10.c | 37 ++++++++++++++++++++++++++++++------- src/hidpp10.h | 6 ++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/hidpp10.c b/src/hidpp10.c index be894f59..12ace185 100644 --- a/src/hidpp10.c +++ b/src/hidpp10.c @@ -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) */ /* -------------------------------------------------------------------------- */ diff --git a/src/hidpp10.h b/src/hidpp10.h index 98152fb5..ee7d32c7 100644 --- a/src/hidpp10.h +++ b/src/hidpp10.h @@ -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) */ /* -------------------------------------------------------------------------- */