source: mainline/uspace/app/mkbd/main.c@ 74341ed

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 74341ed was 6c427cd, checked in by Lubos Slovak <lubos.slovak@…>, 14 years ago

Removed debug output from mkbd

  • Property mode set to 100644
File size: 7.8 KB
RevLine 
[4880210]1/*
2 * Copyright (c) 2011 Lubos Slovak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup mkbd
30 * @{
31 */
32/**
33 * @file
34 * Sample application using the data from multimedia keys on keyboard
35 */
36
37#include <inttypes.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <errno.h>
41#include <str_error.h>
42#include <bool.h>
43#include <getopt.h>
44#include <devman.h>
45#include <devmap.h>
[b2995c3]46#include <usb/dev/hub.h>
[da56be2]47//#include <usb/host.h>
48//#include <usb/driver.h>
[e765ccb]49#include <usb/hid/iface.h>
[b2995c3]50#include <usb/dev/pipes.h>
[4e78236]51#include <async.h>
[d7c72db]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>
[4880210]57
58#define NAME "mkbd"
59
60static int dev_phone = -1;
61
[fa8d346]62static int initialize_report_parser(int dev_phone, usb_hid_report_t **report)
[d7c72db]63{
[fa8d346]64 *report = (usb_hid_report_t *)malloc(sizeof(usb_hid_report_t));
65 if (*report == NULL) {
[d7c72db]66 return ENOMEM;
67 }
68
[fa8d346]69 int rc = usb_hid_report_init(*report);
[d7c72db]70 if (rc != EOK) {
[fa8d346]71 usb_hid_free_report(*report);
72 *report = NULL;
73 printf("usb_hid_report_init() failed.\n");
[d7c72db]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) {
[fa8d346]82 usb_hid_free_report(*report);
83 *report = NULL;
84 printf("usbhid_dev_get_report_descriptor_length() failed.\n");
[d7c72db]85 return rc;
86 }
87
88 if (report_desc_size == 0) {
[fa8d346]89 usb_hid_free_report(*report);
90 *report = NULL;
91 printf("usbhid_dev_get_report_descriptor_length() returned 0.\n");
[d7c72db]92 return EINVAL; // TODO: other error code?
93 }
94
95 uint8_t *desc = (uint8_t *)malloc(report_desc_size);
96 if (desc == NULL) {
[fa8d346]97 usb_hid_free_report(*report);
98 *report = NULL;
[d7c72db]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) {
[fa8d346]107 usb_hid_free_report(*report);
108 *report = NULL;
[d7c72db]109 free(desc);
[fa8d346]110 printf("usbhid_dev_get_report_descriptor() failed.\n");
[d7c72db]111 return rc;
112 }
113
114 if (actual_size != report_desc_size) {
[fa8d346]115 usb_hid_free_report(*report);
116 *report = NULL;
[d7c72db]117 free(desc);
[fa8d346]118 printf("usbhid_dev_get_report_descriptor() returned wrong size:"
119 " %zu, expected: %zu.\n", actual_size, report_desc_size);
[d7c72db]120 return EINVAL; // TODO: other error code?
121 }
122
123 // initialize the report parser
124
[fa8d346]125 rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size);
[d7c72db]126 free(desc);
127
128 if (rc != EOK) {
129 free(desc);
[fa8d346]130 printf("usb_hid_parse_report_descriptor() failed.\n");
[d7c72db]131 return rc;
132 }
133
134 return EOK;
135}
[4880210]136
[d7c72db]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
[266fcd8]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");
[da56be2]148
[d7c72db]149 uint8_t report_id;
[da56be2]150 int rc = usb_hid_parse_report(report, buffer, size, &report_id);
151 if (rc != EOK) {
[266fcd8]152// printf("Error parsing report: %s\n", str_error(rc));
[da56be2]153 return;
154 }
[d7c72db]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);
[4880210]164
[d7c72db]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
[266fcd8]170// printf("Field: %p\n", field);
171
[d7c72db]172 while (field != NULL) {
[266fcd8]173// printf("Field usage: %u, field value: %d\n", field->usage,
174// field->value);
[d7c72db]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);
[266fcd8]185// printf("Next field: %p\n", field);
[d7c72db]186 }
187
188 usb_hid_report_path_free(path);
189}
[4880210]190
[d7c72db]191#define MAX_PATH_LENGTH 1024
[4880210]192
193static void print_usage(char *app_name)
194{
195#define _INDENT " "
196
[d7c72db]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");
[4880210]200
201#undef _OPTION
202#undef _INDENT
203}
204
205int main(int argc, char *argv[])
206{
[266fcd8]207 int act_event = -1;
[4880210]208
209 if (argc <= 1) {
210 print_usage(argv[0]);
211 return -1;
212 }
213
[4e78236]214 //char *devpath = argv[1];
[da56be2]215 const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID1/hid";
[e765ccb]216
217 int rc;
218
219 devman_handle_t dev_handle = 0;
220 rc = devman_device_get_handle(devpath, &dev_handle, 0);
[4880210]221 if (rc != EOK) {
[e765ccb]222 printf("Failed to get handle from devman: %s.\n",
223 str_error(rc));
224 return rc;
[4880210]225 }
226
227 rc = devman_device_connect(dev_handle, 0);
228 if (rc < 0) {
[e765ccb]229 printf(NAME ": failed to connect to the device (handle %"
230 PRIun "): %s.\n", dev_handle, str_error(rc));
231 return rc;
[4880210]232 }
233
234 dev_phone = rc;
[6c427cd]235// printf("Got phone to the device: %d\n", dev_phone);
[4880210]236
[e765ccb]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 }
[4880210]242
[e765ccb]243 printf("Device path: %s\n", path);
244
[d7c72db]245
246 usb_hid_report_t *report = NULL;
[fa8d346]247 rc = initialize_report_parser(dev_phone, &report);
[d7c72db]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
[e765ccb]256 size_t size;
257 rc = usbhid_dev_get_event_length(dev_phone, &size);
258 if (rc != EOK) {
[d7c72db]259 printf("Failed to get event length: %s.\n", str_error(rc));
[e765ccb]260 return rc;
261 }
262
[266fcd8]263// printf("Event length: %zu\n", size);
[d7c72db]264 uint8_t *event = (uint8_t *)malloc(size);
[e765ccb]265 if (event == NULL) {
266 // hangup phone?
267 return ENOMEM;
268 }
269
[266fcd8]270// printf("Event length: %zu\n", size);
[e765ccb]271
272 size_t actual_size;
[266fcd8]273 int event_nr;
[e765ccb]274
275 while (1) {
276 // get event from the driver
[266fcd8]277// printf("Getting event from the driver.\n");
[d7c72db]278
279 /** @todo Try blocking call. */
[e765ccb]280 rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size,
[266fcd8]281 &event_nr, 0);
[e765ccb]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
[266fcd8]289// printf("Got buffer: %p, size: %zu, max size: %zu\n", event,
290// actual_size, size);
[4e78236]291
[266fcd8]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 }
[d7c72db]298
[266fcd8]299 async_usleep(100000);
[e765ccb]300 }
[4880210]301
302 return 0;
303}
304
305
306/** @}
307 */
Note: See TracBrowser for help on using the repository browser.