Changeset d7c72db in mainline for uspace/app/mkbd/main.c


Ignore:
Timestamp:
2011-05-24T21:01:02Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a28b41d
Parents:
4e78236
Message:

A lot of changes to mkbd and HID interface.

  • mkbd Report parser initialization (getting report descriptor, parsing).
  • Getting report descriptor and its length from HID device added to HID interface (client and server stubs not implemented).
  • Fixed event type to uint8_t *.
  • Implemented these functions in generic HID driver.
  • Moved mapping from Consumer page usages to string descriptions moved to libusbhid.
  • Removed some temporary debug output.
File:
1 edited

Legend:

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

    r4e78236 rd7c72db  
    5050#include <usb/dev/pipes.h>
    5151#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>
    5257
    5358#define NAME "mkbd"
     
    5560static int dev_phone = -1;
    5661
    57 //static void print_found_hc(size_t class_index, const char *path)
    58 //{
    59 //      // printf(NAME ": host controller %zu is `%s'.\n", class_index, path);
    60 //      printf("Bus %02zu: %s\n", class_index, path);
    61 //}
    62 //static void print_found_dev(usb_address_t addr, const char *path)
    63 //{
    64 //      // printf(NAME ":     device with address %d is `%s'.\n", addr, path);
    65 //      printf("  Device %02d: %s\n", addr, path);
    66 //}
    67 
    68 //static void print_hc_devices(devman_handle_t hc_handle)
    69 //{
    70 //      int rc;
    71 //      usb_hc_connection_t conn;
    72 
    73 //      usb_hc_connection_initialize(&conn, hc_handle);
    74 //      rc = usb_hc_connection_open(&conn);
    75 //      if (rc != EOK) {
    76 //              printf(NAME ": failed to connect to HC: %s.\n",
    77 //                  str_error(rc));
    78 //              return;
    79 //      }
    80 //      usb_address_t addr;
    81 //      for (addr = 1; addr < 5; addr++) {
    82 //              devman_handle_t dev_handle;
    83 //              rc = usb_hc_get_handle_by_address(&conn, addr, &dev_handle);
    84 //              if (rc != EOK) {
    85 //                      continue;
    86 //              }
    87 //              char path[MAX_PATH_LENGTH];
    88 //              rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
    89 //              if (rc != EOK) {
    90 //                      continue;
    91 //              }
    92 //              print_found_dev(addr, path);
    93 //      }
    94 //      usb_hc_connection_close(&conn);
    95 //}
    96 
    97 //static bool try_parse_class_and_address(const char *path,
    98 //    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    99 //{
    100 //      size_t class_index;
    101 //      size_t address;
    102 //      int rc;
    103 //      char *ptr;
    104 
    105 //      rc = str_size_t(path, &ptr, 10, false, &class_index);
    106 //      if (rc != EOK) {
    107 //              return false;
    108 //      }
    109 //      if ((*ptr == ':') || (*ptr == '.')) {
    110 //              ptr++;
    111 //      } else {
    112 //              return false;
    113 //      }
    114 //      rc = str_size_t(ptr, NULL, 10, true, &address);
    115 //      if (rc != EOK) {
    116 //              return false;
    117 //      }
    118 //      rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle);
    119 //      if (rc != EOK) {
    120 //              return false;
    121 //      }
    122 //      if (out_device_address != NULL) {
    123 //              *out_device_address = (usb_address_t) address;
    124 //      }
    125 //      return true;
    126 //}
    127 
    128 //static bool resolve_hc_handle_and_dev_addr(const char *devpath,
    129 //    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    130 //{
    131 //      int rc;
    132 
    133 //      /* Hack for QEMU to save-up on typing ;-). */
    134 //      if (str_cmp(devpath, "qemu") == 0) {
    135 //              devpath = "/hw/pci0/00:01.2/uhci-rh/usb00_a1";
    136 //      }
    137 
    138 //      /* Hack for virtual keyboard. */
    139 //      if (str_cmp(devpath, "virt") == 0) {
    140 //              devpath = "/virt/usbhc/usb00_a1/usb00_a2";
    141 //      }
    142 
    143 //      if (try_parse_class_and_address(devpath,
    144 //          out_hc_handle, out_device_address)) {
    145 //              return true;
    146 //      }
    147 
    148 //      char *path = str_dup(devpath);
    149 //      if (path == NULL) {
    150 //              return ENOMEM;
    151 //      }
    152 
    153 //      devman_handle_t hc = 0;
    154 //      bool hc_found = false;
    155 //      usb_address_t addr = 0;
    156 //      bool addr_found = false;
    157 
    158 //      /* Remove suffixes and hope that we will encounter device node. */
    159 //      while (str_length(path) > 0) {
    160 //              /* Get device handle first. */
    161 //              devman_handle_t dev_handle;
    162 //              rc = devman_device_get_handle(path, &dev_handle, 0);
    163 //              if (rc != EOK) {
    164 //                      free(path);
    165 //                      return false;
    166 //              }
    167 
    168 //              /* Try to find its host controller. */
    169 //              if (!hc_found) {
    170 //                      rc = usb_hc_find(dev_handle, &hc);
    171 //                      if (rc == EOK) {
    172 //                              hc_found = true;
    173 //                      }
    174 //              }
    175 //              /* Try to get its address. */
    176 //              if (!addr_found) {
    177 //                      addr = usb_device_get_assigned_address(dev_handle);
    178 //                      if (addr >= 0) {
    179 //                              addr_found = true;
    180 //                      }
    181 //              }
    182 
    183 //              /* Speed-up. */
    184 //              if (hc_found && addr_found) {
    185 //                      break;
    186 //              }
    187 
    188 //              /* Remove the last suffix. */
    189 //              char *slash_pos = str_rchr(path, '/');
    190 //              if (slash_pos != NULL) {
    191 //                      *slash_pos = 0;
    192 //              }
    193 //      }
    194 
    195 //      free(path);
    196 
    197 //      if (hc_found && addr_found) {
    198 //              if (out_hc_handle != NULL) {
    199 //                      *out_hc_handle = hc;
    200 //              }
    201 //              if (out_device_address != NULL) {
    202 //                      *out_device_address = addr;
    203 //              }
    204 //              return true;
    205 //      } else {
    206 //              return false;
    207 //      }
    208 //}
     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                return rc;
     73        }
     74       
     75        // get the report descriptor length from the device
     76        size_t report_desc_size;
     77        rc = usbhid_dev_get_report_descriptor_length(
     78            dev_phone, &report_desc_size);
     79        if (rc != EOK) {
     80                usb_hid_free_report(report);
     81                return rc;
     82        }
     83       
     84        if (report_desc_size == 0) {
     85                usb_hid_free_report(report);
     86                return EINVAL;  // TODO: other error code?
     87        }
     88       
     89        uint8_t *desc = (uint8_t *)malloc(report_desc_size);
     90        if (desc == NULL) {
     91                usb_hid_free_report(report);
     92                return ENOMEM;
     93        }
     94       
     95        // get the report descriptor from the device
     96        size_t actual_size;
     97        rc = usbhid_dev_get_report_descriptor(dev_phone, desc, report_desc_size,
     98            &actual_size);
     99        if (rc != EOK) {
     100                usb_hid_free_report(report);
     101                free(desc);
     102                return rc;
     103        }
     104       
     105        if (actual_size != report_desc_size) {
     106                usb_hid_free_report(report);
     107                free(desc);
     108                return EINVAL;  // TODO: other error code?
     109        }
     110       
     111        // initialize the report parser
     112       
     113        rc = usb_hid_parse_report_descriptor(report, desc, report_desc_size);
     114        free(desc);
     115       
     116        if (rc != EOK) {
     117                free(desc);
     118                return rc;
     119        }
     120       
     121        return EOK;
     122}
     123
     124static void print_key(uint8_t *buffer, size_t size, usb_hid_report_t *report)
     125{
     126        assert(buffer != NULL);
     127        assert(report != NULL);
     128       
     129        uint8_t report_id;
     130        usb_hid_parse_report(report, buffer, size, &report_id);
     131       
     132        usb_hid_report_path_t *path = usb_hid_report_path();
     133        if (path == NULL) {
     134                return;
     135        }
     136       
     137        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     138       
     139        usb_hid_report_path_set_report_id(path, report_id);
     140
     141        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
     142            report, NULL, path, USB_HID_PATH_COMPARE_END
     143            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     144            USB_HID_REPORT_TYPE_INPUT);
     145       
     146        while (field != NULL) {
     147                if (field->value != 0) {
     148                        const char *key_str =
     149                            usbhid_multimedia_usage_to_str(field->usage);
     150                        printf("Pressed key: %s\n", key_str);
     151                }
     152               
     153                field = usb_hid_report_get_sibling(
     154                    report, field, path, USB_HID_PATH_COMPARE_END
     155                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     156                    USB_HID_REPORT_TYPE_INPUT);
     157        }
     158       
     159        usb_hid_report_path_free(path);
     160}
     161
     162#define MAX_PATH_LENGTH 1024
    209163
    210164static void print_usage(char *app_name)
     
    212166#define _INDENT "      "
    213167
    214         printf(NAME ": Print out what multimedia keys were pressed.\n\n");
    215         printf("Usage: %s device\n", app_name);
    216         printf(_INDENT "The device is a devman path to the device.\n");
     168       printf(NAME ": Print out what multimedia keys were pressed.\n\n");
     169       printf("Usage: %s device\n", app_name);
     170       printf(_INDENT "The device is a devman path to the device.\n");
    217171
    218172#undef _OPTION
    219173#undef _INDENT
    220174}
    221 
    222 #define MAX_PATH_LENGTH 1024
    223175
    224176int main(int argc, char *argv[])
     
    232184        //char *devpath = argv[1];
    233185        const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID0/hid";
    234 
    235 //      /* The initialization is here only to make compiler happy. */
    236 //      devman_handle_t hc_handle = 0;
    237 //      usb_address_t dev_addr = 0;
    238 //      bool found = resolve_hc_handle_and_dev_addr(devpath,
    239 //          &hc_handle, &dev_addr);
    240 //      if (!found) {
    241 //              fprintf(stderr, NAME ": device `%s' not found "
    242 //                  "or not of USB kind. Exiting.\n", devpath);
    243 //              return -1;
    244 //      }
    245        
    246 //      int rc;
    247 //      usb_hc_connection_t conn;
    248 
    249 //      usb_hc_connection_initialize(&conn, hc_handle);
    250 //      rc = usb_hc_connection_open(&conn);
    251 //      if (rc != EOK) {
    252 //              printf(NAME ": failed to connect to HC: %s.\n",
    253 //                  str_error(rc));
    254 //              return -1;
    255 //      }
    256 
    257 //      devman_handle_t dev_handle;
    258 //      rc = usb_hc_get_handle_by_address(&conn, dev_addr, &dev_handle);
    259 //      if (rc != EOK) {
    260 //              printf(NAME ": failed getting handle to the device: %s.\n",
    261 //                     str_error(rc));
    262 //              return -1;
    263 //      }
    264 
    265 //      usb_hc_connection_close(&conn);
    266186       
    267187        int rc;
     
    293213        printf("Device path: %s\n", path);
    294214       
     215       
     216        usb_hid_report_t *report = NULL;
     217        rc = initialize_report_parser(dev_phone, report);
     218        if (rc != EOK) {
     219                printf("Failed to initialize report parser: %s\n",
     220                    str_error(rc));
     221                return rc;
     222        }
     223       
     224        assert(report != NULL);
     225       
    295226        size_t size;
    296227        rc = usbhid_dev_get_event_length(dev_phone, &size);
    297228        if (rc != EOK) {
    298                 printf("Failed to get event length: %s.\n",
    299                     str_error(rc));
     229                printf("Failed to get event length: %s.\n", str_error(rc));
    300230                return rc;
    301231        }
    302232       
    303233        printf("Event length: %zu\n", size);
    304         int32_t *event = (int32_t *)malloc(size);
     234        uint8_t *event = (uint8_t *)malloc(size);
    305235        if (event == NULL) {
    306236                // hangup phone?
     
    315245                // get event from the driver
    316246                printf("Getting event from the driver.\n");
     247               
     248                /** @todo Try blocking call. */
    317249                rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size,
    318250                    0);
     
    326258                printf("Got buffer: %p, size: %zu\n", event, actual_size);
    327259               
     260                print_key(event, size, report);
     261               
    328262                async_usleep(10000);
    329263        }
Note: See TracChangeset for help on using the changeset viewer.