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.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 Mrton Nmeth <nm127 (at) 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 
     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 
     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 
     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 
    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 
    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 
    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 
    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