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