t_usbhid.c revision 1.9 1 /* $NetBSD: t_usbhid.c,v 1.9 2016/01/04 22:07:16 jakllsch Exp $ */
2
3 /*
4 * Copyright (c) 2016 Jonathan A. Kollasch
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: t_usbhid.c,v 1.9 2016/01/04 22:07:16 jakllsch Exp $");
31
32 #include <atf-c.h>
33
34 #include <inttypes.h>
35 #include <usbhid.h>
36 #include <string.h>
37
38 #include <stdio.h>
39 #include <stdlib.h>
40
41 #include <limits.h>
42
43 ATF_TC(check_hid_logical_range);
44 ATF_TC(check_hid_physical_range);
45 ATF_TC(check_hid_usage);
46 ATF_TC(check_hid_get_data);
47 ATF_TC(check_hid_set_data);
48
49 #define MYd_ATF_CHECK_EQ(d, v) \
50 ATF_CHECK_EQ_MSG(d, v, "== %d", (d))
51
52 #define MYu_ATF_CHECK_EQ(d, v) \
53 ATF_CHECK_EQ_MSG(d, v, "== %u", (d))
54
55 #define MYx_ATF_CHECK_EQ(d, v) \
56 ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d))
57
58 #include "hid_test_data.c"
59
60 ATF_TC_HEAD(check_hid_usage, tc)
61 {
62
63 atf_tc_set_md_var(tc, "descr", "Test libusbhid usage.c");
64 }
65
66 ATF_TC_BODY(check_hid_usage, tc)
67 {
68 char usages_path[PATH_MAX];
69
70 (void)strlcpy(usages_path, atf_tc_get_config_var(tc, "srcdir"),
71 sizeof(usages_path));
72 (void)strlcat(usages_path, "/test_usb_hid_usages",
73 sizeof(usages_path));
74
75 hid_init(usages_path);
76
77 ATF_CHECK_STREQ("t_usbhid_page", hid_usage_page(0xff1b));
78 ATF_CHECK_EQ((uint32_t)hid_parse_usage_page("t_usbhid_page"), 0xff1b);
79
80 ATF_CHECK_STREQ("t_usbhid_usage", hid_usage_in_page(0xff1bff2a));
81 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page(
82 "t_usbhid_page:t_usbhid_usage"), 0xff1bff2a);
83
84 ATF_CHECK_STREQ("Quick_zephyrs_blow_vexing_daft_Jim_",
85 hid_usage_page(0xff2a));
86 ATF_CHECK_EQ((uint32_t)hid_parse_usage_page(
87 "Quick_zephyrs_blow_vexing_daft_Jim_"), 0xff2a);
88
89 ATF_CHECK_STREQ("Usage_ID_Zero_%", hid_usage_in_page(0xff2a0000));
90 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page(
91 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_Zero_%"),
92 0xff2a0000);
93
94 //ATF_CHECK_STREQ("Usage_ID_0_%", hid_usage_in_page(0xff2a0000));
95 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page(
96 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_0_%"), 0xff2a0000);
97
98 ATF_CHECK_STREQ("Usage_ID_65535_%", hid_usage_in_page(0xff2affff));
99 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page(
100 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_65535_%"),
101 0xff2affff);
102
103 MYx_ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page("0xff2a:0xff1b"),
104 0xff2aff1b);
105 }
106
107 ATF_TC_HEAD(check_hid_logical_range, tc)
108 {
109
110 atf_tc_set_md_var(tc, "descr", "Test hid_get_item "
111 "Logical Minimum/Maximum results");
112 }
113
114 ATF_TC_BODY(check_hid_logical_range, tc)
115 {
116 report_desc_t hrd;
117 hid_item_t hi;
118 uint32_t minimum, maximum;
119
120 atf_tc_expect_fail("only the 32-bit opcode works, "
121 "8 and 16-bit is broken");
122
123 ATF_REQUIRE((hrd = hid_use_report_desc(range_test_report_descriptor,
124 __arraycount(range_test_report_descriptor))) != NULL);
125 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi,
126 NO_REPORT_ID) > 0);
127 MYd_ATF_CHECK_EQ(hi.logical_minimum, -128);
128 MYd_ATF_CHECK_EQ(hi.logical_maximum, 127);
129 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi,
130 NO_REPORT_ID) > 0);
131 MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768);
132 MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767);
133 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi,
134 NO_REPORT_ID) > 0);
135 MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648);
136 MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647);
137
138 hid_dispose_report_desc(hrd);
139 hrd = NULL;
140
141 ATF_REQUIRE((hrd = hid_use_report_desc(
142 unsigned_range_test_report_descriptor,
143 __arraycount(unsigned_range_test_report_descriptor))) != NULL);
144 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi,
145 NO_REPORT_ID) > 0);
146 ATF_CHECK(hi.logical_minimum > hi.logical_maximum);
147 minimum = (uint32_t)hi.logical_minimum & ((1ULL<<hi.report_size)-1);
148 MYu_ATF_CHECK_EQ(minimum, 0);
149 maximum = (uint32_t)hi.logical_maximum & ((1ULL<<hi.report_size)-1);
150 MYu_ATF_CHECK_EQ(maximum, 255);
151 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi,
152 NO_REPORT_ID) > 0);
153 ATF_CHECK(hi.logical_minimum > hi.logical_maximum);
154 minimum = hi.logical_minimum & ((1ULL<<hi.report_size)-1);
155 MYu_ATF_CHECK_EQ(minimum, 0);
156 maximum = hi.logical_maximum & ((1ULL<<hi.report_size)-1);
157 MYu_ATF_CHECK_EQ(maximum, 65535);
158 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi,
159 NO_REPORT_ID) > 0);
160 ATF_CHECK(hi.logical_minimum > hi.logical_maximum);
161 minimum = hi.logical_minimum & ((1ULL<<hi.report_size)-1);
162 MYu_ATF_CHECK_EQ(minimum, 0);
163 maximum = hi.logical_maximum & ((1ULL<<hi.report_size)-1);
164 MYu_ATF_CHECK_EQ(maximum, 4294967295);
165
166 hid_dispose_report_desc(hrd);
167 hrd = NULL;
168 }
169
170 ATF_TC_HEAD(check_hid_physical_range, tc)
171 {
172
173 atf_tc_set_md_var(tc, "descr", "Test hid_get_item "
174 "Physical Minimum/Maximum results");
175 }
176
177 ATF_TC_BODY(check_hid_physical_range, tc)
178 {
179 report_desc_t hrd;
180 hid_item_t hi;
181 uint32_t minimum, maximum;
182
183 atf_tc_expect_fail("only the 32-bit opcode works, "
184 "8 and 16-bit is broken");
185
186 ATF_REQUIRE((hrd = hid_use_report_desc(range_test_report_descriptor,
187 __arraycount(range_test_report_descriptor))) != NULL);
188 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi,
189 NO_REPORT_ID) > 0);
190 MYd_ATF_CHECK_EQ(hi.physical_minimum, -128);
191 MYd_ATF_CHECK_EQ(hi.physical_maximum, 127);
192 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi,
193 NO_REPORT_ID) > 0);
194 MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768);
195 MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767);
196 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi,
197 NO_REPORT_ID) > 0);
198 MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648);
199 MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647);
200
201 hid_dispose_report_desc(hrd);
202 hrd = NULL;
203
204 ATF_REQUIRE((hrd = hid_use_report_desc(
205 unsigned_range_test_report_descriptor,
206 __arraycount(unsigned_range_test_report_descriptor))) != NULL);
207 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi,
208 NO_REPORT_ID) > 0);
209 ATF_CHECK(hi.physical_minimum > hi.physical_maximum);
210 minimum = (uint32_t)hi.physical_minimum & ((1ULL<<hi.report_size)-1);
211 MYu_ATF_CHECK_EQ(minimum, 0);
212 maximum = (uint32_t)hi.physical_maximum & ((1ULL<<hi.report_size)-1);
213 MYu_ATF_CHECK_EQ(maximum, 255);
214 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi,
215 NO_REPORT_ID) > 0);
216 ATF_CHECK(hi.physical_minimum > hi.physical_maximum);
217 minimum = hi.physical_minimum & ((1ULL<<hi.report_size)-1);
218 MYu_ATF_CHECK_EQ(minimum, 0);
219 maximum = hi.physical_maximum & ((1ULL<<hi.report_size)-1);
220 MYu_ATF_CHECK_EQ(maximum, 65535);
221 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi,
222 NO_REPORT_ID) > 0);
223 ATF_CHECK(hi.physical_minimum > hi.physical_maximum);
224 minimum = hi.physical_minimum & ((1ULL<<hi.report_size)-1);
225 MYu_ATF_CHECK_EQ(minimum, 0);
226 maximum = hi.physical_maximum & ((1ULL<<hi.report_size)-1);
227 MYu_ATF_CHECK_EQ(maximum, 4294967295);
228
229 hid_dispose_report_desc(hrd);
230 hrd = NULL;
231 }
232
233 ATF_TC_HEAD(check_hid_get_data, tc)
234 {
235
236 atf_tc_set_md_var(tc, "descr", "Test hid_get_data results");
237 }
238
239 ATF_TC_BODY(check_hid_get_data, tc)
240 {
241 report_desc_t hrd;
242 hid_item_t hi;
243 int32_t data;
244 uint32_t udat;
245
246 ATF_REQUIRE((hrd = hid_use_report_desc(
247 range_test_report_descriptor,
248 __arraycount(range_test_report_descriptor))) != NULL);
249
250 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi,
251 NO_REPORT_ID) > 0);
252 data = hid_get_data(range_test_minimum_report, &hi);
253 MYd_ATF_CHECK_EQ(data, -128);
254 data = hid_get_data(range_test_negative_one_report, &hi);
255 MYd_ATF_CHECK_EQ(data, -1);
256 data = hid_get_data(range_test_positive_one_report, &hi);
257 MYd_ATF_CHECK_EQ(data, 1);
258 data = hid_get_data(range_test_maximum_report, &hi);
259 MYd_ATF_CHECK_EQ(data, 127);
260
261 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi,
262 NO_REPORT_ID) > 0);
263 data = hid_get_data(range_test_minimum_report, &hi);
264 MYd_ATF_CHECK_EQ(data, -32768);
265 data = hid_get_data(range_test_negative_one_report, &hi);
266 MYd_ATF_CHECK_EQ(data, -1);
267 data = hid_get_data(range_test_positive_one_report, &hi);
268 MYd_ATF_CHECK_EQ(data, 1);
269 data = hid_get_data(range_test_maximum_report, &hi);
270 MYd_ATF_CHECK_EQ(data, 32767);
271
272 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi,
273 NO_REPORT_ID) > 0);
274 data = hid_get_data(range_test_minimum_report, &hi);
275 MYd_ATF_CHECK_EQ(data, -2147483648);
276 data = hid_get_data(range_test_negative_one_report, &hi);
277 MYd_ATF_CHECK_EQ(data, -1);
278 data = hid_get_data(range_test_positive_one_report, &hi);
279 MYd_ATF_CHECK_EQ(data, 1);
280 data = hid_get_data(range_test_maximum_report, &hi);
281 MYd_ATF_CHECK_EQ(data, 2147483647);
282
283 hid_dispose_report_desc(hrd);
284 hrd = NULL;
285
286 ATF_REQUIRE((hrd = hid_use_report_desc(
287 unsigned_range_test_report_descriptor,
288 __arraycount(unsigned_range_test_report_descriptor))) != NULL);
289 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi,
290 NO_REPORT_ID) > 0);
291 udat = hid_get_data(unsigned_range_test_minimum_report, &hi);
292 MYu_ATF_CHECK_EQ(udat, 0);
293 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi);
294 MYu_ATF_CHECK_EQ(udat, 1);
295 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi);
296 MYu_ATF_CHECK_EQ(udat, 254);
297 udat = hid_get_data(unsigned_range_test_maximum_report, &hi);
298 MYu_ATF_CHECK_EQ(udat, 255);
299
300 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi,
301 NO_REPORT_ID) > 0);
302 udat = hid_get_data(unsigned_range_test_minimum_report, &hi);
303 MYu_ATF_CHECK_EQ(udat, 0);
304 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi);
305 MYu_ATF_CHECK_EQ(udat, 1);
306 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi);
307 MYu_ATF_CHECK_EQ(udat, 65534);
308 udat = hid_get_data(unsigned_range_test_maximum_report, &hi);
309 MYu_ATF_CHECK_EQ(udat, 65535);
310
311 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi,
312 NO_REPORT_ID) > 0);
313 udat = hid_get_data(unsigned_range_test_minimum_report, &hi);
314 MYu_ATF_CHECK_EQ(udat, 0);
315 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi);
316 MYu_ATF_CHECK_EQ(udat, 1);
317 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi);
318 MYu_ATF_CHECK_EQ(udat, 4294967294);
319 udat = hid_get_data(unsigned_range_test_maximum_report, &hi);
320 MYu_ATF_CHECK_EQ(udat, 4294967295);
321
322 hid_dispose_report_desc(hrd);
323 hrd = NULL;
324 }
325
326 ATF_TC_HEAD(check_hid_set_data, tc)
327 {
328
329 atf_tc_set_md_var(tc, "descr", "Test hid_set_data results");
330 }
331
332 ATF_TC_BODY(check_hid_set_data, tc)
333 {
334 report_desc_t hrd;
335 hid_item_t hi;
336 uint8_t test_data_minimum[7];
337 uint8_t test_data_negative_one[7];
338 uint8_t test_data_positive_one[7];
339 uint8_t test_data_maximum[7];
340
341 ATF_REQUIRE((hrd = hid_use_report_desc(
342 range_test_report_descriptor,
343 __arraycount(range_test_report_descriptor))) != NULL);
344 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi,
345 NO_REPORT_ID) > 0);
346 hid_set_data(test_data_minimum, &hi, -128);
347 hid_set_data(test_data_negative_one, &hi, -1);
348 hid_set_data(test_data_positive_one, &hi, 1);
349 hid_set_data(test_data_maximum, &hi, 127);
350 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi,
351 NO_REPORT_ID) > 0);
352 hid_set_data(test_data_minimum, &hi, -32768);
353 hid_set_data(test_data_negative_one, &hi, -1);
354 hid_set_data(test_data_positive_one, &hi, 1);
355 hid_set_data(test_data_maximum, &hi, 32767);
356 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi,
357 NO_REPORT_ID) > 0);
358 hid_set_data(test_data_minimum, &hi, -2147483648);
359 hid_set_data(test_data_negative_one, &hi, -1);
360 hid_set_data(test_data_positive_one, &hi, 1);
361 hid_set_data(test_data_maximum, &hi, 2147483647);
362 ATF_CHECK(memcmp(test_data_minimum, range_test_minimum_report,
363 sizeof test_data_minimum) == 0);
364 ATF_CHECK(memcmp(test_data_negative_one,
365 range_test_negative_one_report,
366 sizeof test_data_negative_one) == 0);
367 ATF_CHECK(memcmp(test_data_positive_one,
368 range_test_positive_one_report,
369 sizeof test_data_positive_one) == 0);
370 ATF_CHECK(memcmp(test_data_maximum, range_test_maximum_report,
371 sizeof test_data_maximum) == 0);
372
373 hid_dispose_report_desc(hrd);
374 hrd = NULL;
375
376 ATF_REQUIRE((hrd = hid_use_report_desc(
377 unsigned_range_test_report_descriptor,
378 __arraycount(range_test_report_descriptor))) != NULL);
379 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi,
380 NO_REPORT_ID) > 0);
381 hid_set_data(test_data_minimum, &hi, 0);
382 hid_set_data(test_data_positive_one, &hi, 1);
383 hid_set_data(test_data_negative_one, &hi, 0xfffffffe);
384 hid_set_data(test_data_maximum, &hi, 0xffffffff);
385 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi,
386 NO_REPORT_ID) > 0);
387 hid_set_data(test_data_minimum, &hi, 0);
388 hid_set_data(test_data_positive_one, &hi, 1);
389 hid_set_data(test_data_negative_one, &hi, 0xfffe);
390 hid_set_data(test_data_maximum, &hi, 0xffff);
391 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi,
392 NO_REPORT_ID) > 0);
393 hid_set_data(test_data_minimum, &hi, 0);
394 hid_set_data(test_data_positive_one, &hi, 1);
395 hid_set_data(test_data_negative_one, &hi, 0xfffffffe);
396 hid_set_data(test_data_maximum, &hi, 0xffffffff);
397 ATF_CHECK(memcmp(test_data_minimum,
398 unsigned_range_test_minimum_report,
399 sizeof test_data_minimum) == 0);
400 ATF_CHECK(memcmp(test_data_negative_one,
401 unsigned_range_test_negative_one_report,
402 sizeof test_data_negative_one) == 0);
403 ATF_CHECK(memcmp(test_data_positive_one,
404 unsigned_range_test_positive_one_report,
405 sizeof test_data_positive_one) == 0);
406 ATF_CHECK(memcmp(test_data_maximum,
407 unsigned_range_test_maximum_report,
408 sizeof test_data_maximum) == 0);
409
410 hid_dispose_report_desc(hrd);
411 hrd = NULL;
412 }
413
414 ATF_TP_ADD_TCS(tp)
415 {
416
417 ATF_TP_ADD_TC(tp, check_hid_logical_range);
418 ATF_TP_ADD_TC(tp, check_hid_physical_range);
419 ATF_TP_ADD_TC(tp, check_hid_usage);
420 ATF_TP_ADD_TC(tp, check_hid_get_data);
421 ATF_TP_ADD_TC(tp, check_hid_set_data);
422
423 return atf_no_error();
424 }
425