source: mainline/uspace/app/mkbd/main.c@ fa8d346

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

Fixes in mkbd and libusbhid.

  • Fixed initialization of report parser in mkbd.
  • Fixed usb_hid_process_report_descriptor() - added some parameters.
  • Property mode set to 100644
File size: 7.1 KB
Line 
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>
46#include <usb/dev/hub.h>
47#include <usb/host.h>
48#include <usb/driver.h>
49#include <usb/hid/iface.h>
50#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>
57
58#define NAME "mkbd"
59
60static int dev_phone = -1;
61
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 uint8_t report_id;
143 usb_hid_parse_report(report, buffer, size, &report_id);
144
145 usb_hid_report_path_t *path = usb_hid_report_path();
146 if (path == NULL) {
147 return;
148 }
149
150 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
151
152 usb_hid_report_path_set_report_id(path, report_id);
153
154 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
155 report, NULL, path, USB_HID_PATH_COMPARE_END
156 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
157 USB_HID_REPORT_TYPE_INPUT);
158
159 while (field != NULL) {
160 if (field->value != 0) {
161 const char *key_str =
162 usbhid_multimedia_usage_to_str(field->usage);
163 printf("Pressed key: %s\n", key_str);
164 }
165
166 field = usb_hid_report_get_sibling(
167 report, field, path, USB_HID_PATH_COMPARE_END
168 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
169 USB_HID_REPORT_TYPE_INPUT);
170 }
171
172 usb_hid_report_path_free(path);
173}
174
175#define MAX_PATH_LENGTH 1024
176
177static void print_usage(char *app_name)
178{
179#define _INDENT " "
180
181 printf(NAME ": Print out what multimedia keys were pressed.\n\n");
182 printf("Usage: %s device\n", app_name);
183 printf(_INDENT "The device is a devman path to the device.\n");
184
185#undef _OPTION
186#undef _INDENT
187}
188
189int main(int argc, char *argv[])
190{
191
192 if (argc <= 1) {
193 print_usage(argv[0]);
194 return -1;
195 }
196
197 //char *devpath = argv[1];
198 const char *devpath = "/hw/pci0/00:06.0/ohci-rh/usb00_a2/HID0/hid";
199
200 int rc;
201
202 devman_handle_t dev_handle = 0;
203 rc = devman_device_get_handle(devpath, &dev_handle, 0);
204 if (rc != EOK) {
205 printf("Failed to get handle from devman: %s.\n",
206 str_error(rc));
207 return rc;
208 }
209
210 rc = devman_device_connect(dev_handle, 0);
211 if (rc < 0) {
212 printf(NAME ": failed to connect to the device (handle %"
213 PRIun "): %s.\n", dev_handle, str_error(rc));
214 return rc;
215 }
216
217 dev_phone = rc;
218 printf("Got phone to the device: %d\n", dev_phone);
219
220 char path[MAX_PATH_LENGTH];
221 rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
222 if (rc != EOK) {
223 return ENOMEM;
224 }
225
226 printf("Device path: %s\n", path);
227
228
229 usb_hid_report_t *report = NULL;
230 rc = initialize_report_parser(dev_phone, &report);
231 if (rc != EOK) {
232 printf("Failed to initialize report parser: %s\n",
233 str_error(rc));
234 return rc;
235 }
236
237 assert(report != NULL);
238
239 size_t size;
240 rc = usbhid_dev_get_event_length(dev_phone, &size);
241 if (rc != EOK) {
242 printf("Failed to get event length: %s.\n", str_error(rc));
243 return rc;
244 }
245
246 printf("Event length: %zu\n", size);
247 uint8_t *event = (uint8_t *)malloc(size);
248 if (event == NULL) {
249 // hangup phone?
250 return ENOMEM;
251 }
252
253 printf("Event length: %zu\n", size);
254
255 size_t actual_size;
256
257 while (1) {
258 // get event from the driver
259 printf("Getting event from the driver.\n");
260
261 /** @todo Try blocking call. */
262 rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size,
263 0);
264 if (rc != EOK) {
265 // hangup phone?
266 printf("Error in getting event from the HID driver:"
267 "%s.\n", str_error(rc));
268 break;
269 }
270
271 printf("Got buffer: %p, size: %zu\n", event, actual_size);
272
273 print_key(event, size, report);
274
275 async_usleep(10000);
276 }
277
278 return 0;
279}
280
281
282/** @}
283 */
Note: See TracBrowser for help on using the repository browser.