00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <inttypes.h>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <errno.h>
00041 #include <str_error.h>
00042 #include <bool.h>
00043 #include <getopt.h>
00044 #include <devman.h>
00045 #include <devmap.h>
00046 #include <usb/dev/hub.h>
00047
00048
00049 #include <usb/hid/iface.h>
00050 #include <usb/dev/pipes.h>
00051 #include <async.h>
00052 #include <usb/hid/usages/core.h>
00053 #include <usb/hid/hidparser.h>
00054 #include <usb/hid/hiddescriptor.h>
00055 #include <usb/hid/usages/consumer.h>
00056 #include <assert.h>
00057
00058 #define NAME "mkbd"
00059
00060 static int dev_phone = -1;
00061
00062 static int initialize_report_parser(int dev_phone, usb_hid_report_t **report)
00063 {
00064 *report = (usb_hid_report_t *)malloc(sizeof(usb_hid_report_t));
00065 if (*report == NULL) {
00066 return ENOMEM;
00067 }
00068
00069 int rc = usb_hid_report_init(*report);
00070 if (rc != EOK) {
00071 usb_hid_free_report(*report);
00072 *report = NULL;
00073
00074 return rc;
00075 }
00076
00077
00078 size_t report_desc_size;
00079 rc = usbhid_dev_get_report_descriptor_length(
00080 dev_phone, &report_desc_size);
00081 if (rc != EOK) {
00082 usb_hid_free_report(*report);
00083 *report = NULL;
00084
00085 return rc;
00086 }
00087
00088 if (report_desc_size == 0) {
00089 usb_hid_free_report(*report);
00090 *report = NULL;
00091
00092 return EINVAL;
00093 }
00094
00095 uint8_t *desc = (uint8_t *)malloc(report_desc_size);
00096 if (desc == NULL) {
00097 usb_hid_free_report(*report);
00098 *report = NULL;
00099 return ENOMEM;
00100 }
00101
00102
00103 size_t actual_size;
00104 rc = usbhid_dev_get_report_descriptor(dev_phone, desc, report_desc_size,
00105 &actual_size);
00106 if (rc != EOK) {
00107 usb_hid_free_report(*report);
00108 *report = NULL;
00109 free(desc);
00110
00111 return rc;
00112 }
00113
00114 if (actual_size != report_desc_size) {
00115 usb_hid_free_report(*report);
00116 *report = NULL;
00117 free(desc);
00118
00119
00120 return EINVAL;
00121 }
00122
00123
00124
00125 rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size);
00126 free(desc);
00127
00128 if (rc != EOK) {
00129 free(desc);
00130
00131 return rc;
00132 }
00133
00134 return EOK;
00135 }
00136
00137 static void print_key(uint8_t *buffer, size_t size, usb_hid_report_t *report)
00138 {
00139 assert(buffer != NULL);
00140 assert(report != NULL);
00141
00142
00143
00144
00145
00146
00147
00148
00149 uint8_t report_id;
00150 int rc = usb_hid_parse_report(report, buffer, size, &report_id);
00151 if (rc != EOK) {
00152
00153 return;
00154 }
00155
00156 usb_hid_report_path_t *path = usb_hid_report_path();
00157 if (path == NULL) {
00158 return;
00159 }
00160
00161 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
00162
00163 usb_hid_report_path_set_report_id(path, report_id);
00164
00165 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
00166 report, NULL, path, USB_HID_PATH_COMPARE_END
00167 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
00168 USB_HID_REPORT_TYPE_INPUT);
00169
00170
00171
00172 while (field != NULL) {
00173
00174
00175 if (field->value != 0) {
00176 const char *key_str =
00177 usbhid_multimedia_usage_to_str(field->usage);
00178 printf("Pressed key: %s\n", key_str);
00179 }
00180
00181 field = usb_hid_report_get_sibling(
00182 report, field, path, USB_HID_PATH_COMPARE_END
00183 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
00184 USB_HID_REPORT_TYPE_INPUT);
00185
00186 }
00187
00188 usb_hid_report_path_free(path);
00189 }
00190
00191 #define MAX_PATH_LENGTH 1024
00192
00193 static void print_usage(char *app_name)
00194 {
00195 #define _INDENT " "
00196
00197 printf(NAME ": Print out what multimedia keys were pressed.\n\n");
00198 printf("Usage: %s device\n", app_name);
00199 printf(_INDENT "The device is a devman path to the device.\n");
00200
00201 #undef _OPTION
00202 #undef _INDENT
00203 }
00204
00205 int main(int argc, char *argv[])
00206 {
00207 int act_event = -1;
00208
00209 if (argc <= 1) {
00210 print_usage(argv[0]);
00211 return -1;
00212 }
00213
00214 char *devpath = argv[1];
00215
00216 devman_handle_t dev_handle = 0;
00217
00218 int rc = usb_resolve_device_handle(devpath, NULL, NULL, &dev_handle);
00219 if (rc != EOK) {
00220 printf("Device not found or not of USB kind: %s.\n",
00221 str_error(rc));
00222 return rc;
00223 }
00224
00225 rc = devman_device_connect(dev_handle, 0);
00226 if (rc < 0) {
00227 printf(NAME ": failed to connect to the device (handle %"
00228 PRIun "): %s.\n", dev_handle, str_error(rc));
00229 return rc;
00230 }
00231
00232 dev_phone = rc;
00233
00234
00235 char path[MAX_PATH_LENGTH];
00236 rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
00237 if (rc != EOK) {
00238 return ENOMEM;
00239 }
00240
00241 printf("Device path: %s\n", path);
00242
00243
00244 usb_hid_report_t *report = NULL;
00245 rc = initialize_report_parser(dev_phone, &report);
00246 if (rc != EOK) {
00247 printf("Failed to initialize report parser: %s\n",
00248 str_error(rc));
00249 return rc;
00250 }
00251
00252 assert(report != NULL);
00253
00254 size_t size;
00255 rc = usbhid_dev_get_event_length(dev_phone, &size);
00256 if (rc != EOK) {
00257 printf("Failed to get event length: %s.\n", str_error(rc));
00258 return rc;
00259 }
00260
00261
00262 uint8_t *event = (uint8_t *)malloc(size);
00263 if (event == NULL) {
00264
00265 return ENOMEM;
00266 }
00267
00268
00269
00270 size_t actual_size;
00271 int event_nr;
00272
00273 while (1) {
00274
00275
00276
00278 rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size,
00279 &event_nr, 0);
00280 if (rc != EOK) {
00281
00282 printf("Error in getting event from the HID driver:"
00283 "%s.\n", str_error(rc));
00284 break;
00285 }
00286
00287
00288
00289
00290
00291
00292 if (event_nr > act_event) {
00293 print_key(event, size, report);
00294 act_event = event_nr;
00295 }
00296
00297 async_usleep(10000);
00298 }
00299
00300 return 0;
00301 }
00302
00303