Changes in uspace/app/mkbd/main.c [e8f826b:266fcd8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkbd/main.c
re8f826b r266fcd8 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 … … 270 235 printf("Got phone to the device: %d\n", dev_phone); 271 236 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 // } 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;
Note:
See TracChangeset
for help on using the changeset viewer.