1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android/hardware/tv/tuner/1.0/types.h>
18 #include <binder/MemoryDealer.h>
19 #include <hidl/HidlSupport.h>
20 #include <hidl/HidlTransportSupport.h>
21 #include <hidl/Status.h>
22 #include <hidlmemory/FrameworkUtils.h>
23
24 using android::hardware::tv::tuner::V1_0::DataFormat;
25 using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
26 using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
27 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
28 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
29 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
30 using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
31 using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
32 using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
33 using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
34 using android::hardware::tv::tuner::V1_0::DemuxTpid;
35 using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
36 using android::hardware::tv::tuner::V1_0::DvrSettings;
37 using android::hardware::tv::tuner::V1_0::DvrType;
38 using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
39 using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
40 using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
41 using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
42 using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
43 using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
44 using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
45 using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
46 using android::hardware::tv::tuner::V1_0::FrontendSettings;
47 using android::hardware::tv::tuner::V1_0::FrontendStatus;
48 using android::hardware::tv::tuner::V1_0::FrontendStatusType;
49 using android::hardware::tv::tuner::V1_0::FrontendType;
50 using android::hardware::tv::tuner::V1_0::LnbPosition;
51 using android::hardware::tv::tuner::V1_0::LnbTone;
52 using android::hardware::tv::tuner::V1_0::LnbVoltage;
53 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
54 using android::hardware::tv::tuner::V1_0::RecordSettings;
55
56 using namespace std;
57
58 const uint32_t FMQ_SIZE_1M = 0x100000;
59 const uint32_t FMQ_SIZE_4M = 0x400000;
60 const uint32_t FMQ_SIZE_16M = 0x1000000;
61
62 #define CLEAR_KEY_SYSTEM_ID 0xF6D8
63 #define FILTER_MAIN_TYPE_BIT_COUNT 32
64 #define PROVISION_STR \
65 "{ " \
66 " \"id\": 21140844, " \
67 " \"name\": \"Test Title\", " \
68 " \"lowercase_organization_name\": \"Android\", " \
69 " \"asset_key\": { " \
70 " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \
71 " }, " \
72 " \"cas_type\": 1, " \
73 " \"track_types\": [ ] " \
74 "} "
75
76 typedef enum {
77 TS_VIDEO0,
78 TS_VIDEO1,
79 TS_AUDIO0,
80 TS_PES0,
81 TS_PCR0,
82 TS_SECTION0,
83 TS_TS0,
84 TS_RECORD0,
85 FILTER_MAX,
86 } Filter;
87
88 typedef enum {
89 TIMER0,
90 TIMER_MAX,
91 } TimeFilter;
92
93 typedef enum {
94 SOURCE,
95 SINK,
96 LINKAGE_DIR,
97 } Linkage;
98
99 typedef enum {
100 DVBT,
101 DVBS,
102 FRONTEND_MAX,
103 } Frontend;
104
105 typedef enum {
106 LNB0,
107 LNB_EXTERNAL,
108 LNB_MAX,
109 } Lnb;
110
111 typedef enum {
112 DISEQC_POWER_ON,
113 DISEQC_MAX,
114 } Diseqc;
115
116 typedef enum {
117 SCAN_DVBT,
118 SCAN_MAX,
119 } FrontendScan;
120
121 typedef enum {
122 DVR_RECORD0,
123 DVR_PLAYBACK0,
124 DVR_SOFTWARE_FE,
125 DVR_MAX,
126 } Dvr;
127
128 typedef enum {
129 DESC_0,
130 DESC_MAX,
131 } Descrambler;
132
133 struct FilterConfig {
134 uint32_t bufferSize;
135 DemuxFilterType type;
136 DemuxFilterSettings settings;
137
138 bool operator<(const FilterConfig& /*c*/) const { return false; }
139 };
140
141 struct TimeFilterConfig {
142 bool supportTimeFilter;
143 uint64_t timeStamp;
144 };
145
146 struct FrontendConfig {
147 bool isSoftwareFe;
148 FrontendType type;
149 FrontendSettings settings;
150 vector<FrontendStatusType> tuneStatusTypes;
151 vector<FrontendStatus> expectTuneStatuses;
152 };
153
154 struct LnbConfig {
155 bool usingLnb;
156 string name;
157 LnbVoltage voltage;
158 LnbTone tone;
159 LnbPosition position;
160 };
161
162 struct ChannelConfig {
163 int32_t frontendId;
164 int32_t channelId;
165 std::string channelName;
166 DemuxTpid videoPid;
167 DemuxTpid audioPid;
168 };
169
170 struct DvrConfig {
171 DvrType type;
172 uint32_t bufferSize;
173 DvrSettings settings;
174 string playbackInputFile;
175 };
176
177 struct DescramblerConfig {
178 uint32_t casSystemId;
179 string provisionStr;
180 vector<uint8_t> hidlPvtData;
181 };
182
183 static FrontendConfig frontendArray[FILTER_MAX];
184 static FrontendConfig frontendScanArray[SCAN_MAX];
185 static LnbConfig lnbArray[LNB_MAX];
186 static vector<uint8_t> diseqcMsgArray[DISEQC_MAX];
187 static ChannelConfig channelArray[FRONTEND_MAX];
188 static FilterConfig filterArray[FILTER_MAX];
189 static TimeFilterConfig timeFilterArray[TIMER_MAX];
190 static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT];
191 static DvrConfig dvrArray[DVR_MAX];
192 static DescramblerConfig descramblerArray[DESC_MAX];
193 static vector<string> goldenOutputFiles;
194
195 /** Configuration array for the frontend tune test */
initFrontendConfig()196 inline void initFrontendConfig() {
197 FrontendDvbtSettings dvbtSettings{
198 .frequency = 578000,
199 .transmissionMode = FrontendDvbtTransmissionMode::AUTO,
200 .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
201 .constellation = FrontendDvbtConstellation::AUTO,
202 .hierarchy = FrontendDvbtHierarchy::AUTO,
203 .hpCoderate = FrontendDvbtCoderate::AUTO,
204 .lpCoderate = FrontendDvbtCoderate::AUTO,
205 .guardInterval = FrontendDvbtGuardInterval::AUTO,
206 .isHighPriority = true,
207 .standard = FrontendDvbtStandard::T,
208 };
209 frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
210 vector<FrontendStatusType> types;
211 types.push_back(FrontendStatusType::DEMOD_LOCK);
212 FrontendStatus status;
213 status.isDemodLocked(true);
214 vector<FrontendStatus> statuses;
215 statuses.push_back(status);
216 frontendArray[DVBT].tuneStatusTypes = types;
217 frontendArray[DVBT].expectTuneStatuses = statuses;
218 frontendArray[DVBT].isSoftwareFe = true;
219 frontendArray[DVBS].type = FrontendType::DVBS;
220 frontendArray[DVBS].isSoftwareFe = true;
221 };
222
223 /** Configuration array for the frontend scan test */
initFrontendScanConfig()224 inline void initFrontendScanConfig() {
225 frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT;
226 frontendScanArray[SCAN_DVBT].settings.dvbt({
227 .frequency = 578000,
228 .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K,
229 .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
230 .constellation = FrontendDvbtConstellation::AUTO,
231 .hierarchy = FrontendDvbtHierarchy::AUTO,
232 .hpCoderate = FrontendDvbtCoderate::AUTO,
233 .lpCoderate = FrontendDvbtCoderate::AUTO,
234 .guardInterval = FrontendDvbtGuardInterval::AUTO,
235 .isHighPriority = true,
236 .standard = FrontendDvbtStandard::T,
237 });
238 };
239
240 /** Configuration array for the Lnb test */
initLnbConfig()241 inline void initLnbConfig() {
242 lnbArray[LNB0].usingLnb = true;
243 lnbArray[LNB0].voltage = LnbVoltage::VOLTAGE_12V;
244 lnbArray[LNB0].tone = LnbTone::NONE;
245 lnbArray[LNB0].position = LnbPosition::UNDEFINED;
246 lnbArray[LNB_EXTERNAL].usingLnb = true;
247 lnbArray[LNB_EXTERNAL].name = "default_lnb_external";
248 lnbArray[LNB_EXTERNAL].voltage = LnbVoltage::VOLTAGE_5V;
249 lnbArray[LNB_EXTERNAL].tone = LnbTone::NONE;
250 lnbArray[LNB_EXTERNAL].position = LnbPosition::UNDEFINED;
251 };
252
253 /** Diseqc messages array for the Lnb test */
initDiseqcMsg()254 inline void initDiseqcMsg() {
255 diseqcMsgArray[DISEQC_POWER_ON] = {0xE, 0x0, 0x0, 0x0, 0x0, 0x3};
256 };
257
258 /** Configuration array for the filter test */
initFilterConfig()259 inline void initFilterConfig() {
260 // TS VIDEO filter setting for default implementation testing
261 filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS;
262 filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
263 filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M;
264 filterArray[TS_VIDEO0].settings.ts().tpid = 256;
265 filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false});
266 filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS;
267 filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
268 filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;
269 filterArray[TS_VIDEO1].settings.ts().tpid = 256;
270 filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false});
271 // TS AUDIO filter setting
272 filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS;
273 filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
274 filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M;
275 filterArray[TS_AUDIO0].settings.ts().tpid = 256;
276 filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false});
277 // TS PES filter setting
278 filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS;
279 filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES);
280 filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M;
281 filterArray[TS_PES0].settings.ts().tpid = 256;
282 filterArray[TS_PES0].settings.ts().filterSettings.pesData({
283 .isRaw = false,
284 .streamId = 0xbd,
285 });
286 // TS PCR filter setting
287 filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS;
288 filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR);
289 filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M;
290 filterArray[TS_PCR0].settings.ts().tpid = 256;
291 filterArray[TS_PCR0].settings.ts().filterSettings.noinit();
292 // TS filter setting
293 filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS;
294 filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS);
295 filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M;
296 filterArray[TS_TS0].settings.ts().tpid = 256;
297 filterArray[TS_TS0].settings.ts().filterSettings.noinit();
298 // TS SECTION filter setting
299 filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS;
300 filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION);
301 filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M;
302 filterArray[TS_SECTION0].settings.ts().tpid = 256;
303 filterArray[TS_SECTION0].settings.ts().filterSettings.section({
304 .isRaw = false,
305 });
306 // TS RECORD filter setting
307 filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS;
308 filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD);
309 filterArray[TS_RECORD0].settings.ts().tpid = 81;
310 filterArray[TS_RECORD0].settings.ts().filterSettings.record({
311 .scIndexType = DemuxRecordScIndexType::NONE,
312 });
313
314 // TS Linkage filter setting
315 filterLinkageTypes[SOURCE][0].mainType = DemuxFilterMainType::TS;
316 filterLinkageTypes[SOURCE][0].subType.tsFilterType(DemuxTsFilterType::TS);
317 filterLinkageTypes[SINK][0] = filterLinkageTypes[SOURCE][0];
318 // MMTP Linkage filter setting
319 filterLinkageTypes[SOURCE][1].mainType = DemuxFilterMainType::MMTP;
320 filterLinkageTypes[SOURCE][1].subType.mmtpFilterType(DemuxMmtpFilterType::AUDIO);
321 filterLinkageTypes[SINK][1] = filterLinkageTypes[SOURCE][1];
322 // IP Linkage filter setting
323 filterLinkageTypes[SOURCE][2].mainType = DemuxFilterMainType::IP;
324 filterLinkageTypes[SOURCE][2].subType.ipFilterType(DemuxIpFilterType::IP);
325 filterLinkageTypes[SINK][2] = filterLinkageTypes[SOURCE][2];
326 // TLV Linkage filter setting
327 filterLinkageTypes[SOURCE][3].mainType = DemuxFilterMainType::TLV;
328 filterLinkageTypes[SOURCE][3].subType.tlvFilterType(DemuxTlvFilterType::TLV);
329 filterLinkageTypes[SINK][3] = filterLinkageTypes[SOURCE][3];
330 // ALP Linkage PTP filter setting
331 filterLinkageTypes[SOURCE][4].mainType = DemuxFilterMainType::ALP;
332 filterLinkageTypes[SOURCE][4].subType.alpFilterType(DemuxAlpFilterType::PTP);
333 filterLinkageTypes[SINK][4] = filterLinkageTypes[SOURCE][4];
334 };
335
336 /** Configuration array for the timer filter test */
initTimeFilterConfig()337 inline void initTimeFilterConfig() {
338 timeFilterArray[TIMER0].supportTimeFilter = true;
339 timeFilterArray[TIMER0].timeStamp = 1;
340 }
341
342 /** Configuration array for the dvr test */
initDvrConfig()343 inline void initDvrConfig() {
344 RecordSettings recordSettings{
345 .statusMask = 0xf,
346 .lowThreshold = 0x1000,
347 .highThreshold = 0x07fff,
348 .dataFormat = DataFormat::TS,
349 .packetSize = 188,
350 };
351 dvrArray[DVR_RECORD0].type = DvrType::RECORD;
352 dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M;
353 dvrArray[DVR_RECORD0].settings.record(recordSettings);
354 PlaybackSettings playbackSettings{
355 .statusMask = 0xf,
356 .lowThreshold = 0x1000,
357 .highThreshold = 0x07fff,
358 .dataFormat = DataFormat::TS,
359 .packetSize = 188,
360 };
361 dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK;
362 dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts";
363 dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M;
364 dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings);
365 PlaybackSettings softwareFePlaybackSettings{
366 .statusMask = 0xf,
367 .lowThreshold = 0x1000,
368 .highThreshold = 0x07fff,
369 .dataFormat = DataFormat::TS,
370 .packetSize = 188,
371 };
372 dvrArray[DVR_SOFTWARE_FE].type = DvrType::PLAYBACK;
373 dvrArray[DVR_SOFTWARE_FE].playbackInputFile = "/data/local/tmp/segment000000.ts";
374 dvrArray[DVR_SOFTWARE_FE].bufferSize = FMQ_SIZE_4M;
375 dvrArray[DVR_SOFTWARE_FE].settings.playback(softwareFePlaybackSettings);
376 };
377
378 /** Configuration array for the descrambler test */
initDescramblerConfig()379 inline void initDescramblerConfig() {
380 descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID;
381 descramblerArray[DESC_0].provisionStr = PROVISION_STR;
382 descramblerArray[DESC_0].hidlPvtData.resize(256);
383 };
384