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