1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4 */
5
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <inttypes.h>
11 #include <getopt.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <sys/ioctl.h>
18 #include <sys/wait.h>
19 #include <sstream>
20 #include <cstdlib>
21
22 #include "cec-compliance.h"
23
24 static const uint8_t tx_ok_retry_mask = CEC_TX_STATUS_OK | CEC_TX_STATUS_MAX_RETRIES;
25 static const uint32_t msg_fl_mask = CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW;
26
27 // Flush any pending messages
flush_pending_msgs(struct node * node)28 static int flush_pending_msgs(struct node *node)
29 {
30 int res;
31
32 do {
33 struct cec_msg msg;
34
35 memset(&msg, 0xff, sizeof(msg));
36 msg.timeout = 1;
37 res = doioctl(node, CEC_RECEIVE, &msg);
38 fail_on_test(res && res != ETIMEDOUT);
39 } while (res == 0);
40 return 0;
41 }
42
testCap(struct node * node)43 static int testCap(struct node *node)
44 {
45 struct cec_caps caps;
46
47 memset(&caps, 0xff, sizeof(caps));
48 fail_on_test(doioctl(node, CEC_ADAP_G_CAPS, NULL) != EFAULT);
49 fail_on_test(doioctl(node, CEC_ADAP_G_CAPS, &caps));
50 fail_on_test(caps.available_log_addrs == 0 ||
51 caps.available_log_addrs > CEC_MAX_LOG_ADDRS);
52 fail_on_test((caps.capabilities & CEC_CAP_PASSTHROUGH) &&
53 !(caps.capabilities & CEC_CAP_TRANSMIT));
54 return 0;
55 }
56
testInvalidIoctls(struct node * node)57 static int testInvalidIoctls(struct node *node)
58 {
59 const char type = 'a';
60 unsigned ioc = _IOC(IOC_VOID, type, 0xff, 0);
61 unsigned char buf[0x4000] = {};
62
63 fail_on_test(doioctl(node, ioc, NULL) != ENOTTY);
64 ioc = _IOC(IOC_VOID, type, 0, 0x3fff);
65 fail_on_test(doioctl(node, ioc, NULL) != ENOTTY);
66 ioc = _IOC(IOC_OUT, type, 0, 0x3fff);
67 fail_on_test(doioctl(node, ioc, buf) != ENOTTY);
68 fail_on_test(check_0(buf, sizeof(buf)));
69 ioc = _IOC(IOC_IN, type, 0, 0x3fff);
70 fail_on_test(doioctl(node, ioc, buf) != ENOTTY);
71 fail_on_test(check_0(buf, sizeof(buf)));
72 ioc = _IOC(IOC_OUT | IOC_IN, type, 0, 0x3fff);
73 fail_on_test(doioctl(node, ioc, buf) != ENOTTY);
74 fail_on_test(check_0(buf, sizeof(buf)));
75 return 0;
76 }
77
testDQEvent(struct node * node)78 static int testDQEvent(struct node *node)
79 {
80 struct cec_event ev;
81
82 memset(&ev, 0xff, sizeof(ev));
83 fail_on_test(doioctl(node, CEC_DQEVENT, &ev));
84 fail_on_test(!(ev.flags & CEC_EVENT_FL_INITIAL_STATE));
85 fail_on_test(ev.flags & ~CEC_EVENT_FL_INITIAL_STATE);
86 fail_on_test(ev.ts == 0 || ev.ts == ~0ULL);
87 fail_on_test(ev.event != CEC_EVENT_STATE_CHANGE);
88 fail_on_test(ev.state_change.log_addr_mask == 0xffff);
89 memset(&ev.state_change, 0, sizeof(ev.state_change));
90 fail_on_test(check_0(ev.raw, sizeof(ev.raw)));
91 return 0;
92 }
93
testAdapPhysAddr(struct node * node)94 static int testAdapPhysAddr(struct node *node)
95 {
96 uint16_t old_pa = 0xefff;
97 uint16_t pa = 0x1000;
98
99 fail_on_test(doioctl(node, CEC_ADAP_G_PHYS_ADDR, &old_pa));
100 fail_on_test(old_pa == 0xefff);
101 if (node->caps & CEC_CAP_PHYS_ADDR) {
102 fail_on_test(doioctl(node, CEC_ADAP_S_PHYS_ADDR, &pa));
103 fail_on_test(doioctl(node, CEC_ADAP_G_PHYS_ADDR, &pa));
104 fail_on_test(pa != 0x1000);
105
106 fail_on_test(doioctl(node, CEC_ADAP_S_PHYS_ADDR, &old_pa));
107 fail_on_test(doioctl(node, CEC_ADAP_G_PHYS_ADDR, &pa));
108 fail_on_test(pa != old_pa);
109 } else {
110 fail_on_test(doioctl(node, CEC_ADAP_S_PHYS_ADDR, &pa) != ENOTTY);
111 }
112 return 0;
113 }
114
testAdapLogAddrs(struct node * node)115 static int testAdapLogAddrs(struct node *node)
116 {
117 static const uint8_t la_types[] = {
118 CEC_LOG_ADDR_TYPE_TV,
119 CEC_LOG_ADDR_TYPE_RECORD,
120 CEC_LOG_ADDR_TYPE_TUNER,
121 CEC_LOG_ADDR_TYPE_AUDIOSYSTEM
122 };
123 static const uint8_t prim_dev_types[] = {
124 CEC_OP_PRIM_DEVTYPE_TV,
125 CEC_OP_PRIM_DEVTYPE_RECORD,
126 CEC_OP_PRIM_DEVTYPE_TUNER,
127 CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
128 };
129 static const uint8_t all_dev_types[2] = {
130 CEC_OP_ALL_DEVTYPE_TV | CEC_OP_ALL_DEVTYPE_RECORD |
131 CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM,
132 CEC_OP_ALL_DEVTYPE_RECORD | CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM,
133 };
134 static const uint8_t features[12] = {
135 0x90, 0x00, 0x8e, 0x00,
136 0xff, 0xff, 0xff, 0xff,
137 0xff, 0xff, 0xff, 0xff
138 };
139 struct cec_log_addrs clear = { };
140 struct cec_log_addrs laddrs;
141 struct cec_event ev;
142 int res;
143
144 memset(&laddrs, 0xff, sizeof(laddrs));
145 fail_on_test(doioctl(node, CEC_ADAP_G_LOG_ADDRS, &laddrs));
146 fail_on_test(laddrs.vendor_id != CEC_VENDOR_ID_NONE &&
147 (laddrs.vendor_id & 0xff000000));
148 fail_on_test(laddrs.cec_version != CEC_OP_CEC_VERSION_1_4 &&
149 laddrs.cec_version != CEC_OP_CEC_VERSION_2_0);
150 fail_on_test(laddrs.num_log_addrs > CEC_MAX_LOG_ADDRS);
151
152 if (node->phys_addr == CEC_PHYS_ADDR_INVALID || laddrs.num_log_addrs == 0)
153 fail_on_test(laddrs.log_addr_mask);
154 else
155 fail_on_test(!laddrs.log_addr_mask);
156
157 if (!(node->caps & CEC_CAP_LOG_ADDRS)) {
158 fail_on_test(!laddrs.num_log_addrs);
159 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &laddrs) != ENOTTY);
160 return 0;
161 }
162
163 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &clear));
164 fail_on_test(clear.num_log_addrs != 0);
165 fail_on_test(clear.log_addr_mask != 0);
166 fail_on_test(doioctl(node, CEC_ADAP_G_LOG_ADDRS, &laddrs));
167 fail_on_test(laddrs.num_log_addrs != 0);
168 fail_on_test(laddrs.log_addr_mask != 0);
169
170 uint16_t pa;
171
172 fail_on_test(doioctl(node, CEC_ADAP_G_PHYS_ADDR, &pa));
173 fail_on_test(pa != node->phys_addr);
174 unsigned skip_tv = pa ? 1 : 0;
175 unsigned available_log_addrs = node->available_log_addrs;
176
177 if (skip_tv && available_log_addrs == CEC_MAX_LOG_ADDRS)
178 available_log_addrs--;
179 memset(&laddrs, 0, sizeof(laddrs));
180 strcpy(laddrs.osd_name, "Compliance");
181 laddrs.num_log_addrs = available_log_addrs;
182 laddrs.cec_version = laddrs.num_log_addrs > 2 ?
183 CEC_OP_CEC_VERSION_1_4: CEC_OP_CEC_VERSION_2_0;
184
185 for (unsigned i = 0; i < CEC_MAX_LOG_ADDRS - skip_tv; i++) {
186 laddrs.log_addr_type[i] = la_types[i + skip_tv];
187 laddrs.primary_device_type[i] = prim_dev_types[i + skip_tv];
188 laddrs.all_device_types[i] = all_dev_types[skip_tv];
189 memcpy(laddrs.features[i], features, sizeof(features));
190 }
191
192 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &laddrs));
193 fail_on_test(laddrs.num_log_addrs != available_log_addrs);
194 fail_on_test(laddrs.log_addr_mask == 0);
195 for (unsigned i = 0; i < laddrs.num_log_addrs; i++) {
196 fail_on_test(laddrs.log_addr[i] == CEC_LOG_ADDR_INVALID);
197 fail_on_test(memcmp(laddrs.features[i], features, 4));
198 fail_on_test(check_0(laddrs.features[i] + 4, 8));
199 }
200 for (unsigned i = laddrs.num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) {
201 fail_on_test(laddrs.log_addr_type[i]);
202 fail_on_test(laddrs.primary_device_type[i]);
203 fail_on_test(laddrs.all_device_types[i]);
204 fail_on_test(check_0(laddrs.features[i], sizeof(laddrs.features[i])));
205 }
206 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &laddrs) != EBUSY);
207
208 fcntl(node->fd, F_SETFL, fcntl(node->fd, F_GETFL) | O_NONBLOCK);
209 do {
210 res = doioctl(node, CEC_DQEVENT, &ev);
211 fail_on_test(res && res != EAGAIN);
212 if (!res) {
213 struct timeval tv = { 0, 10000 }; // 10 ms
214
215 switch (ev.event) {
216 case CEC_EVENT_STATE_CHANGE:
217 fail_on_test(ev.flags & CEC_EVENT_FL_INITIAL_STATE);
218 break;
219 case CEC_EVENT_PIN_CEC_LOW:
220 case CEC_EVENT_PIN_CEC_HIGH:
221 case CEC_EVENT_PIN_HPD_LOW:
222 case CEC_EVENT_PIN_HPD_HIGH:
223 case CEC_EVENT_PIN_5V_LOW:
224 case CEC_EVENT_PIN_5V_HIGH:
225 fail_on_test(!(ev.flags & CEC_EVENT_FL_INITIAL_STATE));
226 break;
227 case CEC_EVENT_LOST_MSGS:
228 fail("Unexpected event %d\n", ev.event);
229 break;
230 default:
231 fail("Unknown event %d\n", ev.event);
232 break;
233 }
234 select(0, NULL, NULL, NULL, &tv);
235 }
236 } while (!res);
237 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &clear));
238 do {
239 struct timeval tv = { 0, 10000 }; // 10 ms
240
241 res = doioctl(node, CEC_DQEVENT, &ev);
242 fail_on_test(res && res != EAGAIN);
243 if (res)
244 select(0, NULL, NULL, NULL, &tv);
245 } while (res);
246 fail_on_test(ev.flags & CEC_EVENT_FL_INITIAL_STATE);
247 fail_on_test(ev.ts == 0);
248 fail_on_test(ev.event != CEC_EVENT_STATE_CHANGE);
249 fail_on_test(ev.state_change.phys_addr != node->phys_addr);
250 fail_on_test(ev.state_change.log_addr_mask);
251
252 fail_on_test(doioctl(node, CEC_ADAP_S_LOG_ADDRS, &laddrs));
253 do {
254 struct timeval tv = { 0, 10000 }; // 10 ms
255
256 res = doioctl(node, CEC_DQEVENT, &ev);
257 fail_on_test(res && res != EAGAIN);
258 if (res)
259 select(0, NULL, NULL, NULL, &tv);
260 } while (res);
261 fail_on_test(ev.flags & CEC_EVENT_FL_INITIAL_STATE);
262 fail_on_test(ev.ts == 0);
263 fail_on_test(ev.event != CEC_EVENT_STATE_CHANGE);
264 fail_on_test(ev.state_change.phys_addr != node->phys_addr);
265 fail_on_test(ev.state_change.log_addr_mask == 0);
266 return 0;
267 }
268
testTransmit(struct node * node)269 static int testTransmit(struct node *node)
270 {
271 struct cec_msg msg = { };
272 unsigned i, la = node->log_addr[0];
273 unsigned valid_la = 15, invalid_la = 15;
274 bool tested_self = false;
275 bool tested_valid_la = false;
276 bool tested_invalid_la = false;
277
278 if (!(node->caps & CEC_CAP_TRANSMIT)) {
279 cec_msg_init(&msg, la, 0);
280 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != ENOTTY);
281 return OK_NOT_SUPPORTED;
282 }
283
284 /* Check invalid messages */
285 cec_msg_init(&msg, la, 0xf);
286 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
287
288 cec_msg_init(&msg, la, 0);
289 msg.timeout = 1000;
290 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
291
292 cec_msg_init(&msg, la, 0);
293 msg.len = 0;
294 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
295
296 cec_msg_init(&msg, la, 0);
297 msg.len = CEC_MAX_MSG_SIZE + 1;
298 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
299
300 cec_msg_init(&msg, la, 0);
301 msg.reply = CEC_MSG_CEC_VERSION;
302 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
303
304 for (i = 0; i < 15; i++) {
305 if (tested_self && (node->adap_la_mask & (1 << i)))
306 continue;
307
308 memset(&msg, 0xff, sizeof(msg));
309 msg.msg[0] = 0xf0 | i;
310 msg.len = 1;
311 msg.timeout = 0;
312 msg.reply = 0;
313 msg.flags &= ~msg_fl_mask;
314
315 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
316
317 fail_on_test(msg.len != 1);
318 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
319 fail_on_test(msg.timeout);
320 fail_on_test(msg.reply);
321 fail_on_test(msg.flags);
322 fail_on_test(msg.rx_status);
323 fail_on_test(msg.rx_ts);
324 fail_on_test(msg.tx_status == 0);
325 fail_on_test(msg.tx_ts == 0);
326 fail_on_test(msg.tx_ts == ~0ULL);
327 fail_on_test(msg.msg[0] != (0xf0 | i));
328 fail_on_test(msg.sequence == 0);
329 fail_on_test(msg.sequence == ~0U);
330 fail_on_test(msg.tx_status & ~0x3f);
331 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
332 fail_on_test(!(msg.tx_status & tx_ok_retry_mask));
333
334 if (node->adap_la_mask & (1 << i)) {
335 // Send message to yourself
336 fail_on_test(msg.tx_status !=
337 (CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES));
338 fail_on_test(msg.tx_nack_cnt != 1);
339 fail_on_test(msg.tx_arb_lost_cnt);
340 fail_on_test(msg.tx_low_drive_cnt);
341 fail_on_test(msg.tx_error_cnt);
342
343 cec_msg_init(&msg, i, i);
344 cec_msg_give_physical_addr(&msg, true);
345 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EINVAL);
346 } else if (msg.tx_status & CEC_TX_STATUS_OK) {
347 if (tested_valid_la)
348 continue;
349 tested_valid_la = true;
350 valid_la = i;
351 // Send message to a remote LA
352 memset(&msg, 0xff, sizeof(msg));
353 msg.msg[0] = (la << 4) | i;
354 msg.timeout = 1001;
355 msg.flags &= ~msg_fl_mask;
356 cec_msg_give_physical_addr(&msg, true);
357 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
358 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_OK));
359 fail_on_test(msg.rx_status & CEC_RX_STATUS_TIMEOUT);
360 fail_on_test(!(msg.rx_status & CEC_RX_STATUS_OK));
361 fail_on_test(msg.len != 5);
362 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
363 fail_on_test(msg.timeout != 1001);
364 fail_on_test(msg.sequence == 0 || msg.sequence == ~0U);
365 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
366 fail_on_test(msg.rx_ts == 0);
367 fail_on_test(msg.rx_ts == ~0ULL);
368 fail_on_test(msg.flags);
369 fail_on_test(msg.rx_status == 0);
370 fail_on_test(msg.rx_status & ~0x07);
371 fail_on_test(msg.tx_ts == 0);
372 fail_on_test(msg.tx_ts == ~0ULL);
373 fail_on_test(msg.rx_ts <= msg.tx_ts);
374 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
375 fail_on_test(msg.tx_nack_cnt == 0xff);
376 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
377 fail_on_test(msg.tx_low_drive_cnt == 0xff);
378 fail_on_test(msg.tx_error_cnt == 0xff);
379
380 memset(&msg, 0xff, sizeof(msg));
381 msg.msg[0] = (la << 4) | i;
382 msg.timeout = 0;
383 msg.flags &= ~msg_fl_mask;
384 cec_msg_give_physical_addr(&msg, false);
385 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
386 fail_on_test(msg.timeout);
387 fail_on_test(msg.sequence == 0 || msg.sequence == ~0U);
388 fail_on_test(msg.reply);
389 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
390 fail_on_test(msg.rx_status);
391 fail_on_test(msg.rx_ts);
392 fail_on_test(msg.flags);
393 fail_on_test(msg.tx_ts == 0);
394 fail_on_test(msg.tx_ts == ~0ULL);
395 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_OK));
396 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
397 fail_on_test(msg.tx_nack_cnt == 0xff);
398 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
399 fail_on_test(msg.tx_low_drive_cnt == 0xff);
400 fail_on_test(msg.tx_error_cnt == 0xff);
401 } else {
402 if (tested_invalid_la)
403 continue;
404 tested_invalid_la = true;
405 invalid_la = i;
406 // Send message to a remote non-existent LA
407 memset(&msg, 0xff, sizeof(msg));
408 msg.msg[0] = (la << 4) | i;
409 msg.timeout = 1002;
410 msg.flags &= ~msg_fl_mask;
411 cec_msg_give_physical_addr(&msg, true);
412 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
413 fail_on_test(msg.timeout != 1002);
414 fail_on_test(msg.sequence == 0);
415 fail_on_test(msg.sequence == ~0U);
416 fail_on_test(msg.len != 2);
417 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
418 fail_on_test(msg.flags);
419 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
420 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_MAX_RETRIES));
421 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
422 fail_on_test(msg.rx_status);
423 fail_on_test(msg.rx_ts);
424 fail_on_test(msg.tx_ts == 0);
425 fail_on_test(msg.tx_ts == ~0ULL);
426 fail_on_test(msg.tx_nack_cnt == 0xff);
427 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
428 fail_on_test(msg.tx_low_drive_cnt == 0xff);
429 fail_on_test(msg.tx_error_cnt == 0xff);
430
431 memset(&msg, 0xff, sizeof(msg));
432 msg.msg[0] = (la << 4) | i;
433 msg.timeout = 0;
434 msg.flags &= ~msg_fl_mask;
435 cec_msg_give_physical_addr(&msg, false);
436 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
437 fail_on_test(msg.timeout);
438 fail_on_test(msg.sequence == 0);
439 fail_on_test(msg.sequence == ~0U);
440 fail_on_test(msg.reply);
441 fail_on_test(msg.len != 2);
442 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
443 fail_on_test(msg.rx_status);
444 fail_on_test(msg.rx_ts);
445 fail_on_test(msg.flags);
446 fail_on_test(msg.tx_ts == 0);
447 fail_on_test(msg.tx_ts == ~0ULL);
448 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_MAX_RETRIES));
449 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
450 fail_on_test(msg.tx_nack_cnt == 0xff);
451 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
452 fail_on_test(msg.tx_low_drive_cnt == 0xff);
453 fail_on_test(msg.tx_error_cnt == 0xff);
454 }
455 }
456
457 if (tested_valid_la) {
458 time_t cur_t = time(NULL), t;
459 time_t last_t = cur_t + 7;
460 unsigned max_cnt = 0;
461 unsigned cnt = 0;
462
463 do {
464 t = time(NULL);
465 if (t != cur_t) {
466 if (cnt > max_cnt)
467 max_cnt = cnt;
468 cnt = 0;
469 cur_t = t;
470 }
471 cec_msg_init(&msg, la, valid_la);
472 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
473 cnt++;
474 } while (t < last_t);
475 // A ping can take 10 * 2.4 + 4.5 + 7 * 2.4 = 45.3 ms (SFT)
476 if (max_cnt < 21)
477 warn("Could only do %u pings per second to a valid LA, expected at least 21\n",
478 max_cnt);
479 }
480
481 if (tested_invalid_la) {
482 time_t cur_t = time(NULL), t;
483 time_t last_t = cur_t + 7;
484 unsigned max_cnt = 0;
485 unsigned cnt = 0;
486
487 do {
488 t = time(NULL);
489 if (t != cur_t) {
490 if (cnt > max_cnt)
491 max_cnt = cnt;
492 cnt = 0;
493 cur_t = t;
494 }
495 cec_msg_init(&msg, la, invalid_la);
496 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
497 cnt++;
498 } while (t < last_t);
499 // A ping to an invalid LA can take 2 * (10 * 2.4 + 4.5) + (3 + 7) * 2.4 = 81 ms (SFT)
500 if (max_cnt < 12)
501 warn("Could only do %u pings per second to an invalid LA, expected at least 12\n",
502 max_cnt);
503 }
504
505 return 0;
506 }
507
testReceive(struct node * node)508 static int testReceive(struct node *node)
509 {
510 unsigned la = node->log_addr[0], remote_la = 0;
511 struct cec_msg msg;
512
513 if (!(node->caps & CEC_CAP_TRANSMIT)) {
514 fail_on_test(doioctl(node, CEC_RECEIVE, &msg) != ENOTTY);
515 return OK_NOT_SUPPORTED;
516 }
517
518 for (unsigned i = 0; i < 15; i++) {
519 if (node->remote_la_mask & (1 << i))
520 break;
521 remote_la++;
522 }
523
524 fail_on_test(flush_pending_msgs(node));
525
526 if (remote_la == 15)
527 return OK_PRESUMED;
528
529 cec_msg_init(&msg, la, remote_la);
530 cec_msg_give_physical_addr(&msg, false);
531 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
532
533 msg.timeout = 1500;
534 fail_on_test(doioctl(node, CEC_RECEIVE, &msg) != ETIMEDOUT);
535 fail_on_test(msg.timeout != 1500);
536
537 uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
538
539 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
540
541 cec_msg_init(&msg, la, remote_la);
542 cec_msg_give_physical_addr(&msg, false);
543 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
544
545 memset(&msg, 0xff, sizeof(msg));
546 msg.timeout = 1500;
547 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
548
549 fail_on_test(msg.tx_ts);
550 fail_on_test(msg.tx_status);
551 fail_on_test(msg.tx_arb_lost_cnt);
552 fail_on_test(msg.tx_nack_cnt);
553 fail_on_test(msg.tx_low_drive_cnt);
554 fail_on_test(msg.tx_error_cnt);
555 fail_on_test(msg.timeout != 1500);
556 fail_on_test(msg.len != 5);
557 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
558 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
559 fail_on_test(msg.msg[0] != ((remote_la << 4) | 0xf));
560 fail_on_test(msg.sequence);
561 fail_on_test(msg.rx_ts == 0);
562 fail_on_test(msg.flags);
563 fail_on_test(msg.reply);
564 fail_on_test(msg.rx_status != CEC_RX_STATUS_OK);
565
566 return 0;
567 }
568
testNonBlocking(struct node * node)569 static int testNonBlocking(struct node *node)
570 {
571 unsigned la = node->log_addr[0], remote_la = 0, invalid_remote = 0xf;
572 struct cec_msg msg;
573
574 if (!(node->caps & CEC_CAP_TRANSMIT))
575 return OK_NOT_SUPPORTED;
576
577 for (unsigned i = 0; i < 15; i++) {
578 if (node->remote_la_mask & (1 << i))
579 break;
580 if (invalid_remote == 0xf && !(node->adap_la_mask & (1 << i)))
581 invalid_remote = i;
582 remote_la++;
583 }
584
585 fail_on_test(flush_pending_msgs(node));
586
587 fcntl(node->fd, F_SETFL, fcntl(node->fd, F_GETFL) | O_NONBLOCK);
588
589 fail_on_test(doioctl(node, CEC_RECEIVE, &msg) != EAGAIN);
590
591 cec_msg_init(&msg, la, la);
592 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
593 fail_on_test(msg.tx_status != (CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES));
594
595 if (invalid_remote < 15) {
596 uint32_t seq;
597
598 // Send non-blocking non-reply message to invalid remote LA
599 memset(&msg, 0xff, sizeof(msg));
600 msg.msg[0] = (la << 4) | invalid_remote;
601 msg.timeout = 0;
602 msg.flags &= ~msg_fl_mask;
603 cec_msg_give_physical_addr(&msg, false);
604 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
605 fail_on_test(msg.len != 2);
606 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
607 fail_on_test(msg.msg[0] != ((la << 4) | invalid_remote));
608 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
609 fail_on_test(msg.timeout);
610 fail_on_test(msg.flags);
611 fail_on_test(msg.sequence == 0);
612 fail_on_test(msg.sequence == ~0U);
613 fail_on_test(msg.reply);
614 fail_on_test(msg.tx_status);
615 fail_on_test(msg.rx_ts);
616 fail_on_test(msg.rx_status);
617 fail_on_test(msg.tx_ts);
618 fail_on_test(msg.tx_nack_cnt);
619 fail_on_test(msg.tx_arb_lost_cnt);
620 fail_on_test(msg.tx_low_drive_cnt);
621 fail_on_test(msg.tx_error_cnt);
622 seq = msg.sequence;
623
624 sleep(1);
625 while (true) {
626 memset(&msg, 0xff, sizeof(msg));
627 msg.timeout = 1500;
628 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
629 if (msg.sequence == 0)
630 continue;
631 fail_on_test(msg.sequence != seq);
632 fail_on_test(msg.len != 2);
633 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
634 fail_on_test(msg.msg[0] != ((la << 4) | invalid_remote));
635 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
636 fail_on_test(msg.timeout != 1500);
637 fail_on_test(msg.flags);
638 fail_on_test(msg.reply);
639 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_MAX_RETRIES));
640 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
641 fail_on_test(msg.tx_nack_cnt == 0xff);
642 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
643 fail_on_test(msg.tx_low_drive_cnt == 0xff);
644 fail_on_test(msg.tx_error_cnt == 0xff);
645 fail_on_test(msg.rx_ts);
646 fail_on_test(msg.rx_status);
647 break;
648 }
649
650 // Send non-blocking reply message to invalid remote LA
651 memset(&msg, 0xff, sizeof(msg));
652 msg.msg[0] = (la << 4) | invalid_remote;
653 msg.timeout = 0;
654 msg.flags &= ~msg_fl_mask;
655 cec_msg_give_physical_addr(&msg, true);
656 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
657 fail_on_test(msg.len != 2);
658 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
659 fail_on_test(msg.msg[0] != ((la << 4) | invalid_remote));
660 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
661 fail_on_test(msg.timeout != 1000);
662 fail_on_test(msg.flags);
663 fail_on_test(msg.sequence == 0);
664 fail_on_test(msg.sequence == ~0U);
665 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
666 fail_on_test(msg.tx_status);
667 fail_on_test(msg.rx_ts);
668 fail_on_test(msg.rx_status);
669 fail_on_test(msg.tx_ts);
670 fail_on_test(msg.tx_nack_cnt);
671 fail_on_test(msg.tx_arb_lost_cnt);
672 fail_on_test(msg.tx_low_drive_cnt);
673 fail_on_test(msg.tx_error_cnt);
674 seq = msg.sequence;
675
676 sleep(1);
677 while (true) {
678 memset(&msg, 0xff, sizeof(msg));
679 msg.timeout = 1500;
680 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
681 if (msg.sequence == 0)
682 continue;
683 fail_on_test(msg.sequence != seq);
684 fail_on_test(msg.len != 2);
685 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
686 fail_on_test(msg.msg[0] != ((la << 4) | invalid_remote));
687 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
688 fail_on_test(msg.timeout != 1500);
689 fail_on_test(msg.flags);
690 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
691 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_MAX_RETRIES));
692 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
693 fail_on_test(msg.tx_nack_cnt == 0xff);
694 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
695 fail_on_test(msg.tx_low_drive_cnt == 0xff);
696 fail_on_test(msg.tx_error_cnt == 0xff);
697 fail_on_test(msg.rx_ts);
698 fail_on_test(msg.rx_status);
699 break;
700 }
701
702 uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
703
704 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
705 }
706 if (remote_la < 15) {
707 uint32_t seq;
708
709 // Send non-blocking non-reply message to valid remote LA
710 memset(&msg, 0xff, sizeof(msg));
711 msg.msg[0] = (la << 4) | remote_la;
712 msg.timeout = 0;
713 msg.flags &= ~msg_fl_mask;
714 cec_msg_give_physical_addr(&msg, false);
715 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
716 fail_on_test(msg.len != 2);
717 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
718 fail_on_test(msg.msg[0] != ((la << 4) | remote_la));
719 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
720 fail_on_test(msg.timeout);
721 fail_on_test(msg.flags);
722 fail_on_test(msg.sequence == 0);
723 fail_on_test(msg.sequence == ~0U);
724 fail_on_test(msg.reply);
725 fail_on_test(msg.tx_status);
726 fail_on_test(msg.rx_ts);
727 fail_on_test(msg.rx_status);
728 fail_on_test(msg.tx_ts);
729 fail_on_test(msg.tx_nack_cnt);
730 fail_on_test(msg.tx_arb_lost_cnt);
731 fail_on_test(msg.tx_low_drive_cnt);
732 fail_on_test(msg.tx_error_cnt);
733 seq = msg.sequence;
734
735 sleep(1);
736 while (true) {
737 memset(&msg, 0xff, sizeof(msg));
738 msg.timeout = 1500;
739 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
740 if (msg.sequence == 0)
741 continue;
742 fail_on_test(msg.sequence != seq);
743 fail_on_test(msg.len != 2);
744 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
745 fail_on_test(msg.msg[0] != ((la << 4) | remote_la));
746 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
747 fail_on_test(msg.timeout != 1500);
748 fail_on_test(msg.flags);
749 fail_on_test(msg.reply);
750 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_OK));
751 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
752 fail_on_test(msg.tx_nack_cnt == 0xff);
753 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
754 fail_on_test(msg.tx_low_drive_cnt == 0xff);
755 fail_on_test(msg.tx_error_cnt == 0xff);
756 fail_on_test(msg.rx_ts || msg.rx_status);
757 break;
758 }
759
760 // Send non-blocking reply message to valid remote LA
761 memset(&msg, 0xff, sizeof(msg));
762 msg.msg[0] = (la << 4) | remote_la;
763 msg.timeout = 0;
764 msg.flags &= ~msg_fl_mask;
765 cec_msg_give_physical_addr(&msg, true);
766 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
767 fail_on_test(msg.len != 2);
768 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
769 fail_on_test(msg.msg[0] != ((la << 4) | remote_la));
770 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
771 fail_on_test(msg.timeout != 1000);
772 fail_on_test(msg.flags);
773 fail_on_test(msg.sequence == 0);
774 fail_on_test(msg.sequence == ~0U);
775 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
776 fail_on_test(msg.tx_status);
777 fail_on_test(msg.rx_ts);
778 fail_on_test(msg.rx_status);
779 fail_on_test(msg.tx_ts);
780 fail_on_test(msg.tx_nack_cnt);
781 fail_on_test(msg.tx_arb_lost_cnt);
782 fail_on_test(msg.tx_low_drive_cnt);
783 fail_on_test(msg.tx_error_cnt);
784 seq = msg.sequence;
785
786 sleep(1);
787 while (true) {
788 memset(&msg, 0xff, sizeof(msg));
789 msg.timeout = 1500;
790 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
791 if (msg.sequence == 0)
792 continue;
793 fail_on_test(msg.sequence != seq);
794 fail_on_test(msg.len != 5);
795 fail_on_test(check_0(msg.msg + msg.len, sizeof(msg.msg) - msg.len));
796 fail_on_test(msg.msg[0] != ((remote_la << 4) | 0xf));
797 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
798 fail_on_test(msg.timeout != 1500);
799 fail_on_test(msg.flags);
800 fail_on_test(msg.reply != CEC_MSG_REPORT_PHYSICAL_ADDR);
801 fail_on_test(!(msg.tx_status & CEC_TX_STATUS_OK));
802 fail_on_test((msg.tx_status & tx_ok_retry_mask) == tx_ok_retry_mask);
803 fail_on_test(msg.tx_nack_cnt == 0xff);
804 fail_on_test(msg.tx_arb_lost_cnt == 0xff);
805 fail_on_test(msg.tx_low_drive_cnt == 0xff);
806 fail_on_test(msg.tx_error_cnt == 0xff);
807 fail_on_test(msg.rx_ts == 0);
808 fail_on_test(msg.rx_ts == ~0ULL);
809 fail_on_test(msg.rx_status != CEC_RX_STATUS_OK);
810 fail_on_test(msg.rx_ts < msg.tx_ts);
811 break;
812 }
813
814 uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
815
816 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
817 }
818 if (remote_la == 15 || invalid_remote == 15)
819 return OK_PRESUMED;
820 return 0;
821 }
822
testModes(struct node * node,struct node * node2)823 static int testModes(struct node *node, struct node *node2)
824 {
825 struct cec_msg msg;
826 uint8_t me = node->log_addr[0];
827 uint8_t remote = CEC_LOG_ADDR_INVALID;
828 uint32_t mode = 0, m;
829
830 for (unsigned i = 0; i < 15; i++) {
831 if (node->remote_la_mask & (1 << i)) {
832 remote = i;
833 break;
834 }
835 }
836
837 cec_msg_init(&msg, me, 0);
838 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
839 fail_on_test(doioctl(node2, CEC_TRANSMIT, &msg));
840
841 fail_on_test(doioctl(node, CEC_G_MODE, &m));
842 fail_on_test(m != CEC_MODE_INITIATOR);
843 fail_on_test(doioctl(node2, CEC_G_MODE, &m));
844 fail_on_test(m != CEC_MODE_INITIATOR);
845
846 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
847 fail_on_test(doioctl(node, CEC_G_MODE, &m));
848 fail_on_test(m != mode);
849 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg) != EBUSY);
850 fail_on_test(doioctl(node2, CEC_TRANSMIT, &msg));
851
852 mode = CEC_MODE_INITIATOR;
853 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
854 fail_on_test(doioctl(node, CEC_G_MODE, &m));
855 fail_on_test(m != mode);
856 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
857
858 mode = CEC_MODE_EXCL_INITIATOR;
859 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
860 fail_on_test(doioctl(node, CEC_G_MODE, &m));
861 fail_on_test(m != mode);
862 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
863 fail_on_test(doioctl(node2, CEC_TRANSMIT, &msg) != EBUSY);
864
865 mode = CEC_MODE_INITIATOR;
866 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
867 fail_on_test(doioctl(node, CEC_G_MODE, &m));
868 fail_on_test(m != mode);
869
870 if (remote == CEC_LOG_ADDR_INVALID)
871 return 0;
872
873 fail_on_test(flush_pending_msgs(node));
874 cec_msg_init(&msg, me, remote);
875 cec_msg_give_physical_addr(&msg, false);
876 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
877 msg.timeout = 1200;
878 fail_on_test(doioctl(node, CEC_RECEIVE, &msg) != ETIMEDOUT);
879
880 mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
881 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
882 fail_on_test(doioctl(node, CEC_G_MODE, &m));
883 fail_on_test(m != mode);
884
885 fail_on_test(flush_pending_msgs(node));
886 cec_msg_init(&msg, me, remote);
887 cec_msg_give_physical_addr(&msg, false);
888 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
889 msg.timeout = 1200;
890 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
891 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
892
893 mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
894 fail_on_test(doioctl(node2, CEC_S_MODE, &mode));
895 fail_on_test(doioctl(node2, CEC_G_MODE, &m));
896 fail_on_test(m != mode);
897
898 fail_on_test(flush_pending_msgs(node));
899 fail_on_test(flush_pending_msgs(node2));
900 cec_msg_init(&msg, me, remote);
901 cec_msg_give_physical_addr(&msg, false);
902 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
903 msg.timeout = 1200;
904 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
905 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
906 msg.timeout = 1;
907 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg));
908 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
909
910 mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER;
911 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
912 fail_on_test(doioctl(node, CEC_G_MODE, &m));
913 fail_on_test(m != mode);
914
915 fail_on_test(flush_pending_msgs(node));
916 fail_on_test(flush_pending_msgs(node2));
917 cec_msg_init(&msg, me, remote);
918 cec_msg_give_physical_addr(&msg, false);
919 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
920 msg.timeout = 1200;
921 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
922 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
923 msg.timeout = 1;
924 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg) != ETIMEDOUT);
925
926 mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
927 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
928 fail_on_test(doioctl(node, CEC_G_MODE, &m));
929 fail_on_test(m != mode);
930
931 // Note: this test is the same as for CEC_MODE_EXCL_FOLLOWER.
932 // Ideally the remote device would send us a passthrough message,
933 // but there is no way to trigger that.
934 fail_on_test(flush_pending_msgs(node));
935 fail_on_test(flush_pending_msgs(node2));
936 cec_msg_init(&msg, me, remote);
937 cec_msg_give_physical_addr(&msg, false);
938 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
939 msg.timeout = 1200;
940 fail_on_test(doioctl(node, CEC_RECEIVE, &msg));
941 fail_on_test(msg.msg[1] != CEC_MSG_REPORT_PHYSICAL_ADDR);
942 msg.timeout = 1;
943 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg) != ETIMEDOUT);
944
945 mode = CEC_MODE_INITIATOR;
946 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
947 fail_on_test(doioctl(node, CEC_G_MODE, &m));
948 fail_on_test(m != mode);
949
950 mode = CEC_MODE_INITIATOR | CEC_MODE_MONITOR;
951 fail_on_test(doioctl(node2, CEC_S_MODE, &mode) != EINVAL);
952 fail_on_test(doioctl(node2, CEC_G_MODE, &m));
953 fail_on_test(m != (CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER));
954
955 bool is_root = getuid() == 0;
956
957 mode = CEC_MODE_MONITOR;
958 fail_on_test(doioctl(node2, CEC_S_MODE, &mode) != (is_root ? 0 : EPERM));
959
960 if (is_root) {
961 fail_on_test(doioctl(node2, CEC_G_MODE, &m));
962 fail_on_test(m != mode);
963 fail_on_test(flush_pending_msgs(node2));
964 cec_msg_init(&msg, me, remote);
965 cec_msg_give_physical_addr(&msg, false);
966 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
967 msg.timeout = 1200;
968 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg));
969 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
970 while (true) {
971 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg));
972 if (msg.msg[1] == CEC_MSG_REPORT_PHYSICAL_ADDR)
973 break;
974 fail_on_test(!cec_msg_is_broadcast(&msg) &&
975 !(node2->adap_la_mask & (1 << cec_msg_destination(&msg))));
976 }
977 }
978
979 mode = CEC_MODE_MONITOR_ALL;
980 int res = doioctl(node2, CEC_S_MODE, &mode);
981 if (node2->caps & CEC_CAP_MONITOR_ALL)
982 fail_on_test(res != (is_root ? 0 : EPERM));
983 else
984 fail_on_test(res != EINVAL);
985
986 if (is_root && (node2->caps & CEC_CAP_MONITOR_ALL)) {
987 fail_on_test(doioctl(node2, CEC_G_MODE, &m));
988 fail_on_test(m != mode);
989 fail_on_test(flush_pending_msgs(node2));
990 cec_msg_init(&msg, me, remote);
991 cec_msg_give_physical_addr(&msg, false);
992 fail_on_test(doioctl(node, CEC_TRANSMIT, &msg));
993 msg.timeout = 1200;
994 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg));
995 fail_on_test(msg.msg[1] != CEC_MSG_GIVE_PHYSICAL_ADDR);
996 while (true) {
997 fail_on_test(doioctl(node2, CEC_RECEIVE, &msg));
998 if (msg.msg[1] == CEC_MSG_REPORT_PHYSICAL_ADDR)
999 break;
1000 }
1001 }
1002 return 0;
1003 }
1004
print_sfts(unsigned sft[12],const char * descr)1005 static void print_sfts(unsigned sft[12], const char *descr)
1006 {
1007 std::string s;
1008 char num[20];
1009
1010 for (unsigned i = 0; i < 12; i++) {
1011 if (sft[i] == 0)
1012 continue;
1013 if (!s.empty())
1014 s += ", ";
1015 sprintf(num, "%u: %d", i, sft[i]);
1016 s += num;
1017 }
1018 if (!s.empty())
1019 printf("\t\t%s: %s\n", descr, s.c_str());
1020 }
1021
testLostMsgs(struct node * node)1022 static int testLostMsgs(struct node *node)
1023 {
1024 struct cec_msg msg;
1025 struct cec_event ev;
1026 uint8_t me = node->log_addr[0];
1027 uint8_t remote = CEC_LOG_ADDR_INVALID;
1028 uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_FOLLOWER;
1029 #define MAX_SFT 11
1030 unsigned sft[2][2][MAX_SFT + 1];
1031
1032 memset(sft, 0, sizeof(sft));
1033
1034 for (unsigned i = 0; i < 15; i++) {
1035 if (node->remote_la_mask & (1 << i)) {
1036 remote = i;
1037 break;
1038 }
1039 }
1040
1041 fail_on_test(flush_pending_msgs(node));
1042 fcntl(node->fd, F_SETFL, fcntl(node->fd, F_GETFL) | O_NONBLOCK);
1043
1044 // Become follower for this test, otherwise all the replies to
1045 // the GET_CEC_VERSION message would have been 'Feature Abort'ed,
1046 // unless some other follower was running. By becoming a follower
1047 // all the CEC_VERSION replies are just ignored.
1048 fail_on_test(doioctl(node, CEC_S_MODE, &mode));
1049 cec_msg_init(&msg, me, remote);
1050 cec_msg_get_cec_version(&msg, false);
1051
1052 // flush pending events
1053 while (doioctl(node, CEC_DQEVENT, &ev) == 0) { }
1054
1055 bool got_busy = false;
1056 unsigned xfer_cnt = 0;
1057 unsigned tx_queue_depth = 0;
1058
1059 do {
1060 int res;
1061
1062 do {
1063 res = doioctl(node, CEC_TRANSMIT, &msg);
1064
1065 fail_on_test(res && res != EBUSY);
1066 if (!res)
1067 xfer_cnt++;
1068
1069 if (res == EBUSY) {
1070 struct timeval tv = { 0, 10000 }; // 10 ms
1071
1072 select(0, NULL, NULL, NULL, &tv);
1073 got_busy = true;
1074 } else if (!got_busy) {
1075 tx_queue_depth++;
1076 }
1077 } while (res == EBUSY);
1078 } while (doioctl(node, CEC_DQEVENT, &ev));
1079 fail_on_test(ev.event != CEC_EVENT_LOST_MSGS);
1080 fail_on_test(!got_busy);
1081
1082 /*
1083 * No more than max 18 transmits can be queued, but one message
1084 * might finish transmitting before the queue fills up, so
1085 * check for 19 instead.
1086 */
1087 fail_on_test(tx_queue_depth == 0 || tx_queue_depth > 19);
1088
1089 if (show_info)
1090 printf("\n\t\tFinished transmitting\n\n");
1091
1092 unsigned pending_msgs = 0;
1093 unsigned pending_quick_msgs = 0;
1094 unsigned pending_tx_ok_msgs = 0;
1095 unsigned pending_tx_timed_out_msgs = 0;
1096 unsigned pending_tx_arb_lost_msgs = 0;
1097 unsigned pending_tx_nack_msgs = 0;
1098 unsigned pending_tx_low_drive_msgs = 0;
1099 unsigned pending_tx_error_msgs = 0;
1100 unsigned pending_tx_aborted_msgs = 0;
1101 unsigned pending_tx_rx_no_reply_msgs = 0;
1102 unsigned pending_tx_rx_ok_msgs = 0;
1103 unsigned pending_tx_rx_timed_out_msgs = 0;
1104 unsigned pending_tx_rx_feat_abort_msgs = 0;
1105 unsigned pending_tx_rx_aborted_msgs = 0;
1106 unsigned pending_rx_msgs = 0;
1107 unsigned pending_rx_cec_version_msgs = 0;
1108 time_t start = time(NULL);
1109 uint8_t last_init = 0xff;
1110 uint64_t last_ts = 0;
1111 unsigned tx_repeats = 0;
1112
1113 for (unsigned i = 0; i < 2; i++) {
1114 msg.timeout = 3000;
1115
1116 while (!doioctl(node, CEC_RECEIVE, &msg)) {
1117 uint64_t ts = msg.tx_ts ? : msg.rx_ts;
1118 uint8_t initiator = cec_msg_initiator(&msg);
1119 uint64_t delta = last_ts ? ts - last_ts : 0;
1120
1121 delta -= msg.len * 24000000ULL + 4500000ULL;
1122 unsigned sft_real = (delta + 1200000ULL) / 2400000ULL;
1123
1124 if (last_ts && sft_real <= MAX_SFT)
1125 sft[last_init == me][initiator == me][sft_real]++;
1126
1127 if (!i && last_ts) {
1128 if (last_init == initiator && initiator == me) {
1129 tx_repeats++;
1130 } else {
1131 if (tx_repeats > 2)
1132 warn("Too many transmits (%d) without receives\n",
1133 tx_repeats);
1134 tx_repeats = 0;
1135 }
1136 }
1137 last_ts = ts;
1138 last_init = initiator;
1139
1140 pending_msgs++;
1141 if (i == 0)
1142 pending_quick_msgs++;
1143 if (!msg.sequence) {
1144 pending_rx_msgs++;
1145 if (msg.len == 3 && msg.msg[1] == CEC_MSG_CEC_VERSION)
1146 pending_rx_cec_version_msgs++;
1147 }
1148 else if (msg.tx_status & CEC_TX_STATUS_TIMEOUT)
1149 pending_tx_timed_out_msgs++;
1150 else if (msg.tx_status & CEC_TX_STATUS_ABORTED)
1151 pending_tx_aborted_msgs++;
1152 else if (msg.tx_status & CEC_TX_STATUS_OK) {
1153 pending_tx_ok_msgs++;
1154 if (msg.rx_status & CEC_RX_STATUS_OK)
1155 pending_tx_rx_ok_msgs++;
1156 else if (msg.rx_status & CEC_RX_STATUS_FEATURE_ABORT)
1157 pending_tx_rx_feat_abort_msgs++;
1158 else if (msg.rx_status & CEC_RX_STATUS_TIMEOUT)
1159 pending_tx_rx_timed_out_msgs++;
1160 else if (msg.rx_status & CEC_RX_STATUS_ABORTED)
1161 pending_tx_rx_aborted_msgs++;
1162 else
1163 pending_tx_rx_no_reply_msgs++;
1164 } else if (msg.tx_status & CEC_TX_STATUS_NACK)
1165 pending_tx_nack_msgs++;
1166 else if (msg.tx_status & CEC_TX_STATUS_ARB_LOST)
1167 pending_tx_arb_lost_msgs++;
1168 else if (msg.tx_status & CEC_TX_STATUS_LOW_DRIVE)
1169 pending_tx_low_drive_msgs++;
1170 else
1171 pending_tx_error_msgs++;
1172 }
1173 fcntl(node->fd, F_SETFL, fcntl(node->fd, F_GETFL) & ~O_NONBLOCK);
1174 if (!i && show_info)
1175 printf("\n\t\tDrained receive queue\n\n");
1176 }
1177
1178 /*
1179 * Should be at least the size of the internal message queue and
1180 * close to the number of transmitted messages. There should also be
1181 * no timed out or aborted transmits.
1182 */
1183
1184 bool fail_msg = pending_tx_error_msgs || pending_tx_timed_out_msgs || pending_tx_aborted_msgs ||
1185 pending_tx_rx_aborted_msgs || pending_quick_msgs < 18 * 3 ||
1186 pending_rx_cec_version_msgs > xfer_cnt;
1187 bool warn_msg = pending_rx_cec_version_msgs < xfer_cnt - 2;
1188
1189 if (fail_msg || warn_msg || show_info) {
1190 if (show_info)
1191 printf("\n");
1192 if (pending_tx_ok_msgs) {
1193 printf("\t\tSuccessful transmits: %d\n", pending_tx_ok_msgs);
1194 printf("\t\t\tReply OK: %d No replies: %d Feature Aborted: %d Timed out: %d Aborted: %d\n",
1195 pending_tx_rx_ok_msgs,
1196 pending_tx_rx_no_reply_msgs, pending_tx_rx_feat_abort_msgs,
1197 pending_tx_rx_timed_out_msgs, pending_tx_rx_aborted_msgs);
1198 }
1199 if (pending_tx_nack_msgs)
1200 printf("\t\tNACKed transmits: %d\n", pending_tx_nack_msgs);
1201 if (pending_tx_timed_out_msgs)
1202 printf("\t\tTimed out transmits: %d\n", pending_tx_timed_out_msgs);
1203 if (pending_tx_aborted_msgs)
1204 printf("\t\tAborted transmits: %d\n", pending_tx_aborted_msgs);
1205 if (pending_tx_arb_lost_msgs)
1206 printf("\t\tArbitration Lost transmits: %d\n", pending_tx_arb_lost_msgs);
1207 if (pending_tx_low_drive_msgs)
1208 printf("\t\tLow Drive transmits: %d\n", pending_tx_low_drive_msgs);
1209 if (pending_tx_error_msgs)
1210 printf("\t\tError transmits: %d\n", pending_tx_error_msgs);
1211 if (pending_rx_msgs)
1212 printf("\t\tReceived messages: %d of which %d were CEC_MSG_CEC_VERSION\n",
1213 pending_rx_msgs, pending_rx_cec_version_msgs);
1214 print_sfts(sft[1][1], "SFTs for repeating messages (>= 7)");
1215 print_sfts(sft[0][1], "SFTs for newly transmitted messages (>= 5)");
1216 print_sfts(sft[0][0], "SFTs for repeating remote messages (>= 7)");
1217 print_sfts(sft[1][0], "SFTs for newly transmitted remote messages (>= 5)");
1218 if (pending_quick_msgs < pending_msgs)
1219 printf("\t\tReceived %d messages immediately, and %d over %ld seconds\n",
1220 pending_quick_msgs, pending_msgs - pending_quick_msgs,
1221 time(NULL) - start);
1222 }
1223 if (fail_msg)
1224 return fail("There were %d messages in the receive queue for %d transmits\n",
1225 pending_msgs, xfer_cnt);
1226 if (warn_msg)
1227 warn("There were %d CEC_GET_VERSION transmits but only %d CEC_VERSION receives\n",
1228 xfer_cnt, pending_rx_cec_version_msgs);
1229 return 0;
1230 }
1231
testAdapter(struct node & node,struct cec_log_addrs & laddrs,const char * device)1232 void testAdapter(struct node &node, struct cec_log_addrs &laddrs,
1233 const char *device)
1234 {
1235 /* Required ioctls */
1236
1237 printf("\nCEC API:\n");
1238 printf("\tCEC_ADAP_G_CAPS: %s\n", ok(testCap(&node)));
1239 printf("\tInvalid ioctls: %s\n", ok(testInvalidIoctls(&node)));
1240 printf("\tCEC_DQEVENT: %s\n", ok(testDQEvent(&node)));
1241 printf("\tCEC_ADAP_G/S_PHYS_ADDR: %s\n", ok(testAdapPhysAddr(&node)));
1242 if (node.caps & CEC_CAP_PHYS_ADDR)
1243 doioctl(&node, CEC_ADAP_S_PHYS_ADDR, &node.phys_addr);
1244 if (node.phys_addr == CEC_PHYS_ADDR_INVALID) {
1245 fprintf(stderr, "FAIL: without a valid physical address this test cannot proceed.\n");
1246 fprintf(stderr, "Make sure that this CEC adapter is connected to another HDMI sink or source.\n");
1247 std::exit(EXIT_FAILURE);
1248 }
1249 printf("\tCEC_ADAP_G/S_LOG_ADDRS: %s\n", ok(testAdapLogAddrs(&node)));
1250 fcntl(node.fd, F_SETFL, fcntl(node.fd, F_GETFL) & ~O_NONBLOCK);
1251 sleep(1);
1252 if (node.caps & CEC_CAP_LOG_ADDRS) {
1253 struct cec_log_addrs clear = { };
1254
1255 doioctl(&node, CEC_ADAP_S_LOG_ADDRS, &clear);
1256 doioctl(&node, CEC_ADAP_S_LOG_ADDRS, &laddrs);
1257 }
1258 doioctl(&node, CEC_ADAP_G_LOG_ADDRS, &laddrs);
1259 if (laddrs.log_addr_mask != node.adap_la_mask)
1260 printf("\tNew Logical Address Mask : 0x%04x\n", laddrs.log_addr_mask);
1261 // The LAs may have changed after these tests, so update these node fields
1262 node.num_log_addrs = laddrs.num_log_addrs;
1263 memcpy(node.log_addr, laddrs.log_addr, laddrs.num_log_addrs);
1264 node.adap_la_mask = laddrs.log_addr_mask;
1265
1266 printf("\tCEC_TRANSMIT: %s\n", ok(testTransmit(&node)));
1267 printf("\tCEC_RECEIVE: %s\n", ok(testReceive(&node)));
1268 uint32_t mode = CEC_MODE_INITIATOR;
1269 doioctl(&node, CEC_S_MODE, &mode);
1270 printf("\tCEC_TRANSMIT/RECEIVE (non-blocking): %s\n", ok(testNonBlocking(&node)));
1271 fcntl(node.fd, F_SETFL, fcntl(node.fd, F_GETFL) & ~O_NONBLOCK);
1272 doioctl(&node, CEC_S_MODE, &mode);
1273
1274 struct node node2 = node;
1275
1276 if ((node2.fd = open(device, O_RDWR)) < 0) {
1277 fprintf(stderr, "Failed to open %s: %s\n", device,
1278 strerror(errno));
1279 std::exit(EXIT_FAILURE);
1280 }
1281
1282 printf("\tCEC_G/S_MODE: %s\n", ok(testModes(&node, &node2)));
1283 close(node2.fd);
1284 doioctl(&node, CEC_S_MODE, &mode);
1285
1286 printf("\tCEC_EVENT_LOST_MSGS: %s\n", ok(testLostMsgs(&node)));
1287 fcntl(node.fd, F_SETFL, fcntl(node.fd, F_GETFL) & ~O_NONBLOCK);
1288 doioctl(&node, CEC_S_MODE, &mode);
1289 }
1290