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


Ignore:
File:
1 edited

Legend:

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

    re8f826b r266fcd8  
    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;
     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//      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]);
    76146//      }
    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);
    123189}
    124190
    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
    206192
    207193static void print_usage(char *app_name)
     
    209195#define _INDENT "      "
    210196
    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");
     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");
    214200
    215201#undef _OPTION
     
    219205int main(int argc, char *argv[])
    220206{
     207        int act_event = -1;
    221208       
    222209        if (argc <= 1) {
     
    225212        }
    226213       
    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";
    239216       
    240217        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",
    247223                    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        }
    261226       
    262227        rc = devman_device_connect(dev_handle, 0);
    263228        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;
    267232        }
    268233       
     
    270235        printf("Got phone to the device: %d\n", dev_phone);
    271236       
    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        }
    292301       
    293302        return 0;
Note: See TracChangeset for help on using the changeset viewer.