1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2 /*
3  * CEC API follower test tool.
4  *
5  * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  */
7 
8 #ifndef _CEC_FOLLOWER_H_
9 #define _CEC_FOLLOWER_H_
10 
11 #include <stdarg.h>
12 #include <ctime>
13 #include <cerrno>
14 #include <string>
15 #include <linux/cec-funcs.h>
16 #include "cec-htng-funcs.h"
17 
18 #ifdef ANDROID
19 #include <android-config.h>
20 #else
21 #include <config.h>
22 #endif
23 
24 #include <cec-info.h>
25 #include <cec-log.h>
26 
27 #define ARRAY_SIZE(a) \
28 	(sizeof(a) / sizeof(*a))
29 
30 extern bool show_info;
31 extern bool show_msgs;
32 extern bool show_state;
33 extern bool show_warnings;
34 extern unsigned warnings;
35 
36 struct state {
37 	uint16_t active_source_pa;
38 	uint8_t old_power_status;
39 	uint8_t power_status;
40 	time_t power_status_changed_time;
41 	char menu_language[4];
42 	uint8_t video_latency;
43 	uint8_t low_latency_mode;
44 	uint8_t audio_out_compensated;
45 	uint8_t audio_out_delay;
46 	bool arc_active;
47 	bool sac_active;
48 	uint8_t volume;
49 	bool mute;
50 	unsigned rc_state;
51 	uint8_t rc_ui_cmd;
52 	uint64_t rc_press_rx_ts;
53 	unsigned rc_press_hold_count;
54 	unsigned rc_duration_sum;
55 	struct cec_op_tuner_device_info tuner_dev_info;
56 	unsigned int service_idx;
57 	bool service_by_dig_id;
58 	bool tuner_report_changes;
59 	bool deck_report_changes;
60 };
61 
62 struct node {
63 	int fd;
64 	const char *device;
65 	unsigned caps;
66 	unsigned available_log_addrs;
67 	unsigned adap_la_mask;
68 	unsigned remote_la_mask;
69 	uint16_t remote_phys_addr[15];
70 	struct state state;
71 	uint16_t phys_addr;
72 	uint8_t cec_version;
73 	bool source_has_arc_rx;
74 	bool sink_has_arc_tx;
75 	bool has_aud_rate;
76 	bool has_deck_ctl;
77 	bool has_rec_tv;
78 	bool has_osd_string;
79 
80 	bool ignore_la[16];
81 	unsigned short ignore_opcode[256];
82 };
83 
84 struct la_info {
85 	uint64_t ts;
86 	struct {
87 		unsigned count;
88 		uint64_t ts;
89 	} feature_aborted[256];
90 	uint16_t phys_addr;
91 };
92 
93 extern struct la_info la_info[15];
94 
95 struct short_audio_desc {
96 	/* Byte 1 */
97 	uint8_t num_channels;
98 	uint8_t format_code;
99 
100 	/* Byte 2 */
101 	uint8_t sample_freq_mask;
102 
103 	/* Byte 3 */
104 	union {
105 		uint8_t bit_depth_mask;    // LPCM
106 		uint8_t max_bitrate;       // Format codes 2-8
107 		uint8_t format_dependent;  // Format codes 9-13
108 		uint8_t wma_profile;       // WMA Pro
109 		uint8_t frame_length_mask; // Extension type codes 4-6, 8-10
110 	};
111 	uint8_t mps;                       // Format codes 8-10
112 	uint8_t extension_type_code;
113 };
114 
115 #define SAD_FMT_CODE_LPCM 		1
116 #define SAD_FMT_CODE_AC3		2
117 #define SAD_FMT_CODE_MPEG1		3
118 #define SAD_FMT_CODE_MP3 		4
119 #define SAD_FMT_CODE_MPEG2 		5
120 #define SAD_FMT_CODE_AAC_LC 		6
121 #define SAD_FMT_CODE_DTS 		7
122 #define SAD_FMT_CODE_ATRAC 		8
123 #define SAD_FMT_CODE_ONE_BIT_AUDIO	9
124 #define SAD_FMT_CODE_ENHANCED_AC3	10
125 #define SAD_FMT_CODE_DTS_HD 		11
126 #define SAD_FMT_CODE_MAT 		12
127 #define SAD_FMT_CODE_DST 		13
128 #define SAD_FMT_CODE_WMA_PRO 		14
129 #define SAD_FMT_CODE_EXTENDED 		15
130 
131 #define SAD_BIT_DEPTH_MASK_16 		1
132 #define SAD_BIT_DEPTH_MASK_20 		(1 << 1)
133 #define SAD_BIT_DEPTH_MASK_24 		(1 << 2)
134 
135 #define SAD_SAMPLE_FREQ_MASK_32 	1
136 #define SAD_SAMPLE_FREQ_MASK_44_1 	(1 << 1)
137 #define SAD_SAMPLE_FREQ_MASK_48 	(1 << 2)
138 #define SAD_SAMPLE_FREQ_MASK_88_2 	(1 << 3)
139 #define SAD_SAMPLE_FREQ_MASK_96 	(1 << 4)
140 #define SAD_SAMPLE_FREQ_MASK_176_4 	(1 << 5)
141 #define SAD_SAMPLE_FREQ_MASK_192 	(1 << 6)
142 
143 #define SAD_FRAME_LENGTH_MASK_960 	1
144 #define SAD_FRAME_LENGTH_MASK_1024	(1 << 1)
145 
146 #define SAD_EXT_TYPE_MPEG4_HE_AAC 		4
147 #define SAD_EXT_TYPE_MPEG4_HE_AACv2 		5
148 #define SAD_EXT_TYPE_MPEG4_AAC_LC 		6
149 #define SAD_EXT_TYPE_DRA 			7
150 #define SAD_EXT_TYPE_MPEG4_HE_AAC_SURROUND 	8
151 #define SAD_EXT_TYPE_MPEG4_AAC_LC_SURROUND	10
152 #define SAD_EXT_TYPE_MPEG_H_3D_AUDIO		11
153 #define SAD_EXT_TYPE_AC_4			12
154 #define SAD_EXT_TYPE_LPCM_3D_AUDIO		13
155 
156 #define info(fmt, args...) 					\
157 	do {							\
158 		if (show_info)					\
159 			printf("\t\tinfo: " fmt, ##args);	\
160 	} while (0)
161 
162 #define dev_info(fmt, args...)					\
163 	do {							\
164 		if (show_state)					\
165 			printf(">>> " fmt, ##args);		\
166 	} while(0)
167 
168 #define warn(fmt, args...) 					\
169 	do {							\
170 		warnings++;					\
171 		if (show_warnings)				\
172 			printf("\t\twarn: %s(%d): " fmt, __FILE__, __LINE__, ##args);	\
173 	} while (0)
174 
175 #define warn_once(fmt, args...)						\
176 	do {								\
177 		static bool show;					\
178 									\
179 		if (!show) {						\
180 			show = true;					\
181 			warnings++;					\
182 			if (show_warnings)				\
183 				printf("\t\twarn: %s(%d): " fmt,	\
184 					__FILE__, __LINE__, ##args); 	\
185 		}							\
186 	} while (0)
187 
188 int cec_named_ioctl(int fd, const char *name,
189 		    unsigned long int request, void *parm);
190 
191 #define doioctl(n, r, p) cec_named_ioctl((n)->fd, #r, r, p)
192 
193 #define transmit(n, m) (doioctl(n, CEC_TRANSMIT, m))
194 
ts_to_ms(uint64_t ts)195 static inline unsigned ts_to_ms(uint64_t ts)
196 {
197 	return ts / 1000000;
198 }
199 
ts_to_s(uint64_t ts)200 static inline unsigned ts_to_s(uint64_t ts)
201 {
202 	return ts / 1000000000;
203 }
204 
get_ts()205 static inline uint64_t get_ts()
206 {
207 	struct timespec timespec;
208 
209 	clock_gettime(CLOCK_MONOTONIC, &timespec);
210 	return timespec.tv_sec * 1000000000ull + timespec.tv_nsec;
211 }
212 
213 const char *la2s(unsigned la);
214 const char *la_type2s(unsigned type);
215 const char *prim_type2s(unsigned type);
216 const char *version2s(unsigned version);
217 std::string status2s(const struct cec_msg &msg);
218 std::string all_dev_types2s(unsigned types);
219 std::string rc_src_prof2s(unsigned prof);
220 std::string dev_feat2s(unsigned feat);
221 std::string audio_format_id_code2s(uint8_t audio_format_id, uint8_t audio_format_code);
222 std::string opcode2s(const struct cec_msg *msg);
223 void sad_encode(const struct short_audio_desc *sad, uint32_t *descriptor);
224 
225 // cec-tuner.cpp
226 void tuner_dev_info_init(struct state *state);
227 void process_tuner_record_timer_msgs(struct node *node, struct cec_msg &msg, unsigned me);
228 
229 // CEC processing
230 void reply_feature_abort(struct node *node, struct cec_msg *msg,
231 			 uint8_t reason = CEC_OP_ABORT_UNRECOGNIZED_OP);
232 void testProcessing(struct node *node, bool wallclock);
233 
234 #endif
235