v4l2-compliance: various fixes/improvements
authorHans Verkuil <hverkuil@xs4all.nl>
Wed, 12 Jan 2011 07:30:33 +0000 (08:30 +0100)
committerHans Verkuil <hverkuil@xs4all.nl>
Wed, 12 Jan 2011 07:30:33 +0000 (08:30 +0100)
- add warn and info macros
- always print fail messages, no longer require --verbose
- a few more QUERYCTRL checks
- better QUERYCAP handling

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
utils/v4l2-compliance/v4l2-compliance.cpp
utils/v4l2-compliance/v4l2-compliance.h
utils/v4l2-compliance/v4l2-test-controls.cpp

index 5dc39d8..ba27e62 100644 (file)
@@ -73,8 +73,8 @@ static int tests_total, tests_ok;
 
 // Globals
 int verbose;
-int ignore_failure;
 unsigned caps;
+unsigned warnings;
 
 static struct option long_options[] = {
        {"device", required_argument, 0, OptSetDevice},
@@ -102,7 +102,7 @@ static void usage(void)
        printf("  -t, --test=<num>   run specified test.\n");
        printf("                     By default all tests are run.\n");
        printf("                     0 = test VIDIOC_QUERYCAP\n");
-       printf("  -v, --verbose      turn on verbose error reporting.\n");
+       printf("  -v, --verbose      turn on verbose reporting.\n");
        printf("  -T, --trace        trace all called ioctls.\n");
        exit(0);
 }
@@ -224,6 +224,12 @@ static int testCap(struct node *node)
                return fail("invalid driver name\n");
        if (check_ustring(vcap.card, sizeof(vcap.card)))
                return fail("invalid card name\n");
+       if (check_ustring(vcap.bus_info, sizeof(vcap.bus_info))) {
+               if (vcap.bus_info[0])
+                       return fail("invalid bus_info\n");
+               else
+                       warn("empty bus_info\n");
+       }
        if (check_0(vcap.reserved, sizeof(vcap.reserved)))
                return fail("non-zero reserved fields\n");
        caps = vcap.capabilities;
@@ -430,7 +436,10 @@ int main(int argc, char **argv)
        printf("\tDriver name   : %s\n", vcap.driver);
        printf("\tCard type     : %s\n", vcap.card);
        printf("\tBus info      : %s\n", vcap.bus_info);
-       printf("\tDriver version: %d\n", vcap.version);
+       printf("\tDriver version: %d.%d.%d\n",
+                       vcap.version >> 16,
+                       (vcap.version >> 8) & 0xff,
+                       vcap.version & 0xff);
        printf("\tCapabilities  : 0x%08X\n", vcap.capabilities);
        printf("%s", cap2s(vcap.capabilities).c_str());
 
@@ -507,7 +516,7 @@ int main(int argc, char **argv)
        }
 
        close(node.fd);
-       printf("Total: %d Succeeded: %d Failed: %d\n",
-                       tests_total, tests_ok, tests_total - tests_ok);
+       printf("Total: %d Succeeded: %d Failed: %d Warnings: %d\n",
+                       tests_total, tests_ok, tests_total - tests_ok, warnings);
        exit(app_result);
 }
index e503ac6..10fdce6 100644 (file)
@@ -26,6 +26,7 @@
 
 extern int verbose;
 extern unsigned caps;
+extern unsigned warnings;
 
 struct node {
        int fd;
@@ -41,10 +42,22 @@ struct node {
        unsigned priv_user_controls_check;
 };
 
+#define info(fmt, args...)                                     \
+       do {                                                    \
+               if (verbose)                                    \
+                       printf("\t\tinfo: " fmt, ##args);       \
+       } while (0)
+
+#define warn(fmt, args...)                                     \
+       do {                                                    \
+               warnings++;                                     \
+               if (verbose)                                    \
+                       printf("\t\twarn: " fmt, ##args);       \
+       } while (0)
+
 #define fail(fmt, args...)                     \
 ({                                             \
-       if (verbose)                            \
-               printf("\t\tfail: " fmt, ##args);       \
+       printf("\t\tfail: " fmt, ##args);       \
        1;                                      \
 })
 
index 7feef2d..ddb1484 100644 (file)
@@ -46,6 +46,13 @@ int validQCtrl(struct node *node, const struct v4l2_queryctrl &qctrl)
                return fail("non-zero reserved fields\n");
        if (check_ustring(qctrl.name, sizeof(qctrl.name)))
                return fail("invalid name\n");
+       if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
+               if ((qctrl.id & 0xffff) != 1)
+                       return fail("invalid control ID for a control class\n");
+       } else {
+               if ((qctrl.id & 0xffff) < 0x900)
+                       return fail("invalid control ID\n");
+       }
        switch (qctrl.type) {
        case V4L2_CTRL_TYPE_BOOLEAN:
                if (qctrl.maximum > 1)
@@ -104,6 +111,10 @@ int validQCtrl(struct node *node, const struct v4l2_queryctrl &qctrl)
                        return fail("invalid flags for control class\n");
                break;
        }
+       if (fl & V4L2_CTRL_FLAG_GRABBED)
+               return fail("GRABBED flag set\n");
+       if (fl & V4L2_CTRL_FLAG_DISABLED)
+               return fail("DISABLED flag set\n");
        if (qctrl.type != V4L2_CTRL_TYPE_MENU) {
                memset(&qmenu, 0xff, sizeof(qmenu));
                qmenu.id = qctrl.id;
@@ -162,6 +173,8 @@ int testQueryControls(struct node *node)
                if (qctrl.id <= id)
                        return fail("id did not increase!\n");
                id = qctrl.id;
+               if (id >= V4L2_CID_PRIVATE_BASE)
+                       return fail("no V4L2_CID_PRIVATE_BASE allowed\n");
                if (V4L2_CTRL_ID2CLASS(id) != ctrl_class) {
                        if (ctrl_class && !found_ctrl_class)
                                return fail("missing control class for class %08x\n", ctrl_class);