aboutsummaryrefslogtreecommitdiffstats
path: root/utils/cec-compliance/cec-test-fuzzing.cpp
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2019-09-30 13:35:25 +0200
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2019-09-30 13:35:25 +0200
commit6c9c63d98d60a4478d0e2a2f45fe0e54793f5582 (patch)
tree86ba59d8ba767dc4cbf5337304104bc7d52d0d48 /utils/cec-compliance/cec-test-fuzzing.cpp
parent9b773c22aee1b871031f3455c519fabb7e789585 (diff)
cec-compliance: add --test-fuzzing option
Add fuzzing support. Randomly generate CEC messages. After every 10 random messages check that you can still get the CEC version from the remote device. This is an initial implementation. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'utils/cec-compliance/cec-test-fuzzing.cpp')
-rw-r--r--utils/cec-compliance/cec-test-fuzzing.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/utils/cec-compliance/cec-test-fuzzing.cpp b/utils/cec-compliance/cec-test-fuzzing.cpp
new file mode 100644
index 00000000..fe3c8f21
--- /dev/null
+++ b/utils/cec-compliance/cec-test-fuzzing.cpp
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <config.h>
+#include <sstream>
+
+#include "cec-compliance.h"
+
+int testFuzzing(struct node &node, unsigned me, unsigned la)
+{
+ printf("test fuzzing CEC local LA %d (%s) to remote LA %d (%s):\n\n",
+ me, la2s(me), la, la2s(la));
+
+ if (node.remote[la].in_standby) {
+ announce("The remote device is in standby. It should be powered on when fuzzing. Aborting.");
+ return 0;
+ }
+ if (!node.remote[la].has_power_status) {
+ announce("The device didn't support Give Device Power Status.");
+ announce("Assuming that the device is powered on.");
+ }
+
+ unsigned int cnt = 0;
+
+ for (;;) {
+ cec_msg msg;
+ __u8 cmd;
+ unsigned offset = 2;
+
+ cec_msg_init(&msg, me, la);
+ msg.msg[1] = cmd = random() & 0xff;
+ if (msg.msg[1] == CEC_MSG_STANDBY)
+ continue;
+ msg.len = (random() & 0xf) + 2;
+ if (msg.msg[1] == CEC_MSG_VENDOR_COMMAND_WITH_ID &&
+ node.remote[la].vendor_id != CEC_VENDOR_ID_NONE) {
+ msg.len += 3;
+ offset += 3;
+ msg.msg[2] = (node.remote[la].vendor_id & 0xff0000) >> 16;
+ msg.msg[3] = (node.remote[la].vendor_id & 0xff00) >> 8;
+ msg.msg[4] = node.remote[la].vendor_id & 0xff;
+ }
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ continue;
+
+ const char *name = opcode2s(msg.msg[1]);
+
+ printf("Send message %u:", cnt);
+ for (unsigned int i = 0; i < offset; i++)
+ printf(" %02x", msg.msg[i]);
+ for (unsigned int i = offset; i < msg.len; i++) {
+ msg.msg[i] = random() & 0xff;
+ printf(" %02x", msg.msg[i]);
+ }
+ if (name)
+ printf(" (%s)", name);
+ printf(": ");
+ msg.reply = CEC_MSG_FEATURE_ABORT;
+ fail_on_test(!transmit_timeout(&node, &msg, 1200));
+ printf("%s", timed_out(&msg) ? "Timed out" : "Feature Abort");
+
+ if (cec_msg_status_is_abort(&msg)) {
+ __u8 abort_msg, reason;
+
+ cec_ops_feature_abort(&msg, &abort_msg, &reason);
+ fail_on_test(abort_msg != cmd);
+ switch (reason) {
+ case CEC_OP_ABORT_UNRECOGNIZED_OP:
+ printf(" (Unrecognized Op)");
+ break;
+ case CEC_OP_ABORT_UNDETERMINED:
+ printf(" (Undetermined)");
+ break;
+ case CEC_OP_ABORT_INVALID_OP:
+ printf(" (Invalid Op)");
+ break;
+ case CEC_OP_ABORT_NO_SOURCE:
+ printf(" (No Source)");
+ break;
+ case CEC_OP_ABORT_REFUSED:
+ printf(" (Refused)");
+ break;
+ case CEC_OP_ABORT_INCORRECT_MODE:
+ printf(" (Incorrect Mode)");
+ break;
+ default:
+ printf(" (0x%02x)\n", reason);
+ fail("Invalid reason\n");
+ break;
+ }
+ }
+ printf("\n");
+ if (++cnt % 10)
+ continue;
+ if (la == CEC_LOG_ADDR_BROADCAST)
+ continue;
+ cec_msg_init(&msg, me, la);
+ cec_msg_get_cec_version(&msg, true);
+ printf("Query CEC Version: ");
+ fail_on_test(!transmit_timeout(&node, &msg) || timed_out_or_abort(&msg));
+ printf("OK\n");
+ }
+}

Privacy Policy