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


Ignore:
File:
1 edited

Legend:

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

    r266fcd8 re8f826b  
    4545#include <devmap.h>
    4646#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>
    5048#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>
    5749
    5850#define NAME "mkbd"
     
    6052static int dev_phone = -1;
    6153
    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
     94static 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
     125static 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) {
    66147                return ENOMEM;
    67148        }
    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]);
    146 //      }
    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);
    189 }
    190 
    191 #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}
    192206
    193207static void print_usage(char *app_name)
     
    195209#define _INDENT "      "
    196210
    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");
     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");
    200214
    201215#undef _OPTION
     
    205219int main(int argc, char *argv[])
    206220{
    207         int act_event = -1;
    208221       
    209222        if (argc <= 1) {
     
    212225        }
    213226       
    214         //char *devpath = argv[1];
    215         const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID1/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        }
    216239       
    217240        int rc;
    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",
     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",
    223247                    str_error(rc));
    224                 return rc;
    225         }
     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);
    226261       
    227262        rc = devman_device_connect(dev_handle, 0);
    228263        if (rc < 0) {
    229                 printf(NAME ": failed to connect to the device (handle %"
    230                        PRIun "): %s.\n", dev_handle, str_error(rc));
    231                 return rc;
     264                printf(NAME ": failed to connect to the device: %s.\n",
     265                       str_error(rc));
     266                return -1;
    232267        }
    233268       
     
    235270        printf("Got phone to the device: %d\n", dev_phone);
    236271       
    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         }
     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//      }
    301292       
    302293        return 0;
Note: See TracChangeset for help on using the changeset viewer.