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, ×pec);
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