1 /* 2 * v4l-test: Test environment for Video For Linux Two API 3 * 4 * 20 Apr 2009 0.5 Added string content validation 5 * 18 Apr 2009 0.4 More strict check for strings 6 * 28 Mar 2009 0.3 Clean up ret and errno variable names and dprintf() output 7 * 9 Feb 2009 0.2 Added test cases for VIDIOC_S_TUNER; 8 * Some typos corrected; 9 * Add some debug messages 10 * 31 Jan 2009 0.1 First release 11 * 12 * Written by Mrton Nmeth <nm127 (at) freemail.hu> 13 * Released under GPL 14 */ 15 16 #include <stdio.h> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #include <fcntl.h> 20 #include <unistd.h> 21 #include <sys/ioctl.h> 22 #include <errno.h> 23 #include <string.h> 24 25 #include <linux/videodev2.h> 26 #include <linux/errno.h> 27 28 #include <CUnit/CUnit.h> 29 30 #include "v4l2_test.h" 31 #include "dev_video.h" 32 #include "video_limits.h" 33 #include "v4l2_validator.h" 34 35 #include "test_VIDIOC_TUNER.h" 36 37 int valid_tuner_type(enum v4l2_tuner_type type) 38 { 39 int valid = 0; 40 41 switch (type) { 42 case V4L2_TUNER_RADIO: 43 case V4L2_TUNER_ANALOG_TV: 44 valid = 1; 45 break; 46 default: 47 valid = 0; 48 } 49 50 return valid; 51 } 52 53 int valid_tuner_sub(__u32 tuner_sub) 54 { 55 int valid = 0; 56 57 CU_ASSERT_EQUAL(V4L2_TUNER_SUB_SAP, V4L2_TUNER_SUB_LANG2); 58 59 if ((tuner_sub & ~(V4L2_TUNER_SUB_MONO | 60 V4L2_TUNER_SUB_STEREO | 61 V4L2_TUNER_SUB_LANG1 | 62 V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_SAP)) 63 == 0) { 64 valid = 1; 65 } else { 66 valid = 0; 67 } 68 return valid; 69 } 70 71 int valid_tuner_audmode(__u32 audmode) 72 { 73 int valid = 0; 74 75 CU_ASSERT_EQUAL(V4L2_TUNER_MODE_SAP, V4L2_TUNER_MODE_LANG2); 76 77 switch (audmode) { 78 case V4L2_TUNER_MODE_MONO: 79 case V4L2_TUNER_MODE_STEREO: 80 case V4L2_TUNER_MODE_LANG1: 81 case V4L2_TUNER_MODE_LANG2: 82 case V4L2_TUNER_MODE_LANG1_LANG2: 83 valid = 1; 84 break; 85 default: 86 valid = 0; 87 } 88 89 return valid; 90 } 91 92 static int do_get_tuner(int f, __u32 index) 93 { 94 int ret_get, errno_get; 95 struct v4l2_tuner tuner; 96 struct v4l2_tuner tuner2; 97 98 memset(&tuner, 0xff, sizeof(tuner)); 99 tuner.index = index; 100 ret_get = ioctl(f, VIDIOC_G_TUNER, &tuner); 101 errno_get = errno; 102 103 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_get=%i, errno_get=%i\n", 104 __FILE__, __LINE__, ret_get, errno_get); 105 106 if (ret_get == 0) { 107 CU_ASSERT_EQUAL(ret_get, 0); 108 109 CU_ASSERT_EQUAL(tuner.index, index); 110 111 CU_ASSERT(0 < strlen((char *)tuner.name)); 112 CU_ASSERT(valid_string((char *)tuner.name, sizeof(tuner.name))); 113 114 CU_ASSERT(valid_tuner_type(tuner.type)); 115 CU_ASSERT(valid_tuner_capability(tuner.capability)); 116 117 CU_ASSERT(tuner.rangelow <= tuner.rangehigh); 118 CU_ASSERT(valid_tuner_sub(tuner.rxsubchans)); 119 CU_ASSERT(valid_tuner_audmode(tuner.audmode)); 120 121 /* tuner.signal can have any value */ 122 //CU_ASSERT_EQUAL(tuner.signal, ???); 123 124 /* tuner.afc can have any value */ 125 //CU_ASSERT_EQUAL(tuner.afc, ???); 126 127 CU_ASSERT_EQUAL(tuner.reserved[0], 0); 128 CU_ASSERT_EQUAL(tuner.reserved[1], 0); 129 CU_ASSERT_EQUAL(tuner.reserved[2], 0); 130 CU_ASSERT_EQUAL(tuner.reserved[3], 0); 131 132 /* Check if the unused bytes of the name string are also filled 133 * with zeros. Also check if there is any padding byte between 134 * any two fields then this padding byte is also filled with 135 * zeros. 136 */ 137 memset(&tuner2, 0, sizeof(tuner2)); 138 tuner2.index = tuner.index; 139 strncpy((char *)tuner2.name, (char *)tuner.name, 140 sizeof(tuner2.name)); 141 tuner2.type = tuner.type; 142 tuner2.capability = tuner.capability; 143 tuner2.rangelow = tuner.rangelow; 144 tuner2.rangehigh = tuner.rangehigh; 145 tuner2.rxsubchans = tuner.rxsubchans; 146 tuner2.audmode = tuner.audmode; 147 tuner2.signal = tuner.signal; 148 tuner2.afc = tuner.afc; 149 CU_ASSERT_EQUAL(memcmp(&tuner, &tuner2, sizeof(tuner)), 0); 150 151 dprintf("\ttuner = { " 152 ".index = %u, " 153 ".name = \"%s\", " 154 ".type = %i, " 155 ".capability = %u, " 156 ".rangelow = %u, " 157 ".rangehigh = %u, " 158 ".rxsubchans = %u, " 159 ".audmode = %u, " 160 ".signal = %u, " 161 ".afc = %i, " 162 ".reserved[]={ 0x%X, 0x%X, 0x%X, 0x%X } }\n", 163 tuner.index, 164 tuner.name, 165 tuner.type, 166 tuner.capability, 167 tuner.rangelow, 168 tuner.rangehigh, 169 tuner.rxsubchans, 170 tuner.audmode, 171 tuner.signal, 172 tuner.afc, 173 tuner.reserved[0], 174 tuner.reserved[1], tuner.reserved[2], tuner.reserved[3] 175 ); 176 177 } else { 178 dprintf("\t%s:%u: ret_get=%d (expected %d)\n", __FILE__, 179 __LINE__, ret_get, -1); 180 dprintf("\t%s:%u: errno_get=%d (expected %d)\n", __FILE__, 181 __LINE__, errno_get, EINVAL); 182 CU_ASSERT_EQUAL(ret_get, -1); 183 CU_ASSERT_EQUAL(errno_get, EINVAL); 184 } 185 186 return ret_get; 187 } 188 189 void test_VIDIOC_G_TUNER() 190 { 191 int ret; 192 __u32 index; 193 int f; 194 195 f = get_video_fd(); 196 197 index = 0; 198 do { 199 ret = do_get_tuner(f, index); 200 index++; 201 } while (ret == 0); 202 203 } 204 205 void test_VIDIOC_G_TUNER_S32_MAX() 206 { 207 int ret_get, errno_get; 208 __u32 index; 209 struct v4l2_tuner tuner; 210 211 index = (__u32) S32_MAX; 212 213 memset(&tuner, 0xff, sizeof(tuner)); 214 tuner.index = index; 215 ret_get = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner); 216 errno_get = errno; 217 218 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_get=%i, errno_get=%i\n", 219 __FILE__, __LINE__, ret_get, errno_get); 220 221 dprintf("\t%s:%u: ret_get=%d (expected %d)\n", __FILE__, __LINE__, 222 ret_get, -1); 223 dprintf("\t%s:%u: errno_get=%d (expected %d)\n", __FILE__, __LINE__, 224 errno_get, EINVAL); 225 CU_ASSERT_EQUAL(ret_get, -1); 226 CU_ASSERT_EQUAL(errno_get, EINVAL); 227 } 228 229 void test_VIDIOC_G_TUNER_S32_MAX_1() 230 { 231 int ret_get, errno_get; 232 __u32 index; 233 struct v4l2_tuner tuner; 234 235 index = (__u32) S32_MAX + 1; 236 237 memset(&tuner, 0xff, sizeof(tuner)); 238 tuner.index = index; 239 ret_get = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner); 240 errno_get = errno; 241 242 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_get=%i\n", 243 __FILE__, __LINE__, ret_get); 244 245 dprintf("\t%s:%u: ret_get=%d (expected %d)\n", __FILE__, __LINE__, 246 ret_get, -1); 247 dprintf("\t%s:%u: errno_get=%d (expected %d)\n", __FILE__, __LINE__, 248 errno_get, EINVAL); 249 CU_ASSERT_EQUAL(ret_get, -1); 250 CU_ASSERT_EQUAL(errno_get, EINVAL); 251 } 252 253 void test_VIDIOC_G_TUNER_U32_MAX() 254 { 255 int ret_get, errno_get; 256 __u32 index; 257 struct v4l2_tuner tuner; 258 259 index = U32_MAX; 260 261 memset(&tuner, 0xff, sizeof(tuner)); 262 tuner.index = index; 263 ret_get = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner); 264 errno_get = errno; 265 266 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_get=%i, errno_get=%i\n", 267 __FILE__, __LINE__, ret_get, errno_get); 268 269 dprintf("\t%s:%u: ret_get=%d (expected %d)\n", __FILE__, __LINE__, 270 ret_get, -1); 271 dprintf("\t%s:%u: errno_get=%d (expected %d)\n", __FILE__, __LINE__, 272 errno_get, EINVAL); 273 CU_ASSERT_EQUAL(ret_get, -1); 274 CU_ASSERT_EQUAL(errno_get, EINVAL); 275 } 276 277 void test_VIDIOC_G_TUNER_NULL() 278 { 279 int ret_get, errno_get; 280 int ret_null, errno_null; 281 struct v4l2_tuner tuner; 282 283 memset(&tuner, 0xff, sizeof(tuner)); 284 tuner.index = 0; 285 ret_get = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner); 286 errno_get = errno; 287 dprintf("\t%s:%u: VIDIOC_G_TUNER: ret_get=%i, errno_get=%i\n", 288 __FILE__, __LINE__, ret_get, errno_get); 289 290 ret_null = ioctl(get_video_fd(), VIDIOC_G_TUNER, NULL); 291 errno_null = errno; 292 293 dprintf("\t%s:%u: VIDIOC_G_TUNER: ret_null=%i, errno_null=%i\n", 294 __FILE__, __LINE__, ret_null, errno_null); 295 296 /* check if VIDIOC_G_TUNER is supported at all or not */ 297 if (ret_get == 0) { 298 /* VIDIOC_G_TUNER is supported, the parameter should be checked */ 299 CU_ASSERT_EQUAL(ret_get, 0); 300 CU_ASSERT_EQUAL(ret_null, -1); 301 CU_ASSERT_EQUAL(errno_null, EFAULT); 302 } else { 303 /* VIDIOC_G_TUNER not supported at all, the parameter should not be evaluated */ 304 CU_ASSERT_EQUAL(ret_get, -1); 305 CU_ASSERT_EQUAL(errno_get, EINVAL); 306 CU_ASSERT_EQUAL(ret_null, -1); 307 CU_ASSERT_EQUAL(errno_null, EINVAL); 308 } 309 310 } 311 312 void do_set_tuner_audmode(__u32 index, __u32 audmode) 313 { 314 int ret_set, errno_set; 315 struct v4l2_tuner tuner; 316 317 memset(&tuner, 0xff, sizeof(tuner)); 318 tuner.index = index; 319 tuner.audmode = audmode; 320 ret_set = ioctl(get_video_fd(), VIDIOC_S_TUNER, &tuner); 321 errno_set = errno; 322 323 dprintf("\t%s:%u: VIDIOC_S_TUNER: index=%u, audmode=%u, " 324 "ret_set=%i (expected %i), errno_set=%i\n", 325 __FILE__, __LINE__, index, audmode, ret_set, 0, errno_set); 326 327 CU_ASSERT_EQUAL(ret_set, 0); 328 329 } 330 331 void do_set_tuner_audmode_invalid(__u32 index, __u32 audmode) 332 { 333 int ret_set, errno_set; 334 struct v4l2_tuner tuner; 335 336 memset(&tuner, 0xff, sizeof(tuner)); 337 tuner.index = index; 338 tuner.audmode = audmode; 339 ret_set = ioctl(get_video_fd(), VIDIOC_S_TUNER, &tuner); 340 errno_set = errno; 341 342 dprintf("\t%s:%u: VIDIOC_S_TUNER: index=%u, audmode=%u, " 343 "ret_set=%i (expected %i), errno_set=%i (expected %i)\n", 344 __FILE__, __LINE__, 345 index, audmode, ret_set, -1, errno_set, EINVAL); 346 347 CU_ASSERT_EQUAL(ret_set, -1); 348 CU_ASSERT_EQUAL(errno_set, EINVAL); 349 } 350 351 void test_VIDIOC_S_TUNER() 352 { 353 int ret_get, errno_get; 354 int ret_set, errno_set; 355 struct v4l2_tuner tuner_orig; 356 struct v4l2_tuner tuner_set; 357 358 /* remember the tuner settings */ 359 memset(&tuner_orig, 0, sizeof(tuner_orig)); 360 ret_get = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner_orig); 361 errno_get = errno; 362 363 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_get=%i, errno_get=%i\n", 364 __FILE__, __LINE__, ret_get, errno_get); 365 366 if (ret_get == 0) { 367 CU_ASSERT_EQUAL(ret_get, 0); 368 369 do_set_tuner_audmode(tuner_orig.index, V4L2_TUNER_MODE_MONO); 370 do_set_tuner_audmode(tuner_orig.index, V4L2_TUNER_MODE_STEREO); 371 do_set_tuner_audmode(tuner_orig.index, V4L2_TUNER_MODE_LANG1); 372 do_set_tuner_audmode(tuner_orig.index, V4L2_TUNER_MODE_LANG2); 373 do_set_tuner_audmode(tuner_orig.index, V4L2_TUNER_MODE_SAP); 374 do_set_tuner_audmode(tuner_orig.index, 375 V4L2_TUNER_MODE_LANG1_LANG2); 376 377 } else { 378 CU_ASSERT_EQUAL(ret_get, -1); 379 CU_ASSERT_EQUAL(errno_get, EINVAL); 380 381 /* if VIDIOC_G_TUNER is not supported then VIDIOC_S_TUNER shall also 382 * not supported. 383 */ 384 do_set_tuner_audmode_invalid(tuner_orig.index, 385 V4L2_TUNER_MODE_MONO); 386 do_set_tuner_audmode_invalid(tuner_orig.index, 387 V4L2_TUNER_MODE_STEREO); 388 do_set_tuner_audmode_invalid(tuner_orig.index, 389 V4L2_TUNER_MODE_LANG1); 390 do_set_tuner_audmode_invalid(tuner_orig.index, 391 V4L2_TUNER_MODE_LANG2); 392 do_set_tuner_audmode_invalid(tuner_orig.index, 393 V4L2_TUNER_MODE_SAP); 394 do_set_tuner_audmode_invalid(tuner_orig.index, 395 V4L2_TUNER_MODE_LANG1_LANG2); 396 397 } 398 399 if (ret_get == 0) { 400 401 /* restore the tuner settings */ 402 memset(&tuner_set, 0xff, sizeof(tuner_set)); 403 tuner_set.index = tuner_orig.index; 404 tuner_set.audmode = tuner_orig.audmode; 405 ret_set = ioctl(get_video_fd(), VIDIOC_S_TUNER, &tuner_orig); 406 errno_set = errno; 407 408 dprintf("\t%s:%u: VIDIOC_S_TUNER, ret_set=%i, errno_set=%i\n", 409 __FILE__, __LINE__, ret_set, errno_set); 410 411 CU_ASSERT_EQUAL(ret_set, 0); 412 } 413 414 } 415 416 void test_VIDIOC_S_TUNER_invalid() 417 { 418 int ret1, errno1; 419 int ret_set, errno_set; 420 struct v4l2_tuner tuner_orig; 421 struct v4l2_tuner tuner_set; 422 423 /* remember the tuner settings */ 424 memset(&tuner_orig, 0, sizeof(tuner_orig)); 425 ret1 = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner_orig); 426 errno1 = errno; 427 428 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret1=%i, errno1=%i\n", 429 __FILE__, __LINE__, ret1, errno1); 430 431 if (ret1 == 0) { 432 CU_ASSERT_EQUAL(ret1, 0); 433 434 /* try with invalid index */ 435 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 436 V4L2_TUNER_MODE_MONO); 437 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 438 V4L2_TUNER_MODE_MONO); 439 do_set_tuner_audmode_invalid((__u32) S32_MAX, 440 V4L2_TUNER_MODE_MONO); 441 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 442 V4L2_TUNER_MODE_MONO); 443 do_set_tuner_audmode_invalid(U32_MAX, V4L2_TUNER_MODE_MONO); 444 445 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 446 V4L2_TUNER_MODE_STEREO); 447 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 448 V4L2_TUNER_MODE_STEREO); 449 do_set_tuner_audmode_invalid((__u32) S32_MAX, 450 V4L2_TUNER_MODE_STEREO); 451 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 452 V4L2_TUNER_MODE_STEREO); 453 do_set_tuner_audmode_invalid(U32_MAX, V4L2_TUNER_MODE_STEREO); 454 455 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 456 V4L2_TUNER_MODE_LANG1); 457 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 458 V4L2_TUNER_MODE_LANG1); 459 do_set_tuner_audmode_invalid((__u32) S32_MAX, 460 V4L2_TUNER_MODE_LANG1); 461 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 462 V4L2_TUNER_MODE_LANG1); 463 do_set_tuner_audmode_invalid(U32_MAX, V4L2_TUNER_MODE_LANG1); 464 465 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 466 V4L2_TUNER_MODE_LANG2); 467 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 468 V4L2_TUNER_MODE_LANG2); 469 do_set_tuner_audmode_invalid((__u32) S32_MAX, 470 V4L2_TUNER_MODE_LANG2); 471 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 472 V4L2_TUNER_MODE_LANG2); 473 do_set_tuner_audmode_invalid(U32_MAX, V4L2_TUNER_MODE_LANG2); 474 475 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 476 V4L2_TUNER_MODE_SAP); 477 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 478 V4L2_TUNER_MODE_SAP); 479 do_set_tuner_audmode_invalid((__u32) S32_MAX, 480 V4L2_TUNER_MODE_SAP); 481 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 482 V4L2_TUNER_MODE_SAP); 483 do_set_tuner_audmode_invalid(U32_MAX, V4L2_TUNER_MODE_SAP); 484 485 do_set_tuner_audmode_invalid(tuner_orig.index + 1, 486 V4L2_TUNER_MODE_LANG1_LANG2); 487 do_set_tuner_audmode_invalid(tuner_orig.index - 1, 488 V4L2_TUNER_MODE_LANG1_LANG2); 489 do_set_tuner_audmode_invalid((__u32) S32_MAX, 490 V4L2_TUNER_MODE_LANG1_LANG2); 491 do_set_tuner_audmode_invalid(((__u32) S32_MAX) + 1, 492 V4L2_TUNER_MODE_LANG1_LANG2); 493 do_set_tuner_audmode_invalid(U32_MAX, 494 V4L2_TUNER_MODE_LANG1_LANG2); 495 496 } else { 497 CU_ASSERT_EQUAL(ret1, -1); 498 CU_ASSERT_EQUAL(errno1, EINVAL); 499 500 } 501 502 /* try with invalid audmode */ 503 do_set_tuner_audmode_invalid(tuner_orig.index, 5); 504 do_set_tuner_audmode_invalid(tuner_orig.index, (__u32) S32_MAX); 505 do_set_tuner_audmode_invalid(tuner_orig.index, ((__u32) S32_MAX) + 1); 506 do_set_tuner_audmode_invalid(tuner_orig.index, U32_MAX); 507 508 if (ret1 == 0) { 509 510 /* restore the tuner settings */ 511 memset(&tuner_set, 0xff, sizeof(tuner_set)); 512 tuner_set.index = tuner_orig.index; 513 tuner_set.audmode = tuner_orig.audmode; 514 ret_set = ioctl(get_video_fd(), VIDIOC_S_TUNER, &tuner_orig); 515 errno_set = errno; 516 517 dprintf("\t%s:%u: VIDIOC_S_TUNER, ret_set=%i, errno_set=%i\n", 518 __FILE__, __LINE__, ret_set, errno_set); 519 520 CU_ASSERT_EQUAL(ret_set, 0); 521 } 522 523 } 524 525 void test_VIDIOC_S_TUNER_NULL() 526 { 527 int ret_orig, errno_orig; 528 int ret_null, errno_null; 529 int ret_set, errno_set; 530 struct v4l2_tuner tuner_orig; 531 struct v4l2_tuner tuner; 532 533 /* remember the tuner settings */ 534 memset(&tuner_orig, 0, sizeof(tuner_orig)); 535 ret_orig = ioctl(get_video_fd(), VIDIOC_G_TUNER, &tuner_orig); 536 errno_orig = errno; 537 538 dprintf("\t%s:%u: VIDIOC_G_TUNER, ret_orig=%i, errno_orig=%i\n", 539 __FILE__, __LINE__, ret_orig, errno_orig); 540 541 memset(&tuner, 0, sizeof(tuner)); 542 tuner.index = tuner_orig.index; 543 tuner.audmode = tuner_orig.audmode; 544 ret_set = ioctl(get_video_fd(), VIDIOC_S_TUNER, &tuner); 545 errno_set = errno; 546 547 dprintf("\t%s:%u:VIDIOC_S_TUNER: ret_set=%i, errno_set=%i\n", 548 __FILE__, __LINE__, ret_set, errno_set); 549 550 ret_null = ioctl(get_video_fd(), VIDIOC_S_TUNER, NULL); 551 errno_null = errno; 552 553 dprintf("\t%s:%u:VIDIOC_S_TUNER: ret_null=%i, errno_null=%i\n", 554 __FILE__, __LINE__, ret_set, errno_set); 555 556 if (ret_set == 0) { 557 CU_ASSERT_EQUAL(ret_set, 0); 558 CU_ASSERT_EQUAL(ret_null, -1); 559 CU_ASSERT_EQUAL(errno_null, EFAULT); 560 } else { 561 CU_ASSERT_EQUAL(ret_set, -1); 562 CU_ASSERT_EQUAL(errno_set, EINVAL); 563 CU_ASSERT_EQUAL(ret_null, -1); 564 CU_ASSERT_EQUAL(errno_null, EINVAL); 565 } 566 567 } 568