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 M�rton N�meth <nm127@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 
valid_control_flag(__u32 flags)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 
valid_control_type(__u32 type)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 
test_VIDIOC_QUERYCTRL()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 
test_VIDIOC_QUERYCTRL_BASE_1()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 
test_VIDIOC_QUERYCTRL_LASTP1()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 
test_VIDIOC_QUERYCTRL_LASTP1_1()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 
test_VIDIOC_QUERYCTRL_flag_NEXT_CTRL()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 
test_VIDIOC_QUERYCTRL_private()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 
test_VIDIOC_QUERYCTRL_private_base_1()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 
test_VIDIOC_QUERYCTRL_private_last_1()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 
test_VIDIOC_QUERYCTRL_NULL()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