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