source: mainline/uspace/lib/usbhid/src/hidiface.c@ ee7e7c93

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

Sending event number in get_event() interface + control in mkbd.

  • Property mode set to 100644
File size: 5.8 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 libusbhid
30 * @{
31 */
32/** @file
33 * Client functions for accessing USB HID interface (implementation).
34 */
35#include <dev_iface.h>
36#include <usbhid_iface.h>
37#include <usb/hid/iface.h>
38#include <errno.h>
39#include <str_error.h>
40#include <async.h>
41#include <assert.h>
42
43/** Ask for event array length.
44 *
45 * @param dev_phone Opened phone to DDF device providing USB HID interface.
46 * @return Number of usages returned or negative error code.
47 */
48int usbhid_dev_get_event_length(int dev_phone, size_t *size)
49{
50 if (dev_phone < 0) {
51 return EINVAL;
52 }
53
54 sysarg_t len;
55 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
56 IPC_M_USBHID_GET_EVENT_LENGTH, &len);
57 if (rc == EOK) {
58 if (size != NULL) {
59 *size = (size_t) len;
60 }
61 }
62
63 return rc;
64}
65
66/** Request for next event from HID device.
67 *
68 * @param[in] dev_phone Opened phone to DDF device providing USB HID interface.
69 * @param[out] usage_pages Where to store usage pages.
70 * @param[out] usages Where to store usages (actual data).
71 * @param[in] usage_count Length of @p usage_pages and @p usages buffer
72 * (in items, not bytes).
73 * @param[out] actual_usage_count Number of usages actually returned by the
74 * device driver.
75 * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
76 * @return Error code.
77 */
78int usbhid_dev_get_event(int dev_phone, uint8_t *buf,
79 size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
80{
81 if (dev_phone < 0) {
82 return EINVAL;
83 }
84 if ((buf == NULL)) {
85 return ENOMEM;
86 }
87 if (size == 0) {
88 return EINVAL;
89 }
90
91// if (size == 0) {
92// return EOK;
93// }
94
95 size_t buffer_size = size;
96 uint8_t *buffer = malloc(buffer_size);
97 if (buffer == NULL) {
98 return ENOMEM;
99 }
100
101 ipc_call_t opening_request_call;
102 aid_t opening_request = async_send_2(dev_phone,
103 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
104 flags, &opening_request_call);
105 if (opening_request == 0) {
106 free(buffer);
107 return ENOMEM;
108 }
109
110 ipc_call_t data_request_call;
111 aid_t data_request = async_data_read(dev_phone, buffer, buffer_size,
112 &data_request_call);
113 if (data_request == 0) {
114 async_wait_for(opening_request, NULL);
115 free(buffer);
116 return ENOMEM;
117 }
118
119 sysarg_t data_request_rc;
120 sysarg_t opening_request_rc;
121 async_wait_for(data_request, &data_request_rc);
122 async_wait_for(opening_request, &opening_request_rc);
123
124 if (data_request_rc != EOK) {
125 /* Prefer return code of the opening request. */
126 if (opening_request_rc != EOK) {
127 return (int) opening_request_rc;
128 } else {
129 return (int) data_request_rc;
130 }
131 }
132
133 if (opening_request_rc != EOK) {
134 return (int) opening_request_rc;
135 }
136
137 size_t act_size = IPC_GET_ARG2(data_request_call);
138
139 /* Copy the individual items. */
140 memcpy(buf, buffer, act_size);
141// memcpy(usages, buffer + items, items * sizeof(int32_t));
142
143 if (actual_size != NULL) {
144 *actual_size = act_size;
145 }
146
147 if (event_nr != NULL) {
148 *event_nr = IPC_GET_ARG1(opening_request_call);
149 }
150
151 return EOK;
152}
153
154
155int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size)
156{
157 if (dev_phone < 0) {
158 return EINVAL;
159 }
160
161 sysarg_t arg_size;
162 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
163 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
164 if (rc == EOK) {
165 if (size != NULL) {
166 *size = (size_t) arg_size;
167 }
168 }
169 return rc;
170}
171
172int usbhid_dev_get_report_descriptor(int dev_phone, uint8_t *buf, size_t size,
173 size_t *actual_size)
174{
175 if (dev_phone < 0) {
176 return EINVAL;
177 }
178 if ((buf == NULL)) {
179 return ENOMEM;
180 }
181 if (size == 0) {
182 return EINVAL;
183 }
184
185 aid_t opening_request = async_send_1(dev_phone,
186 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
187 NULL);
188 if (opening_request == 0) {
189 return ENOMEM;
190 }
191
192 ipc_call_t data_request_call;
193 aid_t data_request = async_data_read(dev_phone, buf, size,
194 &data_request_call);
195 if (data_request == 0) {
196 async_wait_for(opening_request, NULL);
197 return ENOMEM;
198 }
199
200 sysarg_t data_request_rc;
201 sysarg_t opening_request_rc;
202 async_wait_for(data_request, &data_request_rc);
203 async_wait_for(opening_request, &opening_request_rc);
204
205 if (data_request_rc != EOK) {
206 /* Prefer return code of the opening request. */
207 if (opening_request_rc != EOK) {
208 return (int) opening_request_rc;
209 } else {
210 return (int) data_request_rc;
211 }
212 }
213
214 if (opening_request_rc != EOK) {
215 return (int) opening_request_rc;
216 }
217
218 size_t act_size = IPC_GET_ARG2(data_request_call);
219
220 if (actual_size != NULL) {
221 *actual_size = act_size;
222 }
223
224 return EOK;
225}
226
227/**
228 * @}
229 */
Note: See TracBrowser for help on using the repository browser.