Changes in uspace/app/mkbd/main.c [fa8d346:e8f826b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkbd/main.c
rfa8d346 re8f826b 45 45 #include <devmap.h> 46 46 #include <usb/dev/hub.h> 47 #include <usb/host.h> 48 #include <usb/driver.h> 49 #include <usb/hid/iface.h> 47 #include <usb/hc.h> 50 48 #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>57 49 58 50 #define NAME "mkbd" … … 60 52 static int dev_phone = -1; 61 53 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) { 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; 76 // } 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; 123 } 124 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) { 66 147 return ENOMEM; 67 148 } 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 uint8_t report_id; 143 usb_hid_parse_report(report, buffer, size, &report_id); 144 145 usb_hid_report_path_t *path = usb_hid_report_path(); 146 if (path == NULL) { 147 return; 148 } 149 150 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 151 152 usb_hid_report_path_set_report_id(path, report_id); 153 154 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 155 report, NULL, path, USB_HID_PATH_COMPARE_END 156 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 157 USB_HID_REPORT_TYPE_INPUT); 158 159 while (field != NULL) { 160 if (field->value != 0) { 161 const char *key_str = 162 usbhid_multimedia_usage_to_str(field->usage); 163 printf("Pressed key: %s\n", key_str); 164 } 165 166 field = usb_hid_report_get_sibling( 167 report, field, path, USB_HID_PATH_COMPARE_END 168 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 169 USB_HID_REPORT_TYPE_INPUT); 170 } 171 172 usb_hid_report_path_free(path); 173 } 174 175 #define MAX_PATH_LENGTH 1024 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 } 176 206 177 207 static void print_usage(char *app_name) … … 179 209 #define _INDENT " " 180 210 181 182 183 211 printf(NAME ": Print out what multimedia keys were pressed.\n\n"); 212 printf("Usage: %s device\n", app_name); 213 printf(_INDENT "The device is a devman path to the device.\n"); 184 214 185 215 #undef _OPTION … … 195 225 } 196 226 197 //char *devpath = argv[1]; 198 const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID0/hid"; 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 } 199 239 200 240 int rc; 201 202 devman_handle_t dev_handle = 0; 203 rc = devman_device_get_handle(devpath, &dev_handle, 0); 204 if (rc != EOK) { 205 printf("Failed to get handle from devman: %s.\n", 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", 206 247 str_error(rc)); 207 return rc; 208 } 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); 209 261 210 262 rc = devman_device_connect(dev_handle, 0); 211 263 if (rc < 0) { 212 printf(NAME ": failed to connect to the device (handle %"213 PRIun "): %s.\n", dev_handle,str_error(rc));214 return rc;264 printf(NAME ": failed to connect to the device: %s.\n", 265 str_error(rc)); 266 return -1; 215 267 } 216 268 … … 218 270 printf("Got phone to the device: %d\n", dev_phone); 219 271 220 char path[MAX_PATH_LENGTH]; 221 rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH); 222 if (rc != EOK) { 223 return ENOMEM; 224 } 225 226 printf("Device path: %s\n", path); 227 228 229 usb_hid_report_t *report = NULL; 230 rc = initialize_report_parser(dev_phone, &report); 231 if (rc != EOK) { 232 printf("Failed to initialize report parser: %s\n", 233 str_error(rc)); 234 return rc; 235 } 236 237 assert(report != NULL); 238 239 size_t size; 240 rc = usbhid_dev_get_event_length(dev_phone, &size); 241 if (rc != EOK) { 242 printf("Failed to get event length: %s.\n", str_error(rc)); 243 return rc; 244 } 245 246 printf("Event length: %zu\n", size); 247 uint8_t *event = (uint8_t *)malloc(size); 248 if (event == NULL) { 249 // hangup phone? 250 return ENOMEM; 251 } 252 253 printf("Event length: %zu\n", size); 254 255 size_t actual_size; 256 257 while (1) { 258 // get event from the driver 259 printf("Getting event from the driver.\n"); 260 261 /** @todo Try blocking call. */ 262 rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size, 263 0); 264 if (rc != EOK) { 265 // hangup phone? 266 printf("Error in getting event from the HID driver:" 267 "%s.\n", str_error(rc)); 268 break; 269 } 270 271 printf("Got buffer: %p, size: %zu\n", event, actual_size); 272 273 print_key(event, size, report); 274 275 async_usleep(10000); 276 } 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 // } 277 292 278 293 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.