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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e8f826b was e8f826b, checked in by Vojtech Horky <vojtechhorky@…>, 14 years ago

Merged headers in libusb

  • Property mode set to 100644
File size: 7.2 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/hc.h>
48#include <usb/dev/pipes.h>
49
50#define NAME "mkbd"
51
52static int dev_phone = -1;
53
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) {
147 return ENOMEM;
148 }
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}
206
207static void print_usage(char *app_name)
208{
209#define _INDENT " "
210
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");
214
215#undef _OPTION
216#undef _INDENT
217}
218
219int main(int argc, char *argv[])
220{
221
222 if (argc <= 1) {
223 print_usage(argv[0]);
224 return -1;
225 }
226
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 }
239
240 int rc;
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",
247 str_error(rc));
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);
261
262 rc = devman_device_connect(dev_handle, 0);
263 if (rc < 0) {
264 printf(NAME ": failed to connect to the device: %s.\n",
265 str_error(rc));
266 return -1;
267 }
268
269 dev_phone = rc;
270 printf("Got phone to the device: %d\n", dev_phone);
271
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// }
292
293 return 0;
294}
295
296
297/** @}
298 */
Note: See TracBrowser for help on using the repository browser.