Retrieves the device's Usage Page and Usage from the report descriptor. The algorithm is simple, as it just returns the first Usage and Usage Page that it finds in the descriptor. The return value is 0 on success and -1 on failure. */
| 188 | Usage and Usage Page that it finds in the descriptor. |
| 189 | The return value is 0 on success and -1 on failure. */ |
| 190 | static int get_usage(uint8_t *report_descriptor, size_t size, |
| 191 | unsigned short *usage_page, unsigned short *usage) |
| 192 | { |
| 193 | unsigned int i = 0; |
| 194 | int size_code; |
| 195 | int data_len, key_size; |
| 196 | int usage_found = 0, usage_page_found = 0; |
| 197 | |
| 198 | while (i < size) { |
| 199 | int key = report_descriptor[i]; |
| 200 | int key_cmd = key & 0xfc; |
| 201 | |
| 202 | //printf("key: %02hhx\n", key); |
| 203 | |
| 204 | if ((key & 0xf0) == 0xf0) { |
| 205 | /* This is a Long Item. The next byte contains the |
| 206 | length of the data section (value) for this key. |
| 207 | See the HID specification, version 1.11, section |
| 208 | 6.2.2.3, titled "Long Items." */ |
| 209 | if (i+1 < size) |
| 210 | data_len = report_descriptor[i+1]; |
| 211 | else |
| 212 | data_len = 0; /* malformed report */ |
| 213 | key_size = 3; |
| 214 | } |
| 215 | else { |
| 216 | /* This is a Short Item. The bottom two bits of the |
| 217 | key contain the size code for the data section |
| 218 | (value) for this key. Refer to the HID |
| 219 | specification, version 1.11, section 6.2.2.2, |
| 220 | titled "Short Items." */ |
| 221 | size_code = key & 0x3; |
| 222 | switch (size_code) { |
| 223 | case 0: |
| 224 | case 1: |
| 225 | case 2: |
| 226 | data_len = size_code; |
| 227 | break; |
| 228 | case 3: |
| 229 | data_len = 4; |
| 230 | break; |
| 231 | default: |
| 232 | /* Can't ever happen since size_code is & 0x3 */ |
| 233 | data_len = 0; |
| 234 | break; |
| 235 | }; |
| 236 | key_size = 1; |
| 237 | } |
| 238 | |
| 239 | if (key_cmd == 0x4) { |
| 240 | *usage_page = get_bytes(report_descriptor, size, data_len, i); |
| 241 | usage_page_found = 1; |
| 242 | //printf("Usage Page: %x\n", (uint32_t)*usage_page); |
| 243 | } |
| 244 | if (key_cmd == 0x8) { |
| 245 | *usage = get_bytes(report_descriptor, size, data_len, i); |
| 246 | usage_found = 1; |
| 247 | //printf("Usage: %x\n", (uint32_t)*usage); |
no test coverage detected