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