• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <linux/cec-funcs.h>
12 #include "cec-htng-funcs.h"
13 
14 #include <cec-info.h>
15 #include <cec-log.h>
16 #include <set>
17 #include <ctime>
18 
19 extern bool show_info;
20 extern bool show_msgs;
21 extern bool show_state;
22 extern bool show_warnings;
23 extern unsigned warnings;
24 extern std::set<struct Timer> programmed_timers;
25 extern void print_timers(struct node *node);
26 
27 struct state {
28 	__u16 active_source_pa;
29 	__u8 old_power_status;
30 	__u8 power_status;
31 	time_t power_status_changed_time;
32 	char menu_language[4];
33 	__u8 video_latency;
34 	__u8 low_latency_mode;
35 	__u8 audio_out_compensated;
36 	__u8 audio_out_delay;
37 	bool arc_active;
38 	bool sac_active;
39 	__u8 volume;
40 	bool mute;
41 	unsigned rc_state;
42 	__u8 rc_ui_cmd;
43 	__u64 rc_press_rx_ts;
44 	unsigned rc_press_hold_count;
45 	unsigned rc_duration_sum;
46 	struct cec_op_tuner_device_info tuner_dev_info;
47 	unsigned int service_idx;
48 	bool service_by_dig_id;
49 	bool tuner_report_changes;
50 	bool deck_report_changes;
51 	__u8 deck_report_changes_to;
52 	__u8 deck_state;
53 	__u64 deck_skip_start;
54 	bool one_touch_record_on;
55 	bool record_received_standby;
56 	int media_space_available;
57 	bool recording_controlled_by_timer;
58 	time_t toggle_power_status;
59 	__u64 last_aud_rate_rx_ts;
60 };
61 
62 struct node {
63 	int fd;
64 	const char *device;
65 	unsigned caps;
66 	unsigned available_log_addrs;
67 	__u8 remote_prim_devtype[15];
68 	unsigned adap_la_mask;
69 	unsigned remote_la_mask;
70 	__u16 remote_phys_addr[15];
71 	struct state state;
72 	__u16 phys_addr;
73 	__u8 cec_version;
74 	bool source_has_arc_rx;
75 	bool sink_has_arc_tx;
76 	bool has_aud_rate;
77 	bool has_deck_ctl;
78 	bool has_rec_tv;
79 	bool has_osd_string;
80 
81 	bool ignore_la[16];
82 	unsigned short ignore_opcode[256];
83 	unsigned standby_cnt;
84 	unsigned ignore_standby;
85 	unsigned view_on_cnt;
86 	unsigned ignore_view_on;
87 };
88 
89 struct Timer {
90 	time_t start_time;
91 	int duration; /* In seconds. */
92 	__u8 recording_seq;
93 	struct cec_op_record_src src;
94 
TimerTimer95 	Timer()
96 	{
97 		start_time = 0;
98 		duration = 0;
99 		recording_seq = 0;
100 		src = {};
101 	}
102 
TimerTimer103 	Timer(const Timer& timer)
104 	{
105 		start_time = timer.start_time;
106 		duration = timer.duration;
107 		recording_seq = timer.recording_seq;
108 		src = timer.src;
109 	}
110 
111 	bool operator<(const Timer &r) const
112 	{
113 		return start_time < r.start_time ||
114 		       (start_time == r.start_time && duration < r.duration) ||
115 		       (start_time == r.start_time && duration == r.duration && src.type < r.src.type) ||
116 		       (start_time == r.start_time && duration == r.duration && src.type == r.src.type &&
117 		       recording_seq < r.recording_seq);
118 	}
119 
120 	bool operator==(const Timer &right) const
121 	{
122 		return start_time == right.start_time && duration == right.duration &&
123 		       src.type == right.src.type && recording_seq == right.recording_seq;
124 	}
125 };
126 
127 struct la_info {
128 	__u64 ts;
129 	struct {
130 		unsigned count;
131 		__u64 ts;
132 	} feature_aborted[256];
133 	__u16 phys_addr;
134 };
135 
136 extern struct la_info la_info[15];
137 
138 struct short_audio_desc {
139 	/* Byte 1 */
140 	__u8 num_channels;
141 	__u8 format_code;
142 
143 	/* Byte 2 */
144 	__u8 sample_freq_mask;
145 
146 	/* Byte 3 */
147 	union {
148 		__u8 bit_depth_mask;    // LPCM
149 		__u8 max_bitrate;       // Format codes 2-8
150 		__u8 format_dependent;  // Format codes 9-13
151 		__u8 wma_profile;       // WMA Pro
152 		__u8 frame_length_mask; // Extension type codes 4-6, 8-10
153 	};
154 	__u8 mps;                       // Format codes 8-10
155 	__u8 extension_type_code;
156 };
157 
158 #define SAD_FMT_CODE_LPCM 		1
159 #define SAD_FMT_CODE_AC3		2
160 #define SAD_FMT_CODE_MPEG1		3
161 #define SAD_FMT_CODE_MP3 		4
162 #define SAD_FMT_CODE_MPEG2 		5
163 #define SAD_FMT_CODE_AAC_LC 		6
164 #define SAD_FMT_CODE_DTS 		7
165 #define SAD_FMT_CODE_ATRAC 		8
166 #define SAD_FMT_CODE_ONE_BIT_AUDIO	9
167 #define SAD_FMT_CODE_ENHANCED_AC3	10
168 #define SAD_FMT_CODE_DTS_HD 		11
169 #define SAD_FMT_CODE_MAT 		12
170 #define SAD_FMT_CODE_DST 		13
171 #define SAD_FMT_CODE_WMA_PRO 		14
172 #define SAD_FMT_CODE_EXTENDED 		15
173 
174 #define SAD_BIT_DEPTH_MASK_16 		1
175 #define SAD_BIT_DEPTH_MASK_20 		(1 << 1)
176 #define SAD_BIT_DEPTH_MASK_24 		(1 << 2)
177 
178 #define SAD_SAMPLE_FREQ_MASK_32 	1
179 #define SAD_SAMPLE_FREQ_MASK_44_1 	(1 << 1)
180 #define SAD_SAMPLE_FREQ_MASK_48 	(1 << 2)
181 #define SAD_SAMPLE_FREQ_MASK_88_2 	(1 << 3)
182 #define SAD_SAMPLE_FREQ_MASK_96 	(1 << 4)
183 #define SAD_SAMPLE_FREQ_MASK_176_4 	(1 << 5)
184 #define SAD_SAMPLE_FREQ_MASK_192 	(1 << 6)
185 
186 #define SAD_FRAME_LENGTH_MASK_960 	1
187 #define SAD_FRAME_LENGTH_MASK_1024	(1 << 1)
188 
189 #define SAD_EXT_TYPE_MPEG4_HE_AAC 		4
190 #define SAD_EXT_TYPE_MPEG4_HE_AACv2 		5
191 #define SAD_EXT_TYPE_MPEG4_AAC_LC 		6
192 #define SAD_EXT_TYPE_DRA 			7
193 #define SAD_EXT_TYPE_MPEG4_HE_AAC_SURROUND 	8
194 #define SAD_EXT_TYPE_MPEG4_AAC_LC_SURROUND	10
195 #define SAD_EXT_TYPE_MPEG_H_3D_AUDIO		11
196 #define SAD_EXT_TYPE_AC_4			12
197 #define SAD_EXT_TYPE_LPCM_3D_AUDIO		13
198 
199 #ifndef __FILE_NAME__
200 #define __FILE_NAME__ __FILE__
201 #endif
202 
203 #define info(fmt, args...) 					\
204 	do {							\
205 		if (show_info)					\
206 			printf("\t\tinfo: " fmt, ##args);	\
207 	} while (0)
208 
209 #define dev_info(fmt, args...)					\
210 	do {							\
211 		if (show_state)					\
212 			printf(">>> " fmt, ##args);		\
213 	} while(0)
214 
215 #define warn(fmt, args...) 					\
216 	do {							\
217 		warnings++;					\
218 		if (show_warnings)				\
219 			printf("\t\twarn: %s(%d): " fmt, __FILE_NAME__, __LINE__, ##args);	\
220 	} while (0)
221 
222 #define warn_once(fmt, args...)						\
223 	do {								\
224 		static bool show;					\
225 									\
226 		if (!show) {						\
227 			show = true;					\
228 			warnings++;					\
229 			if (show_warnings)				\
230 				printf("\t\twarn: %s(%d): " fmt,	\
231 					__FILE_NAME__, __LINE__, ##args); 	\
232 		}							\
233 	} while (0)
234 
235 int cec_named_ioctl(int fd, const char *name,
236 		    unsigned long int request, void *parm);
237 
238 #define doioctl(n, r, p) cec_named_ioctl((n)->fd, #r, r, p)
239 
240 #define transmit(n, m) (doioctl(n, CEC_TRANSMIT, m))
241 
ts_to_ms(__u64 ts)242 static inline unsigned ts_to_ms(__u64 ts)
243 {
244 	return ts / 1000000;
245 }
246 
ts_to_s(__u64 ts)247 static inline unsigned ts_to_s(__u64 ts)
248 {
249 	return ts / 1000000000;
250 }
251 
get_ts()252 static inline __u64 get_ts()
253 {
254 	struct timespec timespec;
255 
256 	clock_gettime(CLOCK_MONOTONIC, &timespec);
257 	return timespec.tv_sec * 1000000000ull + timespec.tv_nsec;
258 }
259 
260 const char *la2s(unsigned la);
261 const char *la_type2s(unsigned type);
262 const char *prim_type2s(unsigned type);
263 const char *version2s(unsigned version);
264 std::string status2s(const struct cec_msg &msg);
265 std::string all_dev_types2s(unsigned types);
266 std::string rc_src_prof2s(unsigned prof);
267 std::string dev_feat2s(unsigned feat);
268 std::string audio_format_id_code2s(__u8 audio_format_id, __u8 audio_format_code);
269 std::string opcode2s(const struct cec_msg *msg);
270 void sad_encode(const struct short_audio_desc *sad, __u32 *descriptor);
271 
272 // cec-tuner.cpp
273 void tuner_dev_info_init(struct state *state);
274 void process_tuner_msgs(struct node *node, struct cec_msg &msg, unsigned me, __u8 type);
275 void process_record_msgs(struct node *node, struct cec_msg &msg, unsigned me, __u8 type);
276 void process_timer_msgs(struct node *node, struct cec_msg &msg, unsigned me, __u8 type);
277 
278 // CEC processing
279 void reply_feature_abort(struct node *node, struct cec_msg *msg,
280 			 __u8 reason = CEC_OP_ABORT_UNRECOGNIZED_OP);
281 void testProcessing(struct node *node, bool exclusive, bool wallclock);
282 bool enter_standby(struct node *node);
283 
284 #endif
285