t_hid.c revision 1.2
1/*	$NetBSD: t_hid.c,v 1.2 2016/01/07 15:58:23 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.2 2016/01/07 15:58:23 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 <hid.h>
46
47#include "../../lib/libusbhid/hid_test_data.c"
48
49#define MYd_ATF_CHECK_EQ(d, v) \
50	ATF_CHECK_EQ_MSG(d, v, "== %d", (d))
51
52#define MYld_ATF_CHECK_EQ(d, v) \
53	ATF_CHECK_EQ_MSG(d, v, "== %ld", (d))
54
55#define MYu_ATF_CHECK_EQ(d, v) \
56	ATF_CHECK_EQ_MSG(d, v, "== %u", (d))
57
58#define MYlu_ATF_CHECK_EQ(d, v) \
59	ATF_CHECK_EQ_MSG(d, v, "== %lu", (d))
60
61#define MYx_ATF_CHECK_EQ(d, v) \
62	ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d))
63
64#define MYlx_ATF_CHECK_EQ(d, v) \
65	ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d))
66
67int uhidevdebug;
68
69ATF_TC(khid);
70
71ATF_TC_HEAD(khid, tc)
72{
73
74        atf_tc_set_md_var(tc, "descr", "check kernel hid.c");
75}
76
77ATF_TC_BODY(khid, tc)
78{
79	int ret;
80	struct hid_item hi;
81	u_int32_t flags;
82
83	uhidevdebug = 0;
84
85	atf_tc_expect_fail("logical/physical range appears broken");
86
87	ret = hid_locate(range_test_report_descriptor,
88	    sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input,
89	    &hi.loc, &flags);
90	ATF_REQUIRE(ret > 0);
91	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
92	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
93	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
94	MYx_ATF_CHECK_EQ(flags, 0);
95	MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648);
96	MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647);
97	MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648);
98	MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647);
99	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
100	    &hi.loc), -2147483648);
101	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
102	    &hi.loc), -1);
103	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
104	    &hi.loc), 1);
105	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
106	    &hi.loc), 2147483647);
107
108	ret = hid_locate(range_test_report_descriptor,
109	    sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input,
110	    &hi.loc, &flags);
111	ATF_REQUIRE(ret > 0);
112	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
113	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
114	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
115	MYx_ATF_CHECK_EQ(flags, 0);
116	MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768);
117	MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767);
118	MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768);
119	MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767);
120	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
121	    &hi.loc), -32768);
122	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
123	    &hi.loc), -1);
124	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
125	    &hi.loc), 1);
126	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
127	    &hi.loc), 32767);
128
129	ret = hid_locate(range_test_report_descriptor,
130	    sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input,
131	    &hi.loc, &flags);
132	ATF_REQUIRE(ret > 0);
133	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
134	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
135	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
136	MYx_ATF_CHECK_EQ(flags, 0);
137	MYd_ATF_CHECK_EQ(hi.logical_minimum, -128);
138	MYd_ATF_CHECK_EQ(hi.logical_maximum, 127);
139	MYd_ATF_CHECK_EQ(hi.physical_minimum, -128);
140	MYd_ATF_CHECK_EQ(hi.physical_maximum, 127);
141	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
142	    &hi.loc), -128);
143	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
144	    &hi.loc), -1);
145	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
146	    &hi.loc), 1);
147	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
148	    &hi.loc), 127);
149
150
151	ret = hid_locate(unsigned_range_test_report_descriptor,
152	    sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0,
153	    hid_input, &hi.loc, &flags);
154	ATF_REQUIRE(ret > 0);
155	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
156	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
157	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
158	MYx_ATF_CHECK_EQ(flags, 0);
159	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
160	    &hi.loc), 0x0);
161	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
162	    &hi.loc), 0x1);
163	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
164	    &hi.loc), 0xfffffffe);
165	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
166	    &hi.loc), 0xffffffff);
167
168	ret = hid_locate(unsigned_range_test_report_descriptor,
169	    sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0,
170	    hid_input, &hi.loc, &flags);
171	ATF_REQUIRE(ret > 0);
172	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
173	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
174	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
175	MYx_ATF_CHECK_EQ(flags, 0);
176	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
177	    &hi.loc), 0x0);
178	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
179	    &hi.loc), 0x1);
180	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
181	    &hi.loc), 0xfffe);
182	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
183	    &hi.loc), 0xffff);
184
185	ret = hid_locate(unsigned_range_test_report_descriptor,
186	    sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0,
187	    hid_input, &hi.loc, &flags);
188	ATF_REQUIRE(ret > 0);
189	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
190	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
191	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
192	MYx_ATF_CHECK_EQ(flags, 0);
193	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
194	    &hi.loc), 0x0);
195	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
196	    &hi.loc), 0x1);
197	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
198	    &hi.loc), 0xfe);
199	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
200	    &hi.loc), 0xff);
201}
202
203ATF_TC(khid_parse_just_pop);
204
205ATF_TC_HEAD(khid_parse_just_pop, tc)
206{
207
208        atf_tc_set_md_var(tc, "descr", "check kernel hid.c for "
209	    "Pop on empty stack bug");
210}
211
212ATF_TC_BODY(khid_parse_just_pop, tc)
213{
214	struct hid_data *hdp;
215	struct hid_item hi;
216
217	atf_tc_expect_fail("Pop crashes on empty stack.");
218
219	hdp = hid_start_parse(just_pop_report_descriptor,
220	    sizeof just_pop_report_descriptor, hid_none);
221	while (hid_get_item(hdp, &hi) > 0) {
222	}
223	hid_end_parse(hdp);
224}
225
226ATF_TP_ADD_TCS(tp)
227{
228
229        ATF_TP_ADD_TC(tp, khid);
230        ATF_TP_ADD_TC(tp, khid_parse_just_pop);
231
232	return atf_no_error();
233}
234
235