source: mainline/uspace/app/vuhid/main.c@ 78dbf5b

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

Generic virtual USB HID device application

The application works (more or less) as a boot keyboard.

The code needs a lot of refactoring. That will be done later.

  • Property mode set to 100644
File size: 5.3 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
43#include <usb/usb.h>
44#include <usb/descriptor.h>
45#include <usb/debug.h>
46#include <usb/classes/classes.h>
47#include <usb/classes/hid.h>
48#include <usbvirt/device.h>
49
50#include "virthid.h"
51#include "ifaces.h"
52#include "stdreq.h"
53
54static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
55 {
56 .req_direction = USB_DIRECTION_IN,
57 .req_type = USB_REQUEST_TYPE_STANDARD,
58 .req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
59 .request = USB_DEVREQ_GET_DESCRIPTOR,
60 .name = "Get_Descriptor",
61 .callback = req_get_descriptor
62 },
63 {
64 .req_direction = USB_DIRECTION_OUT,
65 .req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
66 .req_type = USB_REQUEST_TYPE_CLASS,
67 .request = USB_HIDREQ_SET_PROTOCOL,
68 .name = "Set_Protocol",
69 .callback = req_set_protocol
70 },
71 {
72 .req_direction = USB_DIRECTION_OUT,
73 .req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
74 .req_type = USB_REQUEST_TYPE_CLASS,
75 .request = USB_HIDREQ_SET_REPORT,
76 .name = "Set_Report",
77 .callback = req_set_report
78 },
79 {
80 .callback = NULL
81 }
82};
83
84/** Keyboard callbacks.
85 * We abuse the fact that static variables are zero-filled.
86 */
87static usbvirt_device_ops_t hid_ops = {
88 .control = endpoint_zero_handlers,
89};
90
91/** Standard configuration descriptor. */
92static usb_standard_configuration_descriptor_t std_configuration_descriptor = {
93 .length = sizeof(usb_standard_configuration_descriptor_t),
94 .descriptor_type = USB_DESCTYPE_CONFIGURATION,
95 /* Will be patched at runtime. */
96 .total_length = sizeof(usb_standard_configuration_descriptor_t),
97 .interface_count = 0,
98 .configuration_number = 1,
99 .str_configuration = 0,
100 .attributes = 128, /* denotes bus-powered device */
101 .max_power = 50
102};
103
104/** Standard device descriptor. */
105static usb_standard_device_descriptor_t std_device_descriptor = {
106 .length = sizeof(usb_standard_device_descriptor_t),
107 .descriptor_type = USB_DESCTYPE_DEVICE,
108 .usb_spec_version = 0x110,
109 .device_class = USB_CLASS_USE_INTERFACE,
110 .device_subclass = 0,
111 .device_protocol = 0,
112 .max_packet_size = 64,
113 .configuration_count = 1
114};
115
116/** HID configuration. */
117usbvirt_device_configuration_t configuration = {
118 .descriptor = &std_configuration_descriptor,
119 .extra = NULL,
120 .extra_count = 0
121};
122
123/** HID standard descriptors. */
124usbvirt_descriptors_t descriptors = {
125 .device = &std_device_descriptor,
126 .configuration = &configuration,
127 .configuration_count = 1,
128};
129
130static vuhid_data_t vuhid_data = {
131 .in_endpoints_mapping = { NULL },
132 .in_endpoint_first_free = 1,
133 .out_endpoints_mapping = { NULL },
134 .out_endpoint_first_free = 1
135};
136
137/** Keyboard device.
138 * Rest of the items will be initialized later.
139 */
140static usbvirt_device_t hid_dev = {
141 .ops = &hid_ops,
142 .descriptors = &descriptors,
143 .name = "HID",
144 .device_data = &vuhid_data
145};
146
147
148int main(int argc, char * argv[])
149{
150 int rc;
151
152 usb_log_enable(USB_LOG_LEVEL_DEBUG2, "vusbhid");
153
154 /* Determine which interfaces to initialize. */
155 int i;
156 for (i = 1; i < argc; i++) {
157 rc = add_interface_by_id(available_hid_interfaces, argv[i],
158 &hid_dev);
159 if (rc != EOK) {
160 fprintf(stderr, "Failed to add device `%s': %s.\n",
161 argv[i], str_error(rc));
162 } else {
163 printf("Added device `%s'.\n", argv[i]);
164 }
165 }
166
167 for (i = 0; i < (int) hid_dev.descriptors->configuration->extra_count; i++) {
168 usb_log_debug("Found extra descriptor: %s.\n",
169 usb_debug_str_buffer(
170 hid_dev.descriptors->configuration->extra[i].data,
171 hid_dev.descriptors->configuration->extra[i].length,
172 0));
173 }
174
175 rc = usbvirt_device_plug(&hid_dev, "/virt/usbhc/hc");
176 if (rc != EOK) {
177 printf("Unable to start communication with VHCD: %s.\n",
178 str_error(rc));
179 return rc;
180 }
181
182 printf("Connected to VHCD...\n");
183
184 while (true) {
185 async_usleep(10 * 1000 * 1000);
186 }
187
188 printf("Terminating...\n");
189
190 return 0;
191}
192
193
194/** @}
195 */
Note: See TracBrowser for help on using the repository browser.