• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4  */
5 
6 #include <ctime>
7 #include <string>
8 
9 #include <sys/ioctl.h>
10 
11 #include "cec-compliance.h"
12 
testFuzzing(struct node & node,unsigned me,unsigned la)13 int testFuzzing(struct node &node, unsigned me, unsigned la)
14 {
15 	printf("test fuzzing CEC local LA %d (%s) to remote LA %d (%s):\n\n",
16 	       me, cec_la2s(me), la, cec_la2s(la));
17 
18 	if (node.remote[la].in_standby) {
19 		announce("The remote device is in standby. It should be powered on when fuzzing. Aborting.");
20 		return 0;
21 	}
22 	if (!node.remote[la].has_power_status) {
23 		announce("The device didn't support Give Device Power Status.");
24 		announce("Assuming that the device is powered on.");
25 	}
26 
27 	unsigned int cnt = 0;
28 
29 	for (;;) {
30 		cec_msg msg;
31 		__u8 cmd;
32 		unsigned offset = 2;
33 
34 		cec_msg_init(&msg, me, la);
35 		msg.msg[1] = cmd = random() & 0xff;
36 		if (msg.msg[1] == CEC_MSG_STANDBY)
37 			continue;
38 		msg.len = (random() & 0xf) + 2;
39 		if (msg.msg[1] == CEC_MSG_VENDOR_COMMAND_WITH_ID &&
40 		    node.remote[la].vendor_id != CEC_VENDOR_ID_NONE) {
41 			msg.len += 3;
42 			offset += 3;
43 			msg.msg[2] = (node.remote[la].vendor_id & 0xff0000) >> 16;
44 			msg.msg[3] = (node.remote[la].vendor_id & 0xff00) >> 8;
45 			msg.msg[4] = node.remote[la].vendor_id & 0xff;
46 		}
47 		if (msg.len > CEC_MAX_MSG_SIZE)
48 			continue;
49 
50 		const char *name = cec_opcode2s(msg.msg[1]);
51 
52 		printf("Send message %u:", cnt);
53 		for (unsigned int i = 0; i < offset; i++)
54 			printf(" %02x", msg.msg[i]);
55 		for (unsigned int i = offset; i < msg.len; i++) {
56 			msg.msg[i] = random() & 0xff;
57 			printf(" %02x", msg.msg[i]);
58 		}
59 		if (name)
60 			printf(" (%s)", name);
61 		printf(": ");
62 		msg.reply = CEC_MSG_FEATURE_ABORT;
63 		fail_on_test(!transmit_timeout(&node, &msg, 1200));
64 		printf("%s", timed_out(&msg) ? "Timed out" : "Feature Abort");
65 
66 		if (cec_msg_status_is_abort(&msg)) {
67 			__u8 abort_msg, reason;
68 
69 			cec_ops_feature_abort(&msg, &abort_msg, &reason);
70 			fail_on_test(abort_msg != cmd);
71 			switch (reason) {
72 			case CEC_OP_ABORT_UNRECOGNIZED_OP:
73 				printf(" (Unrecognized Op)");
74 				break;
75 			case CEC_OP_ABORT_UNDETERMINED:
76 				printf(" (Undetermined)");
77 				break;
78 			case CEC_OP_ABORT_INVALID_OP:
79 				printf(" (Invalid Op)");
80 				break;
81 			case CEC_OP_ABORT_NO_SOURCE:
82 				printf(" (No Source)");
83 				break;
84 			case CEC_OP_ABORT_REFUSED:
85 				printf(" (Refused)");
86 				break;
87 			case CEC_OP_ABORT_INCORRECT_MODE:
88 				printf(" (Incorrect Mode)");
89 				break;
90 			default:
91 				printf(" (0x%02x)\n", reason);
92 				fail("Invalid reason\n");
93 				break;
94 			}
95 		}
96 		printf("\n");
97 		if (++cnt % 10)
98 			continue;
99 		if (la == CEC_LOG_ADDR_BROADCAST)
100 			continue;
101 		cec_msg_init(&msg, me, la);
102 		cec_msg_get_cec_version(&msg, true);
103 		printf("Query CEC Version: ");
104 		fail_on_test(!transmit_timeout(&node, &msg) || timed_out_or_abort(&msg));
105 		printf("OK\n");
106 	}
107 }
108