• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstring>
7 #include <map>
8 #include <sstream>
9 #include <vector>
10 
11 #include <sys/ioctl.h>
12 #include <unistd.h>
13 
14 #include "cec-compliance.h"
15 
16 enum Months { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
17 
18 /* Tuner Control */
19 
bcast_type2s(__u8 bcast_type)20 static const char *bcast_type2s(__u8 bcast_type)
21 {
22 	switch (bcast_type) {
23 	case CEC_OP_ANA_BCAST_TYPE_CABLE:
24 		return "Cable";
25 	case CEC_OP_ANA_BCAST_TYPE_SATELLITE:
26 		return "Satellite";
27 	case CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL:
28 		return "Terrestrial";
29 	default:
30 		return "Future use";
31 	}
32 }
33 
log_tuner_service(const struct cec_op_tuner_device_info & info,const char * prefix="")34 static int log_tuner_service(const struct cec_op_tuner_device_info &info,
35 			     const char *prefix = "")
36 {
37 	printf("\t\t%s", prefix);
38 
39 	if (info.is_analog) {
40 		double freq_mhz = (info.analog.ana_freq * 625) / 10000.0;
41 
42 		printf("Analog Channel %.2f MHz (%s, %s)\n", freq_mhz,
43 		       bcast_system2s(info.analog.bcast_system),
44 		       bcast_type2s(info.analog.ana_bcast_type));
45 
46 		switch (info.analog.bcast_system) {
47 		case CEC_OP_BCAST_SYSTEM_PAL_BG:
48 		case CEC_OP_BCAST_SYSTEM_SECAM_LQ:
49 		case CEC_OP_BCAST_SYSTEM_PAL_M:
50 		case CEC_OP_BCAST_SYSTEM_NTSC_M:
51 		case CEC_OP_BCAST_SYSTEM_PAL_I:
52 		case CEC_OP_BCAST_SYSTEM_SECAM_DK:
53 		case CEC_OP_BCAST_SYSTEM_SECAM_BG:
54 		case CEC_OP_BCAST_SYSTEM_SECAM_L:
55 		case CEC_OP_BCAST_SYSTEM_PAL_DK:
56 			break;
57 		default:
58 			return fail("invalid analog bcast_system %u", info.analog.bcast_system);
59 		}
60 		if (info.analog.ana_bcast_type > CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL)
61 			return fail("invalid analog bcast_type %u\n", info.analog.ana_bcast_type);
62 		fail_on_test(!info.analog.ana_freq);
63 		return 0;
64 	}
65 
66 	__u8 system = info.digital.dig_bcast_system;
67 
68 	printf("%s Channel ", dig_bcast_system2s(system));
69 	if (info.digital.service_id_method) {
70 		__u16 major = info.digital.channel.major;
71 		__u16 minor = info.digital.channel.minor;
72 
73 		switch (info.digital.channel.channel_number_fmt) {
74 		case CEC_OP_CHANNEL_NUMBER_FMT_2_PART:
75 			printf("%u.%u\n", major, minor);
76 			break;
77 		case CEC_OP_CHANNEL_NUMBER_FMT_1_PART:
78 			printf("%u\n", minor);
79 			break;
80 		default:
81 			printf("%u.%u\n", major, minor);
82 			return fail("invalid service ID method\n");
83 		}
84 		return 0;
85 	}
86 
87 
88 	switch (system) {
89 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN:
90 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS:
91 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS:
92 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T: {
93 		__u16 tsid = info.digital.arib.transport_id;
94 		__u16 sid = info.digital.arib.service_id;
95 		__u16 onid = info.digital.arib.orig_network_id;
96 
97 		printf("TSID: %u, SID: %u, ONID: %u\n", tsid, sid, onid);
98 		break;
99 	}
100 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
101 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
102 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
103 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T: {
104 		__u16 tsid = info.digital.atsc.transport_id;
105 		__u16 pn = info.digital.atsc.program_number;
106 
107 		printf("TSID: %u, Program Number: %u\n", tsid, pn);
108 		break;
109 	}
110 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN:
111 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S:
112 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2:
113 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C:
114 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T: {
115 		__u16 tsid = info.digital.dvb.transport_id;
116 		__u16 sid = info.digital.dvb.service_id;
117 		__u16 onid = info.digital.dvb.orig_network_id;
118 
119 		printf("TSID: %u, SID: %u, ONID: %u\n", tsid, sid, onid);
120 		break;
121 	}
122 	default:
123 		break;
124 	}
125 
126 	switch (system) {
127 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN:
128 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
129 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN:
130 		warn_once("generic digital broadcast systems should not be used");
131 		break;
132 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS:
133 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS:
134 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T:
135 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
136 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
137 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
138 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C:
139 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S:
140 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2:
141 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T:
142 		break;
143 	default:
144 		return fail("invalid digital broadcast system %u", system);
145 	}
146 
147 	if (info.digital.service_id_method > CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL)
148 		return fail("invalid service ID method %u\n", info.digital.service_id_method);
149 
150 	return 0;
151 }
152 
tuner_ctl_test(struct node * node,unsigned me,unsigned la,bool interactive)153 static int tuner_ctl_test(struct node *node, unsigned me, unsigned la, bool interactive)
154 {
155 	struct cec_msg msg;
156 	struct cec_op_tuner_device_info info = {};
157 	std::vector<struct cec_op_tuner_device_info> info_vec;
158 	bool has_tuner = (1 << la) & (CEC_LOG_ADDR_MASK_TV | CEC_LOG_ADDR_MASK_TUNER);
159 	int ret;
160 
161 	cec_msg_init(&msg, me, la);
162 	cec_msg_give_tuner_device_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
163 	fail_on_test(!transmit_timeout(node, &msg));
164 	fail_on_test(!has_tuner && !timed_out_or_abort(&msg));
165 	if (!has_tuner)
166 		return OK_NOT_SUPPORTED;
167 	if (timed_out(&msg) || unrecognized_op(&msg))
168 		return OK_NOT_SUPPORTED;
169 	if (cec_msg_status_is_abort(&msg))
170 		return OK_REFUSED;
171 
172 	printf("\t    Start Channel Scan\n");
173 	cec_ops_tuner_device_status(&msg, &info);
174 	info_vec.push_back(info);
175 	ret = log_tuner_service(info);
176 	if (ret)
177 		return ret;
178 
179 	while (true) {
180 		cec_msg_init(&msg, me, la);
181 		cec_msg_tuner_step_increment(&msg);
182 		fail_on_test(!transmit(node, &msg));
183 		fail_on_test(cec_msg_status_is_abort(&msg));
184 		if (cec_msg_status_is_abort(&msg)) {
185 			fail_on_test(abort_reason(&msg) == CEC_OP_ABORT_UNRECOGNIZED_OP);
186 			if (abort_reason(&msg) == CEC_OP_ABORT_REFUSED) {
187 				warn("Tuner step increment does not wrap.\n");
188 				break;
189 			}
190 
191 			warn("Tuner at end of service list did not receive feature abort refused.\n");
192 			break;
193 		}
194 		cec_msg_init(&msg, me, la);
195 		cec_msg_give_tuner_device_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
196 		fail_on_test(!transmit_timeout(node, &msg));
197 		fail_on_test(timed_out_or_abort(&msg));
198 		memset(&info, 0, sizeof(info));
199 		cec_ops_tuner_device_status(&msg, &info);
200 		if (!memcmp(&info, &info_vec[0], sizeof(info)))
201 			break;
202 		ret = log_tuner_service(info);
203 		if (ret)
204 			return ret;
205 		info_vec.push_back(info);
206 	}
207 	printf("\t    Finished Channel Scan\n");
208 
209 	printf("\t    Start Channel Test\n");
210 	for (const auto &iter : info_vec) {
211 		cec_msg_init(&msg, me, la);
212 		log_tuner_service(iter, "Select ");
213 		if (iter.is_analog)
214 			cec_msg_select_analogue_service(&msg, iter.analog.ana_bcast_type,
215 				iter.analog.ana_freq, iter.analog.bcast_system);
216 		else
217 			cec_msg_select_digital_service(&msg, &iter.digital);
218 		fail_on_test(!transmit(node, &msg));
219 		fail_on_test(cec_msg_status_is_abort(&msg));
220 		cec_msg_init(&msg, me, la);
221 		cec_msg_give_tuner_device_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
222 		fail_on_test(!transmit_timeout(node, &msg));
223 		fail_on_test(timed_out_or_abort(&msg));
224 		memset(&info, 0, sizeof(info));
225 		cec_ops_tuner_device_status(&msg, &info);
226 		if (memcmp(&info, &iter, sizeof(info))) {
227 			log_tuner_service(info);
228 			log_tuner_service(iter);
229 		}
230 		fail_on_test(memcmp(&info, &iter, sizeof(info)));
231 	}
232 	printf("\t    Finished Channel Test\n");
233 
234 	cec_msg_init(&msg, me, la);
235 	cec_msg_select_analogue_service(&msg, 3, 16000, 9);
236 	printf("\t\tSelect invalid analog channel\n");
237 	fail_on_test(!transmit_timeout(node, &msg));
238 	fail_on_test(!cec_msg_status_is_abort(&msg));
239 	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
240 	cec_msg_init(&msg, me, la);
241 	info.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID;
242 	info.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2;
243 	info.digital.dvb.transport_id = 0;
244 	info.digital.dvb.service_id = 0;
245 	info.digital.dvb.orig_network_id = 0;
246 	cec_msg_select_digital_service(&msg, &info.digital);
247 	printf("\t\tSelect invalid digital channel\n");
248 	fail_on_test(!transmit_timeout(node, &msg));
249 	fail_on_test(!cec_msg_status_is_abort(&msg));
250 	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
251 
252 	return 0;
253 }
254 
255 const vec_remote_subtests tuner_ctl_subtests{
256 	{ "Tuner Control", CEC_LOG_ADDR_MASK_TUNER | CEC_LOG_ADDR_MASK_TV, tuner_ctl_test },
257 };
258 
259 /* One Touch Record */
260 
one_touch_rec_on_send(struct node * node,unsigned me,unsigned la,const struct cec_op_record_src & rec_src,__u8 & rec_status)261 static int one_touch_rec_on_send(struct node *node, unsigned me, unsigned la,
262                                  const struct cec_op_record_src &rec_src, __u8 &rec_status)
263 {
264 	struct cec_msg msg;
265 
266 	cec_msg_init(&msg, me, la);
267 	cec_msg_record_off(&msg, false);
268 	fail_on_test(!transmit_timeout(node, &msg));
269 
270 	cec_msg_init(&msg, me, la);
271 	cec_msg_record_on(&msg, true, &rec_src);
272 	/* Allow 10s for reply because the spec says it may take several seconds to accurately respond. */
273 	fail_on_test(!transmit_timeout(node, &msg, 10000));
274 	fail_on_test(timed_out_or_abort(&msg));
275 	cec_ops_record_status(&msg, &rec_status);
276 
277 	return OK;
278 }
279 
one_touch_rec_on_send_invalid(struct node * node,unsigned me,unsigned la,const struct cec_op_record_src & rec_src)280 static int one_touch_rec_on_send_invalid(struct node *node, unsigned me, unsigned la,
281                                          const struct cec_op_record_src &rec_src)
282 {
283 	struct cec_msg msg;
284 
285 	cec_msg_init(&msg, me, la);
286 	cec_msg_record_on(&msg, true, &rec_src);
287 	fail_on_test(!transmit_timeout(node, &msg));
288 	fail_on_test(!cec_msg_status_is_abort(&msg));
289 	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
290 
291 	return OK;
292 }
293 
294 /*
295  * Returns true if the Record Status is an error indicating that the
296  * request to start recording has failed.
297  */
rec_status_is_a_valid_error_status(__u8 rec_status)298 static bool rec_status_is_a_valid_error_status(__u8 rec_status)
299 {
300 	switch (rec_status) {
301 	case CEC_OP_RECORD_STATUS_NO_DIG_SERVICE:
302 	case CEC_OP_RECORD_STATUS_NO_ANA_SERVICE:
303 	case CEC_OP_RECORD_STATUS_NO_SERVICE:
304 	case CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG:
305 	case CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR:
306 	case CEC_OP_RECORD_STATUS_UNSUP_CA:
307 	case CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS:
308 	case CEC_OP_RECORD_STATUS_CANT_COPY_SRC:
309 	case CEC_OP_RECORD_STATUS_NO_MORE_COPIES:
310 	case CEC_OP_RECORD_STATUS_NO_MEDIA:
311 	case CEC_OP_RECORD_STATUS_PLAYING:
312 	case CEC_OP_RECORD_STATUS_ALREADY_RECORDING:
313 	case CEC_OP_RECORD_STATUS_MEDIA_PROT:
314 	case CEC_OP_RECORD_STATUS_NO_SIGNAL:
315 	case CEC_OP_RECORD_STATUS_MEDIA_PROBLEM:
316 	case CEC_OP_RECORD_STATUS_NO_SPACE:
317 	case CEC_OP_RECORD_STATUS_PARENTAL_LOCK:
318 	case CEC_OP_RECORD_STATUS_OTHER:
319 		return true;
320 	default:
321 		return false;
322 	}
323 }
324 
one_touch_rec_tv_screen(struct node * node,unsigned me,unsigned la,bool interactive)325 static int one_touch_rec_tv_screen(struct node *node, unsigned me, unsigned la, bool interactive)
326 {
327 	struct cec_msg msg;
328 
329 	cec_msg_init(&msg, me, la);
330 	cec_msg_record_tv_screen(&msg, true);
331 	fail_on_test(!transmit_timeout(node, &msg));
332 	fail_on_test_v2(node->remote[la].cec_version,
333 			node->remote[la].has_rec_tv && unrecognized_op(&msg));
334 	fail_on_test_v2(node->remote[la].cec_version,
335 			!node->remote[la].has_rec_tv && !unrecognized_op(&msg));
336 	if (unrecognized_op(&msg))
337 		return OK_NOT_SUPPORTED;
338 	if (refused(&msg))
339 		return OK_REFUSED;
340 	if (cec_msg_status_is_abort(&msg))
341 		return OK_PRESUMED;
342 	/* Follower should ignore this message if it is not sent by a recording device */
343 	if (node->prim_devtype != CEC_OP_PRIM_DEVTYPE_RECORD) {
344 		fail_on_test(!timed_out(&msg));
345 		return OK;
346 	}
347 	fail_on_test(timed_out(&msg));
348 
349 	struct cec_op_record_src rec_src = {};
350 
351 	cec_ops_record_on(&msg, &rec_src);
352 
353 	fail_on_test(rec_src.type < CEC_OP_RECORD_SRC_OWN ||
354 	             rec_src.type > CEC_OP_RECORD_SRC_EXT_PHYS_ADDR);
355 
356 	if (rec_src.type == CEC_OP_RECORD_SRC_DIGITAL) {
357 		switch (rec_src.digital.dig_bcast_system) {
358 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN:
359 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
360 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN:
361 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS:
362 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS:
363 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T:
364 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
365 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
366 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
367 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C:
368 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S:
369 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2:
370 		case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T:
371 			break;
372 		default:
373 			return fail("Invalid digital service broadcast system operand.\n");
374 		}
375 
376 		if (rec_src.digital.service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL)
377 			fail_on_test(rec_src.digital.channel.channel_number_fmt < CEC_OP_CHANNEL_NUMBER_FMT_1_PART ||
378 			             rec_src.digital.channel.channel_number_fmt > CEC_OP_CHANNEL_NUMBER_FMT_2_PART);
379 	}
380 
381 	if (rec_src.type == CEC_OP_RECORD_SRC_ANALOG) {
382 		fail_on_test(rec_src.analog.ana_bcast_type > CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL);
383 		fail_on_test(rec_src.analog.bcast_system > CEC_OP_BCAST_SYSTEM_PAL_DK &&
384 		             rec_src.analog.bcast_system != CEC_OP_BCAST_SYSTEM_OTHER);
385 		fail_on_test(rec_src.analog.ana_freq == 0 || rec_src.analog.ana_freq == 0xffff);
386 	}
387 
388 	if (rec_src.type == CEC_OP_RECORD_SRC_EXT_PLUG)
389 		fail_on_test(rec_src.ext_plug.plug == 0);
390 
391 	return OK;
392 }
393 
one_touch_rec_on(struct node * node,unsigned me,unsigned la,bool interactive)394 static int one_touch_rec_on(struct node *node, unsigned me, unsigned la, bool interactive)
395 {
396 	struct cec_msg msg;
397 	struct cec_op_record_src rec_src = {};
398 
399 	rec_src.type = CEC_OP_RECORD_SRC_OWN;
400 	cec_msg_init(&msg, me, la);
401 	cec_msg_record_on(&msg, true, &rec_src);
402 	/* Allow 10s for reply because the spec says it may take several seconds to accurately respond. */
403 	fail_on_test(!transmit_timeout(node, &msg, 10000));
404 	fail_on_test(timed_out(&msg));
405 	if (unrecognized_op(&msg)) {
406 		fail_on_test(node->remote[la].prim_type == CEC_OP_PRIM_DEVTYPE_RECORD);
407 		return OK_NOT_SUPPORTED;
408 	}
409 	if (refused(&msg))
410 		return OK_REFUSED;
411 	if (cec_msg_status_is_abort(&msg))
412 		return OK_PRESUMED;
413 
414 	__u8 rec_status;
415 
416 	cec_ops_record_status(&msg, &rec_status);
417 	if (rec_status != CEC_OP_RECORD_STATUS_CUR_SRC)
418 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
419 
420 	/* In the following tests, these digital services are taken from the cec-follower tuner emulation. */
421 	memset(&rec_src, 0, sizeof(rec_src));
422 	rec_src.type = CEC_OP_RECORD_SRC_DIGITAL;
423 	rec_src.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID;
424 	rec_src.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS;
425 	rec_src.digital.arib.transport_id = 1032;
426 	rec_src.digital.arib.service_id = 30203;
427 	rec_src.digital.arib.orig_network_id = 1;
428 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
429 	if (rec_status != CEC_OP_RECORD_STATUS_DIG_SERVICE)
430 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
431 
432 	memset(&rec_src, 0, sizeof(rec_src));
433 	rec_src.type = CEC_OP_RECORD_SRC_DIGITAL;
434 	rec_src.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
435 	rec_src.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T;
436 	rec_src.digital.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_2_PART;
437 	rec_src.digital.channel.major = 4;
438 	rec_src.digital.channel.minor = 1;
439 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
440 	if (rec_status != CEC_OP_RECORD_STATUS_DIG_SERVICE)
441 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
442 
443 	memset(&rec_src, 0, sizeof(rec_src));
444 	rec_src.type = CEC_OP_RECORD_SRC_DIGITAL;
445 	rec_src.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID;
446 	rec_src.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T;
447 	rec_src.digital.dvb.transport_id = 1004;
448 	rec_src.digital.dvb.service_id = 1040;
449 	rec_src.digital.dvb.orig_network_id = 8945;
450 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
451 	if (rec_status != CEC_OP_RECORD_STATUS_DIG_SERVICE)
452 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
453 
454 	/* In the following tests, these channels taken from the cec-follower tuner emulation. */
455 	memset(&rec_src, 0, sizeof(rec_src));
456 	rec_src.type = CEC_OP_RECORD_STATUS_ANA_SERVICE;
457 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_CABLE;
458 	rec_src.analog.ana_freq = (471250 * 10) / 625;
459 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_PAL_BG;
460 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
461 	if (rec_status != CEC_OP_RECORD_STATUS_ANA_SERVICE)
462 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
463 
464 	memset(&rec_src, 0, sizeof(rec_src));
465 	rec_src.type = CEC_OP_RECORD_STATUS_ANA_SERVICE;
466 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_SATELLITE;
467 	rec_src.analog.ana_freq = (551250 * 10) / 625;
468 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_SECAM_BG;
469 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
470 	if (rec_status != CEC_OP_RECORD_STATUS_ANA_SERVICE)
471 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
472 
473 	memset(&rec_src, 0, sizeof(rec_src));
474 	rec_src.type = CEC_OP_RECORD_STATUS_ANA_SERVICE;
475 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL;
476 	rec_src.analog.ana_freq = (185250 * 10) / 625;
477 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_PAL_DK;
478 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
479 	if (rec_status != CEC_OP_RECORD_STATUS_ANA_SERVICE)
480 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
481 
482 	memset(&rec_src, 0, sizeof(rec_src));
483 	rec_src.type = CEC_OP_RECORD_SRC_EXT_PLUG;
484 	rec_src.ext_plug.plug = 1;
485 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
486 	if (rec_status != CEC_OP_RECORD_STATUS_EXT_INPUT)
487 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
488 
489 	memset(&rec_src, 0, sizeof(rec_src));
490 	rec_src.type = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;
491 	fail_on_test(one_touch_rec_on_send(node, me, la, rec_src, rec_status));
492 	if (rec_status != CEC_OP_RECORD_STATUS_EXT_INPUT)
493 		fail_on_test(!rec_status_is_a_valid_error_status(rec_status));
494 
495 	return OK;
496 }
497 
one_touch_rec_on_invalid(struct node * node,unsigned me,unsigned la,bool interactive)498 static int one_touch_rec_on_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
499 {
500 	struct cec_msg msg;
501 
502 	cec_msg_init(&msg, me, la);
503 	cec_msg_record_on_own(&msg);
504 	msg.msg[2] = 0;  /* Invalid source operand */
505 	fail_on_test(!transmit_timeout(node, &msg));
506 	if (unrecognized_op(&msg))
507 		return OK_NOT_SUPPORTED;
508 	fail_on_test(!cec_msg_status_is_abort(&msg));
509 	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
510 
511 	cec_msg_init(&msg, me, la);
512 	cec_msg_record_on_own(&msg);
513 	msg.msg[2] = 6;  /* Invalid source operand */
514 	fail_on_test(!transmit_timeout(node, &msg));
515 	fail_on_test(!cec_msg_status_is_abort(&msg));
516 	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
517 
518 	struct cec_op_record_src rec_src = {};
519 
520 	rec_src.type = CEC_OP_RECORD_SRC_DIGITAL;
521 	rec_src.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
522 	rec_src.digital.dig_bcast_system = 0x7f; /* Invalid digital service broadcast system operand */
523 	rec_src.digital.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
524 	rec_src.digital.channel.major = 0;
525 	rec_src.digital.channel.minor = 30203;
526 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
527 
528 	rec_src.type = CEC_OP_RECORD_SRC_DIGITAL;
529 	rec_src.digital.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
530 	rec_src.digital.dig_bcast_system = CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS;
531 	rec_src.digital.channel.channel_number_fmt = 0; /* Invalid channel number format operand */
532 	rec_src.digital.channel.major = 0;
533 	rec_src.digital.channel.minor = 30609;
534 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
535 
536 	memset(&rec_src, 0, sizeof(rec_src));
537 	rec_src.type = CEC_OP_RECORD_SRC_ANALOG;
538 	rec_src.analog.ana_bcast_type = 0xff; /* Invalid analog broadcast type */
539 	rec_src.analog.ana_freq = (519250 * 10) / 625;
540 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_PAL_BG;
541 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
542 
543 	memset(&rec_src, 0, sizeof(rec_src));
544 	rec_src.type = CEC_OP_RECORD_SRC_ANALOG;
545 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_SATELLITE;
546 	rec_src.analog.ana_freq = (703250 * 10) / 625;
547 	rec_src.analog.bcast_system = 0xff; /* Invalid analog broadcast system */
548 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
549 
550 	memset(&rec_src, 0, sizeof(rec_src));
551 	rec_src.type = CEC_OP_RECORD_SRC_ANALOG;
552 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL;
553 	rec_src.analog.ana_freq = 0; /* Invalid frequency */
554 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_NTSC_M;
555 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
556 
557 	memset(&rec_src, 0, sizeof(rec_src));
558 	rec_src.type = CEC_OP_RECORD_SRC_ANALOG;
559 	rec_src.analog.ana_bcast_type = CEC_OP_ANA_BCAST_TYPE_CABLE;
560 	rec_src.analog.ana_freq = 0xffff; /* Invalid frequency */
561 	rec_src.analog.bcast_system = CEC_OP_BCAST_SYSTEM_SECAM_L;
562 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
563 
564 	memset(&rec_src, 0, sizeof(rec_src));
565 	rec_src.type = CEC_OP_RECORD_SRC_EXT_PLUG;
566 	rec_src.ext_plug.plug = 0; /* Invalid plug */
567 	fail_on_test(one_touch_rec_on_send_invalid(node, me, la, rec_src));
568 
569 	return OK;
570 }
571 
one_touch_rec_off(struct node * node,unsigned me,unsigned la,bool interactive)572 static int one_touch_rec_off(struct node *node, unsigned me, unsigned la, bool interactive)
573 {
574 	struct cec_msg msg;
575 
576 	cec_msg_init(&msg, me, la);
577 	cec_msg_record_off(&msg, true);
578 	/* Allow 10s for reply because the spec says it may take several seconds to accurately respond. */
579 	fail_on_test(!transmit_timeout(node, &msg, 10000));
580 	if (unrecognized_op(&msg)) {
581 		fail_on_test(node->remote[la].prim_type == CEC_OP_PRIM_DEVTYPE_RECORD);
582 		return OK_NOT_SUPPORTED;
583 	}
584 	if (refused(&msg))
585 		return OK_REFUSED;
586 	if (cec_msg_status_is_abort(&msg))
587 		return OK_PRESUMED;
588 	if (timed_out(&msg))
589 		return OK_PRESUMED;
590 
591 	__u8 rec_status;
592 
593 	cec_ops_record_status(&msg, &rec_status);
594 
595 	fail_on_test(rec_status != CEC_OP_RECORD_STATUS_TERMINATED_OK &&
596 	             rec_status != CEC_OP_RECORD_STATUS_ALREADY_TERM);
597 
598 	return OK;
599 }
600 
601 const vec_remote_subtests one_touch_rec_subtests{
602 	{ "Record TV Screen", CEC_LOG_ADDR_MASK_TV, one_touch_rec_tv_screen },
603 	{
604 		"Record On",
605 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
606 		one_touch_rec_on,
607 	},
608 	{
609 		"Record On Invalid Operand",
610 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
611 		one_touch_rec_on_invalid,
612 	},
613 	{ "Record Off", CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP, one_touch_rec_off },
614 
615 };
616 
617 /* Timer Programming */
618 
timer_status_is_valid(const struct cec_msg & msg)619 static int timer_status_is_valid(const struct cec_msg &msg)
620 {
621 	__u8 timer_overlap_warning;
622 	__u8 media_info;
623 	__u8 prog_info;
624 	__u8 prog_error;
625 	__u8 duration_hr;
626 	__u8 duration_min;
627 
628 	cec_ops_timer_status(&msg, &timer_overlap_warning, &media_info, &prog_info,
629 	                     &prog_error, &duration_hr, &duration_min);
630 	fail_on_test(media_info > CEC_OP_MEDIA_INFO_NO_MEDIA);
631 	if (prog_info)
632 		fail_on_test(prog_info < CEC_OP_PROG_INFO_ENOUGH_SPACE ||
633 		             prog_info > CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE);
634 	else
635 		fail_on_test(prog_error < CEC_OP_PROG_ERROR_NO_FREE_TIMER ||
636 		             (prog_error > CEC_OP_PROG_ERROR_CLOCK_FAILURE &&
637 		              prog_error != CEC_OP_PROG_ERROR_DUPLICATE));
638 
639 	return OK;
640 }
641 
timer_cleared_status_is_valid(const struct cec_msg & msg)642 static int timer_cleared_status_is_valid(const struct cec_msg &msg)
643 {
644 	__u8 timer_cleared_status;
645 
646 	cec_ops_timer_cleared_status(&msg, &timer_cleared_status);
647 	fail_on_test(timer_cleared_status != CEC_OP_TIMER_CLR_STAT_RECORDING &&
648 	             timer_cleared_status != CEC_OP_TIMER_CLR_STAT_NO_MATCHING &&
649 	             timer_cleared_status != CEC_OP_TIMER_CLR_STAT_NO_INFO &&
650 	             timer_cleared_status != CEC_OP_TIMER_CLR_STAT_CLEARED);
651 
652 	return OK;
653 }
654 
timer_has_error(const struct cec_msg & msg)655 static bool timer_has_error(const struct cec_msg &msg)
656 {
657 	__u8 timer_overlap_warning;
658 	__u8 media_info;
659 	__u8 prog_info;
660 	__u8 prog_error;
661 	__u8 duration_hr;
662 	__u8 duration_min;
663 
664 	cec_ops_timer_status(&msg, &timer_overlap_warning, &media_info, &prog_info,
665 	                     &prog_error, &duration_hr, &duration_min);
666 	if (prog_error)
667 		return true;
668 
669 	return false;
670 }
671 
send_timer_error(struct node * node,unsigned me,unsigned la,__u8 day,__u8 month,__u8 start_hr,__u8 start_min,__u8 dur_hr,__u8 dur_min,__u8 rec_seq)672 static int send_timer_error(struct node *node, unsigned me, unsigned la, __u8 day, __u8 month,
673                             __u8 start_hr, __u8 start_min, __u8 dur_hr, __u8 dur_min, __u8 rec_seq)
674 {
675 	struct cec_msg msg;
676 	cec_msg_init(&msg, me, la);
677 	cec_msg_set_analogue_timer(&msg, true, day, month, start_hr, start_min, dur_hr, dur_min,
678 	                           rec_seq, CEC_OP_ANA_BCAST_TYPE_CABLE, 7668, // 479.25 MHz
679 	                           node->remote[la].bcast_sys);
680 	fail_on_test(!transmit_timeout(node, &msg, 10000));
681 	fail_on_test(timed_out(&msg));
682 	if (cec_msg_status_is_abort(&msg))
683 		fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_UNRECOGNIZED_OP);
684 	else
685 		fail_on_test(!timer_has_error(msg));
686 
687 	return OK;
688 }
689 
timer_overlap_warning_is_set(const struct cec_msg & msg)690 static bool timer_overlap_warning_is_set(const struct cec_msg &msg)
691 {
692 	__u8 timer_overlap_warning;
693 	__u8 media_info;
694 	__u8 prog_info;
695 	__u8 prog_error;
696 	__u8 duration_hr;
697 	__u8 duration_min;
698 
699 	cec_ops_timer_status(&msg, &timer_overlap_warning, &media_info, &prog_info,
700 	                     &prog_error, &duration_hr, &duration_min);
701 
702 	if (timer_overlap_warning)
703 		return true;
704 
705 	return false;
706 }
707 
send_timer_overlap(struct node * node,unsigned me,unsigned la,__u8 day,__u8 month,__u8 start_hr,__u8 start_min,__u8 dur_hr,__u8 dur_min,__u8 rec_seq)708 static int send_timer_overlap(struct node *node, unsigned me, unsigned la, __u8 day, __u8 month,
709                               __u8 start_hr, __u8 start_min, __u8 dur_hr, __u8 dur_min, __u8 rec_seq)
710 {
711 	struct cec_msg msg;
712 
713 	cec_msg_init(&msg, me, la);
714 	cec_msg_set_analogue_timer(&msg, true, day, month, start_hr, start_min, dur_hr, dur_min,
715 	                           rec_seq, CEC_OP_ANA_BCAST_TYPE_CABLE, 7668, // 479.25 MHz
716 	                           node->remote[la].bcast_sys);
717 	fail_on_test(!transmit_timeout(node, &msg, 10000));
718 	fail_on_test(timed_out_or_abort(&msg));
719 	fail_on_test(timer_has_error(msg));
720 	fail_on_test(!timer_overlap_warning_is_set(msg));
721 
722 	return OK;
723 }
724 
clear_timer(struct node * node,unsigned me,unsigned la,__u8 day,__u8 month,__u8 start_hr,__u8 start_min,__u8 dur_hr,__u8 dur_min,__u8 rec_seq)725 static int clear_timer(struct node *node, unsigned me, unsigned la, __u8 day, __u8 month,
726                        __u8 start_hr, __u8 start_min, __u8 dur_hr, __u8 dur_min, __u8 rec_seq)
727 {
728 	struct cec_msg msg;
729 
730 	cec_msg_init(&msg, me, la);
731 	cec_msg_clear_analogue_timer(&msg, true, day, month, start_hr, start_min, dur_hr, dur_min,
732 	                             rec_seq, CEC_OP_ANA_BCAST_TYPE_CABLE, 7668, // 479.25 MHz
733 	                             node->remote[la].bcast_sys);
734 	fail_on_test(!transmit_timeout(node, &msg, 10000));
735 	fail_on_test(timed_out_or_abort(&msg));
736 	fail_on_test(timer_has_error(msg));
737 	fail_on_test(timer_cleared_status_is_valid(msg));
738 
739 	return OK;
740 }
741 
timer_prog_set_analog_timer(struct node * node,unsigned me,unsigned la,bool interactive)742 static int timer_prog_set_analog_timer(struct node *node, unsigned me, unsigned la, bool interactive)
743 {
744 	struct cec_msg msg;
745 
746 	cec_msg_init(&msg, me, la);
747 	/* Set timer to start tomorrow, at current time, for 2 hr, 30 min. */
748 	time_t tomorrow = node->current_time + (24 * 60 * 60);
749 	struct tm *t = localtime(&tomorrow);
750 	cec_msg_set_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 2, 30,
751 	                           0x7f, CEC_OP_ANA_BCAST_TYPE_CABLE, 7668, // 479.25 MHz
752 	                           node->remote[la].bcast_sys);
753 	fail_on_test(!transmit_timeout(node, &msg, 10000));
754 	fail_on_test(timed_out(&msg));
755 	if (unrecognized_op(&msg))
756 		return OK_NOT_SUPPORTED;
757 	if (refused(&msg))
758 		return OK_REFUSED;
759 	if (cec_msg_status_is_abort(&msg))
760 		return OK_PRESUMED;
761 	fail_on_test(timer_status_is_valid(msg));
762 	node->remote[la].has_analogue_timer = true;
763 
764 	return OK;
765 }
766 
timer_prog_set_digital_timer(struct node * node,unsigned me,unsigned la,bool interactive)767 static int timer_prog_set_digital_timer(struct node *node, unsigned me, unsigned la, bool interactive)
768 {
769 	struct cec_msg msg;
770 	struct cec_op_digital_service_id digital_service_id = {};
771 
772 	digital_service_id.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
773 	digital_service_id.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
774 	digital_service_id.channel.minor = 1;
775 	digital_service_id.dig_bcast_system = node->remote[la].dig_bcast_sys;
776 	cec_msg_init(&msg, me, la);
777 	/* Set timer to start 2 days from now, at current time, for 4 hr, 30 min. */
778 	time_t two_days_ahead = node->current_time + (2 * 24 * 60 * 60);
779 	struct tm *t = localtime(&two_days_ahead);
780 	cec_msg_set_digital_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour,
781 	                          t->tm_min, 4, 30, CEC_OP_REC_SEQ_ONCE_ONLY, &digital_service_id);
782 	fail_on_test(!transmit_timeout(node, &msg, 10000));
783 	fail_on_test(timed_out(&msg));
784 	if (unrecognized_op(&msg))
785 		return OK_NOT_SUPPORTED;
786 	if (refused(&msg))
787 		return OK_REFUSED;
788 	if (cec_msg_status_is_abort(&msg))
789 		return OK_PRESUMED;
790 	fail_on_test(timer_status_is_valid(msg));
791 
792 	return 0;
793 }
794 
timer_prog_set_ext_timer(struct node * node,unsigned me,unsigned la,bool interactive)795 static int timer_prog_set_ext_timer(struct node *node, unsigned me, unsigned la, bool interactive)
796 {
797 	struct cec_msg msg;
798 
799 	cec_msg_init(&msg, me, la);
800 	/* Set timer to start 3 days from now, at current time, for 6 hr, 30 min. */
801 	time_t three_days_ahead = node->current_time + (3 * 24 * 60 * 60);
802 	struct tm *t = localtime(&three_days_ahead);
803 	cec_msg_set_ext_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 6, 30,
804 	                      CEC_OP_REC_SEQ_ONCE_ONLY, CEC_OP_EXT_SRC_PHYS_ADDR, 0, node->phys_addr);
805 	fail_on_test(!transmit_timeout(node, &msg, 10000));
806 	fail_on_test(timed_out(&msg));
807 	if (unrecognized_op(&msg))
808 		return OK_NOT_SUPPORTED;
809 	if (refused(&msg))
810 		return OK_REFUSED;
811 	if (cec_msg_status_is_abort(&msg))
812 		return OK_PRESUMED;
813 	fail_on_test(timer_status_is_valid(msg));
814 
815 	return 0;
816 }
817 
timer_prog_clear_analog_timer(struct node * node,unsigned me,unsigned la,bool interactive)818 static int timer_prog_clear_analog_timer(struct node *node, unsigned me, unsigned la, bool interactive)
819 {
820 	struct cec_msg msg;
821 
822 	cec_msg_init(&msg, me, la);
823 	/* Clear timer set to start tomorrow, at current time, for 2 hr, 30 min. */
824 	time_t tomorrow = node->current_time + (24 * 60 * 60);
825 	struct tm *t = localtime(&tomorrow);
826 	cec_msg_clear_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 2, 30,
827 	                             0x7f, CEC_OP_ANA_BCAST_TYPE_CABLE,7668, // 479.25 MHz
828 	                             node->remote[la].bcast_sys);
829 	fail_on_test(!transmit_timeout(node, &msg, 10000));
830 	fail_on_test(timed_out(&msg));
831 	if (unrecognized_op(&msg))
832 		return OK_NOT_SUPPORTED;
833 	if (refused(&msg))
834 		return OK_REFUSED;
835 	if (cec_msg_status_is_abort(&msg))
836 		return OK_PRESUMED;
837 	fail_on_test(timer_cleared_status_is_valid(msg));
838 
839 	return 0;
840 }
841 
timer_prog_clear_digital_timer(struct node * node,unsigned me,unsigned la,bool interactive)842 static int timer_prog_clear_digital_timer(struct node *node, unsigned me, unsigned la, bool interactive)
843 {
844 	struct cec_msg msg;
845 	struct cec_op_digital_service_id digital_service_id = {};
846 
847 	digital_service_id.service_id_method = CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL;
848 	digital_service_id.channel.channel_number_fmt = CEC_OP_CHANNEL_NUMBER_FMT_1_PART;
849 	digital_service_id.channel.minor = 1;
850 	digital_service_id.dig_bcast_system = node->remote[la].dig_bcast_sys;
851 	cec_msg_init(&msg, me, la);
852 	/* Clear timer set to start 2 days from now, at current time, for 4 hr, 30 min. */
853 	time_t two_days_ahead = node->current_time + (2 * 24 * 60 * 60);
854 	struct tm *t = localtime(&two_days_ahead);
855 	cec_msg_clear_digital_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour,
856 	                            t->tm_min, 4, 30, CEC_OP_REC_SEQ_ONCE_ONLY, &digital_service_id);
857 	fail_on_test(!transmit_timeout(node, &msg, 10000));
858 	fail_on_test(timed_out(&msg));
859 	if (unrecognized_op(&msg))
860 		return OK_NOT_SUPPORTED;
861 	if (refused(&msg))
862 		return OK_REFUSED;
863 	if (cec_msg_status_is_abort(&msg))
864 		return OK_PRESUMED;
865 	fail_on_test(timer_cleared_status_is_valid(msg));
866 
867 	return 0;
868 }
869 
timer_prog_clear_ext_timer(struct node * node,unsigned me,unsigned la,bool interactive)870 static int timer_prog_clear_ext_timer(struct node *node, unsigned me, unsigned la, bool interactive)
871 {
872 	struct cec_msg msg;
873 
874 	cec_msg_init(&msg, me, la);
875 	/* Clear timer set to start 3 days from now, at current time, for 6 hr, 30 min. */
876 	time_t three_days_ahead = node->current_time + (3 * 24 * 60 * 60);
877 	struct tm *t = localtime(&three_days_ahead);
878 	cec_msg_clear_ext_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 6, 30,
879 	                        CEC_OP_REC_SEQ_ONCE_ONLY, CEC_OP_EXT_SRC_PHYS_ADDR, 0, node->phys_addr);
880 	fail_on_test(!transmit_timeout(node, &msg, 10000));
881 	fail_on_test(timed_out(&msg));
882 	if (unrecognized_op(&msg))
883 		return OK_NOT_SUPPORTED;
884 	if (refused(&msg))
885 		return OK_REFUSED;
886 	if (cec_msg_status_is_abort(&msg))
887 		return OK_PRESUMED;
888 	fail_on_test(timer_cleared_status_is_valid(msg));
889 
890 	return 0;
891 }
892 
timer_prog_set_prog_title(struct node * node,unsigned me,unsigned la,bool interactive)893 static int timer_prog_set_prog_title(struct node *node, unsigned me, unsigned la, bool interactive)
894 {
895 	struct cec_msg msg;
896 
897 	cec_msg_init(&msg, me, la);
898 	cec_msg_set_timer_program_title(&msg, "Super-Hans II");
899 	fail_on_test(!transmit_timeout(node, &msg));
900 	if (unrecognized_op(&msg))
901 		return OK_NOT_SUPPORTED;
902 	if (refused(&msg))
903 		return OK_REFUSED;
904 
905 	return OK_PRESUMED;
906 }
907 
timer_errors(struct node * node,unsigned me,unsigned la,bool interactive)908 static int timer_errors(struct node *node, unsigned me, unsigned la, bool interactive)
909 {
910 	struct cec_msg msg;
911 
912 	if (!node->remote[la].has_analogue_timer)
913 		return OK_NOT_SUPPORTED;
914 
915 	/* Day error: November 31, at 6:00 am, for 1 hr. */
916 	fail_on_test(send_timer_error(node, me, la, 31, Nov, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
917 
918 	/* Day error: December 32, at 6:00 am, for 1 hr. */
919 	fail_on_test(send_timer_error(node, me, la, 32, Dec, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
920 
921 	/* Day error: 0, in January, at 6:00 am, for 1 hr. Day range begins at 1. */
922 	fail_on_test(send_timer_error(node, me, la, 0, Jan, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
923 
924 	/* Month error: 0, on day 5, at 6:00 am, for 1 hr. CEC month range is 1-12. */
925 	fail_on_test(send_timer_error(node, me, la, 5, 0, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
926 
927 	/* Month error: 13, on day 5, at 6:00 am, for 1 hr. */
928 	fail_on_test(send_timer_error(node, me, la, 5, 13, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
929 
930 	/* Start hour error: 24 hr, on August 5, for 1 hr. Start hour range is 0-23. */
931 	fail_on_test(send_timer_error(node, me, la, 5, Aug, 24, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
932 
933 	/* Start min error: 60 min, on August 5, for 1 hr. Start min range is 0-59. */
934 	fail_on_test(send_timer_error(node, me, la, 5, Aug, 0, 60, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
935 
936 	/* Recording duration error: 0 hr, 0 min on August 5, at 6:00am. */
937 	fail_on_test(send_timer_error(node, me, la, 5, Aug, 6, 0, 0, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
938 
939 	/* Duplicate timer error: start 2 hrs from now, for 1 hr. */
940 	time_t two_hours_ahead = node->current_time + (2 * 60 * 60);
941 	struct tm *t = localtime(&two_hours_ahead);
942 	cec_msg_init(&msg, me, la);
943 	cec_msg_set_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 1, 0,
944 	                           CEC_OP_REC_SEQ_ONCE_ONLY,CEC_OP_ANA_BCAST_TYPE_CABLE,
945 	                           7668, // 479.25 MHz
946 	                           node->remote[la].bcast_sys);
947 	fail_on_test(!transmit_timeout(node, &msg, 10000));
948 	fail_on_test(timed_out_or_abort(&msg));
949 	fail_on_test(timer_has_error(msg)); /* The first timer should be set. */
950 	fail_on_test(send_timer_error(node, me, la, t->tm_mday, t->tm_mon + 1, t->tm_hour,
951 	                              t->tm_min, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
952 
953 	/* Clear the timer that was set to test duplicate timers. */
954 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, t->tm_hour, t->tm_min, 1, 0,
955 	                         CEC_OP_REC_SEQ_ONCE_ONLY));
956 
957 	/* Recording sequence error: 0xff, on August 5, at 6:00 am, for 1 hr. */
958 	fail_on_test(send_timer_error(node, me, la, 5, Aug, 6, 0, 1, 0, 0xff));
959 
960 	/* Error in last day of February, at 6:00 am, for 1 hr. */
961 	time_t current_time = node->current_time;
962 	t = localtime(&current_time);
963 	if ((t->tm_mon + 1) > Feb)
964 		t->tm_year++; /* The timer will be for next year. */
965 	if (!(t->tm_year % 4) && ((t->tm_year % 100) || !(t->tm_year % 400)))
966 		fail_on_test(send_timer_error(node, me, la, 30, Feb, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
967 	else
968 		fail_on_test(send_timer_error(node, me, la, 29, Feb, 6, 0, 1, 0, CEC_OP_REC_SEQ_ONCE_ONLY));
969 
970 	return OK;
971 }
972 
timer_overlap_warning(struct node * node,unsigned me,unsigned la,bool interactive)973 static int timer_overlap_warning(struct node *node, unsigned me, unsigned la, bool interactive)
974 {
975 	struct cec_msg msg;
976 
977 	time_t tomorrow = node->current_time + (24 * 60 * 60);
978 	struct tm *t = localtime(&tomorrow);
979 
980 	if (!node->remote[la].has_analogue_timer)
981 		return OK_NOT_SUPPORTED;
982 
983 	/* No overlap: set timer for tomorrow at 8:00 am for 2 hr. */
984 	cec_msg_init(&msg, me, la);
985 	cec_msg_set_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, 8, 0, 2, 0,
986 	                           CEC_OP_REC_SEQ_ONCE_ONLY, CEC_OP_ANA_BCAST_TYPE_CABLE,
987 	                           7668, // 479.25 MHz
988 	                           node->remote[la].bcast_sys);
989 	fail_on_test(!transmit_timeout(node, &msg, 10000));
990 	if (unrecognized_op(&msg))
991 		return OK_NOT_SUPPORTED;
992 	fail_on_test(timed_out_or_abort(&msg));
993 	fail_on_test(timer_has_error(msg));
994 	fail_on_test(timer_overlap_warning_is_set(msg));
995 
996 	/* No overlap, just adjacent: set timer for tomorrow at 10:00 am for 15 min. */
997 	cec_msg_init(&msg, me, la);
998 	cec_msg_set_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, 10, 0, 0, 15,
999 	                           CEC_OP_REC_SEQ_ONCE_ONLY, CEC_OP_ANA_BCAST_TYPE_CABLE,
1000 	                           7668, // 479.25 MHz
1001 	                           node->remote[la].bcast_sys);
1002 	fail_on_test(!transmit_timeout(node, &msg, 10000));
1003 	fail_on_test(timed_out_or_abort(&msg));
1004 	fail_on_test(timer_has_error(msg));
1005 	fail_on_test(timer_overlap_warning_is_set(msg));
1006 
1007 	/* No overlap, just adjacent: set timer for tomorrow at 7:45 am for 15 min. */
1008 	cec_msg_init(&msg, me, la);
1009 	cec_msg_set_analogue_timer(&msg, true, t->tm_mday, t->tm_mon + 1, 7, 45, 0, 15,
1010 	                           CEC_OP_REC_SEQ_ONCE_ONLY, CEC_OP_ANA_BCAST_TYPE_CABLE,
1011 	                           7668, // 479.25 MHz
1012 	                           node->remote[la].bcast_sys);
1013 	fail_on_test(!transmit_timeout(node, &msg, 10000));
1014 	fail_on_test(timed_out_or_abort(&msg));
1015 	fail_on_test(timer_has_error(msg));
1016 	fail_on_test(timer_overlap_warning_is_set(msg));
1017 
1018 	/* Overlap tail end: set timer for tomorrow at 9:00 am for 2 hr, repeats on Sun. */
1019 	fail_on_test(send_timer_overlap(node, me, la, t->tm_mday, t->tm_mon + 1, 9, 0, 2, 0, 0x1));
1020 
1021 	/* Overlap front end: set timer for tomorrow at 7:00 am for 1 hr, 30 min. */
1022 	fail_on_test(send_timer_overlap(node, me, la, t->tm_mday, t->tm_mon + 1, 7, 0, 1, 30, 0x1));
1023 
1024 	/* Overlap same start time: set timer for tomorrow at 8:00 am for 30 min. */
1025 	fail_on_test(send_timer_overlap(node, me, la, t->tm_mday, t->tm_mon + 1, 8, 0, 0, 30, 0x1));
1026 
1027 	/* Overlap same end time: set timer for tomorrow at 9:30 am for 30 min. */
1028 	fail_on_test(send_timer_overlap(node, me, la, t->tm_mday, t->tm_mon + 1, 9, 30, 0, 30, 0x1));
1029 
1030 	/* Overlap all timers: set timer for tomorrow at 6:00 am for 6 hr. */
1031 	fail_on_test(send_timer_overlap(node, me, la, t->tm_mday, t->tm_mon + 1, 6, 0, 6, 0, 0x1));
1032 
1033 	/* Clear all the timers. */
1034 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 8, 0, 2, 0,
1035 	                         CEC_OP_REC_SEQ_ONCE_ONLY));
1036 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 10, 0, 0, 15,
1037 	                         CEC_OP_REC_SEQ_ONCE_ONLY));
1038 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 7, 45, 0, 15,
1039 	                         CEC_OP_REC_SEQ_ONCE_ONLY));
1040 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 9, 0, 2, 0, 0x1));
1041 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 7, 0, 1, 30, 0x1));
1042 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 8, 0, 0, 30, 0x1));
1043 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 9, 30, 0, 30, 0x1));
1044 	fail_on_test(clear_timer(node, me, la, t->tm_mday, t->tm_mon + 1, 6, 0, 6, 0, 0x1));
1045 
1046 	return OK;
1047 }
1048 
1049 const vec_remote_subtests timer_prog_subtests{
1050 	{
1051 		"Set Analogue Timer",
1052 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1053 		timer_prog_set_analog_timer,
1054 	},
1055 	{
1056 		"Set Digital Timer",
1057 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1058 		timer_prog_set_digital_timer,
1059 	},
1060 	{
1061 		"Set Timer Program Title",
1062 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1063 		timer_prog_set_prog_title,
1064 	},
1065 	{
1066 		"Set External Timer",
1067 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1068 		timer_prog_set_ext_timer,
1069 	},
1070 	{
1071 		"Clear Analogue Timer",
1072 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1073 		timer_prog_clear_analog_timer,
1074 	},
1075 	{
1076 		"Clear Digital Timer",
1077 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1078 		timer_prog_clear_digital_timer,
1079 	},
1080 	{
1081 		"Clear External Timer",
1082 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1083 		timer_prog_clear_ext_timer,
1084 	},
1085 	{
1086 		"Set Timers with Errors",
1087 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1088 		timer_errors,
1089 	},
1090 	{
1091 		"Set Overlapping Timers",
1092 		CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_BACKUP,
1093 		timer_overlap_warning,
1094 	},
1095 };
1096