Changeset cd83f25 in mainline
- Timestamp:
- 2011-05-27T09:58:08Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e89bb50
- Parents:
- 63d4d4fd (diff), 848dafc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 2 added
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkbd/Makefile
r63d4d4fd rcd83f25 31 31 32 32 LIBS = \ 33 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 34 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 35 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 $(LIBDRV_PREFIX)/libdrv.a 36 37 EXTRA_CFLAGS = \ 37 38 -I$(LIBUSB_PREFIX)/include \ 38 39 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBDRV_PREFIX)/include 40 -I$(LIBDRV_PREFIX)/include \ 41 -I$(LIBUSBHID_PREFIX)/include 40 42 41 43 SOURCES = \ -
uspace/app/mkbd/main.c
r63d4d4fd rcd83f25 45 45 #include <devmap.h> 46 46 #include <usb/dev/hub.h> 47 #include <usb/hc.h> 47 //#include <usb/host.h> 48 //#include <usb/driver.h> 49 #include <usb/hid/iface.h> 48 50 #include <usb/dev/pipes.h> 51 #include <async.h> 52 #include <usb/hid/usages/core.h> 53 #include <usb/hid/hidparser.h> 54 #include <usb/hid/hiddescriptor.h> 55 #include <usb/hid/usages/consumer.h> 56 #include <assert.h> 49 57 50 58 #define NAME "mkbd" … … 52 60 static int dev_phone = -1; 53 61 54 //static void print_found_hc(size_t class_index, const char *path) 55 //{ 56 // // printf(NAME ": host controller %zu is `%s'.\n", class_index, path); 57 // printf("Bus %02zu: %s\n", class_index, path); 58 //} 59 //static void print_found_dev(usb_address_t addr, const char *path) 60 //{ 61 // // printf(NAME ": device with address %d is `%s'.\n", addr, path); 62 // printf(" Device %02d: %s\n", addr, path); 63 //} 64 65 //static void print_hc_devices(devman_handle_t hc_handle) 66 //{ 67 // int rc; 68 // usb_hc_connection_t conn; 69 70 // usb_hc_connection_initialize(&conn, hc_handle); 71 // rc = usb_hc_connection_open(&conn); 72 // if (rc != EOK) { 73 // printf(NAME ": failed to connect to HC: %s.\n", 74 // str_error(rc)); 75 // return; 62 static int initialize_report_parser(int dev_phone, usb_hid_report_t **report) 63 { 64 *report = (usb_hid_report_t *)malloc(sizeof(usb_hid_report_t)); 65 if (*report == NULL) { 66 return ENOMEM; 67 } 68 69 int rc = usb_hid_report_init(*report); 70 if (rc != EOK) { 71 usb_hid_free_report(*report); 72 *report = NULL; 73 printf("usb_hid_report_init() failed.\n"); 74 return rc; 75 } 76 77 // get the report descriptor length from the device 78 size_t report_desc_size; 79 rc = usbhid_dev_get_report_descriptor_length( 80 dev_phone, &report_desc_size); 81 if (rc != EOK) { 82 usb_hid_free_report(*report); 83 *report = NULL; 84 printf("usbhid_dev_get_report_descriptor_length() failed.\n"); 85 return rc; 86 } 87 88 if (report_desc_size == 0) { 89 usb_hid_free_report(*report); 90 *report = NULL; 91 printf("usbhid_dev_get_report_descriptor_length() returned 0.\n"); 92 return EINVAL; // TODO: other error code? 93 } 94 95 uint8_t *desc = (uint8_t *)malloc(report_desc_size); 96 if (desc == NULL) { 97 usb_hid_free_report(*report); 98 *report = NULL; 99 return ENOMEM; 100 } 101 102 // get the report descriptor from the device 103 size_t actual_size; 104 rc = usbhid_dev_get_report_descriptor(dev_phone, desc, report_desc_size, 105 &actual_size); 106 if (rc != EOK) { 107 usb_hid_free_report(*report); 108 *report = NULL; 109 free(desc); 110 printf("usbhid_dev_get_report_descriptor() failed.\n"); 111 return rc; 112 } 113 114 if (actual_size != report_desc_size) { 115 usb_hid_free_report(*report); 116 *report = NULL; 117 free(desc); 118 printf("usbhid_dev_get_report_descriptor() returned wrong size:" 119 " %zu, expected: %zu.\n", actual_size, report_desc_size); 120 return EINVAL; // TODO: other error code? 121 } 122 123 // initialize the report parser 124 125 rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size); 126 free(desc); 127 128 if (rc != EOK) { 129 free(desc); 130 printf("usb_hid_parse_report_descriptor() failed.\n"); 131 return rc; 132 } 133 134 return EOK; 135 } 136 137 static void print_key(uint8_t *buffer, size_t size, usb_hid_report_t *report) 138 { 139 assert(buffer != NULL); 140 assert(report != NULL); 141 142 // printf("Calling usb_hid_parse_report() with size %zu and " 143 // "buffer: \n", size); 144 // for (size_t i = 0; i < size; ++i) { 145 // printf(" %X ", buffer[i]); 76 146 // } 77 // usb_address_t addr; 78 // for (addr = 1; addr < 5; addr++) { 79 // devman_handle_t dev_handle; 80 // rc = usb_hc_get_handle_by_address(&conn, addr, &dev_handle); 81 // if (rc != EOK) { 82 // continue; 83 // } 84 // char path[MAX_PATH_LENGTH]; 85 // rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH); 86 // if (rc != EOK) { 87 // continue; 88 // } 89 // print_found_dev(addr, path); 90 // } 91 // usb_hc_connection_close(&conn); 92 //} 93 94 static bool try_parse_class_and_address(const char *path, 95 devman_handle_t *out_hc_handle, usb_address_t *out_device_address) 96 { 97 size_t class_index; 98 size_t address; 99 int rc; 100 char *ptr; 101 102 rc = str_size_t(path, &ptr, 10, false, &class_index); 103 if (rc != EOK) { 104 return false; 105 } 106 if ((*ptr == ':') || (*ptr == '.')) { 107 ptr++; 108 } else { 109 return false; 110 } 111 rc = str_size_t(ptr, NULL, 10, true, &address); 112 if (rc != EOK) { 113 return false; 114 } 115 rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle); 116 if (rc != EOK) { 117 return false; 118 } 119 if (out_device_address != NULL) { 120 *out_device_address = (usb_address_t) address; 121 } 122 return true; 147 // printf("\n"); 148 149 uint8_t report_id; 150 int rc = usb_hid_parse_report(report, buffer, size, &report_id); 151 if (rc != EOK) { 152 // printf("Error parsing report: %s\n", str_error(rc)); 153 return; 154 } 155 156 usb_hid_report_path_t *path = usb_hid_report_path(); 157 if (path == NULL) { 158 return; 159 } 160 161 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 162 163 usb_hid_report_path_set_report_id(path, report_id); 164 165 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 166 report, NULL, path, USB_HID_PATH_COMPARE_END 167 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 168 USB_HID_REPORT_TYPE_INPUT); 169 170 // printf("Field: %p\n", field); 171 172 while (field != NULL) { 173 // printf("Field usage: %u, field value: %d\n", field->usage, 174 // field->value); 175 if (field->value != 0) { 176 const char *key_str = 177 usbhid_multimedia_usage_to_str(field->usage); 178 printf("Pressed key: %s\n", key_str); 179 } 180 181 field = usb_hid_report_get_sibling( 182 report, field, path, USB_HID_PATH_COMPARE_END 183 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 184 USB_HID_REPORT_TYPE_INPUT); 185 // printf("Next field: %p\n", field); 186 } 187 188 usb_hid_report_path_free(path); 123 189 } 124 190 125 static bool resolve_hc_handle_and_dev_addr(const char *devpath, 126 devman_handle_t *out_hc_handle, usb_address_t *out_device_address) 127 { 128 int rc; 129 130 /* Hack for QEMU to save-up on typing ;-). */ 131 if (str_cmp(devpath, "qemu") == 0) { 132 devpath = "/hw/pci0/00:01.2/uhci-rh/usb00_a1"; 133 } 134 135 /* Hack for virtual keyboard. */ 136 if (str_cmp(devpath, "virt") == 0) { 137 devpath = "/virt/usbhc/usb00_a1/usb00_a2"; 138 } 139 140 if (try_parse_class_and_address(devpath, 141 out_hc_handle, out_device_address)) { 142 return true; 143 } 144 145 char *path = str_dup(devpath); 146 if (path == NULL) { 147 return ENOMEM; 148 } 149 150 devman_handle_t hc = 0; 151 bool hc_found = false; 152 usb_address_t addr = 0; 153 bool addr_found = false; 154 155 /* Remove suffixes and hope that we will encounter device node. */ 156 while (str_length(path) > 0) { 157 /* Get device handle first. */ 158 devman_handle_t dev_handle; 159 rc = devman_device_get_handle(path, &dev_handle, 0); 160 if (rc != EOK) { 161 free(path); 162 return false; 163 } 164 165 /* Try to find its host controller. */ 166 if (!hc_found) { 167 rc = usb_hc_find(dev_handle, &hc); 168 if (rc == EOK) { 169 hc_found = true; 170 } 171 } 172 /* Try to get its address. */ 173 if (!addr_found) { 174 addr = usb_hc_get_address_by_handle(dev_handle); 175 if (addr >= 0) { 176 addr_found = true; 177 } 178 } 179 180 /* Speed-up. */ 181 if (hc_found && addr_found) { 182 break; 183 } 184 185 /* Remove the last suffix. */ 186 char *slash_pos = str_rchr(path, '/'); 187 if (slash_pos != NULL) { 188 *slash_pos = 0; 189 } 190 } 191 192 free(path); 193 194 if (hc_found && addr_found) { 195 if (out_hc_handle != NULL) { 196 *out_hc_handle = hc; 197 } 198 if (out_device_address != NULL) { 199 *out_device_address = addr; 200 } 201 return true; 202 } else { 203 return false; 204 } 205 } 191 #define MAX_PATH_LENGTH 1024 206 192 207 193 static void print_usage(char *app_name) … … 209 195 #define _INDENT " " 210 196 211 212 213 197 printf(NAME ": Print out what multimedia keys were pressed.\n\n"); 198 printf("Usage: %s device\n", app_name); 199 printf(_INDENT "The device is a devman path to the device.\n"); 214 200 215 201 #undef _OPTION … … 219 205 int main(int argc, char *argv[]) 220 206 { 207 int act_event = -1; 221 208 222 209 if (argc <= 1) { … … 225 212 } 226 213 227 char *devpath = argv[1]; 228 229 /* The initialization is here only to make compiler happy. */ 230 devman_handle_t hc_handle = 0; 231 usb_address_t dev_addr = 0; 232 bool found = resolve_hc_handle_and_dev_addr(devpath, 233 &hc_handle, &dev_addr); 234 if (!found) { 235 fprintf(stderr, NAME ": device `%s' not found " 236 "or not of USB kind. Exiting.\n", devpath); 237 return -1; 238 } 214 //char *devpath = argv[1]; 215 const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID1/hid"; 239 216 240 217 int rc; 241 usb_hc_connection_t conn; 242 243 usb_hc_connection_initialize(&conn, hc_handle); 244 rc = usb_hc_connection_open(&conn); 245 if (rc != EOK) { 246 printf(NAME ": failed to connect to HC: %s.\n", 218 219 devman_handle_t dev_handle = 0; 220 rc = devman_device_get_handle(devpath, &dev_handle, 0); 221 if (rc != EOK) { 222 printf("Failed to get handle from devman: %s.\n", 247 223 str_error(rc)); 248 return -1; 249 } 250 usb_address_t addr = 0; 251 252 devman_handle_t dev_handle; 253 rc = usb_hc_get_handle_by_address(&conn, addr, &dev_handle); 254 if (rc != EOK) { 255 printf(NAME ": failed getting handle to the device: %s.\n", 256 str_error(rc)); 257 return -1; 258 } 259 260 usb_hc_connection_close(&conn); 224 return rc; 225 } 261 226 262 227 rc = devman_device_connect(dev_handle, 0); 263 228 if (rc < 0) { 264 printf(NAME ": failed to connect to the device : %s.\n",265 str_error(rc));266 return -1;229 printf(NAME ": failed to connect to the device (handle %" 230 PRIun "): %s.\n", dev_handle, str_error(rc)); 231 return rc; 267 232 } 268 233 269 234 dev_phone = rc; 270 printf("Got phone to the device: %d\n", dev_phone); 271 272 273 // size_t class_index = 0; 274 // size_t failed_attempts = 0; 275 276 // while (failed_attempts < MAX_FAILED_ATTEMPTS) { 277 // class_index++; 278 // devman_handle_t hc_handle = 0; 279 // int rc = usb_ddf_get_hc_handle_by_class(class_index, &hc_handle); 280 // if (rc != EOK) { 281 // failed_attempts++; 282 // continue; 283 // } 284 // char path[MAX_PATH_LENGTH]; 285 // rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH); 286 // if (rc != EOK) { 287 // continue; 288 // } 289 // print_found_hc(class_index, path); 290 // print_hc_devices(hc_handle); 291 // } 235 // printf("Got phone to the device: %d\n", dev_phone); 236 237 char path[MAX_PATH_LENGTH]; 238 rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH); 239 if (rc != EOK) { 240 return ENOMEM; 241 } 242 243 printf("Device path: %s\n", path); 244 245 246 usb_hid_report_t *report = NULL; 247 rc = initialize_report_parser(dev_phone, &report); 248 if (rc != EOK) { 249 printf("Failed to initialize report parser: %s\n", 250 str_error(rc)); 251 return rc; 252 } 253 254 assert(report != NULL); 255 256 size_t size; 257 rc = usbhid_dev_get_event_length(dev_phone, &size); 258 if (rc != EOK) { 259 printf("Failed to get event length: %s.\n", str_error(rc)); 260 return rc; 261 } 262 263 // printf("Event length: %zu\n", size); 264 uint8_t *event = (uint8_t *)malloc(size); 265 if (event == NULL) { 266 // hangup phone? 267 return ENOMEM; 268 } 269 270 // printf("Event length: %zu\n", size); 271 272 size_t actual_size; 273 int event_nr; 274 275 while (1) { 276 // get event from the driver 277 // printf("Getting event from the driver.\n"); 278 279 /** @todo Try blocking call. */ 280 rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size, 281 &event_nr, 0); 282 if (rc != EOK) { 283 // hangup phone? 284 printf("Error in getting event from the HID driver:" 285 "%s.\n", str_error(rc)); 286 break; 287 } 288 289 // printf("Got buffer: %p, size: %zu, max size: %zu\n", event, 290 // actual_size, size); 291 292 // printf("Event number: %d, my actual event: %d\n", event_nr, 293 // act_event); 294 if (event_nr > act_event) { 295 print_key(event, size, report); 296 act_event = event_nr; 297 } 298 299 async_usleep(100000); 300 } 292 301 293 302 return 0; -
uspace/drv/usbhid/generic/hiddev.c
r63d4d4fd rcd83f25 62 62 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 63 63 64 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,65 size_t size, size_t *act_size, unsigned int flags);64 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 65 size_t size, size_t *act_size, int *event_nr, unsigned int flags); 66 66 67 67 static int usb_generic_hid_client_connected(ddf_fun_t *fun); 68 69 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun); 70 71 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 72 size_t size, size_t *actual_size); 68 73 69 74 /*----------------------------------------------------------------------------*/ … … 71 76 static usbhid_iface_t usb_generic_iface = { 72 77 .get_event = usb_generic_hid_get_event, 73 .get_event_length = usb_generic_hid_get_event_length 78 .get_event_length = usb_generic_hid_get_event_length, 79 .get_report_descriptor_length = usb_generic_get_report_descriptor_length, 80 .get_report_descriptor = usb_generic_get_report_descriptor 74 81 }; 75 82 … … 83 90 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 84 91 { 85 if (fun == NULL || fun->driver_data) { 92 usb_log_debug2("Generic HID: Get event length (fun: %p, " 93 "fun->driver_data: %p.\n", fun, fun->driver_data); 94 95 if (fun == NULL || fun->driver_data == NULL) { 86 96 return 0; 87 97 } … … 89 99 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 90 100 91 return hid_dev->input_report_size; 92 } 93 94 /*----------------------------------------------------------------------------*/ 95 96 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 97 size_t size, size_t *act_size, unsigned int flags) 98 { 99 if (fun == NULL || fun->driver_data) { 101 usb_log_debug2("hid_dev: %p, Max input report size (%d).\n", 102 hid_dev, hid_dev->max_input_report_size); 103 104 return hid_dev->max_input_report_size; 105 } 106 107 /*----------------------------------------------------------------------------*/ 108 109 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 110 size_t size, size_t *act_size, int *event_nr, unsigned int flags) 111 { 112 usb_log_debug2("Generic HID: Get event.\n"); 113 114 if (fun == NULL || fun->driver_data == NULL || buffer == NULL 115 || act_size == NULL || event_nr == NULL) { 116 usb_log_debug("No function"); 100 117 return EINVAL; 101 118 } … … 104 121 105 122 if (hid_dev->input_report_size > size) { 123 usb_log_debug("input_report_size > size (%zu, %zu)\n", 124 hid_dev->input_report_size, size); 106 125 return EINVAL; // TODO: other error code 107 126 } 108 127 109 128 /*! @todo This should probably be atomic. */ 110 if (usb_hid_report_ready()) { 111 memcpy(buffer, hid_dev->input_report, 112 hid_dev->input_report_size); 113 *act_size = hid_dev->input_report_size; 114 usb_hid_report_received(); 115 } 129 // if (usb_hid_report_ready()) { 130 // usb_log_debug2("Report ready, size: %zu\n", 131 // hid_dev->input_report_size); 132 133 // usb_hid_report_received(); 134 // } else { 135 // memset(buffer, 0, hid_dev->input_report_size); 136 // } 137 memcpy(buffer, hid_dev->input_report, 138 hid_dev->input_report_size); 139 *act_size = hid_dev->input_report_size; 140 *event_nr = usb_hid_report_number(hid_dev); 116 141 117 142 // clear the buffer so that it will not be received twice … … 120 145 // note that we already received this report 121 146 // report_received = true; 147 usb_log_debug2("OK\n"); 148 149 return EOK; 150 } 151 152 /*----------------------------------------------------------------------------*/ 153 154 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun) 155 { 156 usb_log_debug("Generic HID: Get report descriptor length.\n"); 157 158 if (fun == NULL || fun->driver_data == NULL) { 159 usb_log_debug("No function"); 160 return EINVAL; 161 } 162 163 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 164 165 usb_log_debug2("hid_dev->report_desc_size = %zu\n", 166 hid_dev->report_desc_size); 167 168 return hid_dev->report_desc_size; 169 } 170 171 /*----------------------------------------------------------------------------*/ 172 173 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 174 size_t size, size_t *actual_size) 175 { 176 usb_log_debug2("Generic HID: Get report descriptor.\n"); 177 178 if (fun == NULL || fun->driver_data == NULL) { 179 usb_log_debug("No function"); 180 return EINVAL; 181 } 182 183 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 184 185 if (hid_dev->report_desc_size > size) { 186 return EINVAL; // TODO: other error code 187 } 188 189 memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size); 190 *actual_size = hid_dev->report_desc_size; 122 191 123 192 return EOK; … … 128 197 static int usb_generic_hid_client_connected(ddf_fun_t *fun) 129 198 { 130 usb_ hid_report_received();199 usb_log_debug("Generic HID: Client connected.\n"); 131 200 return EOK; 132 201 } … … 145 214 return ENOMEM; 146 215 } 216 217 fun->ops = &usb_generic_hid_ops; 218 fun->driver_data = hid_dev; 147 219 148 220 int rc = ddf_fun_bind(fun); … … 154 226 } 155 227 156 fun->ops = &usb_generic_hid_ops; 157 fun->driver_data = hid_dev; 228 usb_log_debug("HID function created. Handle: %d\n", fun->handle); 158 229 159 230 return EOK; … … 176 247 uint8_t *buffer, size_t buffer_size) 177 248 { 178 usb_log_debug ("usb_hid_polling_callback(%p, %p, %zu)\n",249 usb_log_debug2("usb_hid_polling_callback(%p, %p, %zu)\n", 179 250 hid_dev, buffer, buffer_size); 180 251 usb_debug_str_buffer(buffer, buffer_size, 0); -
uspace/drv/usbhid/kbd/kbddev.c
r63d4d4fd rcd83f25 798 798 } 799 799 800 usb_log_debug("%s function created. Handle: %d\n", HID_KBD_FUN_NAME, 801 fun->handle); 802 800 803 usb_log_debug("Adding DDF function to class %s...\n", 801 804 HID_KBD_CLASS_NAME); -
uspace/drv/usbhid/multimedia/keymap.c
r63d4d4fd rcd83f25 48 48 */ 49 49 static int usb_hid_keymap_consumer[0x29c] = { 50 [0xf] = KC_F1, /* Just for testing purposes */51 [0x5] = KC_F2, /* Just for testing purposes */52 [0x8] = KC_F3, /* Just for testing purposes */53 [0x6] = KC_F4, /* Just for testing purposes */54 [0x7] = KC_F5, /* Just for testing purposes */55 [0xc] = KC_F6, /* Just for testing purposes */56 57 50 [0xb5] = 0, /* Scan Next Track */ 58 51 [0xb6] = 0, /* Scan Previous Track */ 59 52 [0xb7] = 0, /* Stop */ 60 53 [0xb8] = 0, /* Eject */ 61 [0xcd] = KC_F2, /* Play/Pause */62 [0xe2] = KC_F3, /* Mute */63 [0xe9] = KC_F5, /* Volume Increment */64 [0xea] = KC_F4, /* Volume Decrement */65 [0x183] = 0 , /* AL Consumer Control Configuration */54 [0xcd] = 0/*KC_F2*/, /* Play/Pause */ 55 [0xe2] = 0/*KC_F3*/, /* Mute */ 56 [0xe9] = 0/*KC_F5*/, /* Volume Increment */ 57 [0xea] = 0/*KC_F4*/, /* Volume Decrement */ 58 [0x183] = 0/*KC_F1*/, /* AL Consumer Control Configuration */ 66 59 [0x18a] = 0, /* AL Email Reader */ 67 60 [0x192] = 0, /* AL Calculator */ 68 61 [0x221] = 0, /* AC Search */ 69 [0x223] = 0 , /* AC Home */62 [0x223] = 0/*KC_F6*/, /* AC Home */ 70 63 [0x224] = 0, /* AC Back */ 71 64 [0x225] = 0, /* AC Forward */ 72 65 [0x226] = 0, /* AC Stop */ 73 [0x227] = KC_F1, /* AC Refresh */ 74 [0x22a] = KC_F6 /* AC Bookmarks */ 75 }; 76 77 static const char *usb_hid_consumer_usage_str[0x29d] = { 78 [0x01] = "Consumer Control", 79 [0x02] = "Numeric Key Pad", 80 [0x03] = "Programmable Buttons", 81 [0x04] = "Microphone", 82 [0x05] = "Headphone", 83 [0x06] = "Graphic Equalizer", 84 [0x07] = "Reserved", 85 [0x08] = "Reserved", 86 [0x09] = "Reserved", 87 [0x0a] = "Reserved", 88 [0x0b] = "Reserved", 89 [0x0c] = "Reserved", 90 [0x0d] = "Reserved", 91 [0x0e] = "Reserved", 92 [0x0f] = "Reserved", 93 [0x10] = "Reserved", 94 [0x11] = "Reserved", 95 [0x12] = "Reserved", 96 [0x13] = "Reserved", 97 [0x14] = "Reserved", 98 [0x15] = "Reserved", 99 [0x16] = "Reserved", 100 [0x17] = "Reserved", 101 [0x18] = "Reserved", 102 [0x19] = "Reserved", 103 [0x1a] = "Reserved", 104 [0x1b] = "Reserved", 105 [0x1c] = "Reserved", 106 [0x1d] = "Reserved", 107 [0x1e] = "Reserved", 108 [0x1f] = "Reserved", 109 [0x20] = "+10", 110 [0x21] = "+100", 111 [0x22] = "AM/PM", 112 [0x23] = "Reserved", 113 [0x24] = "Reserved", 114 [0x25] = "Reserved", 115 [0x26] = "Reserved", 116 [0x27] = "Reserved", 117 [0x28] = "Reserved", 118 [0x29] = "Reserved", 119 [0x2a] = "Reserved", 120 [0x2b] = "Reserved", 121 [0x2c] = "Reserved", 122 [0x2d] = "Reserved", 123 [0x2e] = "Reserved", 124 [0x2f] = "Reserved", 125 [0x30] = "Reserved", 126 [0x31] = "Reserved", 127 [0x32] = "Reserved", 128 [0x33] = "Reserved", 129 [0x34] = "Reserved", 130 [0x35] = "Reserved", 131 [0x36] = "Reserved", 132 [0x37] = "Reserved", 133 [0x38] = "Reserved", 134 [0x39] = "Reserved", 135 [0x3a] = "Reserved", 136 [0x3b] = "Reserved", 137 [0x3c] = "Reserved", 138 [0x3d] = "Reserved", 139 [0x3e] = "Reserved", 140 [0x3f] = "Reserved", 141 [0x40] = "Menu", 142 [0x41] = "Menu Pick", 143 [0x42] = "Menu Up", 144 [0x43] = "Menu Down", 145 [0x44] = "Menu Left", 146 [0x45] = "Menu Right", 147 [0x46] = "Menu Escape", 148 [0x47] = "Menu Value Increase", 149 [0x48] = "Menu Value Decrease", 150 [0x49] = "Reserved", 151 [0x4a] = "Reserved", 152 [0x4b] = "Reserved", 153 [0x4c] = "Reserved", 154 [0x4d] = "Reserved", 155 [0x4e] = "Reserved", 156 [0x4f] = "Reserved", 157 [0x50] = "Reserved", 158 [0x51] = "Reserved", 159 [0x52] = "Reserved", 160 [0x53] = "Reserved", 161 [0x54] = "Reserved", 162 [0x55] = "Reserved", 163 [0x56] = "Reserved", 164 [0x57] = "Reserved", 165 [0x58] = "Reserved", 166 [0x59] = "Reserved", 167 [0x5a] = "Reserved", 168 [0x5b] = "Reserved", 169 [0x5c] = "Reserved", 170 [0x5d] = "Reserved", 171 [0x5e] = "Reserved", 172 [0x5f] = "Reserved", 173 [0x60] = "Data On Screen", 174 [0x61] = "Closed Caption", 175 [0x62] = "Closed Caption Select", 176 [0x63] = "VCR/TV", 177 [0x64] = "Broadcast Mode", 178 [0x65] = "Snapshot", 179 [0x66] = "Still", 180 [0x67] = "Reserved", 181 [0x68] = "Reserved", 182 [0x69] = "Reserved", 183 [0x6a] = "Reserved", 184 [0x6b] = "Reserved", 185 [0x6c] = "Reserved", 186 [0x6d] = "Reserved", 187 [0x6e] = "Reserved", 188 [0x6f] = "Reserved", 189 [0x70] = "Reserved", 190 [0x71] = "Reserved", 191 [0x72] = "Reserved", 192 [0x73] = "Reserved", 193 [0x74] = "Reserved", 194 [0x75] = "Reserved", 195 [0x76] = "Reserved", 196 [0x77] = "Reserved", 197 [0x78] = "Reserved", 198 [0x79] = "Reserved", 199 [0x7a] = "Reserved", 200 [0x7b] = "Reserved", 201 [0x7c] = "Reserved", 202 [0x7d] = "Reserved", 203 [0x7e] = "Reserved", 204 [0x7f] = "Reserved", 205 [0x80] = "Selection", 206 [0x81] = "Assign Selection", 207 [0x82] = "Mode Step", 208 [0x83] = "Recall Last", 209 [0x84] = "Enter Channel", 210 [0x85] = "Order Movie", 211 [0x86] = "Channel", 212 [0x87] = "Media Selection", 213 [0x88] = "Media Select Computer", 214 [0x89] = "Media Select TV", 215 [0x8a] = "Media Select WWW", 216 [0x8b] = "Media Select DVD", 217 [0x8c] = "Media Select Telephone", 218 [0x8d] = "Media Select Program Guide", 219 [0x8e] = "Media Select Video Phone", 220 [0x8f] = "Media Select Games", 221 [0x90] = "Media Select Messages", 222 [0x91] = "Media Select CD", 223 [0x92] = "Media Select VCR", 224 [0x93] = "Media Select Tuner", 225 [0x94] = "Quit", 226 [0x95] = "Help", 227 [0x96] = "Media Select Tape", 228 [0x97] = "Media Select Cable", 229 [0x98] = "Media Select Satellite", 230 [0x99] = "Media Select Security", 231 [0x9a] = "Media Select Home", 232 [0x9b] = "Media Select Call", 233 [0x9c] = "Channel Increment", 234 [0x9d] = "Channel Decrement", 235 [0x9e] = "Media Select SAP", 236 [0x9f] = "Reserved", 237 [0xa0] = "VCR Plus", 238 [0xa1] = "Once", 239 [0xa2] = "Daily", 240 [0xa3] = "Weekly", 241 [0xa4] = "Monthly", 242 [0xa5] = "Reserved", 243 [0xa6] = "Reserved", 244 [0xa7] = "Reserved", 245 [0xa8] = "Reserved", 246 [0xa9] = "Reserved", 247 [0xaa] = "Reserved", 248 [0xab] = "Reserved", 249 [0xac] = "Reserved", 250 [0xad] = "Reserved", 251 [0xae] = "Reserved", 252 [0xaf] = "Reserved", 253 [0xb0] = "Play", 254 [0xb1] = "Pause", 255 [0xb2] = "Record", 256 [0xb3] = "Fast Forward", 257 [0xb4] = "Rewind", 258 [0xb5] = "Scan Next Track", 259 [0xb6] = "Scan Previous Trac", 260 [0xb7] = "Stop", 261 [0xb8] = "Eject", 262 [0xb9] = "Random Play", 263 [0xba] = "Select Disc", 264 [0xbb] = "Enter Disc", 265 [0xbc] = "Repeat", 266 [0xbd] = "Tracking", 267 [0xbe] = "Track Normal", 268 [0xbf] = "Slow Tracking", 269 [0xc0] = "Frame Forward", 270 [0xc1] = "Frame Back", 271 [0xc2] = "Mark", 272 [0xc3] = "Clear Mark", 273 [0xc4] = "Repeat From Mark", 274 [0xc5] = "Return to Mark", 275 [0xc6] = "Search Mark Forward", 276 [0xc7] = "Search Mark Backwards", 277 [0xc8] = "Counter Reset", 278 [0xc9] = "Show Counter", 279 [0xca] = "Tracking Increment", 280 [0xcb] = "Tracking Decrement", 281 [0xcc] = "Stop/Eject", 282 [0xcd] = "Play/Pause", 283 [0xce] = "Play/Skip", 284 [0xcf] = "Reserved", 285 [0xd0] = "Reserved", 286 [0xd1] = "Reserved", 287 [0xd2] = "Reserved", 288 [0xd3] = "Reserved", 289 [0xd4] = "Reserved", 290 [0xd5] = "Reserved", 291 [0xd6] = "Reserved", 292 [0xd7] = "Reserved", 293 [0xd8] = "Reserved", 294 [0xd9] = "Reserved", 295 [0xda] = "Reserved", 296 [0xdb] = "Reserved", 297 [0xdc] = "Reserved", 298 [0xdd] = "Reserved", 299 [0xde] = "Reserved", 300 [0xdf] = "Reserved", 301 [0xe0] = "Volume", 302 [0xe1] = "Balance", 303 [0xe2] = "Mute", 304 [0xe3] = "Bass", 305 [0xe4] = "Treble", 306 [0xe5] = "Bass Boost", 307 [0xe6] = "Surround Mode", 308 [0xe7] = "Loudness", 309 [0xe8] = "MPX", 310 [0xe9] = "Volume Increment", 311 [0xea] = "Volume Decrement", 312 [0xeb] = "Reserved", 313 [0xec] = "Reserved", 314 [0xed] = "Reserved", 315 [0xee] = "Reserved", 316 [0xef] = "Reserved", 317 [0xf0] = "Speed Select", 318 [0xf1] = "Playback Speed", 319 [0xf2] = "Standard Play", 320 [0xf3] = "Long Play", 321 [0xf4] = "Extended Play", 322 [0xf5] = "Slow", 323 [0xf6] = "Reserved", 324 [0xf7] = "Reserved", 325 [0xf8] = "Reserved", 326 [0xf9] = "Reserved", 327 [0xfa] = "Reserved", 328 [0xfb] = "Reserved", 329 [0xfc] = "Reserved", 330 [0xfd] = "Reserved", 331 [0xfe] = "Reserved", 332 [0xff] = "Reserved", 333 [0x100] = "Fan Enable", 334 [0x101] = "Fan Speed", 335 [0x102] = "Light Enable", 336 [0x103] = "Light Illumination Level", 337 [0x104] = "Climate Control Enable", 338 [0x105] = "Room Temperature", 339 [0x106] = "Security Enable", 340 [0x107] = "Fire Alarm", 341 [0x108] = "Police Alarm", 342 [0x109] = "Proximity", 343 [0x10a] = "Motion", 344 [0x10b] = "Duress Alarm", 345 [0x10c] = "Holdup Alarm", 346 [0x10d] = "Medical Alarm", 347 [0x10e] = "Reserved", 348 [0x10f] = "Reserved", 349 [0x110] = "Reserved", 350 [0x111] = "Reserved", 351 [0x112] = "Reserved", 352 [0x113] = "Reserved", 353 [0x114] = "Reserved", 354 [0x115] = "Reserved", 355 [0x116] = "Reserved", 356 [0x117] = "Reserved", 357 [0x118] = "Reserved", 358 [0x119] = "Reserved", 359 [0x11a] = "Reserved", 360 [0x11b] = "Reserved", 361 [0x11c] = "Reserved", 362 [0x11d] = "Reserved", 363 [0x11e] = "Reserved", 364 [0x11f] = "Reserved", 365 [0x120] = "Reserved", 366 [0x121] = "Reserved", 367 [0x122] = "Reserved", 368 [0x123] = "Reserved", 369 [0x124] = "Reserved", 370 [0x125] = "Reserved", 371 [0x126] = "Reserved", 372 [0x127] = "Reserved", 373 [0x128] = "Reserved", 374 [0x129] = "Reserved", 375 [0x12a] = "Reserved", 376 [0x12b] = "Reserved", 377 [0x12c] = "Reserved", 378 [0x12d] = "Reserved", 379 [0x12e] = "Reserved", 380 [0x12f] = "Reserved", 381 [0x130] = "Reserved", 382 [0x131] = "Reserved", 383 [0x132] = "Reserved", 384 [0x133] = "Reserved", 385 [0x134] = "Reserved", 386 [0x135] = "Reserved", 387 [0x136] = "Reserved", 388 [0x137] = "Reserved", 389 [0x138] = "Reserved", 390 [0x139] = "Reserved", 391 [0x13a] = "Reserved", 392 [0x13b] = "Reserved", 393 [0x13c] = "Reserved", 394 [0x13d] = "Reserved", 395 [0x13e] = "Reserved", 396 [0x13f] = "Reserved", 397 [0x140] = "Reserved", 398 [0x141] = "Reserved", 399 [0x142] = "Reserved", 400 [0x143] = "Reserved", 401 [0x144] = "Reserved", 402 [0x145] = "Reserved", 403 [0x146] = "Reserved", 404 [0x147] = "Reserved", 405 [0x148] = "Reserved", 406 [0x149] = "Reserved", 407 [0x14a] = "Reserved", 408 [0x14b] = "Reserved", 409 [0x14c] = "Reserved", 410 [0x14d] = "Reserved", 411 [0x14e] = "Reserved", 412 [0x14f] = "Reserved", 413 [0x150] = "Balance Right", 414 [0x151] = "Balance Left", 415 [0x152] = "Bass Increment", 416 [0x153] = "Bass Decrement", 417 [0x154] = "Treble Increment", 418 [0x155] = "Treble Decrement", 419 [0x156] = "Reserved", 420 [0x157] = "Reserved", 421 [0x158] = "Reserved", 422 [0x159] = "Reserved", 423 [0x15a] = "Reserved", 424 [0x15b] = "Reserved", 425 [0x15c] = "Reserved", 426 [0x15d] = "Reserved", 427 [0x15e] = "Reserved", 428 [0x15f] = "Reserved", 429 [0x160] = "Speaker System", 430 [0x161] = "Channel Left", 431 [0x162] = "Channel Right", 432 [0x163] = "Channel Center", 433 [0x164] = "Channel Front", 434 [0x165] = "Channel Center Front", 435 [0x166] = "Channel Side", 436 [0x167] = "Channel Surround", 437 [0x168] = "Channel Low Frequency Enhancement", 438 [0x169] = "Channel Top", 439 [0x16a] = "Channel Unknown", 440 [0x16b] = "Reserved", 441 [0x16c] = "Reserved", 442 [0x16d] = "Reserved", 443 [0x16e] = "Reserved", 444 [0x16f] = "Reserved", 445 [0x170] = "Sub-channel", 446 [0x171] = "Sub-channel Increment", 447 [0x172] = "Sub-channel Decrement", 448 [0x173] = "Alternate Audio Increment", 449 [0x174] = "Alternate Audio Decrement", 450 [0x175] = "Reserved", 451 [0x176] = "Reserved", 452 [0x177] = "Reserved", 453 [0x178] = "Reserved", 454 [0x179] = "Reserved", 455 [0x17a] = "Reserved", 456 [0x17b] = "Reserved", 457 [0x17c] = "Reserved", 458 [0x17d] = "Reserved", 459 [0x17e] = "Reserved", 460 [0x17f] = "Reserved", 461 [0x180] = "Application Launch Buttons", 462 [0x181] = "AL Launch Buttion Configuration Tool", 463 [0x182] = "AL Programmable Button Configuration", 464 [0x183] = "AL Consumer Control Configuration", 465 [0x184] = "AL Word Processor", 466 [0x185] = "AL Text Editor", 467 [0x186] = "AL Spreadsheet", 468 [0x187] = "AL Graphics Editor", 469 [0x188] = "AL Presentation App", 470 [0x189] = "AL Database App", 471 [0x18a] = "AL Email Reader", 472 [0x18b] = "AL Newsreader", 473 [0x18c] = "AL Voicemail", 474 [0x18d] = "AL Contacts/Address Book", 475 [0x18e] = "AL Calendar/Schedule", 476 [0x18f] = "AL Task/Project Manager", 477 [0x190] = "AL Log/Journal/Timecard", 478 [0x191] = "AL Checkbook/Finance", 479 [0x192] = "AL Calculator", 480 [0x193] = "AL A/V Capture/Playback", 481 [0x194] = "AL Local Machine Browser", 482 [0x195] = "AL LAN/WAN Browser", 483 [0x196] = "AL Internet Browser", 484 [0x197] = "AL Remote Networking/ISP Connect", 485 [0x198] = "AL Network Conference", 486 [0x199] = "AL Network Chat", 487 [0x19a] = "AL Telephony/Dialer", 488 [0x19b] = "AL Logon", 489 [0x19c] = "AL Logoff", 490 [0x19d] = "AL Logon/Logoff", 491 [0x19e] = "AL Terminal Lock/Screensaver", 492 [0x19f] = "AL Control Panel", 493 [0x1a0] = "AL Command Line Processor/Run", 494 [0x1a1] = "AL Process/Task Manager", 495 [0x1a2] = "AL Select Task/Application", 496 [0x1a3] = "AL Next Task/Application", 497 [0x1a4] = "AL Previous Task/Application", 498 [0x1a5] = "AL Preemptive Halt Task/Application", 499 [0x1a6] = "AL Integrated Help Center", 500 [0x1a7] = "AL Documents", 501 [0x1a8] = "AL Thesaurus", 502 [0x1a9] = "AL Dictionary", 503 [0x1aa] = "AL Desktop", 504 [0x1ab] = "AL Spell Check", 505 [0x1ac] = "AL Grammar Check", 506 [0x1ad] = "AL Wireless Status", 507 [0x1ae] = "AL Keyboard Layout", 508 [0x1af] = "AL Virus Protection", 509 [0x1b0] = "AL Encryption", 510 [0x1b1] = "AL Screen Saver", 511 [0x1b2] = "AL Alarms", 512 [0x1b3] = "AL Clock", 513 [0x1b4] = "AL File Browser", 514 [0x1b5] = "AL Power Status", 515 [0x1b6] = "AL Image Browser", 516 [0x1b7] = "AL Audio Browser", 517 [0x1b8] = "AL Movie Browser", 518 [0x1b9] = "AL Digital Rights Manager", 519 [0x1ba] = "AL Digital Wallet", 520 [0x1bb] = "Reserved", 521 [0x1bc] = "AL Instant Messaging", 522 [0x1bd] = "AL OEM Features Tips/Tutorial Browser", 523 [0x1be] = "AL OEM Help", 524 [0x1bf] = "AL Online Community", 525 [0x1c0] = "AL Entertainment Content Browser", 526 [0x1c1] = "AL Online Shopping Browser", 527 [0x1c2] = "AL SmartCard Information/Help", 528 [0x1c3] = "AL Market Monitor/Finance Browser", 529 [0x1c4] = "AL Customized Corporate News Browser", 530 [0x1c5] = "AL Online Activity Browser", 531 [0x1c6] = "AL Research/Search Browser", 532 [0x1c7] = "AL Audio Player", 533 [0x1c8] = "Reserved", 534 [0x1c9] = "Reserved", 535 [0x1ca] = "Reserved", 536 [0x1cb] = "Reserved", 537 [0x1cc] = "Reserved", 538 [0x1cd] = "Reserved", 539 [0x1ce] = "Reserved", 540 [0x1cf] = "Reserved", 541 [0x1d0] = "Reserved", 542 [0x1d1] = "Reserved", 543 [0x1d2] = "Reserved", 544 [0x1d3] = "Reserved", 545 [0x1d4] = "Reserved", 546 [0x1d5] = "Reserved", 547 [0x1d6] = "Reserved", 548 [0x1d7] = "Reserved", 549 [0x1d8] = "Reserved", 550 [0x1d9] = "Reserved", 551 [0x1da] = "Reserved", 552 [0x1db] = "Reserved", 553 [0x1dc] = "Reserved", 554 [0x1dd] = "Reserved", 555 [0x1de] = "Reserved", 556 [0x1df] = "Reserved", 557 [0x1e0] = "Reserved", 558 [0x1e1] = "Reserved", 559 [0x1e2] = "Reserved", 560 [0x1e3] = "Reserved", 561 [0x1e4] = "Reserved", 562 [0x1e5] = "Reserved", 563 [0x1e6] = "Reserved", 564 [0x1e7] = "Reserved", 565 [0x1e8] = "Reserved", 566 [0x1e9] = "Reserved", 567 [0x1ea] = "Reserved", 568 [0x1eb] = "Reserved", 569 [0x1ec] = "Reserved", 570 [0x1ed] = "Reserved", 571 [0x1ee] = "Reserved", 572 [0x1ef] = "Reserved", 573 [0x1f0] = "Reserved", 574 [0x1f1] = "Reserved", 575 [0x1f2] = "Reserved", 576 [0x1f3] = "Reserved", 577 [0x1f4] = "Reserved", 578 [0x1f5] = "Reserved", 579 [0x1f6] = "Reserved", 580 [0x1f7] = "Reserved", 581 [0x1f8] = "Reserved", 582 [0x1f9] = "Reserved", 583 [0x1fa] = "Reserved", 584 [0x1fb] = "Reserved", 585 [0x1fc] = "Reserved", 586 [0x1fd] = "Reserved", 587 [0x1fe] = "Reserved", 588 [0x1ff] = "Reserved", 589 [0x200] = "Generic GUI Application Controls", 590 [0x201] = "AC New", 591 [0x202] = "AC Open", 592 [0x203] = "AC Close", 593 [0x204] = "AC Exit", 594 [0x205] = "AC Maximize", 595 [0x206] = "AC Minimize", 596 [0x207] = "AC Save", 597 [0x208] = "AC Print", 598 [0x209] = "AC Properties", 599 [0x20a] = "", 600 [0x20b] = "", 601 [0x20c] = "", 602 [0x20d] = "", 603 [0x20e] = "", 604 [0x20f] = "", 605 [0x210] = "", 606 [0x211] = "", 607 [0x212] = "", 608 [0x213] = "", 609 [0x214] = "", 610 [0x215] = "", 611 [0x216] = "", 612 [0x217] = "", 613 [0x218] = "", 614 [0x219] = "", 615 [0x21a] = "AC Undo", 616 [0x21b] = "AC Copy", 617 [0x21c] = "AC Cut", 618 [0x21d] = "AC Paste", 619 [0x21e] = "AC Select All", 620 [0x21f] = "AC Find", 621 [0x220] = "AC Find and Replace", 622 [0x221] = "AC Search", 623 [0x222] = "AC Go To", 624 [0x223] = "AC Home", 625 [0x224] = "AC Back", 626 [0x225] = "AC Forward", 627 [0x226] = "AC Stop", 628 [0x227] = "AC Refresh", 629 [0x228] = "AC Previous Link", 630 [0x229] = "AC Next Link", 631 [0x22a] = "AC Bookmarks", 632 [0x22b] = "AC History", 633 [0x22c] = "AC Subscriptions", 634 [0x22d] = "AC Zoom In", 635 [0x22e] = "AC Zoom Out", 636 [0x22f] = "AC Zoom", 637 [0x230] = "AC Full Screen View", 638 [0x231] = "AC Normal View", 639 [0x232] = "AC View Toggle", 640 [0x233] = "AC Scroll Up", 641 [0x234] = "AC Scroll Down", 642 [0x235] = "AC Scroll", 643 [0x236] = "AC Pan Left", 644 [0x237] = "AC Pan Right", 645 [0x238] = "AC Pan", 646 [0x239] = "AC New Window", 647 [0x23a] = "AC Tile Horizontally", 648 [0x23b] = "AC Tile Vertically", 649 [0x23c] = "AC Format", 650 [0x23d] = "AC Edit", 651 [0x23e] = "AC Bold", 652 [0x23f] = "AC Italics", 653 [0x240] = "AC Undeline", 654 [0x241] = "AC Strikethrough", 655 [0x242] = "AC Subscript", 656 [0x243] = "AC Superscript", 657 [0x244] = "AC All Caps", 658 [0x245] = "AC Rotate", 659 [0x246] = "AC Resize", 660 [0x247] = "AC Flip Horizontal", 661 [0x248] = "AC Flip Vertical", 662 [0x249] = "AC Mirror Horizontal", 663 [0x24a] = "AC Mirror Vertical", 664 [0x24b] = "AC Font Select", 665 [0x24c] = "AC Font Color", 666 [0x24d] = "AC Font Size", 667 [0x24e] = "AC Justify Left", 668 [0x24f] = "AC Justify Center H", 669 [0x250] = "AC Justify Right", 670 [0x251] = "AC Justify Block H", 671 [0x252] = "AC Justify Top", 672 [0x253] = "AC Justify Center V", 673 [0x254] = "AC Justify Bottom", 674 [0x255] = "AC Justify Block V", 675 [0x256] = "AC Indent Decrease", 676 [0x257] = "AC Indent Increase", 677 [0x258] = "AC Numbered List", 678 [0x259] = "AC Restart Numbering", 679 [0x25a] = "AC Bulleted List", 680 [0x25b] = "AC Promote", 681 [0x25c] = "AC Demote", 682 [0x25d] = "AC Yes", 683 [0x25e] = "AC No", 684 [0x25f] = "AC Cancel", 685 [0x260] = "AC Catalog", 686 [0x261] = "AC Buy/Checkout", 687 [0x262] = "AC Add to Cart", 688 [0x263] = "AC Expand", 689 [0x264] = "AC Expand All", 690 [0x265] = "AC Collapse", 691 [0x266] = "AC Collapse All", 692 [0x267] = "AC Print Preview", 693 [0x268] = "AC Paste Special", 694 [0x269] = "AC Insert Mode", 695 [0x26a] = "AC Delete", 696 [0x26b] = "AC Lock", 697 [0x26c] = "AC Unlock", 698 [0x26d] = "AC Protect", 699 [0x26e] = "AC Unprotect", 700 [0x26f] = "AC Attach Comment", 701 [0x270] = "AC Delete Comment", 702 [0x271] = "AC View Comment", 703 [0x272] = "AC Select Word", 704 [0x273] = "AC Select Sentence", 705 [0x274] = "AC Select Paragraph", 706 [0x275] = "AC Select Column", 707 [0x276] = "AC Select Row", 708 [0x277] = "AC Select Table", 709 [0x278] = "AC Select Object", 710 [0x279] = "AC Redo/Repeat", 711 [0x27a] = "AC Sort", 712 [0x27b] = "AC Sort Ascending", 713 [0x27c] = "AC Sort Descending", 714 [0x27d] = "AC Filter", 715 [0x27e] = "AC Set Clock", 716 [0x27f] = "AC View Clock", 717 [0x280] = "AC Select Time Zone", 718 [0x281] = "AC Edit Time Zones", 719 [0x282] = "AC Set Alarm", 720 [0x283] = "AC Clear Alarm", 721 [0x284] = "AC Snooze Alarm", 722 [0x285] = "AC Reset Alarm", 723 [0x286] = "AC Synchronize", 724 [0x287] = "AC Send/Receive", 725 [0x288] = "AC Send To", 726 [0x289] = "AC Reply", 727 [0x28a] = "AC Reply All", 728 [0x28b] = "AC Forward Msg", 729 [0x28c] = "AC Send", 730 [0x28d] = "AC Attach File", 731 [0x28e] = "AC Upload", 732 [0x28f] = "AC Download (Save Target As)", 733 [0x290] = "AC Set Borders", 734 [0x291] = "AC Insert Row", 735 [0x292] = "AC Insert Column", 736 [0x293] = "AC Insert File", 737 [0x294] = "AC Insert Picture", 738 [0x295] = "AC Insert Object", 739 [0x296] = "AC Insert Symbol", 740 [0x297] = "AC Save and Close", 741 [0x298] = "AC Rename", 742 [0x299] = "AC Merge", 743 [0x29a] = "AC Split", 744 [0x29b] = "AC Distrubute Horizontally", 745 [0x29c] = "AC Distrubute Vertically" 66 [0x227] = 0, /* AC Refresh */ 67 [0x22a] = 0 /* AC Bookmarks */ 746 68 }; 747 69 … … 769 91 770 92 /** 771 * Translates USB HID Usages from the Consumer Page into their string772 * representation.773 *774 * @param usage USB HID Consumer Page Usage number.775 *776 * @retval HelenOS key code corresponding to the given USB Consumer Page Usage.777 */778 const char *usb_multimedia_usage_to_str(int usage)779 {780 size_t map_length = sizeof(usb_hid_consumer_usage_str) / sizeof(char *);781 782 if ((usage < 0) || ((size_t)usage >= map_length))783 return "Unknown usage";784 785 /*! @todo What if the usage is not in the table? */786 return usb_hid_consumer_usage_str[usage];787 }788 789 /**790 93 * @} 791 94 */ -
uspace/drv/usbhid/multimedia/keymap.h
r63d4d4fd rcd83f25 39 39 unsigned int usb_multimedia_map_usage(int usage); 40 40 41 const char *usb_multimedia_usage_to_str(int usage);42 43 41 #endif /* USB_HID_MULTIMEDIA_KEYMAP_H_ */ 44 42 -
uspace/drv/usbhid/multimedia/multimedia.c
r63d4d4fd rcd83f25 43 43 #include <usb/debug.h> 44 44 #include <usb/hid/usages/core.h> 45 #include <usb/hid/usages/consumer.h> 45 46 46 47 #include <errno.h> … … 58 59 typedef struct usb_multimedia_t { 59 60 /** Previously pressed keys (not translated to key codes). */ 60 int32_t *keys_old;61 //int32_t *keys_old; 61 62 /** Currently pressed keys (not translated to key codes). */ 62 int32_t *keys;63 //int32_t *keys; 63 64 /** Count of stored keys (i.e. number of keys in the report). */ 64 size_t key_count;65 //size_t key_count; 65 66 /** IPC phone to the console device (for sending key events). */ 66 67 int console_phone; … … 174 175 175 176 // free all buffers 176 if ((*multim_dev)->keys != NULL) {177 free((*multim_dev)->keys);178 }179 if ((*multim_dev)->keys_old != NULL) {180 free((*multim_dev)->keys_old);181 }177 // if ((*multim_dev)->keys != NULL) { 178 // free((*multim_dev)->keys); 179 // } 180 // if ((*multim_dev)->keys_old != NULL) { 181 // free((*multim_dev)->keys_old); 182 // } 182 183 183 184 free(*multim_dev); … … 209 210 return rc; 210 211 } 212 213 usb_log_debug("%s function created. Handle: %d\n", NAME, fun->handle); 211 214 212 215 rc = ddf_fun_add_to_class(fun, "keyboard"); … … 241 244 multim_dev->console_phone = -1; 242 245 243 usb_hid_report_path_t *path = usb_hid_report_path();244 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);245 246 usb_hid_report_path_set_report_id(path, 1);247 248 multim_dev->key_count = usb_hid_report_size(249 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);250 251 usb_hid_report_path_free(path);252 253 usb_log_debug(NAME " Size of the input report: %zu\n",254 multim_dev->key_count);255 256 multim_dev->keys = (int32_t *)calloc(multim_dev->key_count,257 sizeof(int32_t));258 259 if (multim_dev->keys == NULL) {260 usb_log_fatal("No memory!\n");261 free(multim_dev);262 return ENOMEM;263 }264 265 multim_dev->keys_old =266 (int32_t *)calloc(multim_dev->key_count, sizeof(int32_t));267 268 if (multim_dev->keys_old == NULL) {269 usb_log_fatal("No memory!\n");270 free(multim_dev->keys);271 free(multim_dev);272 return ENOMEM;273 }246 // usb_hid_report_path_t *path = usb_hid_report_path(); 247 // usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 248 249 // usb_hid_report_path_set_report_id(path, 1); 250 251 // multim_dev->key_count = usb_hid_report_size( 252 // hid_dev->report, 1, USB_HID_REPORT_TYPE_INPUT); 253 254 // usb_hid_report_path_free(path); 255 256 // usb_log_debug(NAME " Size of the input report: %zu\n", 257 // multim_dev->key_count); 258 259 // multim_dev->keys = (int32_t *)calloc(multim_dev->key_count, 260 // sizeof(int32_t)); 261 262 // if (multim_dev->keys == NULL) { 263 // usb_log_fatal("No memory!\n"); 264 // free(multim_dev); 265 // return ENOMEM; 266 // } 267 268 // multim_dev->keys_old = 269 // (int32_t *)calloc(multim_dev->key_count, sizeof(int32_t)); 270 271 // if (multim_dev->keys_old == NULL) { 272 // usb_log_fatal("No memory!\n"); 273 // free(multim_dev->keys); 274 // free(multim_dev); 275 // return ENOMEM; 276 // } 274 277 275 278 /*! @todo Autorepeat */ … … 357 360 usb_multimedia_map_usage(field->usage); 358 361 const char *key_str = 359 usb _multimedia_usage_to_str(field->usage);362 usbhid_multimedia_usage_to_str(field->usage); 360 363 usb_log_info("Pressed key: %s\n", key_str); 361 364 usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, -
uspace/drv/usbhid/subdrivers.c
r63d4d4fd rcd83f25 38 38 #include <usb/hid/hidpath.h> 39 39 40 //#include "lgtch-ultrax/lgtch-ultrax.h"41 40 #include "multimedia/multimedia.h" 42 41 #include "mouse/mousedev.h" 42 #include "generic/hiddev.h" 43 43 44 44 static usb_hid_subdriver_usage_t path_kbd[] = { … … 58 58 }; 59 59 60 //static usb_hid_subdriver_usage_t generic_hid_key_path[] = { 61 // {0, 0} 62 //}; 63 60 64 const usb_hid_subdriver_mapping_t usb_hid_subdrivers[] = { 61 65 { 62 66 path_kbd, 63 -1,67 0, 64 68 USB_HID_PATH_COMPARE_BEGIN, 65 69 -1, … … 88 92 { 89 93 path_mouse, 90 -1,94 0, 91 95 USB_HID_PATH_COMPARE_BEGIN, 92 96 -1, … … 99 103 } 100 104 }, 105 // { 106 // generic_hid_key_path, 107 // 0, 108 // USB_HID_PATH_COMPARE_ANYWHERE, 109 // -1, 110 // -1, 111 // { 112 // .init = usb_generic_hid_init, 113 // .deinit = NULL, 114 // .poll = usb_generic_hid_polling_callback, 115 // .poll_end = NULL 116 // } 117 // }, 101 118 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}} 102 119 }; -
uspace/drv/usbhid/usbhid.c
r63d4d4fd rcd83f25 63 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 64 65 static fibril_local bool report_received; 65 /** @todo What happens if this is not fibril local? */ 66 //static fibril_local bool report_number; 66 67 67 68 /*----------------------------------------------------------------------------*/ … … 234 235 } 235 236 236 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count * 237 // add one generic HID subdriver per device 238 239 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 237 240 sizeof(usb_hid_subdriver_t)); 238 241 if (hid_dev->subdrivers == NULL) { … … 247 250 } 248 251 249 hid_dev->subdriver_count = count; 252 hid_dev->subdrivers[count].init = usb_generic_hid_init; 253 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 254 hid_dev->subdrivers[count].deinit = NULL; 255 hid_dev->subdrivers[count].poll_end = NULL; 256 257 hid_dev->subdriver_count = count + 1; 250 258 251 259 return EOK; … … 307 315 308 316 if (matched) { 317 usb_log_debug("Subdriver matched.\n"); 309 318 subdrivers[count++] = &mapping->subdriver; 310 319 } … … 348 357 /*----------------------------------------------------------------------------*/ 349 358 359 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 360 { 361 assert(hid_dev != NULL && hid_dev->report != NULL); 362 363 uint8_t report_id = 0; 364 size_t size;/* = usb_hid_report_byte_size(hid_dev->report, report_id, 365 USB_HID_REPORT_TYPE_INPUT);*/ 366 367 size_t max_size = 0; 368 369 do { 370 size = usb_hid_report_byte_size(hid_dev->report, report_id, 371 USB_HID_REPORT_TYPE_INPUT); 372 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 373 max_size = (size > max_size) ? size : max_size; 374 report_id = usb_hid_get_next_report_id(hid_dev->report, 375 report_id, USB_HID_REPORT_TYPE_INPUT); 376 } while (report_id != 0); 377 378 usb_log_debug("Max size of input report: %zu\n", max_size); 379 380 hid_dev->max_input_report_size = max_size; 381 assert(hid_dev->input_report == NULL); 382 383 hid_dev->input_report = malloc(max_size); 384 if (hid_dev->input_report == NULL) { 385 return ENOMEM; 386 } 387 memset(hid_dev->input_report, 0, max_size); 388 389 return EOK; 390 } 391 392 /*----------------------------------------------------------------------------*/ 393 350 394 usb_hid_dev_t *usb_hid_new(void) 351 395 { … … 402 446 /* Get the report descriptor and parse it. */ 403 447 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 404 hid_dev->report );448 hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size); 405 449 406 450 bool fallback = false; … … 483 527 } 484 528 529 // save max input report size and allocate space for the report 530 rc = usb_hid_init_report(hid_dev); 531 if (rc != EOK) { 532 usb_log_error("Failed to initialize input report buffer.\n"); 533 } 534 485 535 return rc; 486 536 } … … 500 550 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 501 551 502 int allocated = (hid_dev->input_report != NULL); 503 504 if (!allocated 505 || hid_dev->input_report_size < buffer_size) { 506 uint8_t *input_old = hid_dev->input_report; 507 uint8_t *input_new = (uint8_t *)malloc(buffer_size); 508 509 if (input_new == NULL) { 510 usb_log_error("Failed to allocate space for input " 511 "buffer. This event may not be reported\n"); 512 memset(hid_dev->input_report, 0, 513 hid_dev->input_report_size); 514 } else { 515 memcpy(input_new, input_old, 516 hid_dev->input_report_size); 517 hid_dev->input_report = input_new; 518 if (allocated) { 519 free(input_old); 520 } 521 usb_hid_new_report(); 522 } 523 } 552 // int allocated = (hid_dev->input_report != NULL); 553 assert(hid_dev->input_report != NULL); 554 usb_log_debug("Max input report size: %zu, buffer size: %zu\n", 555 hid_dev->max_input_report_size, buffer_size); 556 assert(hid_dev->max_input_report_size >= buffer_size); 557 558 // if (/*!allocated*/ 559 // /*|| *//*hid_dev->input_report_size < buffer_size*/) { 560 // uint8_t *input_old = hid_dev->input_report; 561 // uint8_t *input_new = (uint8_t *)malloc(buffer_size); 562 563 // if (input_new == NULL) { 564 // usb_log_error("Failed to allocate space for input " 565 // "buffer. This event may not be reported\n"); 566 // memset(hid_dev->input_report, 0, 567 // hid_dev->input_report_size); 568 // } else { 569 // memcpy(input_new, input_old, 570 // hid_dev->input_report_size); 571 // hid_dev->input_report = input_new; 572 // if (allocated) { 573 // free(input_old); 574 // } 575 // usb_hid_new_report(); 576 // } 577 // } 524 578 525 579 /*! @todo This should probably be atomic. */ 526 580 memcpy(hid_dev->input_report, buffer, buffer_size); 527 581 hid_dev->input_report_size = buffer_size; 582 usb_hid_new_report(hid_dev); 528 583 529 584 bool cont = false; … … 601 656 /*----------------------------------------------------------------------------*/ 602 657 603 void usb_hid_new_report(void) 604 { 605 report_received = false; 606 } 607 608 /*----------------------------------------------------------------------------*/ 609 610 void usb_hid_report_received(void) 611 { 612 report_received = true; 613 } 614 615 /*----------------------------------------------------------------------------*/ 616 617 bool usb_hid_report_ready(void) 618 { 619 return !report_received; 620 } 658 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 659 { 660 ++hid_dev->report_nr; 661 } 662 663 /*----------------------------------------------------------------------------*/ 664 665 int usb_hid_report_number(usb_hid_dev_t *hid_dev) 666 { 667 return hid_dev->report_nr; 668 } 669 670 /*----------------------------------------------------------------------------*/ 671 672 //void usb_hid_report_received(void) 673 //{ 674 // ++report_number; 675 //} 676 677 /*----------------------------------------------------------------------------*/ 678 679 //bool usb_hid_report_ready(void) 680 //{ 681 // return !report_received; 682 //} 621 683 622 684 /*----------------------------------------------------------------------------*/ -
uspace/drv/usbhid/usbhid.h
r63d4d4fd rcd83f25 98 98 99 99 size_t input_report_size; 100 size_t max_input_report_size; 101 102 int report_nr; 100 103 } usb_hid_dev_t; 101 104 … … 127 130 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev); 128 131 129 void usb_hid_new_report( void);132 void usb_hid_new_report(usb_hid_dev_t *hid_dev); 130 133 131 void usb_hid_report_received(void);134 int usb_hid_report_number(usb_hid_dev_t *hid_dev); 132 135 133 bool usb_hid_report_ready(void); 136 //void usb_hid_report_received(void); 137 138 //bool usb_hid_report_ready(void); 134 139 135 140 void usb_hid_free(usb_hid_dev_t **hid_dev); -
uspace/lib/drv/Makefile
r63d4d4fd rcd83f25 40 40 generic/remote_usb.c \ 41 41 generic/remote_pci.c \ 42 generic/remote_usbhc.c 42 generic/remote_usbhc.c \ 43 generic/remote_usbhid.c 43 44 44 45 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/drv/generic/dev_iface.c
r63d4d4fd rcd83f25 46 46 #include "remote_pci.h" 47 47 48 #include <stdio.h> 49 48 50 static iface_dipatch_table_t remote_ifaces = { 49 51 .ifaces = { … … 60 62 { 61 63 assert(is_valid_iface_idx(idx)); 64 62 65 return remote_ifaces.ifaces[idx]; 63 66 } -
uspace/lib/drv/generic/driver.c
r63d4d4fd rcd83f25 405 405 /* The interface has not such method */ 406 406 printf("%s: driver_connection_gen error - " 407 "invalid interface method.", driver->name); 407 "invalid interface method (%d).\n", 408 driver->name, iface_method_idx); 408 409 async_answer_0(callid, ENOTSUP); 409 410 break; -
uspace/lib/drv/generic/remote_usbhid.c
r63d4d4fd rcd83f25 36 36 #include <errno.h> 37 37 #include <assert.h> 38 #include <stdio.h> 38 39 39 40 #include "usbhid_iface.h" … … 42 43 static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 43 44 static void remote_usbhid_get_event(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 static void remote_usbhid_get_report_descriptor_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 46 static void remote_usbhid_get_report_descriptor(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 44 47 // static void remote_usbhid_(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 48 … … 47 50 static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = { 48 51 remote_usbhid_get_event_length, 49 remote_usbhid_get_event 52 remote_usbhid_get_event, 53 remote_usbhid_get_report_descriptor_length, 54 remote_usbhid_get_report_descriptor 50 55 }; 51 56 … … 58 63 }; 59 64 60 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;65 //usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 61 66 62 67 … … 64 69 ipc_callid_t callid, ipc_call_t *call) 65 70 { 71 printf("remote_usbhid_get_event_length()\n"); 72 66 73 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface; 67 74 68 75 if (!hid_iface->get_event_length) { 69 async_answer_0(callid, ENOTSUP); 70 return; 71 } 72 73 int len = hid_iface->get_event_length(fun); 74 if (len == 0) { 75 len = EEMPTY; 76 } 77 if (len < 0) { 78 async_answer_0(callid, len); 79 } else { 80 async_answer_1(callid, EOK, len); 81 } 76 printf("Get event length not set!\n"); 77 async_answer_0(callid, ENOTSUP); 78 return; 79 } 80 81 size_t len = hid_iface->get_event_length(fun); 82 // if (len == 0) { 83 // len = EEMPTY; 84 // } 85 async_answer_1(callid, EOK, len); 86 87 // if (len < 0) { 88 // async_answer_0(callid, len); 89 // } else { 90 // async_answer_1(callid, EOK, len); 91 // } 82 92 } 83 93 … … 100 110 return; 101 111 } 102 /* Check that length is even number. Truncate otherwise. */103 if ((len % 2) == 1) {104 len--;105 }112 // /* Check that length is even number. Truncate otherwise. */ 113 // if ((len % 2) == 1) { 114 // len--; 115 // } 106 116 if (len == 0) { 107 117 async_answer_0(data_callid, EINVAL); 108 118 async_answer_0(callid, EINVAL); 119 return; 109 120 } 110 121 111 122 int rc; 112 123 113 size_t items = len / 2; 114 uint16_t *usage_pages_and_usages = malloc(sizeof(uint16_t) * len); 115 if (usage_pages_and_usages == NULL) { 124 uint8_t *data = malloc(len); 125 if (data == NULL) { 116 126 async_answer_0(data_callid, ENOMEM); 117 127 async_answer_0(callid, ENOMEM); 118 } 119 120 size_t act_items; 121 int rc = hid_iface->get_event(fun, usage_pages_and_usages, 122 usage_pages_and_usages + items, items, &act_items, flags); 128 return; 129 } 130 131 size_t act_length; 132 int event_nr; 133 rc = hid_iface->get_event(fun, data, len, &act_length, &event_nr, flags); 123 134 if (rc != EOK) { 124 free( usage_pages_and_usages);135 free(data); 125 136 async_answer_0(data_callid, rc); 126 137 async_answer_0(callid, rc); 127 } 128 if (act_items >= items) { 138 return; 139 } 140 if (act_length >= len) { 129 141 /* This shall not happen. */ 130 142 // FIXME: how about an assert here? 131 act_items = items; 132 } 133 134 async_data_read_finalize(data_callid, usage_pages_and_usages, 135 act_items * 2 * sizeof(uint16_t)); 136 137 free(usage_pages_and_usages); 138 143 act_length = len; 144 } 145 146 async_data_read_finalize(data_callid, data, act_length); 147 148 free(data); 149 150 async_answer_1(callid, EOK, event_nr); 151 } 152 153 void remote_usbhid_get_report_descriptor_length(ddf_fun_t *fun, void *iface, 154 ipc_callid_t callid, ipc_call_t *call) 155 { 156 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface; 157 158 if (!hid_iface->get_report_descriptor_length) { 159 async_answer_0(callid, ENOTSUP); 160 return; 161 } 162 163 size_t len = hid_iface->get_report_descriptor_length(fun); 164 async_answer_1(callid, EOK, (sysarg_t) len); 165 } 166 167 void remote_usbhid_get_report_descriptor(ddf_fun_t *fun, void *iface, 168 ipc_callid_t callid, ipc_call_t *call) 169 { 170 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface; 171 172 if (!hid_iface->get_report_descriptor) { 173 async_answer_0(callid, ENOTSUP); 174 return; 175 } 176 177 size_t len; 178 ipc_callid_t data_callid; 179 if (!async_data_read_receive(&data_callid, &len)) { 180 async_answer_0(callid, EINVAL); 181 return; 182 } 183 184 if (len == 0) { 185 async_answer_0(data_callid, EINVAL); 186 async_answer_0(callid, EINVAL); 187 return; 188 } 189 190 uint8_t *descriptor = malloc(len); 191 if (descriptor == NULL) { 192 async_answer_0(data_callid, ENOMEM); 193 async_answer_0(callid, ENOMEM); 194 return; 195 } 196 197 size_t act_len = 0; 198 int rc = hid_iface->get_report_descriptor(fun, descriptor, len, 199 &act_len); 200 if (act_len > len) { 201 rc = ELIMIT; 202 } 203 if (rc != EOK) { 204 free(descriptor); 205 async_answer_0(data_callid, rc); 206 async_answer_0(callid, rc); 207 return; 208 } 209 210 async_data_read_finalize(data_callid, descriptor, act_len); 139 211 async_answer_0(callid, EOK); 140 } 212 213 free(descriptor); 214 } 215 216 141 217 142 218 /** -
uspace/lib/drv/include/remote_usbhid.h
r63d4d4fd rcd83f25 36 36 #define LIBDRV_REMOTE_USBHID_H_ 37 37 38 remote_iface_t remote_usbhid_iface;38 extern remote_iface_t remote_usbhid_iface; 39 39 40 40 #endif -
uspace/lib/drv/include/usbhid_iface.h
r63d4d4fd rcd83f25 45 45 * Parameters: none 46 46 * Answer: 47 * - EOK (expected always as long as device support USB HID interface) 48 * Parameters of the answer: 49 * - number of items 47 * - Size of one report in bytes. 50 48 */ 51 49 IPC_M_USBHID_GET_EVENT_LENGTH, … … 63 61 * It is okay if the client requests less data. Extra data must 64 62 * be truncated by the driver. 63 * 64 * @todo Change this comment. 65 65 */ 66 IPC_M_USBHID_GET_EVENT 66 IPC_M_USBHID_GET_EVENT, 67 68 /** Get the size of the report descriptor from the HID device. 69 * 70 * Parameters: 71 * - none 72 * Answer: 73 * - EOK - method is implemented (expected always) 74 * Parameters of the answer: 75 * - Size of the report in bytes. 76 */ 77 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, 78 79 /** Get the report descriptor from the HID device. 80 * 81 * Parameters: 82 * - none 83 * The call is followed by data read expecting the descriptor itself. 84 * Answer: 85 * - EOK - report descriptor returned. 86 */ 87 IPC_M_USBHID_GET_REPORT_DESCRIPTOR 67 88 } usbhid_iface_funcs_t; 68 89 … … 75 96 * 76 97 * @param[in] fun DDF function answering the request. 77 * @return Number of events or error code.98 * @return Size of the event in bytes. 78 99 */ 79 100 size_t (*get_event_length)(ddf_fun_t *fun); … … 87 108 * @return Error code. 88 109 */ 89 int (*get_event)(ddf_fun_t *fun, int32_t *buffer, size_t size, 90 size_t *act_size, unsigned int flags); 110 int (*get_event)(ddf_fun_t *fun, uint8_t *buffer, size_t size, 111 size_t *act_size, int *event_nr, unsigned int flags); 112 113 /** Get size of the report descriptor in bytes. 114 * 115 * @param[in] fun DDF function answering the request. 116 * @return Size of the report descriptor in bytes. 117 */ 118 size_t (*get_report_descriptor_length)(ddf_fun_t *fun); 119 120 /** Get the report descriptor from the HID device. 121 * 122 * @param[in] fun DDF function answering the request. 123 * @param[out] desc Buffer with the report descriptor. 124 * @param[in] size Size of the allocated @p desc buffer. 125 * @param[out] act_size Actual size of the report descriptor returned. 126 * @return Error code. 127 */ 128 int (*get_report_descriptor)(ddf_fun_t *fun, uint8_t *desc, 129 size_t size, size_t *act_size); 91 130 } usbhid_iface_t; 92 131 -
uspace/lib/usbhid/Makefile
r63d4d4fd rcd83f25 41 41 src/hidpath.c \ 42 42 src/hidreport.c \ 43 src/consumer.c \ 43 44 src/hidreq.c 44 45 -
uspace/lib/usbhid/include/usb/hid/hid_report_items.h
r63d4d4fd rcd83f25 96 96 #define USB_HID_ITEM_FLAG_RELATIVE(flags) ((flags & 0x4) == 0x4) 97 97 98 /** 99 * Indicates whether the data “rolls over” when reaching either the extreme 98 /** Indicates whether the data “rolls over” when reaching either the extreme 100 99 * high or low value. For example, a dial that can spin freely 360 degrees 101 100 * might output values from 0 to 10. If Wrap is indicated, the next value -
uspace/lib/usbhid/include/usb/hid/hiddescriptor.h
r63d4d4fd rcd83f25 43 43 44 44 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 45 45 const uint8_t *data, size_t size); 46 46 47 47 void usb_hid_free_report(usb_hid_report_t *report); … … 51 51 int usb_hid_report_init(usb_hid_report_t *report); 52 52 53 int usb_hid_report_append_fields(usb_hid_report_t *report, 54 53 int usb_hid_report_append_fields(usb_hid_report_t *report, 54 usb_hid_report_item_t *report_item); 55 55 56 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type); 56 usb_hid_report_description_t * usb_hid_report_find_description( 57 const usb_hid_report_t *report, uint8_t report_id, 58 usb_hid_report_type_t type); 57 59 58 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 59 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 60 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 61 size_t item_size, usb_hid_report_item_t *report_item, 62 usb_hid_report_path_t *usage_path); 60 63 61 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 62 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 64 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 65 size_t item_size, usb_hid_report_item_t *report_item, 66 usb_hid_report_path_t *usage_path); 63 67 64 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 65 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 68 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 69 size_t item_size, usb_hid_report_item_t *report_item, 70 usb_hid_report_path_t *usage_path); 66 71 67 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 68 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 72 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 73 size_t item_size, usb_hid_report_item_t *report_item, 74 usb_hid_report_path_t *usage_path); 69 75 70 76 void usb_hid_descriptor_print_list(link_t *head); … … 74 80 void usb_hid_free_report_list(link_t *head); 75 81 76 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item); 82 usb_hid_report_item_t *usb_hid_report_item_clone( 83 const usb_hid_report_item_t *item); 77 84 78 85 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 79 86 80 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path); 87 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t*report, 88 usb_hid_report_path_t *cmp_path); 81 89 82 90 -
uspace/lib/usbhid/include/usb/hid/hidparser.h
r63d4d4fd rcd83f25 47 47 * Input report parser functions 48 48 */ 49 /** */ 50 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 51 size_t size, uint8_t *report_id); 49 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 50 size_t size, uint8_t *report_id); 52 51 53 52 /* 54 53 * Output report parser functions 55 54 */ 56 /** Allocates output report buffer*/57 55 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 58 56 uint8_t report_id); 59 57 60 /** Frees output report buffer*/61 58 void usb_hid_report_output_free(uint8_t *output); 62 59 63 /** Returns size of report in items */ 64 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 65 usb_hid_report_type_t type); 60 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 61 usb_hid_report_type_t type); 66 62 67 /** Makes the output report buffer by translated given data */ 68 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 69 uint8_t *buffer, size_t size); 63 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id, 64 usb_hid_report_type_t type); 70 65 71 /** */72 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,73 usb_hid_report_field_t *field,74 usb_hid_report_path_t *path,75 int flags,76 usb_hid_report_type_t type);77 66 78 /** */ 79 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, 80 uint8_t report_id, 81 usb_hid_report_type_t type); 67 int usb_hid_report_output_translate(usb_hid_report_t *report, 68 uint8_t report_id, uint8_t *buffer, size_t size); 69 70 71 /* 72 * Report descriptor structure observing functions 73 */ 74 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 75 usb_hid_report_field_t *field, usb_hid_report_path_t *path, 76 int flags, usb_hid_report_type_t type); 77 78 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, 79 uint8_t report_id, usb_hid_report_type_t type); 82 80 83 81 #endif -
uspace/lib/usbhid/include/usb/hid/hidpath.h
r63d4d4fd rcd83f25 42 42 43 43 /*---------------------------------------------------------------------------*/ 44 /* *44 /* 45 45 * Flags of usage paths comparison modes. 46 46 * 47 47 */ 48 /** Wanted usage path must be exactly the same as the searched one. 49 * Thisoption cannot be combined with the others.48 /** Wanted usage path must be exactly the same as the searched one. This 49 * option cannot be combined with the others. 50 50 */ 51 51 #define USB_HID_PATH_COMPARE_STRICT 0 … … 57 57 58 58 /** 59 * Only usage page are compared along the usage path. 60 * This option can becombined with others.59 * Only usage page are compared along the usage path. This option can be 60 * combined with others. 61 61 */ 62 62 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 2 … … 101 101 int depth; 102 102 103 /** Report id. Zero is reserved and means that report id is not used. */ 103 /** Report id. Zero is reserved and means that report id is not used. 104 * */ 104 105 uint8_t report_id; 105 106 … … 117 118 void usb_hid_report_path_free(usb_hid_report_path_t *path); 118 119 119 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 120 120 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 121 uint8_t report_id); 121 122 122 123 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 123 124 int32_t usage_page, int32_t usage); 124 125 125 126 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); … … 128 129 129 130 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 130 131 int32_t tag, int32_t data); 131 132 132 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 133 133 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 134 usb_hid_report_path_t *path, int flags); 134 135 135 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 136 usb_hid_report_path_t *usb_hid_report_path_clone( 137 usb_hid_report_path_t *usage_path); 136 138 137 139 void usb_hid_print_usage_path(usb_hid_report_path_t *path); -
uspace/lib/usbhid/include/usb/hid/hidreport.h
r63d4d4fd rcd83f25 44 44 * report parser. 45 45 * 46 * \param dev USB device representing a HID device. 47 * \param parser HID Report parser. 46 * \param[in] dev USB device representing a HID device. 47 * \param[in/out] parser HID Report parser. 48 * \param[out] report_desc Place to save report descriptor into. 49 * \param[out] report_size 48 50 * 49 51 * \retval EOK if successful. … … 57 59 */ 58 60 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_t *report );61 usb_hid_report_t *report, uint8_t **report_desc, size_t *report_size); 60 62 61 63 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usbhid/include/usb/hid/hidtypes.h
r63d4d4fd rcd83f25 72 72 73 73 /** 74 * Report type74 * Enum of report types 75 75 */ 76 76 typedef enum { 77 /** Input report. Data are sent from device to system */ 77 78 USB_HID_REPORT_TYPE_INPUT = 1, 79 80 /** Output report. Data are sent from system to device */ 78 81 USB_HID_REPORT_TYPE_OUTPUT = 2, 82 83 /** Feature report. Describes device configuration information that 84 * can be sent to the device */ 79 85 USB_HID_REPORT_TYPE_FEATURE = 3 80 86 } usb_hid_report_type_t; -
uspace/lib/usbhid/include/usb/hid/iface.h
r63d4d4fd rcd83f25 38 38 #include <sys/types.h> 39 39 40 int usbhid_dev_get_event_length(int );41 int usbhid_dev_get_event(int, uint 16_t *, uint16_t *, size_t, size_t *,40 int usbhid_dev_get_event_length(int, size_t *); 41 int usbhid_dev_get_event(int, uint8_t *, size_t, size_t *, int *, 42 42 unsigned int); 43 int usbhid_dev_get_report_descriptor_length(int, size_t *); 44 int usbhid_dev_get_report_descriptor(int, uint8_t *, size_t, size_t *); 43 45 44 46 #endif -
uspace/lib/usbhid/src/hiddescriptor.c
r63d4d4fd rcd83f25 41 41 #include <assert.h> 42 42 43 43 /*---------------------------------------------------------------------------*/ 44 /* 45 * Constants defining current parsing mode for correct parsing of the set of 46 * local tags (usage) enclosed in delimter tags. 47 */ 48 /** 49 * Second delimiter tag was read. The set of local items (usage) ended. 50 */ 44 51 #define OUTSIDE_DELIMITER_SET 0 52 53 /** 54 * First delimiter tag was read. The set of local items (usage) started. 55 */ 45 56 #define START_DELIMITER_SET 1 57 58 /** 59 * Parser is in the set of local items. 60 */ 46 61 #define INSIDE_DELIMITER_SET 2 62 63 /*---------------------------------------------------------------------------*/ 47 64 48 65 /** The new report item flag. Used to determine when the item is completly … … 61 78 #define USB_HID_UNKNOWN_TAG -99 62 79 63 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) 64 { 65 /* find or append current collection path to the list */ 66 //link_t *path_it = report->collection_paths.next; 80 /*---------------------------------------------------------------------------*/ 81 /** 82 * Checks if given collection path is already present in report structure and 83 * inserts it if not. 84 * 85 * @param report Report structure 86 * @param cmp_path The collection path 87 * @return Pointer to the result collection path in report structure. 88 * @retval NULL If some error occurs 89 */ 90 usb_hid_report_path_t *usb_hid_report_path_try_insert( 91 usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) { 92 67 93 link_t *path_it = report->collection_paths.prev->next; 68 94 usb_hid_report_path_t *path = NULL; 69 95 96 if((report == NULL) || (cmp_path == NULL)) { 97 return NULL; 98 } 70 99 71 100 while(path_it != &report->collection_paths) { 72 path = list_get_instance(path_it, usb_hid_report_path_t, link); 73 74 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 101 path = list_get_instance(path_it, usb_hid_report_path_t, 102 link); 103 104 if(usb_hid_report_compare_usage_path(path, cmp_path, 105 USB_HID_PATH_COMPARE_STRICT) == EOK){ 75 106 break; 76 107 } … … 78 109 } 79 110 if(path_it == &report->collection_paths) { 80 path = usb_hid_report_path_clone(cmp_path); 111 path = usb_hid_report_path_clone(cmp_path); 112 if(path == NULL) { 113 return NULL; 114 } 81 115 list_append(&path->link, &report->collection_paths); 82 116 report->collection_paths_count++; … … 85 119 } 86 120 else { 87 return list_get_instance(path_it, usb_hid_report_path_t, link); 88 } 89 } 90 121 return list_get_instance(path_it, usb_hid_report_path_t, 122 link); 123 } 124 } 125 126 /*---------------------------------------------------------------------------*/ 91 127 /** 92 128 * Initialize the report descriptor parser structure … … 94 130 * @param parser Report descriptor parser structure 95 131 * @return Error code 132 * @retval EINVAL If no report structure was given 133 * @retval EOK If report structure was successfully initialized 96 134 */ 97 135 int usb_hid_report_init(usb_hid_report_t *report) … … 109 147 } 110 148 111 112 /* 113 * 114 * 115 */ 116 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 117 { 149 /*---------------------------------------------------------------------------*/ 150 151 /** 152 * 153 * 154 * @param report Report structure in which the new report items should be 155 * stored 156 * @param report_item Current report descriptor's parsing state table 157 * @return Error code 158 * @retval EOK If all fields were successfully append to report 159 * @retval EINVAL If invalid parameters (NULL) was given 160 * @retval ENOMEM If there is no memmory to store new report description 161 * 162 */ 163 int usb_hid_report_append_fields(usb_hid_report_t *report, 164 usb_hid_report_item_t *report_item) { 165 118 166 usb_hid_report_field_t *field; 119 167 int i; … … 121 169 uint32_t *usages; 122 170 int usages_used=0; 171 172 if((report == NULL) || (report_item == NULL)) { 173 return EINVAL; 174 } 175 123 176 if(report_item->usages_count > 0){ 124 177 usages = malloc(sizeof(int32_t) * report_item->usages_count); 125 memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count); 178 memcpy(usages, report_item->usages, sizeof(int32_t) * 179 report_item->usages_count); 126 180 } 127 181 else { … … 144 198 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){ 145 199 /* 146 Store usage array. The Correct Usage Page and Usage is depending147 200 Store usage array. The Correct Usage Page and Usage is 201 depending on data in report and will be filled later 148 202 */ 149 203 field->usage = 0; … … 162 216 } 163 217 else { 164 usage = report_item->usages[report_item->usages_count - 1]; 218 usage = report_item->usages[ 219 report_item->usages_count- 1]; 165 220 } 166 221 167 222 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 168 223 field->usage = USB_HID_EXTENDED_USAGE(usage); 169 field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage); 224 field->usage_page = 225 USB_HID_EXTENDED_USAGE_PAGE(usage); 170 226 } 171 227 else { … … 176 232 } 177 233 178 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page); 179 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage); 180 181 field->collection_path = usb_hid_report_path_try_insert(report, path); 234 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, 235 field->usage_page); 236 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, 237 field->usage); 238 239 field->collection_path = 240 usb_hid_report_path_try_insert(report, path); 182 241 183 242 field->size = report_item->size; 184 243 185 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8; 186 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size; 244 size_t offset_byte = (report_item->offset + (i * 245 report_item->size)) / 8; 246 247 size_t offset_bit = 8 - ((report_item->offset + (i * 248 report_item->size)) % 8) - report_item->size; 187 249 188 250 field->offset = 8 * offset_byte + offset_bit; … … 195 257 /* find the right report list*/ 196 258 usb_hid_report_description_t *report_des; 197 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 259 report_des = usb_hid_report_find_description(report, 260 report_item->id, report_item->type); 261 198 262 if(report_des == NULL){ 199 report_des = malloc(sizeof(usb_hid_report_description_t)); 200 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 263 report_des = malloc( 264 sizeof(usb_hid_report_description_t)); 265 if(report_des == NULL) { 266 return ENOMEM; 267 } 268 269 memset(report_des, 0, 270 sizeof(usb_hid_report_description_t)); 201 271 202 272 report_des->type = report_item->type; 203 273 report_des->report_id = report_item->id; 274 if(report_des->report_id != 0) { 275 /* set up the bit length by report_id field */ 276 report_des->bit_length = 8; 277 } 278 204 279 list_initialize (&report_des->link); 205 280 list_initialize (&report_des->report_items); … … 225 300 return EOK; 226 301 } 227 228 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 229 { 302 /*---------------------------------------------------------------------------*/ 303 /** 304 * Finds description of report with given report_id and of given type in 305 * opaque report structure. 306 * 307 * @param report Opaque structure containing the parsed report descriptor 308 * @param report_id ReportId of report we are searching 309 * @param type Type of report we are searching 310 * @return Pointer to the particular report description 311 * @retval NULL If no description is founded 312 */ 313 usb_hid_report_description_t * usb_hid_report_find_description( 314 const usb_hid_report_t *report, uint8_t report_id, 315 usb_hid_report_type_t type) { 316 230 317 link_t *report_it = report->reports.next; 231 318 usb_hid_report_description_t *report_des = NULL; 232 319 233 320 while(report_it != &report->reports) { 234 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 235 236 if((report_des->report_id == report_id) && (report_des->type == type)){ 321 report_des = list_get_instance(report_it, 322 usb_hid_report_description_t, link); 323 324 if((report_des->report_id == report_id) && 325 (report_des->type == type)) { 237 326 return report_des; 238 327 } … … 243 332 return NULL; 244 333 } 334 /*---------------------------------------------------------------------------*/ 245 335 246 336 /** Parse HID report descriptor. … … 249 339 * @param data Data describing the report. 250 340 * @return Error code. 341 * @retval ENOMEM If no more memmory is available 342 * @retval EINVAL If invalid data are founded 343 * @retval EOK If report descriptor is successfully parsed 251 344 */ 252 345 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 299 392 300 393 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 301 item_size,report_item, usage_path); 394 item_size,report_item, usage_path); 395 302 396 switch(ret){ 303 case USB_HID_NEW_REPORT_ITEM: 304 // store report item to report and create the new one 305 // store current collection path 306 report_item->usage_path = usage_path; 397 case USB_HID_NEW_REPORT_ITEM: 398 /* store report item to report and create the 399 * new one store current collection path 400 */ 401 report_item->usage_path = usage_path; 307 402 308 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 309 if(report_item->id != 0){ 310 report->use_report_ids = 1; 311 } 403 usb_hid_report_path_set_report_id( 404 report_item->usage_path, report_item->id); 405 406 if(report_item->id != 0){ 407 report->use_report_ids = 1; 408 } 312 409 313 switch(tag) { 314 case USB_HID_REPORT_TAG_INPUT: 315 report_item->type = USB_HID_REPORT_TYPE_INPUT; 316 report_item->offset = offset_input; 317 offset_input += report_item->count * report_item->size; 318 break; 319 case USB_HID_REPORT_TAG_OUTPUT: 320 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 321 report_item->offset = offset_output; 322 offset_output += report_item->count * report_item->size; 323 324 break; 325 case USB_HID_REPORT_TAG_FEATURE: 326 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 327 report_item->offset = offset_feature; 328 offset_feature += report_item->count * report_item->size; 329 break; 330 default: 331 usb_log_debug("\tjump over - tag %X\n", tag); 332 break; 333 } 410 switch(tag) { 411 case USB_HID_REPORT_TAG_INPUT: 412 report_item->type = 413 USB_HID_REPORT_TYPE_INPUT; 414 415 report_item->offset = offset_input; 416 offset_input += report_item->count * 417 report_item->size; 418 break; 419 420 case USB_HID_REPORT_TAG_OUTPUT: 421 report_item->type = 422 USB_HID_REPORT_TYPE_OUTPUT; 334 423 335 /* 336 * append new fields to the report 337 * structure 338 */ 339 usb_hid_report_append_fields(report, report_item); 340 341 /* reset local items */ 342 usb_hid_report_reset_local_items (report_item); 343 424 report_item->offset = offset_output; 425 offset_output += report_item->count * 426 report_item->size; 344 427 break; 345 346 case USB_HID_RESET_OFFSET: 347 offset_input = 0; 348 offset_output = 0; 349 offset_feature = 0; 350 usb_hid_report_path_set_report_id (usage_path, report_item->id); 428 429 case USB_HID_REPORT_TAG_FEATURE: 430 report_item->type = 431 USB_HID_REPORT_TYPE_FEATURE; 432 433 report_item->offset = offset_feature; 434 offset_feature += report_item->count * 435 report_item->size; 351 436 break; 352 353 case USB_HID_REPORT_TAG_PUSH: 354 // push current state to stack 355 new_report_item = usb_hid_report_item_clone(report_item); 356 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 357 new_report_item->usage_path = tmp_path; 358 359 list_prepend (&new_report_item->link, &stack); 360 break; 361 case USB_HID_REPORT_TAG_POP: 362 // restore current state from stack 363 if(list_empty (&stack)) { 364 return EINVAL; 365 } 366 free(report_item); 437 438 default: 439 usb_log_debug2( 440 "\tjump over - tag %X\n", tag); 441 break; 442 } 443 444 /* 445 * append new fields to the report structure 446 */ 447 usb_hid_report_append_fields(report, 448 report_item); 449 450 /* reset local items */ 451 usb_hid_report_reset_local_items (report_item); 452 break; 453 454 case USB_HID_RESET_OFFSET: 455 offset_input = 0; 456 offset_output = 0; 457 offset_feature = 0; 458 usb_hid_report_path_set_report_id (usage_path, 459 report_item->id); 460 break; 461 462 case USB_HID_REPORT_TAG_PUSH: 463 // push current state to stack 464 new_report_item = usb_hid_report_item_clone( 465 report_item); 466 467 usb_hid_report_path_t *tmp_path = 468 usb_hid_report_path_clone(usage_path); 469 470 new_report_item->usage_path = tmp_path; 471 472 list_prepend (&new_report_item->link, &stack); 473 break; 474 case USB_HID_REPORT_TAG_POP: 475 // restore current state from stack 476 if(list_empty (&stack)) { 477 return EINVAL; 478 } 479 free(report_item); 367 480 368 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 481 report_item = list_get_instance(stack.next, 482 usb_hid_report_item_t, link); 369 483 370 usb_hid_report_usage_path_t *tmp_usage_path; 371 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 484 usb_hid_report_usage_path_t *tmp_usage_path; 485 tmp_usage_path = list_get_instance( 486 report_item->usage_path->link.prev, 487 usb_hid_report_usage_path_t, link); 372 488 373 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 374 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 375 376 usb_hid_report_path_free(report_item->usage_path); 377 list_initialize(&report_item->usage_path->link); 378 list_remove (stack.next); 489 usb_hid_report_set_last_item(usage_path, 490 USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 491 492 usb_hid_report_set_last_item(usage_path, 493 USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 494 495 usb_hid_report_path_free(report_item->usage_path); 496 list_initialize(&report_item->usage_path->link); 497 list_remove (stack.next); 379 498 380 499 break; 381 500 382 383 384 501 default: 502 // nothing special to do 503 break; 385 504 } 386 505 … … 399 518 } 400 519 520 /*---------------------------------------------------------------------------*/ 401 521 402 522 /** … … 409 529 * @return Code of action to be done next 410 530 */ 411 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 412 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 413 { 531 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 532 size_t item_size, usb_hid_report_item_t *report_item, 533 usb_hid_report_path_t *usage_path) { 534 414 535 int ret; 415 536 416 537 switch(class){ 417 case USB_HID_TAG_CLASS_MAIN: 418 419 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 420 return USB_HID_NEW_REPORT_ITEM; 421 } 422 else { 423 /*TODO process the error */ 424 return ret; 425 } 426 break; 427 428 case USB_HID_TAG_CLASS_GLOBAL: 429 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 430 break; 431 432 case USB_HID_TAG_CLASS_LOCAL: 433 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 434 break; 435 default: 436 return USB_HID_NO_ACTION; 538 case USB_HID_TAG_CLASS_MAIN: 539 540 if((ret=usb_hid_report_parse_main_tag(tag, data, item_size, 541 report_item, usage_path)) == EOK) { 542 543 return USB_HID_NEW_REPORT_ITEM; 544 } 545 else { 546 return ret; 547 } 548 break; 549 550 case USB_HID_TAG_CLASS_GLOBAL: 551 return usb_hid_report_parse_global_tag(tag, data, item_size, 552 report_item, usage_path); 553 break; 554 555 case USB_HID_TAG_CLASS_LOCAL: 556 return usb_hid_report_parse_local_tag(tag, data, item_size, 557 report_item, usage_path); 558 break; 559 560 default: 561 return USB_HID_NO_ACTION; 437 562 } 438 563 } … … 448 573 */ 449 574 450 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 451 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 575 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 576 size_t item_size, usb_hid_report_item_t *report_item, 577 usb_hid_report_path_t *usage_path) 452 578 { 453 579 usb_hid_report_usage_path_t *path_item; … … 455 581 switch(tag) 456 582 { 457 458 459 460 461 462 583 case USB_HID_REPORT_TAG_INPUT: 584 case USB_HID_REPORT_TAG_OUTPUT: 585 case USB_HID_REPORT_TAG_FEATURE: 586 report_item->item_flags = *data; 587 return EOK; 588 break; 463 589 464 case USB_HID_REPORT_TAG_COLLECTION: 465 466 // store collection atributes 467 path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 468 path_item->flags = *data; 590 case USB_HID_REPORT_TAG_COLLECTION: 591 592 /* store collection atributes */ 593 path_item = list_get_instance(usage_path->head.prev, 594 usb_hid_report_usage_path_t, link); 595 path_item->flags = *data; 469 596 470 // set last item 471 usb_hid_report_set_last_item(usage_path, 472 USB_HID_TAG_CLASS_GLOBAL, 473 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1])); 474 usb_hid_report_set_last_item(usage_path, 475 USB_HID_TAG_CLASS_LOCAL, 476 USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1])); 597 /* set last item */ 598 usb_hid_report_set_last_item(usage_path, 599 USB_HID_TAG_CLASS_GLOBAL, 600 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[ 601 report_item->usages_count-1])); 602 603 usb_hid_report_set_last_item(usage_path, 604 USB_HID_TAG_CLASS_LOCAL, 605 USB_HID_EXTENDED_USAGE(report_item->usages[ 606 report_item->usages_count-1])); 477 607 478 // append the new one which will be set by common 479 // usage/usage page 480 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 481 usb_hid_report_reset_local_items (report_item); 482 return USB_HID_NO_ACTION; 483 break; 608 /* append the new one which will be set by common usage/usage 609 * page */ 610 usb_hid_report_path_append_item(usage_path, 611 report_item->usage_page, 612 report_item->usages[report_item->usages_count-1]); 613 614 usb_hid_report_reset_local_items (report_item); 615 return USB_HID_NO_ACTION; 616 break; 484 617 485 case USB_HID_REPORT_TAG_END_COLLECTION: 486 usb_hid_report_remove_last_item(usage_path); 487 return USB_HID_NO_ACTION; 488 break; 489 default: 490 return USB_HID_NO_ACTION; 618 case USB_HID_REPORT_TAG_END_COLLECTION: 619 usb_hid_report_remove_last_item(usage_path); 620 return USB_HID_NO_ACTION; 621 break; 622 623 default: 624 return USB_HID_NO_ACTION; 491 625 } 492 626 … … 503 637 * @return Error code 504 638 */ 505 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,506 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 507 { 508 // TODO take care about the bit length of data639 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 640 size_t item_size, usb_hid_report_item_t *report_item, 641 usb_hid_report_path_t *usage_path) { 642 509 643 switch(tag) 510 644 { 511 case USB_HID_REPORT_TAG_USAGE_PAGE: 512 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 513 break; 514 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 515 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 516 break; 517 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 518 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 519 break; 520 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 521 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 522 break; 523 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 524 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 525 526 break; 527 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 528 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 529 break; 530 case USB_HID_REPORT_TAG_UNIT: 531 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 532 break; 533 case USB_HID_REPORT_TAG_REPORT_SIZE: 534 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 535 break; 536 case USB_HID_REPORT_TAG_REPORT_COUNT: 537 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 538 break; 539 case USB_HID_REPORT_TAG_REPORT_ID: 540 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 541 return USB_HID_RESET_OFFSET; 542 break; 543 case USB_HID_REPORT_TAG_PUSH: 544 case USB_HID_REPORT_TAG_POP: 545 /* 546 * stack operations are done in top level parsing 547 * function 548 */ 549 return tag; 550 break; 645 case USB_HID_REPORT_TAG_USAGE_PAGE: 646 report_item->usage_page = 647 usb_hid_report_tag_data_uint32(data, item_size); 648 break; 649 650 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 651 report_item->logical_minimum = USB_HID_UINT32_TO_INT32( 652 usb_hid_report_tag_data_uint32(data,item_size), 653 item_size * 8); 654 break; 655 656 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 657 report_item->logical_maximum = USB_HID_UINT32_TO_INT32( 658 usb_hid_report_tag_data_uint32(data,item_size), 659 item_size * 8); 660 break; 661 662 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 663 report_item->physical_minimum = USB_HID_UINT32_TO_INT32( 664 usb_hid_report_tag_data_uint32(data,item_size), 665 item_size * 8); 666 break; 667 668 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 669 report_item->physical_maximum = USB_HID_UINT32_TO_INT32( 670 usb_hid_report_tag_data_uint32(data,item_size), 671 item_size * 8); 672 break; 673 674 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 675 report_item->unit_exponent = usb_hid_report_tag_data_uint32( 676 data,item_size); 677 break; 678 679 case USB_HID_REPORT_TAG_UNIT: 680 report_item->unit = usb_hid_report_tag_data_uint32( 681 data,item_size); 682 break; 683 684 case USB_HID_REPORT_TAG_REPORT_SIZE: 685 report_item->size = usb_hid_report_tag_data_uint32( 686 data,item_size); 687 break; 688 689 case USB_HID_REPORT_TAG_REPORT_COUNT: 690 report_item->count = usb_hid_report_tag_data_uint32( 691 data,item_size); 692 break; 693 694 case USB_HID_REPORT_TAG_REPORT_ID: 695 report_item->id = usb_hid_report_tag_data_uint32(data, 696 item_size); 697 return USB_HID_RESET_OFFSET; 698 break; 699 700 case USB_HID_REPORT_TAG_PUSH: 701 case USB_HID_REPORT_TAG_POP: 702 /* 703 * stack operations are done in top level parsing 704 * function 705 */ 706 return tag; 707 break; 551 708 552 553 709 default: 710 return USB_HID_NO_ACTION; 554 711 } 555 712 … … 566 723 * @return Error code 567 724 */ 568 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 569 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 725 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 726 size_t item_size, usb_hid_report_item_t *report_item, 727 usb_hid_report_path_t *usage_path) 570 728 { 571 729 int32_t extended_usage; 572 730 573 731 switch(tag) { 574 case USB_HID_REPORT_TAG_USAGE: 575 switch(report_item->in_delimiter) { 576 case INSIDE_DELIMITER_SET: 577 // nothing to do 578 break; 579 case START_DELIMITER_SET: 580 report_item->in_delimiter = INSIDE_DELIMITER_SET; 581 case OUTSIDE_DELIMITER_SET: 582 extended_usage = ((report_item->usage_page) << 16); 583 extended_usage += usb_hid_report_tag_data_uint32(data,item_size); 584 report_item->usages[report_item->usages_count] = extended_usage; 585 report_item->usages_count++; 586 break; 732 case USB_HID_REPORT_TAG_USAGE: 733 switch(report_item->in_delimiter) { 734 case INSIDE_DELIMITER_SET: 735 /* nothing to do 736 * we catch only the first one 737 */ 738 break; 739 740 case START_DELIMITER_SET: 741 report_item->in_delimiter = INSIDE_DELIMITER_SET; 742 case OUTSIDE_DELIMITER_SET: 743 extended_usage = ((report_item->usage_page) << 16); 744 extended_usage += usb_hid_report_tag_data_uint32( 745 data,item_size); 746 747 report_item->usages[report_item->usages_count] = 748 extended_usage; 749 750 report_item->usages_count++; 751 break; 752 } 753 break; 754 755 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 756 if (item_size == 3) { 757 // usage extended usages 758 report_item->extended_usage_page = 759 USB_HID_EXTENDED_USAGE_PAGE( 760 usb_hid_report_tag_data_uint32(data,item_size)); 761 762 763 report_item->usage_minimum = 764 USB_HID_EXTENDED_USAGE( 765 usb_hid_report_tag_data_uint32(data,item_size)); 766 } 767 else { 768 report_item->usage_minimum = 769 usb_hid_report_tag_data_uint32(data,item_size); 770 } 771 break; 772 773 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 774 if (item_size == 3) { 775 if(report_item->extended_usage_page != 776 USB_HID_EXTENDED_USAGE_PAGE( 777 usb_hid_report_tag_data_uint32(data,item_size))) { 778 779 return EINVAL; 587 780 } 588 break; 589 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 590 if (item_size == 3) { 591 // usage extended usages 592 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 593 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 781 782 // usage extended usages 783 report_item->extended_usage_page = 784 USB_HID_EXTENDED_USAGE_PAGE( 785 usb_hid_report_tag_data_uint32(data,item_size)); 786 787 report_item->usage_maximum = 788 USB_HID_EXTENDED_USAGE( 789 usb_hid_report_tag_data_uint32(data,item_size)); 790 } 791 else { 792 report_item->usage_maximum = 793 usb_hid_report_tag_data_uint32(data,item_size); 794 } 795 796 // vlozit zaznamy do pole usages 797 int32_t i; 798 for(i = report_item->usage_minimum; 799 i <= report_item->usage_maximum; i++) { 800 801 if(report_item->extended_usage_page) { 802 report_item->usages[report_item->usages_count++] = 803 (report_item->extended_usage_page << 16) + i; 594 804 } 595 else { 596 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 805 else { 806 report_item->usages[report_item->usages_count++] = 807 (report_item->usage_page << 16) + i; 597 808 } 598 break; 599 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 600 if (item_size == 3) { 601 602 if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) { 603 return EINVAL; 604 } 605 606 // usage extended usages 607 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 608 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 609 } 610 else { 611 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 612 } 613 614 // vlozit zaznamy do pole usages 615 int32_t i; 616 for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) { 617 if(report_item->extended_usage_page) { 618 report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i; 619 } 620 else { 621 622 report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i; 623 } 624 } 625 report_item->extended_usage_page = 0; 809 } 810 report_item->extended_usage_page = 0; 626 811 627 break; 628 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 629 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 630 break; 631 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 632 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 633 break; 634 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 635 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 636 break; 637 case USB_HID_REPORT_TAG_STRING_INDEX: 638 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 639 break; 640 case USB_HID_REPORT_TAG_STRING_MINIMUM: 641 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 642 break; 643 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 644 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 645 break; 646 case USB_HID_REPORT_TAG_DELIMITER: 647 report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size); 648 break; 649 650 default: 651 return USB_HID_NO_ACTION; 812 break; 813 814 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 815 report_item->designator_index = 816 usb_hid_report_tag_data_uint32(data,item_size); 817 break; 818 819 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 820 report_item->designator_minimum = 821 usb_hid_report_tag_data_uint32(data,item_size); 822 break; 823 824 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 825 report_item->designator_maximum = 826 usb_hid_report_tag_data_uint32(data,item_size); 827 break; 828 829 case USB_HID_REPORT_TAG_STRING_INDEX: 830 report_item->string_index = 831 usb_hid_report_tag_data_uint32(data,item_size); 832 break; 833 834 case USB_HID_REPORT_TAG_STRING_MINIMUM: 835 report_item->string_minimum = 836 usb_hid_report_tag_data_uint32(data,item_size); 837 break; 838 839 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 840 report_item->string_maximum = 841 usb_hid_report_tag_data_uint32(data,item_size); 842 break; 843 844 case USB_HID_REPORT_TAG_DELIMITER: 845 report_item->in_delimiter = 846 usb_hid_report_tag_data_uint32(data,item_size); 847 break; 848 849 default: 850 return USB_HID_NO_ACTION; 652 851 } 653 852 654 853 return EOK; 655 854 } 855 /*---------------------------------------------------------------------------*/ 656 856 657 857 /** … … 674 874 return result; 675 875 } 876 /*---------------------------------------------------------------------------*/ 676 877 677 878 /** … … 694 895 for(item = head->next; item != head; item = item->next) { 695 896 696 report_item = list_get_instance(item, usb_hid_report_field_t, link); 897 report_item = list_get_instance(item, usb_hid_report_field_t, 898 link); 697 899 698 900 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 699 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 700 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 701 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 702 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 703 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 704 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 705 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 706 usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count); 901 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 902 usb_log_debug("\t\tLOGMIN: %d\n", 903 report_item->logical_minimum); 904 usb_log_debug("\t\tLOGMAX: %d\n", 905 report_item->logical_maximum); 906 usb_log_debug("\t\tPHYMIN: %d\n", 907 report_item->physical_minimum); 908 usb_log_debug("\t\tPHYMAX: %d\n", 909 report_item->physical_maximum); 910 usb_log_debug("\t\ttUSAGEMIN: %X\n", 911 report_item->usage_minimum); 912 usb_log_debug("\t\tUSAGEMAX: %X\n", 913 report_item->usage_maximum); 914 usb_log_debug("\t\tUSAGES COUNT: %zu\n", 915 report_item->usages_count); 707 916 708 917 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 716 925 } 717 926 718 719 } 927 } 928 /*---------------------------------------------------------------------------*/ 929 720 930 /** 721 931 * Prints content of given report descriptor in human readable format. … … 734 944 735 945 while(report_it != &report->reports) { 736 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 946 report_des = list_get_instance(report_it, 947 usb_hid_report_description_t, link); 737 948 usb_log_debug("Report ID: %d\n", report_des->report_id); 738 949 usb_log_debug("\tType: %d\n", report_des->type); 739 950 usb_log_debug("\tLength: %zu\n", report_des->bit_length); 951 usb_log_debug("\tB Size: %zu\n", 952 usb_hid_report_byte_size(report, 953 report_des->report_id, 954 report_des->type)); 740 955 usb_log_debug("\tItems: %zu\n", report_des->item_length); 741 956 742 957 usb_hid_descriptor_print_list(&report_des->report_items); 743 958 744 /*745 link_t *path_it = report->collection_paths.next;746 while(path_it != &report->collection_paths) {747 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));748 path_it = path_it->next;749 }750 */751 959 report_it = report_it->next; 752 960 } 753 961 } 962 /*---------------------------------------------------------------------------*/ 754 963 755 964 /** … … 776 985 777 986 while(!list_empty(&report_item->usage_path->link)) { 778 987 usb_hid_report_remove_last_item(report_item->usage_path); 779 988 } 780 989 … … 788 997 789 998 } 999 /*---------------------------------------------------------------------------*/ 790 1000 791 1001 /** Frees the HID report descriptor parser structure … … 803 1013 usb_hid_report_path_t *path; 804 1014 while(!list_empty(&report->collection_paths)) { 805 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 1015 path = list_get_instance(report->collection_paths.next, 1016 usb_hid_report_path_t, link); 1017 806 1018 usb_hid_report_path_free(path); 807 1019 } … … 811 1023 usb_hid_report_field_t *field; 812 1024 while(!list_empty(&report->reports)) { 813 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 1025 report_des = list_get_instance(report->reports.next, 1026 usb_hid_report_description_t, link); 1027 814 1028 list_remove(&report_des->link); 815 1029 816 1030 while(!list_empty(&report_des->report_items)) { 817 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 1031 field = list_get_instance( 1032 report_des->report_items.next, 1033 usb_hid_report_field_t, link); 1034 818 1035 list_remove(&field->link); 819 1036 … … 826 1043 return; 827 1044 } 1045 /*---------------------------------------------------------------------------*/ 828 1046 829 1047 /** -
uspace/lib/usbhid/src/hidiface.c
r63d4d4fd rcd83f25 46 46 * @return Number of usages returned or negative error code. 47 47 */ 48 int usbhid_dev_get_event_length(int dev_phone )48 int usbhid_dev_get_event_length(int dev_phone, size_t *size) 49 49 { 50 50 if (dev_phone < 0) { … … 56 56 IPC_M_USBHID_GET_EVENT_LENGTH, &len); 57 57 if (rc == EOK) { 58 return (int) len; 59 } else { 60 return rc; 61 } 58 if (size != NULL) { 59 *size = (size_t) len; 60 } 61 } 62 63 return rc; 62 64 } 63 65 … … 74 76 * @return Error code. 75 77 */ 76 int usbhid_dev_get_event(int dev_phone, uint16_t *usage_pages, uint16_t *usages, 77 size_t usage_count, size_t *actual_usage_count, unsigned int flags) 78 { 79 if (dev_phone < 0) { 80 return EINVAL; 81 } 82 if ((usage_pages == NULL) || (usages == NULL)) { 83 return ENOMEM; 84 } 85 if (usage_count == 0) { 86 return EINVAL; 87 } 88 89 size_t buffer_size = sizeof(uint16_t) * usage_count * 2; 90 uint16_t *buffer = malloc(buffer_size); 78 int usbhid_dev_get_event(int dev_phone, uint8_t *buf, 79 size_t size, size_t *actual_size, int *event_nr, unsigned int flags) 80 { 81 if (dev_phone < 0) { 82 return EINVAL; 83 } 84 if ((buf == NULL)) { 85 return ENOMEM; 86 } 87 if (size == 0) { 88 return EINVAL; 89 } 90 91 // if (size == 0) { 92 // return EOK; 93 // } 94 95 size_t buffer_size = size; 96 uint8_t *buffer = malloc(buffer_size); 91 97 if (buffer == NULL) { 92 98 return ENOMEM; 93 99 } 94 100 101 ipc_call_t opening_request_call; 95 102 aid_t opening_request = async_send_2(dev_phone, 96 103 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT, 97 flags, NULL);104 flags, &opening_request_call); 98 105 if (opening_request == 0) { 99 106 free(buffer); … … 128 135 } 129 136 130 size_t actual_size = IPC_GET_ARG2(data_request_call); 131 size_t items = actual_size / 2; 137 size_t act_size = IPC_GET_ARG2(data_request_call); 132 138 133 139 /* Copy the individual items. */ 134 memcpy(usage_pages, buffer, items * sizeof(uint16_t)); 135 memcpy(usages, buffer + items, items * sizeof(uint16_t)); 136 137 if (actual_usage_count != NULL) { 138 *actual_usage_count = items; 140 memcpy(buf, buffer, act_size); 141 // memcpy(usages, buffer + items, items * sizeof(int32_t)); 142 143 if (actual_size != NULL) { 144 *actual_size = act_size; 145 } 146 147 if (event_nr != NULL) { 148 *event_nr = IPC_GET_ARG1(opening_request_call); 149 } 150 151 return EOK; 152 } 153 154 155 int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size) 156 { 157 if (dev_phone < 0) { 158 return EINVAL; 159 } 160 161 sysarg_t arg_size; 162 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE), 163 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size); 164 if (rc == EOK) { 165 if (size != NULL) { 166 *size = (size_t) arg_size; 167 } 168 } 169 return rc; 170 } 171 172 int usbhid_dev_get_report_descriptor(int dev_phone, uint8_t *buf, size_t size, 173 size_t *actual_size) 174 { 175 if (dev_phone < 0) { 176 return EINVAL; 177 } 178 if ((buf == NULL)) { 179 return ENOMEM; 180 } 181 if (size == 0) { 182 return EINVAL; 183 } 184 185 aid_t opening_request = async_send_1(dev_phone, 186 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR, 187 NULL); 188 if (opening_request == 0) { 189 return ENOMEM; 190 } 191 192 ipc_call_t data_request_call; 193 aid_t data_request = async_data_read(dev_phone, buf, size, 194 &data_request_call); 195 if (data_request == 0) { 196 async_wait_for(opening_request, NULL); 197 return ENOMEM; 198 } 199 200 sysarg_t data_request_rc; 201 sysarg_t opening_request_rc; 202 async_wait_for(data_request, &data_request_rc); 203 async_wait_for(opening_request, &opening_request_rc); 204 205 if (data_request_rc != EOK) { 206 /* Prefer return code of the opening request. */ 207 if (opening_request_rc != EOK) { 208 return (int) opening_request_rc; 209 } else { 210 return (int) data_request_rc; 211 } 212 } 213 214 if (opening_request_rc != EOK) { 215 return (int) opening_request_rc; 216 } 217 218 size_t act_size = IPC_GET_ARG2(data_request_call); 219 220 if (actual_size != NULL) { 221 *actual_size = act_size; 139 222 } 140 223 -
uspace/lib/usbhid/src/hidparser.c
r63d4d4fd rcd83f25 31 31 */ 32 32 /** @file 33 * HID report descriptor andreport data parser implementation.33 * USB HID report data parser implementation. 34 34 */ 35 35 #include <usb/hid/hidparser.h> … … 41 41 #include <assert.h> 42 42 43 43 /*---------------------------------------------------------------------------*/ 44 44 /* 45 45 * Data translation private functions 46 46 */ 47 47 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 48 //inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 48 49 49 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data); 50 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 50 51 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 52 int32_t value); 53 51 54 int usb_pow(int a, int b); 52 55 56 /*---------------------------------------------------------------------------*/ 53 57 54 58 // TODO: tohle ma bejt asi jinde … … 56 60 { 57 61 switch(b) { 58 59 60 61 62 63 64 65 66 67 } 68 } 69 62 case 0: 63 return 1; 64 break; 65 case 1: 66 return a; 67 break; 68 default: 69 return a * usb_pow(a, b-1); 70 break; 71 } 72 } 73 /*---------------------------------------------------------------------------*/ 70 74 71 75 /** Returns size of report of specified report id and type in items … … 94 98 } 95 99 100 /** Returns size of report of specified report id and type in bytes 101 * 102 * @param parser Opaque report parser structure 103 * @param report_id 104 * @param type 105 * @return Number of items in specified report 106 */ 107 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id, 108 usb_hid_report_type_t type) 109 { 110 usb_hid_report_description_t *report_des; 111 112 if(report == NULL) { 113 return 0; 114 } 115 116 report_des = usb_hid_report_find_description (report, report_id, type); 117 if(report_des == NULL){ 118 return 0; 119 } 120 else { 121 return ((report_des->bit_length + 7) / 8) ; 122 } 123 } 124 /*---------------------------------------------------------------------------*/ 96 125 97 126 /** Parse and act upon a HID report. … … 103 132 * @return Error code. 104 133 */ 105 int usb_hid_parse_report(const usb_hid_report_t *report, 106 const uint8_t *data,size_t size, uint8_t *report_id)134 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 135 size_t size, uint8_t *report_id) 107 136 { 108 137 link_t *list_item; … … 125 154 126 155 report_des = usb_hid_report_find_description(report, *report_id, type); 156 if(report_des == NULL) { 157 return EINVAL; 158 } 127 159 128 160 /* read data */ … … 130 162 while(list_item != &(report_des->report_items)) { 131 163 132 item = list_get_instance(list_item, usb_hid_report_field_t, link); 164 item = list_get_instance(list_item, usb_hid_report_field_t, 165 link); 133 166 134 167 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) { … … 137 170 138 171 // array 139 item->value = usb_hid_translate_data(item, data); 172 item->value = 173 usb_hid_translate_data(item, data); 140 174 141 item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]); 142 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]); 175 item->usage = USB_HID_EXTENDED_USAGE( 176 item->usages[item->value - item->physical_minimum]); 177 178 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE( 179 item->usages[item->value - item->physical_minimum]); 143 180 144 181 usb_hid_report_set_last_item (item->collection_path, 145 USB_HID_TAG_CLASS_GLOBAL,146 item->usage_page); 182 USB_HID_TAG_CLASS_GLOBAL, item->usage_page); 183 147 184 usb_hid_report_set_last_item (item->collection_path, 148 USB_HID_TAG_CLASS_LOCAL, 149 item->usage); 185 USB_HID_TAG_CLASS_LOCAL, item->usage); 150 186 151 187 } … … 162 198 } 163 199 200 /*---------------------------------------------------------------------------*/ 164 201 /** 165 202 * Translate data from the report as specified in report descriptor item … … 167 204 * @param item Report descriptor item with definition of translation 168 205 * @param data Data to translate 169 * @param j Index of processed field in report descriptor item170 206 * @return Translated data 171 207 */ … … 236 272 } 237 273 238 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 239 240 } 241 242 /*** OUTPUT API **/ 274 return (int)(((value - item->logical_minimum) / resolution) + 275 item->physical_minimum); 276 277 } 278 279 /*---------------------------------------------------------------------------*/ 280 /* OUTPUT API */ 243 281 244 282 /** … … 250 288 * @return Returns allocated output buffer for specified output 251 289 */ 252 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 290 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 291 uint8_t report_id) 253 292 { 254 293 if(report == NULL) { … … 260 299 usb_hid_report_description_t *report_des = NULL; 261 300 while(report_it != &report->reports) { 262 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 263 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 301 report_des = list_get_instance(report_it, 302 usb_hid_report_description_t, link); 303 304 if((report_des->report_id == report_id) && 305 (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 264 306 break; 265 307 } … … 303 345 * @return Error code 304 346 */ 305 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,306 347 int usb_hid_report_output_translate(usb_hid_report_t *report, 348 uint8_t report_id, uint8_t *buffer, size_t size) 307 349 { 308 350 link_t *item; … … 320 362 } 321 363 322 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));323 324 364 usb_hid_report_description_t *report_des; 325 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT); 365 report_des = usb_hid_report_find_description (report, report_id, 366 USB_HID_REPORT_TYPE_OUTPUT); 367 326 368 if(report_des == NULL){ 327 369 return EINVAL; … … 333 375 report_item = list_get_instance(item, usb_hid_report_field_t, link); 334 376 335 usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value);336 337 377 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 338 378 339 379 // array 340 value = usb_hid_translate_data_reverse(report_item, report_item->value); 380 value = usb_hid_translate_data_reverse(report_item, 381 report_item->value); 382 341 383 offset = report_item->offset; 342 384 length = report_item->size; … … 344 386 else { 345 387 // variable item 346 value = usb_hid_translate_data_reverse(report_item, report_item->value); 388 value = usb_hid_translate_data_reverse(report_item, 389 report_item->value); 390 347 391 offset = report_item->offset; 348 392 length = report_item->size; … … 353 397 if((offset/8) == ((offset+length-1)/8)) { 354 398 // je to v jednom bytu 355 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) { 399 if(((size_t)(offset/8) >= size) || 400 ((size_t)(offset+length-1)/8) >= size) { 356 401 break; // TODO ErrorCode 357 402 } … … 370 415 if(i == (offset/8)) { 371 416 tmp_value = value; 372 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 417 tmp_value = tmp_value & 418 ((1 << (8-(offset%8)))-1); 419 373 420 tmp_value = tmp_value << (offset%8); 374 421 375 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 376 buffer[i] = (buffer[i] & mask) | tmp_value; 422 mask = ~(((1 << (8-(offset%8)))-1) << 423 (offset%8)); 424 425 buffer[i] = (buffer[i] & mask) | 426 tmp_value; 377 427 } 378 428 else if (i == ((offset + length -1)/8)) { 379 429 380 value = value >> (length - ((offset + length) % 8)); 381 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 430 value = value >> (length - 431 ((offset + length) % 8)); 432 433 value = value & ((1 << (length - 434 ((offset + length) % 8))) - 1); 382 435 383 mask = (1 << (length - ((offset + length) % 8))) - 1; 436 mask = (1 << (length - 437 ((offset + length) % 8))) - 1; 438 384 439 buffer[i] = (buffer[i] & mask) | value; 385 440 } … … 396 451 } 397 452 398 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));399 400 453 return EOK; 401 454 } 402 455 456 /*---------------------------------------------------------------------------*/ 403 457 /** 404 458 * Translate given data for putting them into the outoput report … … 407 461 * @return ranslated value 408 462 */ 409 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 463 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 464 int value) 410 465 { 411 466 int ret=0; … … 431 486 } 432 487 433 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum; 434 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret); 488 ret = ((value - item->physical_minimum) * resolution) + 489 item->logical_minimum; 490 491 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), \ 492 ret(%x)\n", value, resolution, item->physical_minimum, 493 item->logical_minimum, ret); 435 494 436 495 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ … … 440 499 } 441 500 442 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item) 501 /*---------------------------------------------------------------------------*/ 502 /** 503 * Clones given state table 504 * 505 * @param item State table to clone 506 * @return Pointer to the cloned item 507 */ 508 usb_hid_report_item_t *usb_hid_report_item_clone( 509 const usb_hid_report_item_t *item) 443 510 { 444 511 usb_hid_report_item_t *new_report_item; … … 453 520 } 454 521 455 522 /*---------------------------------------------------------------------------*/ 523 /** 524 * Function for sequence walking through the report. Returns next field in the 525 * report or the first one when no field is given. 526 * 527 * @param report Searched report structure 528 * @param field Current field. If NULL is given, the first one in the report 529 * is returned. Otherwise the next one i nthe list is returned. 530 * @param path Usage path specifying which fields wa are interested in. 531 * @param flags Flags defining mode of usage paths comparison 532 * @param type Type of report we search. 533 * @retval NULL if no field is founded 534 * @retval Pointer to the founded report structure when founded 535 */ 456 536 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 457 usb_hid_report_field_t *field, 458 usb_hid_report_path_t *path, int flags, 459 usb_hid_report_type_t type) 460 { 461 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type); 537 usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, 538 usb_hid_report_type_t type) 539 { 540 usb_hid_report_description_t *report_des = 541 usb_hid_report_find_description(report, path->report_id, type); 542 462 543 link_t *field_it; 463 544 … … 467 548 468 549 if(field == NULL){ 469 // vezmu prvni co mathuje podle path!!470 550 field_it = report_des->report_items.next; 471 551 } … … 475 555 476 556 while(field_it != &report_des->report_items) { 477 field = list_get_instance(field_it, usb_hid_report_field_t, link); 557 field = list_get_instance(field_it, usb_hid_report_field_t, 558 link); 478 559 479 560 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 480 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 481 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){ 482 usb_hid_report_remove_last_item (field->collection_path); 561 usb_hid_report_path_append_item ( 562 field->collection_path, field->usage_page, 563 field->usage); 564 565 if(usb_hid_report_compare_usage_path( 566 field->collection_path, path, flags) == EOK){ 567 568 usb_hid_report_remove_last_item( 569 field->collection_path); 570 483 571 return field; 484 572 } 485 usb_hid_report_remove_last_item (field->collection_path); 573 usb_hid_report_remove_last_item ( 574 field->collection_path); 486 575 } 487 576 field_it = field_it->next; … … 491 580 } 492 581 493 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 582 /*---------------------------------------------------------------------------*/ 583 /** 584 * Returns next report_id of report of specified type. If zero is given than 585 * first report_id of specified type is returned (0 is not legal value for 586 * repotr_id) 587 * 588 * @param report_id Current report_id, 0 if there is no current report_id 589 * @param type Type of searched report 590 * @param report Report structure inwhich we search 591 * @retval 0 if report structure is null or there is no specified report 592 * @retval report_id otherwise 593 */ 594 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, 595 uint8_t report_id, usb_hid_report_type_t type) 494 596 { 495 597 if(report == NULL){ … … 500 602 link_t *report_it; 501 603 502 if(report_id == 0) { 503 report_it = usb_hid_report_find_description (report, report_id, type)->link.next; 604 if(report_id > 0) { 605 report_it = usb_hid_report_find_description(report, report_id, 606 type)->link.next; 504 607 } 505 608 else { … … 508 611 509 612 while(report_it != &report->reports) { 510 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 613 report_des = list_get_instance(report_it, 614 usb_hid_report_description_t, link); 615 511 616 if(report_des->type == type){ 512 617 return report_des->report_id; … … 517 622 } 518 623 624 /*---------------------------------------------------------------------------*/ 625 /** 626 * Reset all local items in given state table 627 * 628 * @param report_item State table containing current state of report 629 * descriptor parsing 630 * 631 * @return void 632 */ 519 633 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item) 520 634 { -
uspace/lib/usbhid/src/hidpath.c
r63d4d4fd rcd83f25 41 41 #include <assert.h> 42 42 43 44 #define USB_HID_SAME_USAGE(usage1, usage2) ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0)) 45 #define USB_HID_SAME_USAGE_PAGE(page1, page2) ((page1 == page2) || (page1 == 0) || (page2 == 0)) 46 43 /*---------------------------------------------------------------------------*/ 44 /** 45 * Compares two usages if they are same or not or one of the usages is not 46 * set. 47 * 48 * @param usage1 49 * @param usage2 50 * @return boolean 51 */ 52 #define USB_HID_SAME_USAGE(usage1, usage2) \ 53 ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0)) 54 55 /** 56 * Compares two usage pages if they are same or not or one of them is not set. 57 * 58 * @param page1 59 * @param page2 60 * @return boolean 61 */ 62 #define USB_HID_SAME_USAGE_PAGE(page1, page2) \ 63 ((page1 == page2) || (page1 == 0) || (page2 == 0)) 64 65 /*---------------------------------------------------------------------------*/ 47 66 /** 48 67 * Appends one item (couple of usage_path and usage) into the usage path … … 73 92 } 74 93 94 /*---------------------------------------------------------------------------*/ 75 95 /** 76 96 * Removes last item from the usage path structure … … 91 111 } 92 112 113 /*---------------------------------------------------------------------------*/ 93 114 /** 94 115 * Nulls last item of the usage path structure. … … 102 123 103 124 if(!list_empty(&usage_path->head)){ 104 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 125 item = list_get_instance(usage_path->head.prev, 126 usb_hid_report_usage_path_t, link); 127 105 128 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 106 129 } 107 130 } 108 131 132 /*---------------------------------------------------------------------------*/ 109 133 /** 110 134 * Modifies last item of usage path structure by given usage page or usage … … 137 161 } 138 162 139 163 /*---------------------------------------------------------------------------*/ 164 /** 165 * 166 * 167 * 168 * 169 */ 140 170 void usb_hid_print_usage_path(usb_hid_report_path_t *path) 141 171 { … … 147 177 while(item != &path->head) { 148 178 149 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link); 179 path_item = list_get_instance(item, usb_hid_report_usage_path_t, 180 link); 181 150 182 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page); 151 183 usb_log_debug("\tUSAGE: %X\n", path_item->usage); 152 184 usb_log_debug("\tFLAGS: %d\n", path_item->flags); 153 185 154 item = item->next; 155 } 156 } 157 186 item = item->next; 187 } 188 } 189 190 /*---------------------------------------------------------------------------*/ 158 191 /** 159 192 * Compares two usage paths structures … … 192 225 193 226 switch(flags){ 194 /* path is somewhere in report_path */ 195 case USB_HID_PATH_COMPARE_ANYWHERE: 196 if(path->depth != 1){ 197 return 1; 198 } 199 200 // projit skrz cestu a kdyz nekde sedi tak vratim EOK 201 // dojduli az za konec tak nnesedi 202 report_link = report_path->head.next; 203 path_link = path->head.next; 204 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 205 206 while(report_link != &report_path->head) { 207 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 208 if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page)){ 209 if(only_page == 0){ 210 if(USB_HID_SAME_USAGE(report_item->usage, path_item->usage)) { 211 return EOK; 212 } 213 } 214 else { 227 /* path is somewhere in report_path */ 228 case USB_HID_PATH_COMPARE_ANYWHERE: 229 if(path->depth != 1){ 230 return 1; 231 } 232 233 report_link = report_path->head.next; 234 path_link = path->head.next; 235 path_item = list_get_instance(path_link, 236 usb_hid_report_usage_path_t, link); 237 238 while(report_link != &report_path->head) { 239 report_item = list_get_instance(report_link, 240 usb_hid_report_usage_path_t, link); 241 242 if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 243 path_item->usage_page)){ 244 245 if(only_page == 0){ 246 if(USB_HID_SAME_USAGE( 247 report_item->usage, 248 path_item->usage)) { 249 215 250 return EOK; 216 251 } 217 252 } 218 253 else { 254 return EOK; 255 } 256 } 257 258 report_link = report_link->next; 259 } 260 261 return 1; 262 break; 263 264 /* the paths must be identical */ 265 case USB_HID_PATH_COMPARE_STRICT: 266 if(report_path->depth != path->depth){ 267 return 1; 268 } 269 270 /* path is prefix of the report_path */ 271 case USB_HID_PATH_COMPARE_BEGIN: 272 273 report_link = report_path->head.next; 274 path_link = path->head.next; 275 276 while((report_link != &report_path->head) && 277 (path_link != &path->head)) { 278 279 report_item = list_get_instance(report_link, 280 usb_hid_report_usage_path_t, link); 281 282 path_item = list_get_instance(path_link, 283 usb_hid_report_usage_path_t, link); 284 285 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 286 path_item->usage_page) || ((only_page == 0) && 287 !USB_HID_SAME_USAGE(report_item->usage, 288 path_item->usage))) { 289 290 return 1; 291 } 292 else { 219 293 report_link = report_link->next; 294 path_link = path_link->next; 220 295 } 221 222 return 1;223 break;224 /* the paths must be identical */225 case USB_HID_PATH_COMPARE_STRICT:226 if(report_path->depth != path->depth){227 return 1;228 }229 230 /* path is prefix of the report_path */231 case USB_HID_PATH_COMPARE_BEGIN:232 233 report_link = report_path->head.next;234 path_link = path->head.next;235 236 while((report_link != &report_path->head) &&237 (path_link != &path->head)) {238 239 report_item = list_get_instance(report_link,240 usb_hid_report_usage_path_t,241 link);242 243 path_item = list_get_instance(path_link,244 usb_hid_report_usage_path_t,245 link);246 247 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) ||248 ((only_page == 0) &&249 !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) {250 251 return 1;252 } else {253 report_link = report_link->next;254 path_link = path_link->next;255 }256 296 257 297 } 258 298 259 if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) || 260 ((report_link == &report_path->head) && (path_link == &path->head))) { 261 return EOK; 262 } 263 else { 299 if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && 300 (path_link == &path->head)) || 301 ((report_link == &report_path->head) && 302 (path_link == &path->head))) { 303 304 return EOK; 305 } 306 else { 307 return 1; 308 } 309 break; 310 311 /* path is suffix of report_path */ 312 case USB_HID_PATH_COMPARE_END: 313 314 report_link = report_path->head.prev; 315 path_link = path->head.prev; 316 317 if(list_empty(&path->head)){ 318 return EOK; 319 } 320 321 while((report_link != &report_path->head) && 322 (path_link != &path->head)) { 323 324 report_item = list_get_instance(report_link, 325 usb_hid_report_usage_path_t, link); 326 327 path_item = list_get_instance(path_link, 328 usb_hid_report_usage_path_t, link); 329 330 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 331 path_item->usage_page) || ((only_page == 0) && 332 !USB_HID_SAME_USAGE(report_item->usage, 333 path_item->usage))) { 334 264 335 return 1; 265 } 266 break; 267 268 /* path is suffix of report_path */ 269 case USB_HID_PATH_COMPARE_END: 270 271 report_link = report_path->head.prev; 272 path_link = path->head.prev; 273 274 if(list_empty(&path->head)){ 275 return EOK; 276 } 336 } else { 337 report_link = report_link->prev; 338 path_link = path_link->prev; 339 } 340 341 } 342 343 if(path_link == &path->head) { 344 return EOK; 345 } 346 else { 347 return 1; 348 } 277 349 278 while((report_link != &report_path->head) && 279 (path_link != &path->head)) { 280 281 report_item = list_get_instance(report_link, 282 usb_hid_report_usage_path_t, 283 link); 284 path_item = list_get_instance(path_link, 285 usb_hid_report_usage_path_t, 286 link); 287 288 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) || 289 ((only_page == 0) && 290 !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) { 291 return 1; 292 } else { 293 report_link = report_link->prev; 294 path_link = path_link->prev; 295 } 296 297 } 298 299 if(path_link == &path->head) { 300 return EOK; 301 } 302 else { 303 return 1; 304 } 305 306 break; 307 308 default: 309 return EINVAL; 310 } 311 } 312 350 break; 351 352 default: 353 return EINVAL; 354 } 355 } 356 357 /*---------------------------------------------------------------------------*/ 313 358 /** 314 359 * Allocates and initializes new usage path structure. … … 332 377 } 333 378 379 /*---------------------------------------------------------------------------*/ 334 380 /** 335 381 * Releases given usage path structure. … … 348 394 } 349 395 350 396 /*---------------------------------------------------------------------------*/ 351 397 /** 352 398 * Clone content of given usage path to the new one … … 355 401 * @return New copy of given usage path structure 356 402 */ 357 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 403 usb_hid_report_path_t *usb_hid_report_path_clone( 404 usb_hid_report_path_t *usage_path) 358 405 { 359 406 link_t *path_link; … … 374 421 path_link = usage_path->head.next; 375 422 while(path_link != &usage_path->head) { 376 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, 377 link); 423 path_item = list_get_instance(path_link, 424 usb_hid_report_usage_path_t, link); 425 378 426 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t)); 379 427 if(new_path_item == NULL) { … … 395 443 } 396 444 397 445 /*---------------------------------------------------------------------------*/ 398 446 /** 399 447 * Sets report id in usage path structure … … 403 451 * @return Error code 404 452 */ 405 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id) 453 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, 454 uint8_t report_id) 406 455 { 407 456 if(path == NULL){ -
uspace/lib/usbhid/src/hidreport.c
r63d4d4fd rcd83f25 164 164 165 165 int usb_hid_process_report_descriptor(usb_device_t *dev, 166 usb_hid_report_t *report )166 usb_hid_report_t *report, uint8_t **report_desc, size_t *report_size) 167 167 { 168 168 if (dev == NULL || report == NULL) { … … 172 172 } 173 173 174 uint8_t *report_desc = NULL; 175 size_t report_size; 176 177 int rc = usb_hid_get_report_descriptor(dev, &report_desc, 178 &report_size); 174 // uint8_t *report_desc = NULL; 175 // size_t report_size; 176 177 int rc = usb_hid_get_report_descriptor(dev, report_desc, report_size); 179 178 180 179 if (rc != EOK) { 181 180 usb_log_error("Problem with getting Report descriptor: %s.\n", 182 181 str_error(rc)); 183 if (report_desc != NULL) { 184 free(report_desc); 182 if (*report_desc != NULL) { 183 free(*report_desc); 184 *report_desc = NULL; 185 185 } 186 186 return rc; 187 187 } 188 188 189 assert( report_desc != NULL);190 191 rc = usb_hid_parse_report_descriptor(report, report_desc,report_size);189 assert(*report_desc != NULL); 190 191 rc = usb_hid_parse_report_descriptor(report, *report_desc, *report_size); 192 192 if (rc != EOK) { 193 193 usb_log_error("Problem parsing Report descriptor: %s.\n", 194 194 str_error(rc)); 195 free(report_desc); 195 free(*report_desc); 196 *report_desc = NULL; 196 197 return rc; 197 198 } 198 199 199 200 usb_hid_descriptor_print(report); 200 free(report_desc);201 201 202 202 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.