1 /* 2 * v4l-test: Test environment for Video For Linux Two API 3 * 4 * 20 Apr 2009 0.4 Added string content validation 5 * 18 Apr 2009 0.3 More strict check for strings 6 * 28 Mar 2009 0.2 Clean up ret and errno variable names and dprintf() output 7 * 2 Jan 2009 0.1 First release 8 * 9 * Written by Mrton Nmeth <nm127 (at) freemail.hu> 10 * Released under GPL 11 */ 12 13 /* 14 * Note: V4L2_CID_LASTP1 != V4L2_CID_BASE_LASTP1 15 */ 16 17 #include <sys/ioctl.h> 18 #include <errno.h> 19 #include <string.h> 20 21 #include <linux/videodev2.h> 22 #include <linux/errno.h> 23 24 #include <CUnit/CUnit.h> 25 26 #include "v4l2_test.h" 27 #include "dev_video.h" 28 #include "video_limits.h" 29 #include "v4l2_validator.h" 30 31 #include "test_VIDIOC_QUERYCTRL.h" 32 33 static int valid_control_flag(__u32 flags) 34 { 35 int valid = 0; 36 37 if ((flags & ~(V4L2_CTRL_FLAG_DISABLED | 38 V4L2_CTRL_FLAG_GRABBED | 39 V4L2_CTRL_FLAG_READ_ONLY | 40 V4L2_CTRL_FLAG_UPDATE | 41 V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_SLIDER)) 42 == 0) { 43 valid = 1; 44 } else { 45 valid = 0; 46 } 47 return valid; 48 } 49 50 static int valid_control_type(__u32 type) 51 { 52 int valid = 0; 53 54 switch (type) { 55 case V4L2_CTRL_TYPE_INTEGER: 56 case V4L2_CTRL_TYPE_BOOLEAN: 57 case V4L2_CTRL_TYPE_MENU: 58 case V4L2_CTRL_TYPE_BUTTON: 59 case V4L2_CTRL_TYPE_INTEGER64: 60 case V4L2_CTRL_TYPE_CTRL_CLASS: 61 valid = 1; 62 break; 63 default: 64 valid = 0; 65 } 66 return valid; 67 } 68 69 void test_VIDIOC_QUERYCTRL() 70 { 71 int ret_query, errno_query; 72 struct v4l2_queryctrl queryctrl; 73 struct v4l2_queryctrl queryctrl2; 74 __u32 i; 75 76 /* The available controls and their parameters 77 * may change with different 78 * - input or output 79 * - tuner or modulator 80 * - audio input or audio output 81 * See V4L API specification rev. 0.24, Chapter 1.8. 82 * "User Controls" for details 83 * 84 * TODO: iterate through the mentioned settings. 85 * TODO: check for deprecated controls (maybe in a 86 * separated test case which could fail when a 87 * deprecated control is supported) 88 */ 89 90 for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) { 91 92 memset(&queryctrl, 0xff, sizeof(queryctrl)); 93 queryctrl.id = i; 94 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 95 errno_query = errno; 96 97 dprintf 98 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n", 99 __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query, 100 errno_query); 101 102 if (ret_query == 0) { 103 CU_ASSERT_EQUAL(ret_query, 0); 104 CU_ASSERT_EQUAL(queryctrl.id, i); 105 106 CU_ASSERT(0 < strlen((char *)queryctrl.name)); 107 CU_ASSERT(valid_string 108 ((char *)queryctrl.name, 109 sizeof(queryctrl.name))); 110 111 CU_ASSERT(valid_control_type(queryctrl.type)); 112 113 switch (queryctrl.type) { 114 case V4L2_CTRL_TYPE_INTEGER: 115 /* min < max, because otherwise this control makes no sense */ 116 CU_ASSERT(queryctrl.minimum < 117 queryctrl.maximum); 118 119 CU_ASSERT(0 < queryctrl.step); 120 121 CU_ASSERT(queryctrl.minimum <= 122 queryctrl.default_value); 123 CU_ASSERT(queryctrl.default_value <= 124 queryctrl.maximum); 125 break; 126 127 case V4L2_CTRL_TYPE_BOOLEAN: 128 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 129 CU_ASSERT_EQUAL(queryctrl.maximum, 1); 130 CU_ASSERT_EQUAL(queryctrl.step, 1); 131 CU_ASSERT((queryctrl.default_value == 0) 132 || (queryctrl.default_value == 1)); 133 break; 134 135 case V4L2_CTRL_TYPE_MENU: 136 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 137 CU_ASSERT(queryctrl.minimum <= 138 queryctrl.default_value); 139 CU_ASSERT_EQUAL(queryctrl.step, 1); 140 CU_ASSERT(queryctrl.minimum <= 141 queryctrl.default_value); 142 CU_ASSERT(queryctrl.default_value <= 143 queryctrl.maximum); 144 break; 145 146 case V4L2_CTRL_TYPE_BUTTON: 147 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 148 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 149 CU_ASSERT_EQUAL(queryctrl.step, 0); 150 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 151 break; 152 153 case V4L2_CTRL_TYPE_INTEGER64: /* fallthrough */ 154 case V4L2_CTRL_TYPE_CTRL_CLASS: 155 /* These parameters are defined as n/a by V4L2, so 156 * they should be filled with zeros, the same like 157 * the reserved fields. 158 */ 159 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 160 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 161 CU_ASSERT_EQUAL(queryctrl.step, 0); 162 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 163 break; 164 165 default: 166 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 167 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 168 CU_ASSERT_EQUAL(queryctrl.step, 0); 169 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 170 } 171 172 CU_ASSERT(valid_control_flag(queryctrl.flags)); 173 174 CU_ASSERT_EQUAL(queryctrl.reserved[0], 0); 175 CU_ASSERT_EQUAL(queryctrl.reserved[1], 0); 176 177 /* Check if the unused bytes of the name string are 178 * also filled with zeros. Also check if there is any 179 * padding byte between any two fields then this 180 * padding byte is also filled with zeros. 181 */ 182 memset(&queryctrl2, 0, sizeof(queryctrl2)); 183 queryctrl2.id = queryctrl.id; 184 queryctrl2.type = queryctrl.type; 185 strncpy((char *)queryctrl2.name, (char *)queryctrl.name, 186 sizeof(queryctrl2.name)); 187 queryctrl2.minimum = queryctrl.minimum; 188 queryctrl2.maximum = queryctrl.maximum; 189 queryctrl2.step = queryctrl.step; 190 queryctrl2.default_value = queryctrl.default_value; 191 queryctrl2.flags = queryctrl.flags; 192 CU_ASSERT_EQUAL(memcmp 193 (&queryctrl, &queryctrl2, 194 sizeof(queryctrl)), 0); 195 196 dprintf 197 ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", " 198 ".minimum=%i, .maximum=%i, .step=%i, " 199 ".default_value=%i, " ".flags=0x%X, " 200 ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id, 201 queryctrl.type, queryctrl.name, queryctrl.minimum, 202 queryctrl.maximum, queryctrl.step, 203 queryctrl.default_value, queryctrl.flags, 204 queryctrl.reserved[0], queryctrl.reserved[1] 205 ); 206 207 } else { 208 CU_ASSERT_EQUAL(ret_query, -1); 209 CU_ASSERT_EQUAL(errno_query, EINVAL); 210 211 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 212 queryctrl2.id = i; 213 CU_ASSERT_EQUAL(memcmp 214 (&queryctrl, &queryctrl2, 215 sizeof(queryctrl)), 0); 216 217 } 218 } 219 220 } 221 222 void test_VIDIOC_QUERYCTRL_BASE_1() 223 { 224 int ret_query, errno_query; 225 struct v4l2_queryctrl queryctrl; 226 struct v4l2_queryctrl queryctrl2; 227 228 memset(&queryctrl, 0xff, sizeof(queryctrl)); 229 queryctrl.id = V4L2_CID_BASE - 1; 230 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 231 errno_query = errno; 232 233 dprintf 234 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE-1), ret_query=%i, errno_query=%i\n", 235 __FILE__, __LINE__, V4L2_CID_BASE - 1, ret_query, errno_query); 236 237 CU_ASSERT_EQUAL(ret_query, -1); 238 CU_ASSERT_EQUAL(errno_query, EINVAL); 239 240 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 241 queryctrl2.id = V4L2_CID_BASE - 1; 242 CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0); 243 244 } 245 246 void test_VIDIOC_QUERYCTRL_LASTP1() 247 { 248 int ret_query, errno_query; 249 struct v4l2_queryctrl queryctrl; 250 struct v4l2_queryctrl queryctrl2; 251 252 memset(&queryctrl, 0xff, sizeof(queryctrl)); 253 queryctrl.id = V4L2_CID_LASTP1; 254 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 255 errno_query = errno; 256 257 dprintf 258 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_LASTP1), ret_query=%i, errno_query=%i\n", 259 __FILE__, __LINE__, V4L2_CID_LASTP1, ret_query, errno_query); 260 261 CU_ASSERT_EQUAL(ret_query, -1); 262 CU_ASSERT_EQUAL(errno_query, EINVAL); 263 264 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 265 queryctrl2.id = V4L2_CID_LASTP1; 266 CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0); 267 268 } 269 270 void test_VIDIOC_QUERYCTRL_LASTP1_1() 271 { 272 int ret_query, errno_query; 273 struct v4l2_queryctrl queryctrl; 274 struct v4l2_queryctrl queryctrl2; 275 276 memset(&queryctrl, 0xff, sizeof(queryctrl)); 277 queryctrl.id = V4L2_CID_LASTP1 + 1; 278 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 279 errno_query = errno; 280 281 dprintf 282 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_LASTP1+1), ret_query=%i, errno_query=%i\n", 283 __FILE__, __LINE__, V4L2_CID_LASTP1 + 1, ret_query, errno_query); 284 285 CU_ASSERT_EQUAL(ret_query, -1); 286 CU_ASSERT_EQUAL(errno_query, EINVAL); 287 288 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 289 queryctrl2.id = V4L2_CID_LASTP1 + 1; 290 CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0); 291 292 } 293 294 void test_VIDIOC_QUERYCTRL_flag_NEXT_CTRL() 295 { 296 int ret_query, errno_query; 297 char count_controls1[V4L2_CID_LASTP1 - V4L2_CID_BASE]; 298 char count_controls2[V4L2_CID_LASTP1 - V4L2_CID_BASE]; 299 struct v4l2_queryctrl controls[V4L2_CID_LASTP1 - V4L2_CID_BASE]; 300 struct v4l2_queryctrl queryctrl; 301 __u32 i; 302 303 /* find out all the possible user controls */ 304 memset(count_controls1, 0, sizeof(count_controls1)); 305 memset(controls, 0, sizeof(controls)); 306 307 for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) { 308 309 memset(&queryctrl, 0xff, sizeof(queryctrl)); 310 queryctrl.id = i; 311 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 312 errno_query = errno; 313 314 if (ret_query == 0) { 315 CU_ASSERT_EQUAL(ret_query, 0); 316 CU_ASSERT_EQUAL(queryctrl.id, i); 317 count_controls1[i - V4L2_CID_BASE]++; 318 controls[i - V4L2_CID_BASE] = queryctrl; 319 320 dprintf 321 ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", " 322 ".minimum=%i, .maximum=%i, .step=%i, " 323 ".default_value=%i, " ".flags=0x%X, " 324 ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id, 325 queryctrl.type, queryctrl.name, queryctrl.minimum, 326 queryctrl.maximum, queryctrl.step, 327 queryctrl.default_value, queryctrl.flags, 328 queryctrl.reserved[0], queryctrl.reserved[1] 329 ); 330 331 } else { 332 CU_ASSERT_EQUAL(ret_query, -1); 333 CU_ASSERT_EQUAL(errno_query, EINVAL); 334 } 335 } 336 337 /* enumerate the controls with V4L2_CTRL_FLAG_NEXT_CTRL */ 338 dprintf1("\tStarting enumeration with V4L2_CTRL_FLAG_NEXT_CTRL\n"); 339 memset(count_controls2, 0, sizeof(count_controls2)); 340 341 /* As described at V4L2 Chapter 1.9.3. Enumerating Extended Controls */ 342 i = 0; 343 memset(&queryctrl, 0xff, sizeof(queryctrl)); 344 queryctrl.id = i | V4L2_CTRL_FLAG_NEXT_CTRL; 345 dprintf 346 ("\tasking for id=%i=V4L2_CID_BASE+%i | V4L2_CTRL_FLAG_NEXT_CTRL\n", 347 i, i - V4L2_CID_BASE); 348 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 349 errno_query = errno; 350 351 dprintf("\tret_query=%i\n", ret_query); 352 353 if (ret_query == 0) { 354 do { 355 /* protect the count_controls2[] from overindexing */ 356 if ((V4L2_CID_BASE <= queryctrl.id) 357 && (queryctrl.id < V4L2_CID_LASTP1)) { 358 count_controls2[queryctrl.id - V4L2_CID_BASE]++; 359 CU_ASSERT_EQUAL(memcmp 360 (&queryctrl, 361 &controls[queryctrl.id - 362 V4L2_CID_BASE], 363 sizeof(queryctrl)), 0); 364 } 365 366 /* "The VIDIOC_QUERYCTRL ioctl will return the first 367 * control with a higher ID than the specified one." 368 */ 369 CU_ASSERT(i < queryctrl.id); 370 371 CU_ASSERT(V4L2_CID_BASE <= queryctrl.id); 372 CU_ASSERT(queryctrl.id < V4L2_CID_LASTP1); 373 374 dprintf 375 ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", " 376 ".minimum=%i, .maximum=%i, .step=%i, " 377 ".default_value=%i, " ".flags=0x%X, " 378 ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id, 379 queryctrl.type, queryctrl.name, queryctrl.minimum, 380 queryctrl.maximum, queryctrl.step, 381 queryctrl.default_value, queryctrl.flags, 382 queryctrl.reserved[0], queryctrl.reserved[1] 383 ); 384 385 i = queryctrl.id; 386 memset(&queryctrl, 0xff, sizeof(queryctrl)); 387 queryctrl.id = i | V4L2_CTRL_FLAG_NEXT_CTRL; 388 dprintf 389 ("\tasking for id=%i=V4L2_CID_BASE+%i | V4L2_CTRL_FLAG_NEXT_CTRL\n", 390 i, i - V4L2_CID_BASE); 391 ret_query = 392 ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 393 errno_query = errno; 394 395 dprintf("\tret_query=%i\n", ret_query); 396 397 } while (ret_query == 0 398 && V4L2_CTRL_ID2CLASS(queryctrl.id) == 399 V4L2_CTRL_CLASS_USER); 400 401 if (ret_query == 0) { 402 /* some other controls also exists, stop for now. */ 403 } else { 404 CU_ASSERT_EQUAL(ret_query, -1); 405 CU_ASSERT_EQUAL(errno_query, EINVAL); 406 } 407 408 /* Check whether the same controls are reported if using 409 * V4L2_CTRL_FLAG_NEXT_CTRL and without using it. 410 * This also checks if one control is not reported twice. 411 */ 412 CU_ASSERT_EQUAL(memcmp 413 (count_controls1, count_controls2, 414 sizeof(count_controls1)), 0); 415 416 dprintf1("count_controls1 = { "); 417 for (i = 0; 418 i < sizeof(count_controls1) / sizeof(*count_controls1); 419 i++) { 420 dprintf("%i ", count_controls1[i]); 421 } 422 dprintf1("}\n"); 423 424 dprintf1("count_controls2 = { "); 425 for (i = 0; 426 i < sizeof(count_controls2) / sizeof(*count_controls2); 427 i++) { 428 dprintf("%i ", count_controls2[i]); 429 } 430 dprintf1("}\n"); 431 432 } else { 433 dprintf1 434 ("V4L2_CTRL_FLAG_NEXT_CTRL is not supported or no control is available\n"); 435 /* The flag V4L2_CTRL_FLAG_NEXT_CTRL is not supported 436 * or no control is avaliable at all. Do not continue the 437 * enumeration. 438 */ 439 CU_ASSERT_EQUAL(ret_query, -1); 440 CU_ASSERT_EQUAL(errno_query, EINVAL); 441 } 442 443 } 444 445 void test_VIDIOC_QUERYCTRL_private() 446 { 447 int ret_query, errno_query; 448 struct v4l2_queryctrl queryctrl; 449 struct v4l2_queryctrl queryctrl2; 450 __u32 i; 451 452 i = V4L2_CID_PRIVATE_BASE; 453 do { 454 memset(&queryctrl, 0xff, sizeof(queryctrl)); 455 queryctrl.id = i; 456 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 457 errno_query = errno; 458 459 dprintf 460 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n", 461 __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query, 462 errno_query); 463 464 if (ret_query == 0) { 465 CU_ASSERT_EQUAL(ret_query, 0); 466 CU_ASSERT_EQUAL(queryctrl.id, i); 467 468 CU_ASSERT(0 < strlen((char *)queryctrl.name)); 469 CU_ASSERT(valid_string 470 ((char *)queryctrl.name, 471 sizeof(queryctrl.name))); 472 473 CU_ASSERT(valid_control_type(queryctrl.type)); 474 475 switch (queryctrl.type) { 476 case V4L2_CTRL_TYPE_INTEGER: 477 /* min < max, because otherwise this control makes no sense */ 478 CU_ASSERT(queryctrl.minimum < 479 queryctrl.maximum); 480 481 CU_ASSERT(0 < queryctrl.step); 482 483 CU_ASSERT(queryctrl.minimum <= 484 queryctrl.default_value); 485 CU_ASSERT(queryctrl.default_value <= 486 queryctrl.maximum); 487 break; 488 489 case V4L2_CTRL_TYPE_BOOLEAN: 490 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 491 CU_ASSERT_EQUAL(queryctrl.maximum, 1); 492 CU_ASSERT_EQUAL(queryctrl.step, 1); 493 CU_ASSERT((queryctrl.default_value == 0) 494 || (queryctrl.default_value == 1)); 495 break; 496 497 case V4L2_CTRL_TYPE_MENU: 498 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 499 CU_ASSERT(queryctrl.minimum <= 500 queryctrl.default_value); 501 CU_ASSERT_EQUAL(queryctrl.step, 1); 502 CU_ASSERT(queryctrl.minimum <= 503 queryctrl.default_value); 504 CU_ASSERT(queryctrl.default_value <= 505 queryctrl.maximum); 506 break; 507 508 case V4L2_CTRL_TYPE_BUTTON: 509 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 510 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 511 CU_ASSERT_EQUAL(queryctrl.step, 0); 512 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 513 break; 514 515 case V4L2_CTRL_TYPE_INTEGER64: /* fallthrough */ 516 case V4L2_CTRL_TYPE_CTRL_CLASS: 517 /* These parameters are defined as n/a by V4L2, so 518 * they should be filled with zeros, the same like 519 * the reserved fields. 520 */ 521 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 522 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 523 CU_ASSERT_EQUAL(queryctrl.step, 0); 524 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 525 break; 526 527 default: 528 CU_ASSERT_EQUAL(queryctrl.minimum, 0); 529 CU_ASSERT_EQUAL(queryctrl.maximum, 0); 530 CU_ASSERT_EQUAL(queryctrl.step, 0); 531 CU_ASSERT_EQUAL(queryctrl.default_value, 0); 532 } 533 534 CU_ASSERT(valid_control_flag(queryctrl.flags)); 535 536 CU_ASSERT_EQUAL(queryctrl.reserved[0], 0); 537 CU_ASSERT_EQUAL(queryctrl.reserved[1], 0); 538 539 /* Check if the unused bytes of the name string are 540 * also filled with zeros. Also check if there is any 541 * padding byte between any two fields then this 542 * padding byte is also filled with zeros. 543 */ 544 memset(&queryctrl2, 0, sizeof(queryctrl2)); 545 queryctrl2.id = queryctrl.id; 546 queryctrl2.type = queryctrl.type; 547 strncpy((char *)queryctrl2.name, (char *)queryctrl.name, 548 sizeof(queryctrl2.name)); 549 queryctrl2.minimum = queryctrl.minimum; 550 queryctrl2.maximum = queryctrl.maximum; 551 queryctrl2.step = queryctrl.step; 552 queryctrl2.default_value = queryctrl.default_value; 553 queryctrl2.flags = queryctrl.flags; 554 CU_ASSERT_EQUAL(memcmp 555 (&queryctrl, &queryctrl2, 556 sizeof(queryctrl)), 0); 557 558 dprintf 559 ("\tqueryctrl = {.id=%u, .type=%i, .name=\"%s\", " 560 ".minimum=%i, .maximum=%i, .step=%i, " 561 ".default_value=%i, " ".flags=0x%X, " 562 ".reserved[]={ 0x%X, 0x%X } }\n", queryctrl.id, 563 queryctrl.type, queryctrl.name, queryctrl.minimum, 564 queryctrl.maximum, queryctrl.step, 565 queryctrl.default_value, queryctrl.flags, 566 queryctrl.reserved[0], queryctrl.reserved[1] 567 ); 568 569 } else { 570 CU_ASSERT_EQUAL(ret_query, -1); 571 CU_ASSERT_EQUAL(errno_query, EINVAL); 572 573 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 574 queryctrl2.id = i; 575 CU_ASSERT_EQUAL(memcmp 576 (&queryctrl, &queryctrl2, 577 sizeof(queryctrl)), 0); 578 579 } 580 } while (ret_query == 0); 581 582 } 583 584 void test_VIDIOC_QUERYCTRL_private_base_1() 585 { 586 int ret_query, errno_query; 587 struct v4l2_queryctrl queryctrl; 588 struct v4l2_queryctrl queryctrl2; 589 590 memset(&queryctrl, 0xff, sizeof(queryctrl)); 591 queryctrl.id = V4L2_CID_PRIVATE_BASE - 1; 592 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 593 errno_query = errno; 594 595 dprintf 596 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE-1), ret_query=%i, errno_query=%i\n", 597 __FILE__, __LINE__, V4L2_CID_PRIVATE_BASE - 1, ret_query, 598 errno_query); 599 600 CU_ASSERT_EQUAL(ret_query, -1); 601 CU_ASSERT_EQUAL(errno_query, EINVAL); 602 603 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 604 queryctrl2.id = V4L2_CID_PRIVATE_BASE - 1; 605 CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0); 606 607 } 608 609 void test_VIDIOC_QUERYCTRL_private_last_1() 610 { 611 int ret_query, errno_query; 612 struct v4l2_queryctrl queryctrl; 613 struct v4l2_queryctrl queryctrl2; 614 __u32 i; 615 616 i = V4L2_CID_PRIVATE_BASE; 617 do { 618 memset(&queryctrl, 0xff, sizeof(queryctrl)); 619 queryctrl.id = i; 620 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 621 errno_query = errno; 622 623 i++; 624 } while (ret_query == 0); 625 626 memset(&queryctrl, 0xff, sizeof(queryctrl)); 627 queryctrl.id = i; 628 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 629 630 dprintf 631 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE+%u), ret_query=%i, errno_query=%i\n", 632 __FILE__, __LINE__, i, i - V4L2_CID_PRIVATE_BASE, ret_query, 633 errno_query); 634 635 CU_ASSERT_EQUAL(ret_query, -1); 636 CU_ASSERT_EQUAL(errno_query, EINVAL); 637 638 memset(&queryctrl2, 0xff, sizeof(queryctrl2)); 639 queryctrl2.id = i; 640 CU_ASSERT_EQUAL(memcmp(&queryctrl, &queryctrl2, sizeof(queryctrl)), 0); 641 642 } 643 644 void test_VIDIOC_QUERYCTRL_NULL() 645 { 646 int ret_query, errno_query; 647 int ret_null, errno_null; 648 struct v4l2_queryctrl queryctrl; 649 __u32 i; 650 unsigned int count_ctrl; 651 652 count_ctrl = 0; 653 654 i = V4L2_CID_BASE; 655 for (i = V4L2_CID_BASE; i < V4L2_CID_LASTP1; i++) { 656 memset(&queryctrl, 0xff, sizeof(queryctrl)); 657 queryctrl.id = i; 658 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 659 errno_query = errno; 660 661 dprintf 662 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_BASE+%i), ret_query=%i, errno_query=%i\n", 663 __FILE__, __LINE__, i, i - V4L2_CID_BASE, ret_query, 664 errno_query); 665 666 if (ret_query == 0) { 667 CU_ASSERT_EQUAL(ret_query, 0); 668 count_ctrl++; 669 } else { 670 CU_ASSERT_EQUAL(ret_query, -1); 671 CU_ASSERT_EQUAL(errno_query, EINVAL); 672 } 673 } 674 675 i = V4L2_CID_PRIVATE_BASE; 676 do { 677 memset(&queryctrl, 0xff, sizeof(queryctrl)); 678 queryctrl.id = i; 679 ret_query = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, &queryctrl); 680 errno_query = errno; 681 682 dprintf 683 ("\t%s:%u: VIDIOC_QUERYCTRL, id=%u (V4L2_CID_PRIVATE_BASE+%i), ret_query=%i, errno_query=%i\n", 684 __FILE__, __LINE__, i, i - V4L2_CID_PRIVATE_BASE, 685 ret_query, errno_query); 686 687 if (ret_query == 0) { 688 CU_ASSERT_EQUAL(ret_query, 0); 689 count_ctrl++; 690 } else { 691 CU_ASSERT_EQUAL(ret_query, -1); 692 CU_ASSERT_EQUAL(errno_query, EINVAL); 693 } 694 695 i++; 696 } while (ret_query == 0 && V4L2_CID_PRIVATE_BASE <= i); 697 698 ret_null = ioctl(get_video_fd(), VIDIOC_QUERYCTRL, NULL); 699 errno_null = errno; 700 701 dprintf("\t%s:%u: VIDIOC_QUERYCTRL, ret_null=%i, errno_null=%i\n", 702 __FILE__, __LINE__, ret_null, errno_null); 703 704 if (0 < count_ctrl) { 705 CU_ASSERT_EQUAL(ret_null, -1); 706 CU_ASSERT_EQUAL(errno_null, EFAULT); 707 } else { 708 CU_ASSERT_EQUAL(ret_null, -1); 709 CU_ASSERT_EQUAL(errno_null, EINVAL); 710 } 711 712 } 713