From e550b99ad66cb1901bbca9433ea36cc665a8cfd6 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Sun, 19 Aug 2018 20:17:13 +0200 Subject: [PATCH] v4l2: improve control ID printing Control ID space is hierarchical, so, higher bits provide information about control class. * v4l2.c (print_v4l2_cid): New function. (print_v4l2_control): Use print_v4l2_cid for printing control ID field. * tests/ioctl_v4l2.c: Add checks for control ID printing. --- tests/ioctl_v4l2.c | 30 ++++++++++++++++++++++++++++++ v4l2.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tests/ioctl_v4l2.c b/tests/ioctl_v4l2.c index 54e9ee7c..5ddab1c6 100644 --- a/tests/ioctl_v4l2.c +++ b/tests/ioctl_v4l2.c @@ -690,6 +690,23 @@ main(void) ioctl(-1, VIDIOC_G_CTRL, 0); printf("ioctl(-1, VIDIOC_G_CTRL, NULL) = -1 EBADF (%m)\n"); + static const struct v4l2_control v4l2_control_vals[] = { + { .id = 0, .value = 3141592653U }, + { .id = 0x97abcd, .value = 1234567890U }, + { .id = V4L2_CTRL_CLASS_USER, .value = 0 }, + { .id = 0x990a64, .value = 42 }, + { .id = 0xa31234, .value = 1 }, + { .id = 0xa40000, .value = -1 }, + }; + static const char *id_strs[] = { + "0 /* V4L2_CID_??? */", + "0x97abcd /* V4L2_CID_??? */", + "V4L2_CTRL_CLASS_USER+0", + "V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE", + "V4L2_CTRL_CLASS_DETECT+0x1234", + "0xa40000 /* V4L2_CID_??? */", + }; + struct v4l2_control *const p_v4l2_control = page_end - sizeof(*p_v4l2_control); ioctl(-1, VIDIOC_G_CTRL, p_v4l2_control); @@ -705,6 +722,19 @@ main(void) ", value=%d}) = -1 EBADF (%m)\n", p_v4l2_control->id, p_v4l2_control->value); + for (size_t i = 0; i < ARRAY_SIZE(id_strs); i++) { + struct v4l2_control v4l2_c = v4l2_control_vals[i]; + + ioctl(-1, VIDIOC_G_CTRL, &v4l2_c); + printf("ioctl(-1, VIDIOC_G_CTRL, {id=%s}) = -1 EBADF (%m)\n", + id_strs[i]); + + ioctl(-1, VIDIOC_S_CTRL, &v4l2_c); + printf("ioctl(-1, VIDIOC_S_CTRL, {id=%s, value=%d})" + " = -1 EBADF (%m)\n", + id_strs[i], v4l2_c.value); + } + /* VIDIOC_G_TUNER */ ioctl(-1, VIDIOC_G_TUNER, 0); printf("ioctl(-1, VIDIOC_G_TUNER, NULL) = -1 EBADF (%m)\n"); diff --git a/v4l2.c b/v4l2.c index b325cf8b..5da457c6 100644 --- a/v4l2.c +++ b/v4l2.c @@ -598,6 +598,34 @@ print_v4l2_input(struct tcb *const tcp, const kernel_ulong_t arg) #include "xlat/v4l2_control_id_bases.h" #include "xlat/v4l2_control_ids.h" +static void +print_v4l2_cid(const uint32_t cid) +{ + const char *id_name = xlookup(v4l2_control_ids, cid); + + if (id_name) { + print_xlat_ex(cid, id_name, XLAT_STYLE_DEFAULT); + return; + } + + uint64_t class_id = cid; + const char *class_str = xlookup_le(v4l2_control_classes, &class_id); + + if (!class_str || (cid - class_id) >= 0x10000) { + print_xlat_ex(cid, "V4L2_CID_???", PXF_DEFAULT_STR); + return; + } + + char *tmp_str; + + if (asprintf(&tmp_str, "%s+%#" PRIx64, + class_str, cid - class_id) < 0) + tmp_str = NULL; + + print_xlat_ex(cid, tmp_str, XLAT_STYLE_DEFAULT); + free(tmp_str); +} + static int print_v4l2_control(struct tcb *const tcp, const kernel_ulong_t arg, const bool is_get) @@ -608,8 +636,9 @@ print_v4l2_control(struct tcb *const tcp, const kernel_ulong_t arg, tprints(", "); if (umove_or_printaddr(tcp, arg, &c)) return RVAL_IOCTL_DECODED; + tprints("{id="); - printxval(v4l2_control_ids, c.id, "V4L2_CID_???"); + print_v4l2_cid(c.id); if (!is_get) tprintf(", value=%d", c.value); return 0; -- 2.40.0