1 /*
2 * v4l-test: Test environment for Video For Linux Two API
3 *
4 * 4 Apr 2009 0.5 Test case for NULL parameter reworked
5 * 22 Mar 2009 0.4 Cleanup dprintf() outputs and ret and errno names
6 * 9 Feb 2009 0.3 Modify test cases to support drivers without any inputs
7 * 22 Dec 2008 0.2 Test case with NULL parameter added
8 * 18 Dec 2008 0.1 First release
9 *
10 * Written by M�rton N�meth <nm127@freemail.hu>
11 * Released under GPL
12 */
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <sys/ioctl.h>
20 #include <errno.h>
21 #include <string.h>
22
23 #include <linux/videodev2.h>
24 #include <linux/errno.h>
25
26 #include <CUnit/CUnit.h>
27
28 #include "v4l2_test.h"
29 #include "dev_video.h"
30 #include "video_limits.h"
31
32 #include "test_VIDIOC_INPUT.h"
33
valid_input_index(int f,__u32 index)34 int valid_input_index(int f, __u32 index)
35 {
36 __u32 i;
37 struct v4l2_input input;
38 int ret_enum, errno_enum;
39 int valid = 0;
40
41 /* Search for index with VIDIOC_ENUMINPUT. Do not just
42 * check the given index with VIDIOC_ENUMINPUT because
43 * we could miss the end of the enumeration. After the
44 * end of enumeration no more indexes are allowed.
45 */
46 i = 0;
47 do {
48 memset(&input, 0xff, sizeof(input));
49 input.index = i;
50 ret_enum = ioctl(f, VIDIOC_ENUMINPUT, &input);
51 errno_enum = errno;
52 if (ret_enum == 0 && index == i) {
53 valid = 1;
54 break;
55 }
56 i++;
57 } while (ret_enum == 0 && i != 0);
58 return valid;
59 }
60
test_VIDIOC_G_INPUT()61 void test_VIDIOC_G_INPUT()
62 {
63 int ret_get, errno_get;
64 __u32 index;
65 int f;
66
67 f = get_video_fd();
68
69 memset(&index, 0xff, sizeof(index));
70 ret_get = ioctl(f, VIDIOC_G_INPUT, &index);
71 errno_get = errno;
72
73 dprintf("\tVIDIOC_G_INPUT, ret_get=%i, errno_get=%i\n", ret_get,
74 errno_get);
75
76 if (ret_get == 0) {
77 CU_ASSERT_EQUAL(ret_get, 0);
78 CU_ASSERT(valid_input_index(f, index));
79
80 dprintf("\tindex=0x%X\n", index);
81
82 } else {
83 CU_ASSERT_EQUAL(ret_get, -1);
84 CU_ASSERT_EQUAL(errno_get, EINVAL);
85 }
86
87 }
88
test_VIDIOC_S_INPUT_from_enum()89 void test_VIDIOC_S_INPUT_from_enum()
90 {
91 int ret_get, errno_get;
92 int ret_enum, errno_enum;
93 int ret_set, errno_set;
94 __u32 input_index_orig;
95 struct v4l2_input input;
96 __u32 i;
97 int f;
98
99 f = get_video_fd();
100
101 memset(&input_index_orig, 0xff, sizeof(input_index_orig));
102 ret_get = ioctl(f, VIDIOC_G_INPUT, &input_index_orig);
103 errno_get = errno;
104 if (ret_get == 0) {
105 CU_ASSERT_EQUAL(ret_get, 0);
106
107 i = 0;
108 do {
109 memset(&input, 0xff, sizeof(input));
110 input.index = i;
111 ret_enum = ioctl(f, VIDIOC_ENUMINPUT, &input);
112 errno_enum = errno;
113
114 dprintf("\tENUMINPUT: i=%u, ret_enum=%i, errno=%i\n", i,
115 ret_enum, errno);
116
117 if (ret_enum == 0) {
118 ret_set =
119 ioctl(f, VIDIOC_S_INPUT, &input.index);
120 errno_set = errno;
121 CU_ASSERT_EQUAL(ret_set, 0);
122
123 dprintf
124 ("\tinput.index=0x%X, ret_set=%i, errno_set=%i\n",
125 input.index, ret_set, errno_set);
126
127 }
128 i++;
129 } while (ret_enum == 0 && i != 0);
130
131 /* Setting the original input_id should not fail */
132 ret_set = ioctl(f, VIDIOC_S_INPUT, &input_index_orig);
133 CU_ASSERT_EQUAL(ret_set, 0);
134 } else {
135 CU_ASSERT_EQUAL(ret_get, -1);
136 CU_ASSERT_EQUAL(errno_get, EINVAL);
137 }
138 }
139
do_set_input(int f,__u32 first_wrong_input,__u32 index)140 static void do_set_input(int f, __u32 first_wrong_input, __u32 index)
141 {
142 struct v4l2_input input;
143 int ret_set, errno_set;
144
145 if (first_wrong_input <= index) {
146
147 dprintf("\tdo_set_input(f, 0x%X, 0x%X)\n", first_wrong_input,
148 index);
149
150 memset(&input, 0xff, sizeof(input));
151 input.index = index;
152 ret_set = ioctl(f, VIDIOC_S_INPUT, &input.index);
153 errno_set = errno;
154
155 CU_ASSERT_EQUAL(ret_set, -1);
156 CU_ASSERT_EQUAL(errno_set, EINVAL);
157
158 dprintf("\t%s:%u: input.index=0x%X, ret_set=%i, errno_set=%i\n",
159 __FILE__, __LINE__, input.index, ret_set, errno_set);
160
161 }
162
163 }
164
test_VIDIOC_S_INPUT_invalid_inputs()165 void test_VIDIOC_S_INPUT_invalid_inputs()
166 {
167 int ret_get, errno_get;
168 int ret_enum, errno_enum;
169 int ret_set, errno_set;
170 __u32 input_index_orig;
171 struct v4l2_input input;
172 __u32 i, first_wrong_input;
173 int f;
174
175 f = get_video_fd();
176
177 memset(&input_index_orig, 0xff, sizeof(input_index_orig));
178 ret_get = ioctl(f, VIDIOC_G_INPUT, &input_index_orig);
179 errno_get = errno;
180
181 if (ret_get == 0) {
182 CU_ASSERT_EQUAL(ret_get, 0);
183 i = 0;
184 do {
185 memset(&input, 0xff, sizeof(input));
186 input.index = i;
187 ret_enum = ioctl(f, VIDIOC_ENUMINPUT, &input);
188 errno_enum = errno;
189
190 dprintf
191 ("\t%s:%u: ENUMINPUT: i=%u, ret_enum=%i, errno_enum=%i\n",
192 __FILE__, __LINE__, i, ret_enum, errno_enum);
193
194 i++;
195 } while (ret_enum == 0 && i != 0);
196
197 if (i != 0) {
198 first_wrong_input = i;
199
200 /* The input index range 0..(i-1) are valid inputs. */
201 /* Try index values from range i..U32_MAX */
202 do_set_input(f, first_wrong_input, i);
203 do_set_input(f, first_wrong_input, i + 1);
204
205 /* Check for signed/unsigned mismatch near S32_MAX */
206 for (i = 0; i <= first_wrong_input + 1; i++) {
207 do_set_input(f, first_wrong_input,
208 ((__u32) S32_MAX) + i);
209 }
210
211 i = (U32_MAX - 1) - first_wrong_input;
212 do {
213 do_set_input(f, first_wrong_input, i);
214 i++;
215 } while (i != 0);
216 }
217
218 /* Setting the original input_id should not fail */
219 ret_set = ioctl(f, VIDIOC_S_INPUT, &input_index_orig);
220 errno_set = errno;
221
222 CU_ASSERT_EQUAL(ret_set, 0);
223 } else {
224 CU_ASSERT_EQUAL(ret_get, -1);
225 CU_ASSERT_EQUAL(errno_get, EINVAL);
226 }
227 }
228
test_VIDIOC_G_INPUT_NULL()229 void test_VIDIOC_G_INPUT_NULL()
230 {
231 int ret_get, errno_get;
232 int ret_null, errno_null;
233 __u32 index;
234
235 memset(&index, 0xff, sizeof(index));
236 ret_get = ioctl(get_video_fd(), VIDIOC_G_INPUT, &index);
237 errno_get = errno;
238
239 dprintf("\t%s:%u: VIDIOC_G_INPUT, ret_get=%i, errno_get=%i\n",
240 __FILE__, __LINE__, ret_get, errno_get);
241
242 ret_null = ioctl(get_video_fd(), VIDIOC_G_INPUT, NULL);
243 errno_null = errno;
244
245 dprintf("\t%s:%u: VIDIOC_G_INPUT: ret_null=%i, errno_null=%i\n",
246 __FILE__, __LINE__, ret_null, errno_null);
247
248 if (ret_get == 0) {
249 CU_ASSERT_EQUAL(ret_get, 0);
250 CU_ASSERT_EQUAL(ret_null, -1);
251 CU_ASSERT_EQUAL(errno_null, EFAULT);
252 } else {
253 CU_ASSERT_EQUAL(ret_get, -1);
254 CU_ASSERT_EQUAL(errno_get, EINVAL);
255 CU_ASSERT_EQUAL(ret_null, -1);
256 CU_ASSERT_EQUAL(errno_null, EINVAL);
257 }
258
259 }
260
test_VIDIOC_S_INPUT_NULL()261 void test_VIDIOC_S_INPUT_NULL()
262 {
263 int ret_orig, errno_orig;
264 int ret_set, errno_set;
265 int ret_null, errno_null;
266 __u32 index_orig;
267 __u32 index;
268
269 /* save the original input */
270 memset(&index_orig, 0, sizeof(index_orig));
271 ret_orig = ioctl(get_video_fd(), VIDIOC_G_INPUT, &index_orig);
272 errno_orig = errno;
273
274 dprintf("\t%s:%u: VIDIOC_G_INPUT, ret_orig=%i, errno_orig=%i\n",
275 __FILE__, __LINE__, ret_orig, errno_orig);
276
277 memset(&index, 0xff, sizeof(index));
278 index = index_orig;
279 ret_set = ioctl(get_video_fd(), VIDIOC_S_INPUT, &index);
280 errno_set = errno;
281
282 dprintf("\t%s:%u: VIDIOC_S_INPUT ret_set=%i, errno_set=%i\n",
283 __FILE__, __LINE__, ret_set, errno_set);
284
285 ret_null = ioctl(get_video_fd(), VIDIOC_S_INPUT, NULL);
286 errno_null = errno;
287
288 dprintf("\t%s:%u: VIDIOC_S_INPUT: ret_null=%i, errno_null=%i\n",
289 __FILE__, __LINE__, ret_null, errno_null);
290
291 if (ret_set == 0) {
292 CU_ASSERT_EQUAL(ret_set, 0);
293 CU_ASSERT_EQUAL(ret_null, -1);
294 CU_ASSERT_EQUAL(errno_null, EFAULT);
295 } else {
296 CU_ASSERT_EQUAL(ret_set, -1);
297 CU_ASSERT_EQUAL(errno_set, EINVAL);
298 CU_ASSERT_EQUAL(ret_null, -1);
299 CU_ASSERT_EQUAL(errno_null, EINVAL);
300 }
301
302 }
303