Changes in uspace/app/mkbd/main.c [e8f826b:fa8d346] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/mkbd/main.c

    re8f826b rfa8d346  
    4545#include <devmap.h>
    4646#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>
    4850#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>
    4957
    5058#define NAME "mkbd"
     
    5260static int dev_phone = -1;
    5361
    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);
     62static 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
     137static 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();
    146146        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;
     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);
    163164                }
    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 }
     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
    206176
    207177static void print_usage(char *app_name)
     
    209179#define _INDENT "      "
    210180
    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");
     181       printf(NAME ": Print out what multimedia keys were pressed.\n\n");
     182       printf("Usage: %s device\n", app_name);
     183       printf(_INDENT "The device is a devman path to the device.\n");
    214184
    215185#undef _OPTION
     
    225195        }
    226196       
    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         }
     197        //char *devpath = argv[1];
     198        const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID0/hid";
    239199       
    240200        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",
     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",
    247206                    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);
     207                return rc;
     208        }
    261209       
    262210        rc = devman_device_connect(dev_handle, 0);
    263211        if (rc < 0) {
    264                 printf(NAME ": failed to connect to the device: %s.\n",
    265                        str_error(rc));
    266                 return -1;
     212                printf(NAME ": failed to connect to the device (handle %"
     213                       PRIun "): %s.\n", dev_handle, str_error(rc));
     214                return rc;
    267215        }
    268216       
     
    270218        printf("Got phone to the device: %d\n", dev_phone);
    271219       
    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 //      }
     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        }
    292277       
    293278        return 0;
Note: See TracChangeset for help on using the changeset viewer.