source: mainline/uspace/app/vuhid/main.c@ eb34d8e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since eb34d8e was eb34d8e, checked in by Jan Vesely <jano.vesely@…>, 10 years ago

virtualusb: Rename device connection function to virtual to avoid conflict with libusbhost

this must have been broken for long time.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky
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 usbvirthid
30 * @{
31 */
32/**
33 * @file
34 * Virtual USB HID device.
35 */
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <unistd.h>
40#include <errno.h>
41#include <str_error.h>
42#include <getopt.h>
43
44#include <usb/usb.h>
45#include <usb/descriptor.h>
46#include <usb/debug.h>
47#include <usb/classes/classes.h>
48#include <usb/hid/hid.h>
49#include <usbvirt/device.h>
50
51#include "virthid.h"
52#include "ifaces.h"
53#include "stdreq.h"
54
55#define DEFAULT_CONTROLLER "/virt/usbhc/virtual"
56
57static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
58 {
59 STD_REQ_IN(USB_REQUEST_RECIPIENT_INTERFACE, USB_DEVREQ_GET_DESCRIPTOR),
60 .name = "Get_Descriptor",
61 .callback = req_get_descriptor
62 },
63 {
64 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_INTERFACE, USB_HIDREQ_SET_PROTOCOL),
65 .name = "Set_Protocol",
66 .callback = req_set_protocol
67 },
68 {
69 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_INTERFACE, USB_HIDREQ_SET_REPORT),
70 .name = "Set_Report",
71 .callback = req_set_report
72 },
73 {
74 .callback = NULL
75 }
76};
77
78/** Keyboard callbacks.
79 * We abuse the fact that static variables are zero-filled.
80 */
81static usbvirt_device_ops_t hid_ops = {
82 .control = endpoint_zero_handlers,
83};
84
85/** Standard configuration descriptor. */
86static usb_standard_configuration_descriptor_t std_configuration_descriptor = {
87 .length = sizeof(usb_standard_configuration_descriptor_t),
88 .descriptor_type = USB_DESCTYPE_CONFIGURATION,
89 /* Will be patched at runtime. */
90 .total_length = sizeof(usb_standard_configuration_descriptor_t),
91 .interface_count = 0,
92 .configuration_number = 1,
93 .str_configuration = 0,
94 .attributes = 128, /* denotes bus-powered device */
95 .max_power = 50
96};
97
98/** Standard device descriptor. */
99static usb_standard_device_descriptor_t std_device_descriptor = {
100 .length = sizeof(usb_standard_device_descriptor_t),
101 .descriptor_type = USB_DESCTYPE_DEVICE,
102 .usb_spec_version = 0x110,
103 .device_class = USB_CLASS_USE_INTERFACE,
104 .device_subclass = 0,
105 .device_protocol = 0,
106 .max_packet_size = 64,
107 .configuration_count = 1
108};
109
110/** HID configuration. */
111usbvirt_device_configuration_t configuration = {
112 .descriptor = &std_configuration_descriptor,
113 .extra = NULL,
114 .extra_count = 0
115};
116
117/** HID standard descriptors. */
118usbvirt_descriptors_t descriptors = {
119 .device = &std_device_descriptor,
120 .configuration = &configuration,
121 .configuration_count = 1,
122};
123
124static vuhid_data_t vuhid_data = {
125 .in_endpoints_mapping = { NULL },
126 .in_endpoint_first_free = 1,
127 .out_endpoints_mapping = { NULL },
128 .out_endpoint_first_free = 1,
129
130 .iface_count = 0,
131 .iface_died_count = 0
132 // mutex and CV must be initialized elsewhere
133};
134
135
136/** Keyboard device.
137 * Rest of the items will be initialized later.
138 */
139static usbvirt_device_t hid_dev = {
140 .ops = &hid_ops,
141 .descriptors = &descriptors,
142 .name = "HID",
143 .device_data = &vuhid_data
144};
145
146
147static struct option long_options[] = {
148 {"help", optional_argument, NULL, 'h'},
149 {"controller", required_argument, NULL, 'c' },
150 {"list", no_argument, NULL, 'l' },
151 {0, 0, NULL, 0}
152};
153static const char *short_options = "hc:l";
154
155static void print_help(const char* name, const char* module)
156{
157 if (module == NULL) {
158 /* Default help */
159 printf("Usage: %s [options] device.\n", name);
160 printf("\t-h, --help [device]\n");
161 printf("\t\to With no argument print this help and exit.\n");
162 printf("\t\to With argument print device specific help and exit.\n");
163 printf("\t-l, --list \n\t\tPrint list of available devices.\n");
164 printf("\t-c, --controller \n\t\t"
165 "Use provided virtual hc instead of default (%s)\n",
166 DEFAULT_CONTROLLER);
167 return;
168 }
169 printf("HELP for module %s\n", module);
170}
171
172static void print_list(void)
173{
174 printf("Available devices:\n");
175 for (vuhid_interface_t **i = available_hid_interfaces; *i != NULL; ++i)
176 {
177 printf("\t`%s'\t%s\n", (*i)->id, (*i)->name);
178 }
179
180}
181
182static const char *controller = DEFAULT_CONTROLLER;
183
184int main(int argc, char * argv[])
185{
186
187 if (argc == 1) {
188 print_help(*argv, NULL);
189 return 0;
190 }
191
192 int opt = 0;
193 while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) > 0) {
194 switch (opt)
195 {
196 case 'h':
197 print_help(*argv, optarg);
198 return 0;
199 case 'c':
200 controller = optarg;
201 break;
202 case 'l':
203 print_list();
204 return 0;
205 case -1:
206 default:
207 break;
208 }
209 }
210
211
212 log_init("vuhid");
213
214 fibril_mutex_initialize(&vuhid_data.iface_count_mutex);
215 fibril_condvar_initialize(&vuhid_data.iface_count_cv);
216
217 /* Determine which interfaces to initialize. */
218 for (int i = optind; i < argc; i++) {
219 int rc = add_interface_by_id(available_hid_interfaces, argv[i],
220 &hid_dev);
221 if (rc != EOK) {
222 fprintf(stderr, "Failed to add device `%s': %s.\n",
223 argv[i], str_error(rc));
224 } else {
225 printf("Added device `%s'.\n", argv[i]);
226 }
227 }
228
229 for (int i = 0; i < (int) hid_dev.descriptors->configuration->extra_count; i++) {
230 usb_log_debug("Found extra descriptor: %s.\n",
231 usb_debug_str_buffer(
232 hid_dev.descriptors->configuration->extra[i].data,
233 hid_dev.descriptors->configuration->extra[i].length,
234 0));
235 }
236
237 const int rc = usbvirt_device_plug(&hid_dev, controller);
238 if (rc != EOK) {
239 printf("Unable to start communication with VHCD `%s': %s.\n",
240 controller, str_error(rc));
241 return rc;
242 }
243
244 printf("Connected to VHCD `%s'...\n", controller);
245
246 wait_for_interfaces_death(&hid_dev);
247
248 printf("Terminating...\n");
249
250 usbvirt_device_unplug(&hid_dev);
251
252 return 0;
253}
254
255
256/** @}
257 */
Note: See TracBrowser for help on using the repository browser.