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