1 /* $NetBSD: t_usbhid.c,v 1.12 2016/08/17 12:10:42 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.12 2016/08/17 12:10:42 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 ATF_TC(check_parse_just_pop); 49 50 #define MYd_ATF_CHECK_EQ(d, v) \ 51 ATF_CHECK_EQ_MSG(d, v, "== %d", (d)) 52 53 #define MYu_ATF_CHECK_EQ(d, v) \ 54 ATF_CHECK_EQ_MSG(d, v, "== %u", (d)) 55 56 #define MYx_ATF_CHECK_EQ(d, v) \ 57 ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d)) 58 59 #include "hid_test_data.c" 60 61 ATF_TC_HEAD(check_hid_usage, tc) 62 { 63 64 atf_tc_set_md_var(tc, "descr", "Test libusbhid usage.c"); 65 } 66 67 ATF_TC_BODY(check_hid_usage, tc) 68 { 69 char usages_path[PATH_MAX]; 70 71 (void)strlcpy(usages_path, atf_tc_get_config_var(tc, "srcdir"), 72 sizeof(usages_path)); 73 (void)strlcat(usages_path, "/test_usb_hid_usages", 74 sizeof(usages_path)); 75 76 hid_init(usages_path); 77 78 ATF_CHECK_STREQ("t_usbhid_page", hid_usage_page(0xff1b)); 79 ATF_CHECK_EQ((uint32_t)hid_parse_usage_page("t_usbhid_page"), 0xff1b); 80 81 ATF_CHECK_STREQ("t_usbhid_usage", hid_usage_in_page(0xff1bff2a)); 82 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( 83 "t_usbhid_page:t_usbhid_usage"), 0xff1bff2a); 84 85 ATF_CHECK_STREQ("Quick_zephyrs_blow_vexing_daft_Jim_", 86 hid_usage_page(0xff2a)); 87 ATF_CHECK_EQ((uint32_t)hid_parse_usage_page( 88 "Quick_zephyrs_blow_vexing_daft_Jim_"), 0xff2a); 89 90 ATF_CHECK_STREQ("Usage_ID_Zero_%", hid_usage_in_page(0xff2a0000)); 91 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( 92 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_Zero_%"), 93 0xff2a0000); 94 95 //ATF_CHECK_STREQ("Usage_ID_0_%", hid_usage_in_page(0xff2a0000)); 96 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( 97 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_0_%"), 0xff2a0000); 98 99 ATF_CHECK_STREQ("Usage_ID_65535_%", hid_usage_in_page(0xff2affff)); 100 ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( 101 "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_65535_%"), 102 0xff2affff); 103 104 MYx_ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page("0xff2a:0xff1b"), 105 0xff2aff1b); 106 } 107 108 ATF_TC_HEAD(check_hid_logical_range, tc) 109 { 110 111 atf_tc_set_md_var(tc, "descr", "Test hid_get_item " 112 "Logical Minimum/Maximum results"); 113 } 114 115 ATF_TC_BODY(check_hid_logical_range, tc) 116 { 117 report_desc_t hrd; 118 hid_item_t hi; 119 uint32_t minimum, maximum; 120 121 atf_tc_expect_fail("only the 32-bit opcode works, " 122 "8 and 16-bit is broken"); 123 124 ATF_REQUIRE((hrd = hid_use_report_desc(range_test_report_descriptor, 125 __arraycount(range_test_report_descriptor))) != NULL); 126 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, 127 NO_REPORT_ID) > 0); 128 MYd_ATF_CHECK_EQ(hi.logical_minimum, -128); 129 MYd_ATF_CHECK_EQ(hi.logical_maximum, 127); 130 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, 131 NO_REPORT_ID) > 0); 132 MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768); 133 MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767); 134 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, 135 NO_REPORT_ID) > 0); 136 MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648); 137 MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647); 138 139 hid_dispose_report_desc(hrd); 140 hrd = NULL; 141 142 ATF_REQUIRE((hrd = hid_use_report_desc( 143 unsigned_range_test_report_descriptor, 144 __arraycount(unsigned_range_test_report_descriptor))) != NULL); 145 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, 146 NO_REPORT_ID) > 0); 147 ATF_CHECK(hi.logical_minimum > hi.logical_maximum); 148 minimum = (uint32_t)hi.logical_minimum & ((1ULL<<hi.report_size)-1); 149 MYu_ATF_CHECK_EQ(minimum, 0); 150 maximum = (uint32_t)hi.logical_maximum & ((1ULL<<hi.report_size)-1); 151 MYu_ATF_CHECK_EQ(maximum, 255); 152 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, 153 NO_REPORT_ID) > 0); 154 ATF_CHECK(hi.logical_minimum > hi.logical_maximum); 155 minimum = hi.logical_minimum & ((1ULL<<hi.report_size)-1); 156 MYu_ATF_CHECK_EQ(minimum, 0); 157 maximum = hi.logical_maximum & ((1ULL<<hi.report_size)-1); 158 MYu_ATF_CHECK_EQ(maximum, 65535); 159 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, 160 NO_REPORT_ID) > 0); 161 ATF_CHECK(hi.logical_minimum > hi.logical_maximum); 162 minimum = hi.logical_minimum & ((1ULL<<hi.report_size)-1); 163 MYu_ATF_CHECK_EQ(minimum, 0); 164 maximum = hi.logical_maximum & ((1ULL<<hi.report_size)-1); 165 MYu_ATF_CHECK_EQ(maximum, 4294967295); 166 167 hid_dispose_report_desc(hrd); 168 hrd = NULL; 169 } 170 171 ATF_TC_HEAD(check_hid_physical_range, tc) 172 { 173 174 atf_tc_set_md_var(tc, "descr", "Test hid_get_item " 175 "Physical Minimum/Maximum results"); 176 } 177 178 ATF_TC_BODY(check_hid_physical_range, tc) 179 { 180 report_desc_t hrd; 181 hid_item_t hi; 182 uint32_t minimum, maximum; 183 184 atf_tc_expect_fail("only the 32-bit opcode works, " 185 "8 and 16-bit is broken"); 186 187 ATF_REQUIRE((hrd = hid_use_report_desc(range_test_report_descriptor, 188 __arraycount(range_test_report_descriptor))) != NULL); 189 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, 190 NO_REPORT_ID) > 0); 191 MYd_ATF_CHECK_EQ(hi.physical_minimum, -128); 192 MYd_ATF_CHECK_EQ(hi.physical_maximum, 127); 193 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, 194 NO_REPORT_ID) > 0); 195 MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768); 196 MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767); 197 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, 198 NO_REPORT_ID) > 0); 199 MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648); 200 MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647); 201 202 hid_dispose_report_desc(hrd); 203 hrd = NULL; 204 205 ATF_REQUIRE((hrd = hid_use_report_desc( 206 unsigned_range_test_report_descriptor, 207 __arraycount(unsigned_range_test_report_descriptor))) != NULL); 208 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, 209 NO_REPORT_ID) > 0); 210 ATF_CHECK(hi.physical_minimum > hi.physical_maximum); 211 minimum = (uint32_t)hi.physical_minimum & ((1ULL<<hi.report_size)-1); 212 MYu_ATF_CHECK_EQ(minimum, 0); 213 maximum = (uint32_t)hi.physical_maximum & ((1ULL<<hi.report_size)-1); 214 MYu_ATF_CHECK_EQ(maximum, 255); 215 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, 216 NO_REPORT_ID) > 0); 217 ATF_CHECK(hi.physical_minimum > hi.physical_maximum); 218 minimum = hi.physical_minimum & ((1ULL<<hi.report_size)-1); 219 MYu_ATF_CHECK_EQ(minimum, 0); 220 maximum = hi.physical_maximum & ((1ULL<<hi.report_size)-1); 221 MYu_ATF_CHECK_EQ(maximum, 65535); 222 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, 223 NO_REPORT_ID) > 0); 224 ATF_CHECK(hi.physical_minimum > hi.physical_maximum); 225 minimum = hi.physical_minimum & ((1ULL<<hi.report_size)-1); 226 MYu_ATF_CHECK_EQ(minimum, 0); 227 maximum = hi.physical_maximum & ((1ULL<<hi.report_size)-1); 228 MYu_ATF_CHECK_EQ(maximum, 4294967295); 229 230 hid_dispose_report_desc(hrd); 231 hrd = NULL; 232 } 233 234 ATF_TC_HEAD(check_hid_get_data, tc) 235 { 236 237 atf_tc_set_md_var(tc, "descr", "Test hid_get_data results"); 238 } 239 240 ATF_TC_BODY(check_hid_get_data, tc) 241 { 242 report_desc_t hrd; 243 hid_item_t hi; 244 int32_t data; 245 uint32_t udat; 246 247 atf_tc_expect_fail("only the 32-bit opcode works, " 248 "8 and 16-bit is broken"); 249 250 ATF_REQUIRE((hrd = hid_use_report_desc( 251 range_test_report_descriptor, 252 __arraycount(range_test_report_descriptor))) != NULL); 253 254 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, 255 NO_REPORT_ID) > 0); 256 data = hid_get_data(range_test_minimum_report, &hi); 257 MYd_ATF_CHECK_EQ(data, -128); 258 data = hid_get_data(range_test_negative_one_report, &hi); 259 MYd_ATF_CHECK_EQ(data, -1); 260 data = hid_get_data(range_test_positive_one_report, &hi); 261 MYd_ATF_CHECK_EQ(data, 1); 262 data = hid_get_data(range_test_maximum_report, &hi); 263 MYd_ATF_CHECK_EQ(data, 127); 264 265 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, 266 NO_REPORT_ID) > 0); 267 data = hid_get_data(range_test_minimum_report, &hi); 268 MYd_ATF_CHECK_EQ(data, -32768); 269 data = hid_get_data(range_test_negative_one_report, &hi); 270 MYd_ATF_CHECK_EQ(data, -1); 271 data = hid_get_data(range_test_positive_one_report, &hi); 272 MYd_ATF_CHECK_EQ(data, 1); 273 data = hid_get_data(range_test_maximum_report, &hi); 274 MYd_ATF_CHECK_EQ(data, 32767); 275 276 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, 277 NO_REPORT_ID) > 0); 278 data = hid_get_data(range_test_minimum_report, &hi); 279 MYd_ATF_CHECK_EQ(data, -2147483648); 280 data = hid_get_data(range_test_negative_one_report, &hi); 281 MYd_ATF_CHECK_EQ(data, -1); 282 data = hid_get_data(range_test_positive_one_report, &hi); 283 MYd_ATF_CHECK_EQ(data, 1); 284 data = hid_get_data(range_test_maximum_report, &hi); 285 MYd_ATF_CHECK_EQ(data, 2147483647); 286 287 hid_dispose_report_desc(hrd); 288 hrd = NULL; 289 290 ATF_REQUIRE((hrd = hid_use_report_desc( 291 unsigned_range_test_report_descriptor, 292 __arraycount(unsigned_range_test_report_descriptor))) != NULL); 293 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, 294 NO_REPORT_ID) > 0); 295 udat = hid_get_data(unsigned_range_test_minimum_report, &hi); 296 MYu_ATF_CHECK_EQ(udat, 0); 297 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); 298 MYu_ATF_CHECK_EQ(udat, 1); 299 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); 300 MYu_ATF_CHECK_EQ(udat, 254); 301 udat = hid_get_data(unsigned_range_test_maximum_report, &hi); 302 MYu_ATF_CHECK_EQ(udat, 255); 303 304 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, 305 NO_REPORT_ID) > 0); 306 udat = hid_get_data(unsigned_range_test_minimum_report, &hi); 307 MYu_ATF_CHECK_EQ(udat, 0); 308 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); 309 MYu_ATF_CHECK_EQ(udat, 1); 310 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); 311 MYu_ATF_CHECK_EQ(udat, 65534); 312 udat = hid_get_data(unsigned_range_test_maximum_report, &hi); 313 MYu_ATF_CHECK_EQ(udat, 65535); 314 315 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, 316 NO_REPORT_ID) > 0); 317 udat = hid_get_data(unsigned_range_test_minimum_report, &hi); 318 MYu_ATF_CHECK_EQ(udat, 0); 319 udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); 320 MYu_ATF_CHECK_EQ(udat, 1); 321 udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); 322 MYu_ATF_CHECK_EQ(udat, 4294967294); 323 udat = hid_get_data(unsigned_range_test_maximum_report, &hi); 324 MYu_ATF_CHECK_EQ(udat, 4294967295); 325 326 hid_dispose_report_desc(hrd); 327 hrd = NULL; 328 } 329 330 ATF_TC_HEAD(check_hid_set_data, tc) 331 { 332 333 atf_tc_set_md_var(tc, "descr", "Test hid_set_data results"); 334 } 335 336 ATF_TC_BODY(check_hid_set_data, tc) 337 { 338 report_desc_t hrd; 339 hid_item_t hi; 340 uint8_t test_data_minimum[7]; 341 uint8_t test_data_negative_one[7]; 342 uint8_t test_data_positive_one[7]; 343 uint8_t test_data_maximum[7]; 344 345 ATF_REQUIRE((hrd = hid_use_report_desc( 346 range_test_report_descriptor, 347 __arraycount(range_test_report_descriptor))) != NULL); 348 ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, 349 NO_REPORT_ID) > 0); 350 hid_set_data(test_data_minimum, &hi, -128); 351 hid_set_data(test_data_negative_one, &hi, -1); 352 hid_set_data(test_data_positive_one, &hi, 1); 353 hid_set_data(test_data_maximum, &hi, 127); 354 ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, 355 NO_REPORT_ID) > 0); 356 hid_set_data(test_data_minimum, &hi, -32768); 357 hid_set_data(test_data_negative_one, &hi, -1); 358 hid_set_data(test_data_positive_one, &hi, 1); 359 hid_set_data(test_data_maximum, &hi, 32767); 360 ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, 361 NO_REPORT_ID) > 0); 362 hid_set_data(test_data_minimum, &hi, -2147483648); 363 hid_set_data(test_data_negative_one, &hi, -1); 364 hid_set_data(test_data_positive_one, &hi, 1); 365 hid_set_data(test_data_maximum, &hi, 2147483647); 366 ATF_CHECK(memcmp(test_data_minimum, range_test_minimum_report, 367 sizeof test_data_minimum) == 0); 368 ATF_CHECK(memcmp(test_data_negative_one, 369 range_test_negative_one_report, 370 sizeof test_data_negative_one) == 0); 371 ATF_CHECK(memcmp(test_data_positive_one, 372 range_test_positive_one_report, 373 sizeof test_data_positive_one) == 0); 374 ATF_CHECK(memcmp(test_data_maximum, range_test_maximum_report, 375 sizeof test_data_maximum) == 0); 376 377 hid_dispose_report_desc(hrd); 378 hrd = NULL; 379 380 ATF_REQUIRE((hrd = hid_use_report_desc( 381 unsigned_range_test_report_descriptor, 382 __arraycount(range_test_report_descriptor))) != NULL); 383 ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, 384 NO_REPORT_ID) > 0); 385 hid_set_data(test_data_minimum, &hi, 0); 386 hid_set_data(test_data_positive_one, &hi, 1); 387 hid_set_data(test_data_negative_one, &hi, 0xfffffffe); 388 hid_set_data(test_data_maximum, &hi, 0xffffffff); 389 ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, 390 NO_REPORT_ID) > 0); 391 hid_set_data(test_data_minimum, &hi, 0); 392 hid_set_data(test_data_positive_one, &hi, 1); 393 hid_set_data(test_data_negative_one, &hi, 0xfffe); 394 hid_set_data(test_data_maximum, &hi, 0xffff); 395 ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, 396 NO_REPORT_ID) > 0); 397 hid_set_data(test_data_minimum, &hi, 0); 398 hid_set_data(test_data_positive_one, &hi, 1); 399 hid_set_data(test_data_negative_one, &hi, 0xfffffffe); 400 hid_set_data(test_data_maximum, &hi, 0xffffffff); 401 ATF_CHECK(memcmp(test_data_minimum, 402 unsigned_range_test_minimum_report, 403 sizeof test_data_minimum) == 0); 404 ATF_CHECK(memcmp(test_data_negative_one, 405 unsigned_range_test_negative_one_report, 406 sizeof test_data_negative_one) == 0); 407 ATF_CHECK(memcmp(test_data_positive_one, 408 unsigned_range_test_positive_one_report, 409 sizeof test_data_positive_one) == 0); 410 ATF_CHECK(memcmp(test_data_maximum, 411 unsigned_range_test_maximum_report, 412 sizeof test_data_maximum) == 0); 413 414 hid_dispose_report_desc(hrd); 415 hrd = NULL; 416 } 417 418 ATF_TC_HEAD(check_parse_just_pop, tc) 419 { 420 421 atf_tc_set_md_var(tc, "descr", "check Pop on empty stack bug"); 422 } 423 424 ATF_TC_BODY(check_parse_just_pop, tc) 425 { 426 report_desc_t hrd; 427 hid_data_t hd; 428 hid_item_t hi; 429 430 ATF_REQUIRE((hrd = hid_use_report_desc( 431 just_pop_report_descriptor, 432 sizeof just_pop_report_descriptor)) != NULL); 433 hd = hid_start_parse(hrd, 0, NO_REPORT_ID); 434 while (hid_get_item(hd, &hi) > 0) { 435 } 436 hid_end_parse(hd); 437 hid_dispose_report_desc(hrd); 438 hrd = NULL; 439 } 440 441 ATF_TP_ADD_TCS(tp) 442 { 443 444 ATF_TP_ADD_TC(tp, check_hid_logical_range); 445 ATF_TP_ADD_TC(tp, check_hid_physical_range); 446 ATF_TP_ADD_TC(tp, check_hid_usage); 447 ATF_TP_ADD_TC(tp, check_hid_get_data); 448 ATF_TP_ADD_TC(tp, check_hid_set_data); 449 ATF_TP_ADD_TC(tp, check_parse_just_pop); 450 451 return atf_no_error(); 452 } 453