t_hid.c revision 1.5
1/*	$NetBSD: t_hid.c,v 1.5 2016/01/09 14:31:19 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_hid.c,v 1.5 2016/01/09 14:31:19 jakllsch Exp $");
31
32#include <machine/types.h>
33#include <stdlib.h>
34#include <string.h>
35#include <stdio.h>
36#include <atf-c.h>
37#define hid_start_parse rumpns_hid_start_parse
38#define hid_end_parse rumpns_hid_end_parse
39#define hid_get_item rumpns_hid_get_item
40#define hid_locate rumpns_hid_locate
41#define hid_report_size rumpns_hid_report_size
42#define hid_get_data rumpns_hid_get_data
43#define hid_get_udata rumpns_hid_get_udata
44#define uhidevdebug rumpns_uhidevdebug
45#include <usb.h>
46#include <usbhid.h>
47#include <hid.h>
48
49#include "../../lib/libusbhid/hid_test_data.c"
50
51#define MYd_ATF_CHECK_EQ(d, v) \
52	ATF_CHECK_EQ_MSG(d, v, "== %d", (d))
53
54#define MYld_ATF_CHECK_EQ(d, v) \
55	ATF_CHECK_EQ_MSG(d, v, "== %ld", (d))
56
57#define MYu_ATF_CHECK_EQ(d, v) \
58	ATF_CHECK_EQ_MSG(d, v, "== %u", (d))
59
60#define MYlu_ATF_CHECK_EQ(d, v) \
61	ATF_CHECK_EQ_MSG(d, v, "== %lu", (d))
62
63#define MYx_ATF_CHECK_EQ(d, v) \
64	ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d))
65
66#define MYlx_ATF_CHECK_EQ(d, v) \
67	ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d))
68
69int uhidevdebug;
70
71ATF_TC(khid);
72
73ATF_TC_HEAD(khid, tc)
74{
75
76        atf_tc_set_md_var(tc, "descr", "check kernel hid.c");
77}
78
79static int
80locate_item(const void *desc, int size, u_int32_t u, u_int8_t id,
81    enum hid_kind k, struct hid_item *hip)
82{
83	struct hid_data *d;
84	struct hid_item h;
85
86	h.report_ID = 0;
87	for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
88		if (h.kind == k && !(h.flags & HIO_CONST) &&
89		    (/*XXX*/uint32_t)h.usage == u && h.report_ID == id) {
90			if (hip != NULL)
91				*hip = h;
92			hid_end_parse(d);
93			return (1);
94		}
95	}
96	hid_end_parse(d);
97	return (0);
98}
99
100ATF_TC_BODY(khid, tc)
101{
102	int ret;
103	struct hid_item hi;
104
105	uhidevdebug = 0;
106
107	ret = locate_item(range_test_report_descriptor,
108	    sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input,
109	    &hi);
110	ATF_REQUIRE(ret > 0);
111	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
112	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
113	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
114	MYx_ATF_CHECK_EQ(hi.flags, 0);
115	MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648);
116	MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647);
117	MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648);
118	MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647);
119	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
120	    &hi.loc), -2147483648);
121	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
122	    &hi.loc), -1);
123	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
124	    &hi.loc), 1);
125	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
126	    &hi.loc), 2147483647);
127
128	ret = locate_item(range_test_report_descriptor,
129	    sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input,
130	    &hi);
131	ATF_REQUIRE(ret > 0);
132	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
133	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
134	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
135	MYx_ATF_CHECK_EQ(hi.flags, 0);
136	MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768);
137	MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767);
138	MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768);
139	MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767);
140	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
141	    &hi.loc), -32768);
142	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
143	    &hi.loc), -1);
144	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
145	    &hi.loc), 1);
146	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
147	    &hi.loc), 32767);
148
149	ret = locate_item(range_test_report_descriptor,
150	    sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input,
151	    &hi);
152	ATF_REQUIRE(ret > 0);
153	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
154	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
155	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
156	MYx_ATF_CHECK_EQ(hi.flags, 0);
157	MYd_ATF_CHECK_EQ(hi.logical_minimum, -128);
158	MYd_ATF_CHECK_EQ(hi.logical_maximum, 127);
159	MYd_ATF_CHECK_EQ(hi.physical_minimum, -128);
160	MYd_ATF_CHECK_EQ(hi.physical_maximum, 127);
161	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
162	    &hi.loc), -128);
163	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
164	    &hi.loc), -1);
165	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
166	    &hi.loc), 1);
167	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
168	    &hi.loc), 127);
169
170
171	ret = locate_item(unsigned_range_test_report_descriptor,
172	    sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0,
173	    hid_input, &hi);
174	ATF_REQUIRE(ret > 0);
175	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
176	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
177	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
178	MYx_ATF_CHECK_EQ(hi.flags, 0);
179	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
180	    &hi.loc), 0x0);
181	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
182	    &hi.loc), 0x1);
183	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
184	    &hi.loc), 0xfffffffe);
185	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
186	    &hi.loc), 0xffffffff);
187
188	ret = locate_item(unsigned_range_test_report_descriptor,
189	    sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0,
190	    hid_input, &hi);
191	ATF_REQUIRE(ret > 0);
192	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
193	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
194	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
195	MYx_ATF_CHECK_EQ(hi.flags, 0);
196	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
197	    &hi.loc), 0x0);
198	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
199	    &hi.loc), 0x1);
200	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
201	    &hi.loc), 0xfffe);
202	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
203	    &hi.loc), 0xffff);
204
205	ret = locate_item(unsigned_range_test_report_descriptor,
206	    sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0,
207	    hid_input, &hi);
208	ATF_REQUIRE(ret > 0);
209	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
210	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
211	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
212	MYx_ATF_CHECK_EQ(hi.flags, 0);
213	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
214	    &hi.loc), 0x0);
215	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
216	    &hi.loc), 0x1);
217	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
218	    &hi.loc), 0xfe);
219	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
220	    &hi.loc), 0xff);
221}
222
223ATF_TC(khid_parse_just_pop);
224
225ATF_TC_HEAD(khid_parse_just_pop, tc)
226{
227
228        atf_tc_set_md_var(tc, "descr", "check kernel hid.c for "
229	    "Pop on empty stack bug");
230}
231
232ATF_TC_BODY(khid_parse_just_pop, tc)
233{
234	struct hid_data *hdp;
235	struct hid_item hi;
236
237	hdp = hid_start_parse(just_pop_report_descriptor,
238	    sizeof just_pop_report_descriptor, hid_none);
239	while (hid_get_item(hdp, &hi) > 0) {
240	}
241	hid_end_parse(hdp);
242}
243
244ATF_TP_ADD_TCS(tp)
245{
246
247        ATF_TP_ADD_TC(tp, khid);
248        ATF_TP_ADD_TC(tp, khid_parse_just_pop);
249
250	return atf_no_error();
251}
252
253