Home | History | Annotate | Download | only in user_space
      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 Mrton Nmeth <nm127 (at) 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 
     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 
     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 
     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 
    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 
    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 
    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 
    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