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