• 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 <ctime>
7 #include <sstream>
8 #include <string>
9 
10 #include <sys/ioctl.h>
11 #include <unistd.h>
12 
13 #include "cec-compliance.h"
14 #include "compiler.h"
15 
audio_format_code2s(__u8 format_code)16 static std::string audio_format_code2s(__u8 format_code)
17 {
18 	switch (format_code) {
19 	case 0:
20 		return "Reserved";
21 	case SAD_FMT_CODE_LPCM:
22 		return "L-PCM";
23 	case SAD_FMT_CODE_AC3:
24 		return "AC-3";
25 	case SAD_FMT_CODE_MPEG1:
26 		return "MPEG-1";
27 	case SAD_FMT_CODE_MP3:
28 		return "MP3";
29 	case SAD_FMT_CODE_MPEG2:
30 		return "MPEG2";
31 	case SAD_FMT_CODE_AAC_LC:
32 		return "AAC LC";
33 	case SAD_FMT_CODE_DTS:
34 		return "DTS";
35 	case SAD_FMT_CODE_ATRAC:
36 		return "ATRAC";
37 	case SAD_FMT_CODE_ONE_BIT_AUDIO:
38 		return "One Bit Audio";
39 	case SAD_FMT_CODE_ENHANCED_AC3:
40 		return "Enhanced AC-3";
41 	case SAD_FMT_CODE_DTS_HD:
42 		return "DTS-HD";
43 	case SAD_FMT_CODE_MAT:
44 		return "MAT";
45 	case SAD_FMT_CODE_DST:
46 		return "DST";
47 	case SAD_FMT_CODE_WMA_PRO:
48 		return "WMA Pro";
49 	case SAD_FMT_CODE_EXTENDED:
50 		return "Extended";
51 	default:
52 		return "Illegal";
53 	}
54 }
55 
extension_type_code2s(__u8 type_code)56 static std::string extension_type_code2s(__u8 type_code)
57 {
58 	switch (type_code) {
59 	case 0:
60 	case 1:
61 	case 2:
62 	case 3:
63 		return "Not in use";
64 	case SAD_EXT_TYPE_MPEG4_HE_AAC:
65 		return "MPEG-4 HE AAC";
66 	case SAD_EXT_TYPE_MPEG4_HE_AACv2:
67 		return "MPEG-4 HE AAC v2";
68 	case SAD_EXT_TYPE_MPEG4_AAC_LC:
69 		return "MPEG-4 AAC LC";
70 	case SAD_EXT_TYPE_DRA:
71 		return "DRA";
72 	case SAD_EXT_TYPE_MPEG4_HE_AAC_SURROUND:
73 		return "MPEG-4 HE AAC + MPEG Surround";
74 	case SAD_EXT_TYPE_MPEG4_AAC_LC_SURROUND:
75 		return "MPEG-4 AAC LC + MPEG Surround";
76 	case SAD_EXT_TYPE_MPEG_H_3D_AUDIO:
77 		return "MPEG-H 3D Audio";
78 	case SAD_EXT_TYPE_AC_4:
79 		return "AC-4";
80 	case SAD_EXT_TYPE_LPCM_3D_AUDIO:
81 		return "L-PCM 3D Audio";
82 	default:
83 		return "Reserved";
84 	}
85 }
86 
short_audio_desc2s(const struct short_audio_desc & sad)87 static std::string short_audio_desc2s(const struct short_audio_desc &sad)
88 {
89 	std::stringstream oss;
90 
91 	if (sad.format_code != SAD_FMT_CODE_EXTENDED)
92 		oss << audio_format_code2s(sad.format_code);
93 	else
94 		oss << extension_type_code2s(sad.extension_type_code);
95 	oss << ", " << static_cast<int>(sad.num_channels) << " channels";
96 
97 	oss << ", sampling rates (kHz): ";
98 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_32)
99 		oss << "32,";
100 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_44_1)
101 		oss << "44.1,";
102 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_48)
103 		oss << "48,";
104 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_88_2)
105 		oss << "88.2,";
106 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_96)
107 		oss << "96,";
108 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_176_4)
109 		oss << "176.4,";
110 	if (sad.sample_freq_mask & SAD_SAMPLE_FREQ_MASK_192)
111 		oss << "192,";
112 	if (sad.sample_freq_mask & (1 << 7))
113 		oss << "Reserved,";
114 	oss << "\b \b";
115 
116 	if (sad.format_code == SAD_FMT_CODE_LPCM ||
117 	    (sad.format_code == SAD_FMT_CODE_EXTENDED &&
118 	     sad.extension_type_code == SAD_EXT_TYPE_LPCM_3D_AUDIO)) {
119 		oss << ", bit depth: ";
120 		if (sad.bit_depth_mask & SAD_BIT_DEPTH_MASK_16)
121 			oss << "16,";
122 		if (sad.bit_depth_mask & SAD_BIT_DEPTH_MASK_20)
123 			oss << "20,";
124 		if (sad.bit_depth_mask & SAD_BIT_DEPTH_MASK_24)
125 			oss << "24,";
126 		oss << "\b \b";
127 	} else if (sad.format_code >= 2 && sad.format_code <= 8)
128 		oss << " max bitrate (kbit/s): " << 8 * sad.max_bitrate;
129 
130 	if (sad.format_code == SAD_FMT_CODE_EXTENDED) {
131 		switch (sad.extension_type_code) {
132 		case 4:
133 		case 5:
134 		case 6:
135 		case 8:
136 		case 10:
137 			oss << ", frame length: ";
138 			if (sad.frame_length_mask & SAD_FRAME_LENGTH_MASK_960)
139 				oss << "960,";
140 			if (sad.frame_length_mask & SAD_FRAME_LENGTH_MASK_1024)
141 				oss << "1024,";
142 			oss << "\b";
143 			break;
144 		}
145 
146 		if (sad.extension_type_code == 8 || sad.extension_type_code == 10)
147 			oss << ", MPS";
148 	}
149 
150 	return oss.str();
151 }
152 
sad_decode(struct short_audio_desc * sad,__u32 descriptor)153 static void sad_decode(struct short_audio_desc *sad, __u32 descriptor)
154 {
155 	__u8 b1 = (descriptor >> 16) & 0xff;
156 	__u8 b2 = (descriptor >> 8) & 0xff;
157 	__u8 b3 = descriptor & 0xff;
158 
159 	sad->num_channels = (b1 & 0x07) + 1;
160 	sad->format_code = (b1 >> 3) & 0x0f;
161 	sad->sample_freq_mask = b2;
162 
163 	switch (sad->format_code) {
164 	case SAD_FMT_CODE_LPCM:
165 		sad->bit_depth_mask = b3 & 0x07;
166 		break;
167 	case 2:
168 	case 3:
169 	case 4:
170 	case 5:
171 	case 6:
172 	case 7:
173 	case 8:
174 		sad->max_bitrate = b3;
175 		break;
176 	case 9:
177 	case 10:
178 	case 11:
179 	case 12:
180 	case 13:
181 		sad->format_dependent = b3;
182 		break;
183 	case SAD_FMT_CODE_WMA_PRO:
184 		sad->wma_profile = b3 & 0x03;
185 		break;
186 	case SAD_FMT_CODE_EXTENDED:
187 	        sad->extension_type_code = (b3 >> 3) & 0x1f;
188 
189 		switch (sad->extension_type_code) {
190 		case 4:
191 		case 5:
192 		case 6:
193 			sad->frame_length_mask = (b3 >> 1) & 0x03;
194 			break;
195 		case 8:
196 		case 10:
197 			sad->frame_length_mask = (b3 >> 1) & 0x03;
198 			sad->mps = b3 & 1;
199 			break;
200 		case SAD_EXT_TYPE_MPEG_H_3D_AUDIO:
201 		case SAD_EXT_TYPE_AC_4:
202 			sad->format_dependent = b3 & 0x07;
203 			fallthrough;
204 		case SAD_EXT_TYPE_LPCM_3D_AUDIO:
205 			sad->bit_depth_mask = b3 & 0x07;
206 			break;
207 		}
208 		break;
209 	}
210 }
211 
212 /* Dynamic Auto Lipsync */
213 
dal_request_current_latency(struct node * node,unsigned me,unsigned la,bool interactive)214 static int dal_request_current_latency(struct node *node, unsigned me, unsigned la, bool interactive)
215 {
216 	struct cec_msg msg;
217 
218 	cec_msg_init(&msg, me, la);
219 	cec_msg_request_current_latency(&msg, true, node->remote[la].phys_addr);
220 	fail_on_test(!transmit_timeout(node, &msg));
221 	fail_on_test_v2(node->remote[la].cec_version,
222 			timed_out(&msg) && is_tv(la, node->remote[la].prim_type));
223 	if (timed_out(&msg))
224 		return OK_NOT_SUPPORTED;
225 
226 	/* When the device supports Dynamic Auto Lipsync but does not implement
227 	   CEC 1.4b, or 2.0, a very strict subset of CEC can be supported. If we
228 	   get here and the version is < 1.4, we know that the device is not
229 	   complying to this specification. */
230 	if (node->remote[la].cec_version < CEC_OP_CEC_VERSION_1_4) {
231 		warn("CEC 2.0 specifies that devices with CEC version < 1.4 which implement\n");
232 		warn("Dynamic Auto Lipsync shall only implement a very strict subset of CEC.\n");
233 	}
234 
235 	__u16 phys_addr;
236 	__u8 video_latency, low_latency_mode, audio_out_compensated, audio_out_delay;
237 
238 	cec_ops_report_current_latency(&msg, &phys_addr, &video_latency, &low_latency_mode,
239 				       &audio_out_compensated, &audio_out_delay);
240 	// cec_ops_report_current_latency will hardcode audio_out_delay
241 	// if it is unused, but for this test we want the real value, so
242 	// get it from the actual message.
243 	if (msg.len >= 7)
244 		audio_out_delay = msg.msg[6];
245 	else
246 		audio_out_delay = 1;
247 	fail_on_test(phys_addr != node->remote[la].phys_addr);
248 	info("Video latency: %d (%dms)\n", video_latency, (video_latency - 1) * 2);
249 	info("Low latency mode: %d\n", low_latency_mode);
250 	info("Audio output compensation: %d\n", audio_out_compensated);
251 	if (audio_out_compensated == CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY) {
252 		info("Audio out delay: %d (%dms)\n", audio_out_delay, (audio_out_delay - 1) * 2);
253 		fail_on_test(audio_out_delay == 0 || audio_out_delay > 251);
254 		// Warn if the delay is more than 50 ms
255 		warn_on_test(audio_out_delay > (50 / 2) + 1);
256 	} else {
257 		// Although this value will be ignored, it shouldn't use
258 		// reserved values.
259 		if (audio_out_delay == 0 || audio_out_delay > 251)
260 			warn("Audio out delay is set to a reserved value (%d), set it to 1 instead (recommended value when this field is unused).\n", audio_out_delay);
261 		else if (audio_out_delay != 1)
262 			warn("Audio out delay is %d (%dms), but value 1 is recommended when this field is unused.\n",
263 			     audio_out_delay, (audio_out_delay - 1) * 2);
264 	}
265 	fail_on_test(video_latency == 0 || video_latency > 251);
266 	// Warn if the delay is more than 50 ms and low latency mode is set
267 	if (video_latency > (50 / 2) + 1) {
268 		if (low_latency_mode)
269 			fail("Low latency mode is set, but video latency is > 50ms\n");
270 		else
271 			warn("Video latency is > 50ms\n");
272 	}
273 
274 	return 0;
275 }
276 
dal_req_current_latency_invalid(struct node * node,unsigned me,unsigned la,bool interactive)277 static int dal_req_current_latency_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
278 {
279 	struct cec_msg msg;
280 
281 	/* Test that there is no reply when the physical address operand is not the
282 	   physical address of the remote device. */
283 	cec_msg_init(&msg, me, la);
284 	cec_msg_request_current_latency(&msg, true, CEC_PHYS_ADDR_INVALID);
285 	fail_on_test(!transmit_timeout(node, &msg));
286 	fail_on_test(!timed_out(&msg));
287 
288 	return 0;
289 }
290 
291 const vec_remote_subtests dal_subtests{
292 	{ "Request Current Latency", CEC_LOG_ADDR_MASK_ALL, dal_request_current_latency },
293 	{ "Request Current Latency with invalid PA", CEC_LOG_ADDR_MASK_ALL, dal_req_current_latency_invalid },
294 };
295 
296 /* Audio Return Channel Control */
297 
pa_common_mask(__u16 pa1,__u16 pa2)298 static __u16 pa_common_mask(__u16 pa1, __u16 pa2)
299 {
300 	__u16 mask = 0xf000;
301 
302 	for (int i = 0; i < 3; i++) {
303 		if ((pa1 & mask) != (pa2 & mask))
304 			break;
305 		mask = (mask >> 4) | 0xf000;
306 	}
307 	return mask << 4;
308 }
pa_are_adjacent(__u16 pa1,__u16 pa2)309 static bool pa_are_adjacent(__u16 pa1, __u16 pa2)
310 {
311 	const __u16 mask = pa_common_mask(pa1, pa2);
312 	const __u16 trail_mask = ((~mask) & 0xffff) >> 4;
313 
314 	if (pa1 == CEC_PHYS_ADDR_INVALID || pa2 == CEC_PHYS_ADDR_INVALID || pa1 == pa2)
315 		return false;
316 	if ((pa1 & trail_mask) || (pa2 & trail_mask))
317 		return false;
318 	return !((pa1 & ~mask) && (pa2 & ~mask));
319 }
320 
pa_is_upstream_from(__u16 pa1,__u16 pa2)321 static bool pa_is_upstream_from(__u16 pa1, __u16 pa2)
322 {
323 	const __u16 mask = pa_common_mask(pa1, pa2);
324 
325 	if (pa1 == CEC_PHYS_ADDR_INVALID || pa2 == CEC_PHYS_ADDR_INVALID)
326 		return false;
327 	return !(pa1 & ~mask) && (pa2 & ~mask);
328 }
329 
arc_initiate_tx(struct node * node,unsigned me,unsigned la,bool interactive)330 static int arc_initiate_tx(struct node *node, unsigned me, unsigned la, bool interactive)
331 {
332 	/* Check if we are upstream from the device. If we are, then the device is
333 	   an HDMI source, which means that it is an ARC receiver, not a transmitter. */
334 	if (pa_is_upstream_from(node->phys_addr, node->remote[la].phys_addr))
335 		return NOTAPPLICABLE;
336 
337 	struct cec_msg msg;
338 
339 	/*
340 	 * Note that this is a special case: INITIATE_ARC can reply with two possible
341 	 * messages: CEC_MSG_REPORT_ARC_INITIATED or CEC_MSG_REPORT_ARC_TERMINATED.
342 	 * It's the only message that behaves like this.
343 	 */
344 	cec_msg_init(&msg, me, la);
345 	cec_msg_initiate_arc(&msg, true);
346 	fail_on_test(!transmit_timeout(node, &msg));
347 	if (timed_out(&msg)) {
348 		fail_on_test_v2(node->remote[la].cec_version, node->remote[la].sink_has_arc_tx);
349 		warn("Timed out waiting for Report ARC Initiated/Terminated.\n");
350 		return OK_PRESUMED;
351 	}
352 	if (unrecognized_op(&msg)) {
353 		fail_on_test_v2(node->remote[la].cec_version, node->remote[la].sink_has_arc_tx);
354 		return OK_NOT_SUPPORTED;
355 	}
356 	if (cec_msg_opcode(&msg) == CEC_MSG_REPORT_ARC_INITIATED) {
357 		fail_on_test(!pa_are_adjacent(node->phys_addr, node->remote[la].phys_addr));
358 		fail_on_test_v2(node->remote[la].cec_version, !node->remote[la].sink_has_arc_tx);
359 		node->remote[la].arc_initiated = true;
360 	}
361 	else if (cec_msg_opcode(&msg) == CEC_MSG_REPORT_ARC_TERMINATED)
362 		announce("Device supports ARC but is not ready to initiate.");
363 	else if (refused(&msg))
364 		return OK_REFUSED;
365 	else if (cec_msg_status_is_abort(&msg))
366 		return OK_PRESUMED;
367 
368 	return 0;
369 }
370 
arc_terminate_tx(struct node * node,unsigned me,unsigned la,bool interactive)371 static int arc_terminate_tx(struct node *node, unsigned me, unsigned la, bool interactive)
372 {
373 	/* Check if we are upstream from the device. If we are, then the device is
374 	   an HDMI source, which means that it is an ARC receiver, not a transmitter. */
375 	if (pa_is_upstream_from(node->phys_addr, node->remote[la].phys_addr))
376 		return NOTAPPLICABLE;
377 	if (!node->remote[la].arc_initiated)
378 		return NOTAPPLICABLE;
379 
380 	struct cec_msg msg;
381 
382 	cec_msg_init(&msg, me, la);
383 	cec_msg_terminate_arc(&msg, true);
384 	fail_on_test(!transmit_timeout(node, &msg));
385 	if (timed_out(&msg)) {
386 		warn("Timed out waiting for Report ARC Terminated.\n");
387 		return OK_PRESUMED;
388 	}
389 	fail_on_test(unrecognized_op(&msg));
390 	if (cec_msg_status_is_abort(&msg)) {
391 		warn("Received Feature Abort for Terminate ARC (but the message was recognized).\n");
392 		if (refused(&msg))
393 			return OK_REFUSED;
394 		return OK_PRESUMED;
395 	}
396 
397 	return 0;
398 }
399 
arc_initiate_rx(struct node * node,unsigned me,unsigned la,bool interactive)400 static int arc_initiate_rx(struct node *node, unsigned me, unsigned la, bool interactive)
401 {
402 	/* Check if the DUT is upstream from us. If it is, then it is an
403 	   HDMI sink, which means that it is an ARC transmitter, not receiver. */
404 	if (pa_is_upstream_from(node->remote[la].phys_addr, node->phys_addr))
405 		return NOTAPPLICABLE;
406 
407 	struct cec_msg msg;
408 
409 	cec_msg_init(&msg, me, la);
410 	cec_msg_request_arc_initiation(&msg, true);
411 
412 	bool unsupported = false;
413 
414 	fail_on_test(!transmit_timeout(node, &msg));
415 	if (timed_out(&msg) || unrecognized_op(&msg))
416 		unsupported = true;
417 	else if (cec_msg_status_is_abort(&msg)) {
418 		__u8 abort_msg, reason;
419 
420 		cec_ops_feature_abort(&msg, &abort_msg, &reason);
421 		if (reason == CEC_OP_ABORT_INCORRECT_MODE) {
422 			announce("The device supports ARC but is not ready to initiate.");
423 			return 0;
424 		}
425 
426 		warn("Device responded Feature Abort with unexpected abort reason. Assuming no ARC support.\n");
427 		unsupported = true;
428 	}
429 
430 	if (unsupported) {
431 		fail_on_test_v2(node->remote[la].cec_version, node->remote[la].source_has_arc_rx);
432 		return OK_NOT_SUPPORTED;
433 	}
434 	fail_on_test(!pa_are_adjacent(node->phys_addr, node->remote[la].phys_addr));
435 	fail_on_test_v2(node->remote[la].cec_version, !node->remote[la].source_has_arc_rx);
436 
437 	cec_msg_init(&msg, me, la);
438 	cec_msg_report_arc_initiated(&msg);
439 	fail_on_test(!transmit_timeout(node, &msg));
440 	fail_on_test(unrecognized_op(&msg));
441 	node->remote[la].arc_initiated = true;
442 
443 	return 0;
444 }
445 
arc_terminate_rx(struct node * node,unsigned me,unsigned la,bool interactive)446 static int arc_terminate_rx(struct node *node, unsigned me, unsigned la, bool interactive)
447 {
448 	/* Check if the DUT is upstream from us. If it is, then it is an
449 	   HDMI sink, which means that it is an ARC transmitter, not receiver. */
450 	if (pa_is_upstream_from(node->remote[la].phys_addr, node->phys_addr))
451 		return NOTAPPLICABLE;
452 	if (!node->remote[la].arc_initiated)
453 		return NOTAPPLICABLE;
454 
455 	struct cec_msg msg;
456 
457 	cec_msg_init(&msg, me, la);
458 	cec_msg_request_arc_termination(&msg, true);
459 	fail_on_test(!transmit_timeout(node, &msg));
460 	if (timed_out(&msg)) {
461 		warn("Timed out waiting for Terminate ARC.\n");
462 		return OK_PRESUMED;
463 	}
464 	fail_on_test(unrecognized_op(&msg));
465 	if (cec_msg_status_is_abort(&msg)) {
466 		warn("Received Feature Abort for Request ARC Termination (but the message was recognized).\n");
467 		if (refused(&msg))
468 			return OK_REFUSED;
469 		return OK_PRESUMED;
470 	}
471 
472 	cec_msg_init(&msg, me, la);
473 	cec_msg_report_arc_terminated(&msg);
474 	fail_on_test(!transmit_timeout(node, &msg));
475 	fail_on_test(unrecognized_op(&msg));
476 
477 	return 0;
478 }
479 
480 const vec_remote_subtests arc_subtests{
481 	{ "Initiate ARC (RX)", CEC_LOG_ADDR_MASK_ALL, arc_initiate_rx },
482 	{ "Terminate ARC (RX)", CEC_LOG_ADDR_MASK_ALL, arc_terminate_rx },
483 	{ "Initiate ARC (TX)", CEC_LOG_ADDR_MASK_ALL, arc_initiate_tx },
484 	{ "Terminate ARC (TX)", CEC_LOG_ADDR_MASK_ALL, arc_terminate_tx },
485 };
486 
487 /* System Audio Control */
488 
489 /*
490  * The following scenarios are defined in section 13.15 of the CEC 1.4
491  * specification.
492  *
493  * These are not tested as they need three CEC devices.  An amplifier
494  * provides the audio for a source that is being displayed on a TV.
495  *
496  * 1.  Amplifier initiated <System Audio Mode Request> and active source
497  *     discovery with a <Request Active Source> broadcast plus the
498  *     <Active Source> response.
499  * 2.  Post discovery, subsequent amplifier <Set System Audio Mode> [On]
500  *     and System Audio Control feature confirmation with TV.
501  * 3.  Amplifier broadcasts <Set System Audio Mode> [On] to mute the TV and
502  *     unmute amplifier.
503  * 4.  Amplifier broadcasts <Set System Audio Mode> [Off] to unmute the TV
504  *     and mute the amplifier.
505  * 5.  When System Audio Mode is On, muting and unmuting an amplifier sends
506  *     a <Report Audio Status> message to the TV.
507  * 6.  When System Audio Mode is On, the amplifier sends a <Set System Audio
508  *     Mode> [Off] to unmute the TV before going into standby.
509  * 7.  When System Audio Mode is On, only the amplifier can control system
510  *     volume.
511  *
512  * These are not tested as they are hard-to-test corner cases.
513  *
514  * 1.  Optional features in subsection 13.15.4 of version 1.4.
515  *
516  * These are not tested as they deal with 1.3a or older versions and is not
517  * worth spending time on.
518  *
519  * 1.  <Request Audio Descriptor> message is from version 1.4 so older versions
520  *     report <Feature Abort>.
521  * 2.  <Report Audio Descriptor> message is from version 1.4 so older versions
522  *     report <Feature Abort>.
523  * 3.  System Audio Control is from version 1.3a so older versions report
524  *     <Feature Abort>.
525  */
526 
sac_request_sad_probe(struct node * node,unsigned me,unsigned la,bool interactive)527 static int sac_request_sad_probe(struct node *node, unsigned me, unsigned la, bool interactive)
528 {
529 	struct cec_msg msg;
530 	__u8 audio_format_id = 0;
531 	__u8 audio_format_code = 1;
532 
533 	cec_msg_init(&msg, me, la);
534 	cec_msg_request_short_audio_descriptor(&msg, true, 1, &audio_format_id, &audio_format_code);
535 	fail_on_test(!transmit_timeout(node, &msg));
536 	fail_on_test(timed_out(&msg));
537 	if (unrecognized_op(&msg))
538 		return OK_NOT_SUPPORTED;
539 	if (refused(&msg))
540 		return OK_REFUSED;
541 	if (cec_msg_status_is_abort(&msg))
542 		return OK_PRESUMED;
543 	node->remote[la].has_sad = true;
544 
545 	return 0;
546 }
547 
sac_request_sad_invalid(struct node * node,unsigned me,unsigned la,bool interactive)548 static int sac_request_sad_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
549 {
550 	if (!node->remote[la].has_sad)
551 		return NOTAPPLICABLE;
552 
553 	struct cec_msg msg;
554 	__u8 audio_format_id = CEC_OP_AUD_FMT_ID_CEA861;
555 	__u8 audio_format_code = 63; // This is outside the range of CEA861-F
556 
557 	cec_msg_init(&msg, me, la);
558 	cec_msg_request_short_audio_descriptor(&msg, true, 1, &audio_format_id, &audio_format_code);
559 	fail_on_test(!transmit_timeout(node, &msg));
560 	fail_on_test(timed_out(&msg));
561 	fail_on_test(!cec_msg_status_is_abort(&msg));
562 	if (abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP) {
563 		warn("Expected Feature Abort [Invalid operand] in reply to Request Short\n");
564 		warn("Audio Descriptor with invalid audio format as operand.\n");
565 	}
566 
567 	return 0;
568 }
569 
sac_sad_format_check(struct node * node,unsigned me,unsigned la,bool interactive)570 static int sac_sad_format_check(struct node *node, unsigned me, unsigned la, bool interactive)
571 {
572 	if (!node->remote[la].has_sad)
573 		return NOTAPPLICABLE;
574 
575 	struct cec_msg msg;
576 	__u8 audio_format_id;
577 	__u8 audio_format_code;
578 
579 	for (unsigned int id = 0; id <= 1; id++) {
580 		audio_format_id = id;
581 		for (unsigned int fmt_code = 1; fmt_code <= 14; fmt_code++) {
582 			audio_format_code = fmt_code;
583 
584 			cec_msg_init(&msg, me, la);
585 			cec_msg_request_short_audio_descriptor(&msg, true, 1, &audio_format_id, &audio_format_code);
586 			fail_on_test(!transmit_timeout(node, &msg));
587 			fail_on_test(timed_out(&msg));
588 			fail_on_test(unrecognized_op(&msg) || refused(&msg));
589 
590 			if (cec_msg_status_is_abort(&msg) &&
591 			    abort_reason(&msg) == CEC_OP_ABORT_INVALID_OP)
592 				continue;
593 
594 			__u8 num_descriptors;
595 			__u32 descriptors[4] = {};
596 
597 			cec_ops_report_short_audio_descriptor(&msg, &num_descriptors, descriptors);
598 			fail_on_test(num_descriptors == 0);
599 			if (id == 1 && node->remote[la].cec_version < CEC_OP_CEC_VERSION_2_0)
600 				warn("The device has CEC version < 2.0 but reports audio format(s) introduced in CEC 2.0.\n");
601 
602 			for (int j = 0; j < num_descriptors; j++) {
603 				struct short_audio_desc sad = {};
604 
605 				sad_decode(&sad, descriptors[j]);
606 				if ((id == 0 && sad.format_code != fmt_code) ||
607 				    (id == 1 && sad.extension_type_code != fmt_code))
608 					return fail("Different audio format code reported than requested.\n");
609 				info("Supports format %s\n", short_audio_desc2s(sad).c_str());
610 
611 				/* We need to store the ID and Code for one of the audio formats found,
612 				   for use in later test(s) */
613 				node->remote[la].supp_format_id = audio_format_id;
614 				node->remote[la].supp_format_code = audio_format_code;
615 			}
616 		}
617 	}
618 
619 	return 0;
620 }
621 
sac_sad_req_multiple(struct node * node,unsigned me,unsigned la,bool interactive)622 static int sac_sad_req_multiple(struct node *node, unsigned me, unsigned la, bool interactive)
623 {
624 	if (!node->remote[la].has_sad || node->remote[la].supp_format_code == 0)
625 		return NOTAPPLICABLE;
626 
627 	/* Check that if we got a response to a Request Short Audio Descriptor
628 	   with a single format, we also get a response when the same audio format
629 	   occurs in a request together with other formats. */
630 	struct cec_msg msg;
631 	__u8 audio_format_id[4] = { };
632 	__u8 audio_format_code[4];
633 
634 	for (int i = 0; i < 4; i++) {
635 		if (node->remote[la].supp_format_code <= 12)
636 			audio_format_code[i] = node->remote[la].supp_format_code - 1 + i;
637 		else
638 			audio_format_code[i] = node->remote[la].supp_format_code - 1 - i;
639 	}
640 	cec_msg_init(&msg, me, la);
641 	cec_msg_request_short_audio_descriptor(&msg, true, 4, audio_format_id, audio_format_code);
642 	fail_on_test(!transmit_timeout(node, &msg));
643 	fail_on_test(timed_out(&msg));
644 	fail_on_test(cec_msg_status_is_abort(&msg));
645 
646 	return 0;
647 }
648 
sac_set_system_audio_mode_direct(struct node * node,unsigned me,unsigned la,bool interactive)649 static int sac_set_system_audio_mode_direct(struct node *node, unsigned me, unsigned la, bool interactive)
650 {
651 	struct cec_msg msg;
652 
653 	cec_msg_init(&msg, me, la);
654 	cec_msg_set_system_audio_mode(&msg, CEC_OP_SYS_AUD_STATUS_ON);
655 	fail_on_test(!transmit_timeout(node, &msg));
656 	fail_on_test_v2(node->remote[la].cec_version,
657 			unrecognized_op(&msg) && is_tv(la, node->remote[la].prim_type));
658 	if (unrecognized_op(&msg))
659 		return OK_NOT_SUPPORTED;
660 	if (refused(&msg))
661 		return OK_REFUSED;
662 	node->remote[la].has_set_sys_audio_mode = true;
663 
664 	return OK_PRESUMED;
665 }
666 
sac_set_system_audio_mode_broadcast_on(struct node * node,unsigned me,unsigned la,bool interactive)667 static int sac_set_system_audio_mode_broadcast_on(struct node *node, unsigned me, unsigned la, bool interactive)
668 {
669 	struct cec_msg msg;
670 
671 	cec_msg_init(&msg, me, CEC_LOG_ADDR_BROADCAST);
672 	cec_msg_set_system_audio_mode(&msg, CEC_OP_SYS_AUD_STATUS_ON);
673 	fail_on_test(!transmit_timeout(node, &msg));
674 
675 	return OK_PRESUMED;
676 }
677 
sac_system_audio_mode_status(struct node * node,unsigned me,unsigned la,bool interactive)678 static int sac_system_audio_mode_status(struct node *node, unsigned me, unsigned la, bool interactive)
679 {
680 	struct cec_msg msg;
681 
682 	/* The device shall not feature abort System Audio Status if it did not
683 	   feature abort Set System Audio Mode.
684 
685 	   The message is mandatory for TVs in CEC 2.0. */
686 	cec_msg_init(&msg, me, la);
687 	cec_msg_system_audio_mode_status(&msg, CEC_OP_SYS_AUD_STATUS_ON);
688 	fail_on_test(!transmit_timeout(node, &msg));
689 	fail_on_test_v2(node->remote[la].cec_version,
690 			is_tv(la, node->remote[la].prim_type) && unrecognized_op(&msg));
691 	if (unrecognized_op(&msg) && !node->remote[la].has_set_sys_audio_mode)
692 		return OK_NOT_SUPPORTED;
693 	fail_on_test(unrecognized_op(&msg));
694 	if (refused(&msg))
695 		return OK_REFUSED;
696 	if (cec_msg_status_is_abort(&msg))
697 		return OK_PRESUMED;
698 
699 	return 0;
700 }
701 
sac_set_system_audio_mode_broadcast_off(struct node * node,unsigned me,unsigned la,bool interactive)702 static int sac_set_system_audio_mode_broadcast_off(struct node *node, unsigned me, unsigned la, bool interactive)
703 {
704 	struct cec_msg msg;
705 
706 	cec_msg_init(&msg, me, CEC_LOG_ADDR_BROADCAST);
707 	cec_msg_set_system_audio_mode(&msg, CEC_OP_SYS_AUD_STATUS_OFF);
708 	fail_on_test(!transmit_timeout(node, &msg));
709 
710 	return OK_PRESUMED;
711 }
712 
sac_system_audio_mode_req_on(struct node * node,unsigned me,unsigned la,bool interactive)713 static int sac_system_audio_mode_req_on(struct node *node, unsigned me, unsigned la, bool interactive)
714 {
715 	struct cec_msg msg;
716 	__u8 status;
717 
718 	/* Send a System Audio Mode Request to the audio system. This notifies the
719 	   audio system that our device has SAC capabilities, so it should enable
720 	   the feature right away by sending Set System Audio Mode with On as status.
721 
722 	   The message is mandatory for audio systems in CEC 2.0. */
723 	cec_msg_init(&msg, me, la);
724 	cec_msg_system_audio_mode_request(&msg, true, node->phys_addr);
725 	fail_on_test(!transmit_timeout(node, &msg));
726 	fail_on_test(timed_out(&msg));
727 	fail_on_test_v2(node->remote[la].cec_version,
728 			cec_has_audiosystem(1 << la) && unrecognized_op(&msg));
729 	if (unrecognized_op(&msg))
730 		return OK_NOT_SUPPORTED;
731 	if (refused(&msg))
732 		return OK_REFUSED;
733 	if (cec_msg_status_is_abort(&msg))
734 		return OK_PRESUMED;
735 	node->remote[la].has_sys_audio_mode_req = true;
736 	cec_ops_set_system_audio_mode(&msg, &status);
737 	fail_on_test(status != CEC_OP_SYS_AUD_STATUS_ON);
738 
739 	return 0;
740 }
741 
sac_give_system_audio_mode_status(struct node * node,unsigned me,unsigned la,bool interactive)742 static int sac_give_system_audio_mode_status(struct node *node, unsigned me, unsigned la, bool interactive)
743 {
744 	struct cec_msg msg;
745 	__u8 system_audio_status;
746 
747 	/* The device shall not feature abort Give System Audio Mode Status if it did not
748 	   feature abort System Audio Mode Request.
749 
750 	   The message is mandatory for audio systems in CEC 2.0. */
751 	cec_msg_init(&msg, me, la);
752 	cec_msg_give_system_audio_mode_status(&msg, true);
753 	fail_on_test(!transmit_timeout(node, &msg));
754 	fail_on_test(timed_out(&msg));
755 	fail_on_test_v2(node->remote[la].cec_version,
756 			cec_has_audiosystem(1 << la) && unrecognized_op(&msg));
757 	if (unrecognized_op(&msg) && !node->remote[la].has_sys_audio_mode_req)
758 		return OK_NOT_SUPPORTED;
759 	fail_on_test(unrecognized_op(&msg));
760 	if (refused(&msg))
761 		return OK_REFUSED;
762 	if (cec_msg_status_is_abort(&msg))
763 		return OK_PRESUMED;
764 	cec_ops_system_audio_mode_status(&msg, &system_audio_status);
765 	fail_on_test(system_audio_status != CEC_OP_SYS_AUD_STATUS_ON);
766 
767 	return 0;
768 }
769 
sac_give_audio_status(struct node * node,unsigned me,unsigned la,bool interactive)770 static int sac_give_audio_status(struct node *node, unsigned me, unsigned la, bool interactive)
771 {
772 	struct cec_msg msg;
773 
774 	/* Give Audio Status is mandatory for audio systems in CEC 2.0, except
775 	   for systems that lack external controls for volume/mute status. */
776 	cec_msg_init(&msg, me, la);
777 	cec_msg_give_audio_status(&msg, true);
778 	fail_on_test(!transmit_timeout(node, &msg));
779 	fail_on_test(timed_out(&msg));
780 	fail_on_test_v2(node->remote[la].cec_version,
781 			cec_has_audiosystem(1 << la) && unrecognized_op(&msg));
782 	if (unrecognized_op(&msg))
783 		return OK_NOT_SUPPORTED;
784 	if (refused(&msg))
785 		return OK_REFUSED;
786 	if (cec_msg_status_is_abort(&msg))
787 		return OK_PRESUMED;
788 
789 	cec_ops_report_audio_status(&msg, &node->remote[la].mute, &node->remote[la].volume);
790 	fail_on_test(node->remote[la].volume > 100);
791 	info("Volume: %d %s\n", node->remote[la].volume, node->remote[la].mute ? "(muted)" : "");
792 
793 	return 0;
794 }
795 
sac_util_send_user_control_press(struct node * node,unsigned me,unsigned la,__u8 ui_cmd)796 static int sac_util_send_user_control_press(struct node *node, unsigned me, unsigned la, __u8 ui_cmd)
797 {
798 	struct cec_msg msg;
799 	struct cec_op_ui_command rc_press = {};
800 
801 	/* The device shall not feature abort
802 	     - User Control Pressed ["Volume Up"]
803 	     - User Control Pressed ["Volume Down"]
804 	     - User Control Pressed ["Mute"]
805 	   if it did not feature abort System Audio Mode Request.
806 
807 	   The messages are mandatory for audio systems and TVs in CEC 2.0,
808 	   and it is mandatory for audio systems to send Report Audio Status
809 	   back to the TV in CEC 2.0.
810 
811 	   It is recommended for devices to not send Report Audio Status back
812 	   more often than once every 500ms. We therefore sleep a second before
813 	   each User Control Pressed is sent. */
814 	bool got_response;
815 
816 	sleep(1);
817 	mode_set_follower(node);
818 	cec_msg_init(&msg, me, la);
819 	rc_press.ui_cmd = ui_cmd;
820 	cec_msg_user_control_pressed(&msg, &rc_press);
821 	fail_on_test(!transmit(node, &msg));
822 	cec_msg_init(&msg, me, la);
823 	cec_msg_user_control_released(&msg);
824 	fail_on_test(!transmit_timeout(node, &msg));
825 	got_response = util_receive(node, la, 1000, &msg,
826 				    CEC_MSG_USER_CONTROL_PRESSED, CEC_MSG_REPORT_AUDIO_STATUS) >= 0;
827 
828 	fail_on_test_v2(node->remote[la].cec_version, !got_response &&
829 			cec_has_audiosystem(1 << la));
830 	fail_on_test_v2(node->remote[la].cec_version, unrecognized_op(&msg) &&
831 			(is_tv(la, node->remote[la].prim_type) || cec_has_audiosystem(1 << la)));
832 	if (unrecognized_op(&msg) && !node->remote[la].has_sys_audio_mode_req)
833 		return OK_NOT_SUPPORTED;
834 	fail_on_test(unrecognized_op(&msg));
835 	if (refused(&msg))
836 		return OK_REFUSED;
837 	if (cec_msg_status_is_abort(&msg))
838 		return OK_PRESUMED;
839 	if (got_response) {
840 		cec_ops_report_audio_status(&msg, &node->remote[la].mute, &node->remote[la].volume);
841 		return 0;
842 	}
843 
844 	return OK_PRESUMED;
845 }
846 
sac_user_control_press_vol_up(struct node * node,unsigned me,unsigned la,bool interactive)847 static int sac_user_control_press_vol_up(struct node *node, unsigned me, unsigned la, bool interactive)
848 {
849 	__u8 ret, old_volume = node->remote[la].volume;
850 
851 	if ((ret = sac_util_send_user_control_press(node, me, la, 0x41)))
852 		return ret;
853 	/* Check that if not already at the highest, the volume was increased. */
854 	fail_on_test_v2(node->remote[la].cec_version,
855 			la == CEC_LOG_ADDR_AUDIOSYSTEM &&
856 			old_volume < 100 && node->remote[la].volume <= old_volume);
857 
858 	return 0;
859 }
860 
sac_user_control_press_vol_down(struct node * node,unsigned me,unsigned la,bool interactive)861 static int sac_user_control_press_vol_down(struct node *node, unsigned me, unsigned la, bool interactive)
862 {
863 	__u8 ret, old_volume = node->remote[la].volume;
864 
865 	if ((ret = sac_util_send_user_control_press(node, me, la, 0x42)))
866 		return ret;
867 	/* Check that if not already at the lowest, the volume was lowered. */
868 	fail_on_test_v2(node->remote[la].cec_version,
869 			la == CEC_LOG_ADDR_AUDIOSYSTEM &&
870 			old_volume > 0 && node->remote[la].volume >= old_volume);
871 
872 	return 0;
873 }
874 
sac_user_control_press_mute(struct node * node,unsigned me,unsigned la,bool interactive)875 static int sac_user_control_press_mute(struct node *node, unsigned me, unsigned la, bool interactive)
876 {
877 	__u8 ret, old_mute = node->remote[la].mute;
878 
879 	if ((ret = sac_util_send_user_control_press(node, me, la, 0x43)))
880 		return ret;
881 	/* Check that mute has been toggled from what it was before. */
882 	fail_on_test_v2(node->remote[la].cec_version,
883 			la == CEC_LOG_ADDR_AUDIOSYSTEM &&
884 			node->remote[la].mute == old_mute);
885 
886 	return 0;
887 }
888 
sac_user_control_press_mute_function(struct node * node,unsigned me,unsigned la,bool interactive)889 static int sac_user_control_press_mute_function(struct node *node, unsigned me, unsigned la, bool interactive)
890 {
891 	__u8 ret;
892 
893 	if ((ret = sac_util_send_user_control_press(node, me, la, 0x65)))
894 		return ret;
895 	fail_on_test_v2(node->remote[la].cec_version,
896 			la == CEC_LOG_ADDR_AUDIOSYSTEM &&
897 			node->remote[la].mute == CEC_OP_AUD_MUTE_STATUS_ON);
898 
899 	return 0;
900 }
901 
sac_user_control_press_restore_volume_function(struct node * node,unsigned me,unsigned la,bool interactive)902 static int sac_user_control_press_restore_volume_function(struct node *node, unsigned me, unsigned la, bool interactive)
903 {
904 	__u8 ret;
905 
906 	if ((ret = sac_util_send_user_control_press(node, me, la, 0x66)))
907 		return ret;
908 	fail_on_test_v2(node->remote[la].cec_version,
909 			la == CEC_LOG_ADDR_AUDIOSYSTEM &&
910 			node->remote[la].mute == CEC_OP_AUD_MUTE_STATUS_OFF);
911 
912 	return 0;
913 }
914 
sac_user_control_release(struct node * node,unsigned me,unsigned la,bool interactive)915 static int sac_user_control_release(struct node *node, unsigned me, unsigned la, bool interactive)
916 {
917 	struct cec_msg msg;
918 
919 	/* The device shall not feature abort User Control Released if it did not
920 	   feature abort System Audio Mode Request
921 
922 	   The message is mandatory for audio systems and TVs in CEC 2.0. */
923 	cec_msg_init(&msg, me, la);
924 	cec_msg_user_control_released(&msg);
925 	fail_on_test(!transmit_timeout(node, &msg));
926 	fail_on_test_v2(node->remote[la].cec_version, unrecognized_op(&msg) &&
927 			(is_tv(la, node->remote[la].prim_type) || cec_has_audiosystem(1 << la)));
928 	if (unrecognized_op(&msg) && !node->remote[la].has_sys_audio_mode_req)
929 		return OK_NOT_SUPPORTED;
930 	fail_on_test(unrecognized_op(&msg));
931 	if (refused(&msg))
932 		return OK_REFUSED;
933 	if (cec_msg_status_is_abort(&msg))
934 		return OK_PRESUMED;
935 
936 	return OK_PRESUMED;
937 }
938 
sac_system_audio_mode_req_off(struct node * node,unsigned me,unsigned la,bool interactive)939 static int sac_system_audio_mode_req_off(struct node *node, unsigned me, unsigned la, bool interactive)
940 {
941 	if (!node->remote[la].has_sys_audio_mode_req)
942 		return NOTAPPLICABLE;
943 
944 	struct cec_msg msg;
945 	__u8 status;
946 
947 	cec_msg_init(&msg, me, la);
948 	cec_msg_system_audio_mode_request(&msg, true, CEC_PHYS_ADDR_INVALID);
949 	fail_on_test(!transmit_timeout(node, &msg));
950 	fail_on_test(timed_out(&msg));
951 	fail_on_test_v2(node->remote[la].cec_version,
952 			cec_has_audiosystem(1 << la) && unrecognized_op(&msg));
953 	if (unrecognized_op(&msg))
954 		return OK_NOT_SUPPORTED;
955 	if (refused(&msg))
956 		return OK_REFUSED;
957 	if (cec_msg_status_is_abort(&msg))
958 		return OK_PRESUMED;
959 	cec_ops_set_system_audio_mode(&msg, &status);
960 	fail_on_test(status != CEC_OP_SYS_AUD_STATUS_OFF);
961 
962 	return 0;
963 }
964 
965 const vec_remote_subtests sac_subtests{
966 	{
967 		"Request Short Audio Descriptor",
968 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
969 		sac_request_sad_probe,
970 	},
971 	{
972 		"Request Short Audio Descriptor, invalid",
973 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
974 		sac_request_sad_invalid,
975 	},
976 	{
977 		"Report Short Audio Descriptor consistency",
978 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
979 		sac_sad_format_check,
980 	},
981 	{
982 		"Report Short Audio Descriptor, multiple requests in one",
983 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
984 		sac_sad_req_multiple,
985 	},
986 	{
987 		"Set System Audio Mode (directly addressed)",
988 		CEC_LOG_ADDR_MASK_TV,
989 		sac_set_system_audio_mode_direct,
990 	},
991 	{
992 		"Set System Audio Mode (broadcast on)",
993 		CEC_LOG_ADDR_MASK_TV,
994 		sac_set_system_audio_mode_broadcast_on,
995 	},
996 	{
997 		"System Audio Mode Status",
998 		CEC_LOG_ADDR_MASK_TV,
999 		sac_system_audio_mode_status,
1000 	},
1001 	{
1002 		"System Audio Mode Request (on)",
1003 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1004 		sac_system_audio_mode_req_on,
1005 	},
1006 	{
1007 		"Give System Audio Mode Status",
1008 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1009 		sac_give_system_audio_mode_status,
1010 	},
1011 	{
1012 		"Give Audio Status",
1013 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1014 		sac_give_audio_status,
1015 	},
1016 	{
1017 		"User Control Pressed (Volume Up)",
1018 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1019 		sac_user_control_press_vol_up,
1020 	},
1021 	{
1022 		"User Control Pressed (Volume Down)",
1023 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1024 		sac_user_control_press_vol_down,
1025 	},
1026 	{
1027 		"User Control Pressed (Mute)",
1028 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1029 		sac_user_control_press_mute,
1030 	},
1031 	{
1032 		"User Control Pressed (Restore Volume Function)",
1033 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1034 		sac_user_control_press_restore_volume_function,
1035 	},
1036 	{
1037 		"User Control Pressed (Mute Function)",
1038 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1039 		sac_user_control_press_mute_function,
1040 	},
1041 	{
1042 		"User Control Released (Audio)",
1043 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM | CEC_LOG_ADDR_MASK_TV,
1044 		sac_user_control_release,
1045 	},
1046 	{
1047 		"Set System Audio Mode (broadcast off)",
1048 		CEC_LOG_ADDR_MASK_TV,
1049 		sac_set_system_audio_mode_broadcast_off,
1050 	},
1051 	{
1052 		"System Audio Mode Request (off)",
1053 		CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1054 		sac_system_audio_mode_req_off,
1055 	},
1056 };
1057 
1058 /* Audio Rate Control */
1059 
audio_rate_ctl_set_audio_rate(struct node * node,unsigned me,unsigned la,bool interactive)1060 static int audio_rate_ctl_set_audio_rate(struct node *node, unsigned me, unsigned la, bool interactive)
1061 {
1062 	struct cec_msg msg;
1063 
1064 	cec_msg_init(&msg, me, la);
1065 	cec_msg_set_audio_rate(&msg, CEC_OP_AUD_RATE_WIDE_STD);
1066 	fail_on_test(!transmit_timeout(node, &msg));
1067 	/* CEC 2.0: Devices shall use the device feature bit to indicate support. */
1068 	fail_on_test_v2(node->remote[la].cec_version,
1069 			node->remote[la].has_aud_rate && unrecognized_op(&msg));
1070 	fail_on_test_v2(node->remote[la].cec_version,
1071 			!node->remote[la].has_aud_rate && !unrecognized_op(&msg));
1072 	if (unrecognized_op(&msg))
1073 		return OK_NOT_SUPPORTED;
1074 	if (refused(&msg))
1075 		return OK_REFUSED;
1076 
1077 	return OK_PRESUMED;
1078 }
1079 
audio_rate_ctl_active_sensing(struct node * node,unsigned me,unsigned la,bool interactive)1080 static int audio_rate_ctl_active_sensing(struct node *node, unsigned me, unsigned la, bool interactive)
1081 {
1082 	/*
1083 	 * The source shall go back to Rate Control Off if no Set Audio Rate message is
1084 	 * received for more than 2 seconds.
1085 	 */
1086 	if (!node->remote[la].has_aud_rate)
1087 		return NOTAPPLICABLE;
1088 
1089 	struct cec_msg msg;
1090 
1091 	cec_msg_init(&msg, me, la);
1092 
1093 	/*
1094 	 * Since this subtest runs immediately after Set Audio Rate, delaying the interval
1095 	 * between the two tests is sufficient to test that the Source turns off rate control.
1096 	 */
1097 	sleep(3);
1098 	cec_msg_set_audio_rate(&msg, CEC_OP_AUD_RATE_OFF);
1099 	fail_on_test(!transmit_timeout(node, &msg));
1100 	fail_on_test_v2(node->remote[la].cec_version, unrecognized_op(&msg));
1101 	return OK_PRESUMED;
1102 }
1103 
audio_rate_ctl_invalid(struct node * node,unsigned me,unsigned la,bool interactive)1104 static int audio_rate_ctl_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
1105 {
1106 	if (!node->remote[la].has_aud_rate)
1107 		return NOTAPPLICABLE;
1108 
1109 	struct cec_msg msg;
1110 
1111 	cec_msg_init(&msg, me, la);
1112 	cec_msg_set_audio_rate(&msg, 0xa); /* Invalid Audio Rate Control message operand */
1113 	fail_on_test(!transmit_timeout(node, &msg));
1114 	fail_on_test(timed_out(&msg));
1115 	fail_on_test(!cec_msg_status_is_abort(&msg));
1116 	if (abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP) {
1117 		warn("Expected Feature Abort [Invalid operand]\n");
1118 		return FAIL;
1119 	}
1120 	return OK;
1121 }
1122 
1123 const vec_remote_subtests audio_rate_ctl_subtests{
1124 	{
1125 		"Set Audio Rate",
1126 		CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD |
1127 		CEC_LOG_ADDR_MASK_TUNER | CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1128 		audio_rate_ctl_set_audio_rate,
1129 	},
1130 	{
1131 		"Audio Rate Active Sensing",
1132 		CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD |
1133 		CEC_LOG_ADDR_MASK_TUNER | CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1134 		audio_rate_ctl_active_sensing,
1135 	},
1136 	{
1137 		"Audio Rate Invalid Operand",
1138 		CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD |
1139 		CEC_LOG_ADDR_MASK_TUNER | CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
1140 		audio_rate_ctl_invalid,
1141 	},
1142 };
1143