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