diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp index 986518b327..09265f7fce 100644 --- a/tv/tuner/1.0/Android.bp +++ b/tv/tuner/1.0/Android.bp @@ -13,6 +13,7 @@ hidl_interface { "IDescrambler.hal", "IFrontend.hal", "IFrontendCallback.hal", + "ILnb.hal", "ITuner.hal", ], interfaces: [ diff --git a/tv/tuner/1.0/IFrontend.hal b/tv/tuner/1.0/IFrontend.hal index 05cee910fd..f9f78efaeb 100644 --- a/tv/tuner/1.0/IFrontend.hal +++ b/tv/tuner/1.0/IFrontend.hal @@ -16,6 +16,7 @@ package android.hardware.tv.tuner@1.0; import IFrontendCallback; +import ILnb; /** * A Tuner Frontend is used to tune to a frequency and lock signal. It provide @@ -79,4 +80,98 @@ interface IFrontend { * UNKNOWN_ERROR if failed for other reasons. */ close() generates (Result result); + + /** + * Scan the frontend to use the settings given. + * + * This uses the frontend to start a scan from signal delivery information. + * If previous scan isn't completed, this call MUST stop previous scan, + * and start a new scan. + * Scan is an async call, with FrontendScanMessage sent via callback. + * + * @param settings Signal delivery information which the frontend uses to + * scan the signal. + * @param type the type which the frontend uses to scan the signal. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + */ + scan(FrontendSettings settings, FrontendScanType type) generates (Result result); + + /** + * Stops a previous scanning. + * + * If the method completes successfully, the frontend stop previous + * scanning. + * + * @return result Result status of the operation. + * SUCCESS if successfully stop tuning. + * UNKNOWN_ERROR if failed for other reasons. + */ + stopScan() generates (Result result); + + /** + * Gets the statuses of the frontend. + * + * This retrieve the statuses of the frontend for given status types. + * + * @param statusTypes an array of status type which the caller request. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + * @return statuses an array of statuses which response the caller's + * request. + */ + getStatus(vec statusTypes) generates (Result result, vec statuses); + + /** + * Sets Low-Noise Block downconverter (LNB) for satellite frontend. + * + * This assigns a hardware LNB resource to the satellite frontend. It can be + * called multiple times to update LNB assignment. The LNB resource must be + * released when the frontend is closed. + * + * @param lnbId the Id of assigned LNB resource. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if the frontend can't be set with a LNB, such as + * cable frontend. + * UNKNOWN_ERROR if failed for other reasons. + */ + setLnb(ILnb lnb) generates (Result result); + + /** + * Enble or Disable Low Noise Amplifier (LNA). + * + * @param bEnable true if activate LNA module; false if deactivate LNA + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if the frontend doesn't support LNA. + * UNKNOWN_ERROR if failed for other reasons. + */ + setLna(bool bEnable) generates (Result result); + + /** + * Sends DiSEqC (Digital Satellite Equipment Control) message. + * + * Client sends DiSeqc message to DiSEqc compatible device through the + * frontend. The response message from the device comes back to the client + * through frontend's callback onDiseqcMessage. + * + * @param diseqcMessage a byte array of data for DiSEqC message which is + * specified by EUTELSAT Bus Functional Specification Version 4.2. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if the frontend can't send DiSEqc Message, such as + * cable frontend. + * UNKNOWN_ERROR if failed for other reasons. + */ + sendDiseqcMessage(vec diseqcMessage) generates (Result result); }; diff --git a/tv/tuner/1.0/IFrontendCallback.hal b/tv/tuner/1.0/IFrontendCallback.hal index e9070495c3..8896a09b62 100644 --- a/tv/tuner/1.0/IFrontendCallback.hal +++ b/tv/tuner/1.0/IFrontendCallback.hal @@ -33,5 +33,13 @@ interface IFrontendCallback { * Specification Version 4.2. */ oneway onDiseqcMessage(vec diseqcMessage); -}; + /** + * The callback function that must be called by HAL implementation to notify + * the client of scan messages. + * + * @param type the type of scan message. + * @param message the scan message sent by HAL to the client. + */ + oneway onScanMessage(FrontendScanMessageType type, FrontendScanMessage message); +}; diff --git a/tv/tuner/1.0/ILnb.hal b/tv/tuner/1.0/ILnb.hal new file mode 100644 index 0000000000..49fc3b44d8 --- /dev/null +++ b/tv/tuner/1.0/ILnb.hal @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.tv.tuner@1.0; + +/** + * A Tuner LNB (low-noise block downconverter) is used by satellite frontend + * to receive the microwave signal from the satellite, amplify it, and + * downconvert the frequency to a lower frequency. + */ +interface ILnb { + /** + * Set the lnb's power voltage. + * + * @param voltage the power's voltage the Lnb to use. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if the selected voltage isn't allowed, + * UNKNOWN_ERROR if failed for other reasons. + */ + setVoltage(FrontendLnbVoltage voltage) generates (Result result); + + /** + * Set the lnb's tone mode. + * + * @param tone the tone mode the Lnb to use. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if the selected tone mode isn't allowed, + * UNKNOWN_ERROR if failed for other reasons. + */ + setTone(FrontendLnbTone tone) generates (Result result); + + /** + * Select the lnb's position. + * + * @param position the position the Lnb to use. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if the selected position isn't allowed, + * UNKNOWN_ERROR if failed for other reasons. + */ + setSatellitePosition(FrontendLnbPosition position) generates (Result result); + + /** + * Releases the LNB instance + * + * Associated resources are released. close may be called more than once. + * Calls to any other method after this will return an error + * + * @return result Result status of the operation. + * SUCCESS if successful, + * UNKNOWN_ERROR if failed for other reasons. + */ + close() generates (Result result); +}; diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal index a0f3e8e7d1..f1a8617261 100644 --- a/tv/tuner/1.0/ITuner.hal +++ b/tv/tuner/1.0/ITuner.hal @@ -19,6 +19,7 @@ package android.hardware.tv.tuner@1.0; import IDemux; import IDescrambler; import IFrontend; +import ILnb; /** * Top level interface to manage Frontend, Demux and Decrambler hardware @@ -45,6 +46,7 @@ interface ITuner { * @param frontendId the id of the frontend to be opened. * @return result Result status of the operation. * SUCCESS if successful, + * UNAVAILABLE if no resource. * UNKNOWN_ERROR if creation failed for other reasons. * @return frontend the newly created frontend interface. */ @@ -62,7 +64,7 @@ interface ITuner { * @return demuxId newly created demux id. * @return demux the newly created demux interface. */ - openDemux() + openDemux() generates (Result result, DemuxId demuxId, IDemux demux); /** @@ -75,6 +77,48 @@ interface ITuner { * UNKNOWN_ERROR if creation failed for other reasons. * @return descrambler the newly created descrambler interface. */ - openDescrambler() + openDescrambler() generates (Result result, IDescrambler descrambler); + + /** + * Create a new instance of Descrambler. + * + * It is used by the client to create a Descrambler instance. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * UNKNOWN_ERROR if creation failed for other reasons. + * @return descrambler the newly created descrambler interface. + */ + getFrontendInfo(FrontendId frontendId) + generates (Result result, FrontendInfo info); + + /** + * Get low-noise block downconverter (LNB) IDs. + * + * It is used by the client to get all available LNBs' IDs. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * UNKNOWN_ERROR if tuning failed for other reasons. + * @return frontendIds an array of LnbId for the available LNBs. + */ + getLnbIds() generates (Result result, vec lnbIds); + + /** + * Create a new instance of Lnb given a lnbId. + * + * It is used by the client to create a Lnb instance for satellite Frontend. + * + * @param lnbId the id of the LNB to be opened. + * @return result Result status of the operation. + * SUCCESS if successful, + * UNAVAILABLE if no resource. + * UNKNOWN_ERROR if creation failed for other reasons. + * @return lnb the newly created Lnb interface. + */ + openLnbById(LnbId lnbId) + generates (Result result, ILnb lnb); + }; + diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp index b211dd249f..0ae8bcdac8 100644 --- a/tv/tuner/1.0/default/Android.bp +++ b/tv/tuner/1.0/default/Android.bp @@ -8,6 +8,7 @@ cc_defaults { "Descrambler.cpp", "Demux.cpp", "Tuner.cpp", + "Lnb.cpp", "service.cpp", ], diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp index 3dcc2b1ebd..0609d05121 100644 --- a/tv/tuner/1.0/default/Frontend.cpp +++ b/tv/tuner/1.0/default/Frontend.cpp @@ -77,6 +77,46 @@ Return Frontend::stopTune() { return Result::SUCCESS; } +Return Frontend::scan(const FrontendSettings& /* settings */, FrontendScanType /* type */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Frontend::stopScan() { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Frontend::getStatus(const hidl_vec& /* statusTypes */, + getStatus_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector statuses; + _hidl_cb(Result::SUCCESS, statuses); + + return Void(); +} + +Return Frontend::setLna(bool /* bEnable */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Frontend::setLnb(const sp& /* lnb */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Frontend::sendDiseqcMessage(const hidl_vec& /* diseqcMessage */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + FrontendType Frontend::getFrontendType() { return mType; } diff --git a/tv/tuner/1.0/default/Frontend.h b/tv/tuner/1.0/default/Frontend.h index f77a0d8894..fc586b5174 100644 --- a/tv/tuner/1.0/default/Frontend.h +++ b/tv/tuner/1.0/default/Frontend.h @@ -38,6 +38,7 @@ using ::android::hardware::tv::tuner::V1_0::Result; class Frontend : public IFrontend { public: Frontend(); + Frontend(FrontendType type, FrontendId id); virtual Return close() override; @@ -48,6 +49,19 @@ class Frontend : public IFrontend { virtual Return stopTune() override; + virtual Return scan(const FrontendSettings& settings, FrontendScanType type) override; + + virtual Return stopScan() override; + + virtual Return getStatus(const hidl_vec& statusTypes, + getStatus_cb _hidl_cb) override; + + virtual Return sendDiseqcMessage(const hidl_vec& diseqcMessage) override; + + virtual Return setLna(bool bEnable) override; + + virtual Return setLnb(const sp& lnb) override; + FrontendType getFrontendType(); FrontendId getFrontendId(); diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp new file mode 100644 index 0000000000..b81bb1508b --- /dev/null +++ b/tv/tuner/1.0/default/Lnb.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.0-Lnb" + +#include "Lnb.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +Lnb::Lnb() {} + +Lnb::~Lnb() {} + +Return Lnb::setVoltage(FrontendLnbVoltage /* voltage */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::setTone(FrontendLnbTone /* tone */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::setSatellitePosition(FrontendLnbPosition /* position */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::close() { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h new file mode 100644 index 0000000000..df7e0fe2b3 --- /dev/null +++ b/tv/tuner/1.0/default/Lnb.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_ + +#include +#include + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::tv::tuner::V1_0::FrontendLnbPosition; +using ::android::hardware::tv::tuner::V1_0::FrontendLnbTone; +using ::android::hardware::tv::tuner::V1_0::FrontendLnbVoltage; +using ::android::hardware::tv::tuner::V1_0::Result; + +class Lnb : public ILnb { + public: + Lnb(); + + virtual Return setVoltage(FrontendLnbVoltage voltage); + + virtual Return setTone(FrontendLnbTone tone) override; + + virtual Return setSatellitePosition(FrontendLnbPosition position) override; + + virtual Return close() override; + + private: + virtual ~Lnb(); +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_ \ No newline at end of file diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp index 68b34368ee..00831aea30 100644 --- a/tv/tuner/1.0/default/Tuner.cpp +++ b/tv/tuner/1.0/default/Tuner.cpp @@ -22,6 +22,7 @@ #include "Demux.h" #include "Descrambler.h" #include "Frontend.h" +#include "Lnb.h" namespace android { namespace hardware { @@ -95,6 +96,33 @@ Return Tuner::openDescrambler(openDescrambler_cb _hidl_cb) { return Void(); } +Return Tuner::getFrontendInfo(FrontendId /* frontendId */, getFrontendInfo_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + FrontendInfo info; + + _hidl_cb(Result::SUCCESS, info); + return Void(); +} + +Return Tuner::getLnbIds(getLnbIds_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector lnbIds; + + _hidl_cb(Result::SUCCESS, lnbIds); + return Void(); +} + +Return Tuner::openLnbById(LnbId /* lnbId */, openLnbById_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + sp lnb = new Lnb(); + + _hidl_cb(Result::SUCCESS, lnb); + return Void(); +} + } // namespace implementation } // namespace V1_0 } // namespace tuner diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h index 12e959406a..62227eefcd 100644 --- a/tv/tuner/1.0/default/Tuner.h +++ b/tv/tuner/1.0/default/Tuner.h @@ -41,6 +41,13 @@ class Tuner : public ITuner { virtual Return openDescrambler(openDescrambler_cb _hidl_cb) override; + virtual Return getFrontendInfo(FrontendId frontendId, + getFrontendInfo_cb _hidl_cb) override; + + virtual Return getLnbIds(getLnbIds_cb _hidl_cb) override; + + virtual Return openLnbById(LnbId lnbId, openLnbById_cb _hidl_cb) override; + private: virtual ~Tuner(); // Static mFrontends array to maintain local frontends information diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal index aa2a95c2af..a1153e9c29 100644 --- a/tv/tuner/1.0/types.hal +++ b/tv/tuner/1.0/types.hal @@ -41,42 +41,121 @@ typedef uint32_t FrontendId; enum FrontendType : uint32_t { UNDEFINED = 0, ANALOG, + /* Advanced Television Systems Committee (ATSC) Standard A/72. */ ATSC, + /* Advanced Television Systems Committee (ATSC 3.0) Standard A/330. */ + ATSC3, + /** + * Digital Video Broadcasting - Cable + * DVB Cable Frontend Standard ETSI EN 300 468 V1.15.1. + */ DVBC, + /** + * Digital Video Broadcasting - Satellite + * DVB Satellite Frontend Standard ETSI EN 300 468 V1.15.1 and + * ETSI EN 302 307-2 V1.1.1. + */ DVBS, + /** + * Digital Video Broadcasting - Terrestrial + * DVB Terresttrial Frontend Standard ETSI EN 300 468 V1.15.1 and + * ETSI EN 302 755 V1.4.1. + */ DVBT, + /* Integrated Services Digital Broadcasting-Satellite (ISDB-S) + * ARIB SDT-B20 is technical document of ISDB-S. + */ + ISDBS, + /* Integrated Services Digital Broadcasting-Satellite (ISDB-S) + * ARIB TR-B15 is technical document of ISDB-S3. + */ + ISDBS3, + /* Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD) + * ABNT NBR 15603 is technical document of ISDB-T. + */ ISDBT, }; /** * Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1 - * It's a 4-bit field specifying the inner FEC scheme used according to the - * table 35 in the spec. + * and ETSI EN 302 307-2 V1.1.1. */ @export -enum FrontendInnerFec : uint32_t { +enum FrontendInnerFec : uint64_t { /* Not defined */ FEC_UNDEFINED = 0, - /* 1/2 conv. code rate */ - FEC_1_2 = 1 << 0, - /* 2/3 conv. code rate */ - FEC_2_3 = 1 << 1, - /* 3/4 conv. code rate */ - FEC_3_4 = 1 << 2, - /* 5/6 conv. code rate */ - FEC_5_6 = 1 << 3, - /* 7/8 conv. code rate */ - FEC_7_8 = 1 << 4, - /* 8/9 conv. code rate */ - FEC_8_9 = 1 << 5, - /* 3/5 conv. code rate */ - FEC_3_5 = 1 << 6, - /* 4/5 conv. code rate */ - FEC_4_5 = 1 << 7, - /* 9/10 conv. code rate */ - FEC_9_10 = 1 << 8, /* hardware is able to detect and set FEC automatically */ - FEC_AUTO = 1 << 9, + AUTO = 1 << 0, + /* 1/2 conv. code rate */ + FEC_1_2 = 1 << 1, + /* 1/3 conv. code rate */ + FEC_1_3 = 1 << 2, + /* 1/4 conv. code rate */ + FEC_1_4 = 1 << 3, + /* 1/5 conv. code rate */ + FEC_1_5 = 1 << 4, + /* 2/3 conv. code rate */ + FEC_2_3 = 1 << 5, + /* 2/5 conv. code rate */ + FEC_2_5 = 1 << 6, + /* 2/9 conv. code rate */ + FEC_2_9 = 1 << 7, + /* 3/4 conv. code rate */ + FEC_3_4 = 1 << 8, + /* 3/5 conv. code rate */ + FEC_3_5 = 1 << 9, + /* 4/5 conv. code rate */ + FEC_4_5 = 1 << 10, + /* 4/15 conv. code rate */ + FEC_4_15 = 1 << 11, + /* 5/6 conv. code rate */ + FEC_5_6 = 1 << 12, + /* 5/9 conv. code rate */ + FEC_5_9 = 1 << 13, + /* 6/7 conv. code rate */ + FEC_6_7 = 1 << 14, + /* 7/8 conv. code rate */ + FEC_7_8 = 1 << 15, + /* 7/9 conv. code rate */ + FEC_7_9 = 1 << 16, + /* 7/15 conv. code rate */ + FEC_7_15 = 1 << 17, + /* 8/9 conv. code rate */ + FEC_8_9 = 1 << 18, + /* 8/15 conv. code rate */ + FEC_8_15 = 1 << 19, + /* 9/10 conv. code rate */ + FEC_9_10 = 1 << 20, + /* 9/20 conv. code rate */ + FEC_9_20 = 1 << 21, + /* 11/15 conv. code rate */ + FEC_11_15 = 1 << 22, + /* 11/20 conv. code rate */ + FEC_11_20 = 1 << 23, + /* 11/45 conv. code rate */ + FEC_11_45 = 1 << 24, + /* 13/18 conv. code rate */ + FEC_13_18 = 1 << 25, + /* 13/45 conv. code rate */ + FEC_13_45 = 1 << 26, + /* 14/45 conv. code rate */ + FEC_14_45 = 1 << 27, + /* 23/36 conv. code rate */ + FEC_23_36 = 1 << 28, + /* 25/36 conv. code rate */ + FEC_25_36 = 1 << 29, + /* 26/45 conv. code rate */ + FEC_26_45 = 1 << 30, + /* 28/45 conv. code rate */ + FEC_28_45 = 1 << 31, + /* 29/45 conv. code rate */ + FEC_29_45 = 1 << 32, + /* 31/45 conv. code rate */ + FEC_31_45 = 1 << 33, + /* 32/45 conv. code rate */ + FEC_32_45 = 1 << 34, + /* 77/90 conv. code rate */ + FEC_77_90 = 1 << 35, }; /** @@ -98,22 +177,761 @@ struct FrontendAtscSettings { FrontendAtscModulation modulation; }; +/** + * Capabilities for ATSC Frontend. + */ +struct FrontendAtscCapabilities { + /** Modulation capability */ + bitfield modulationCap; +}; + +/** + * Modulation Type for ATSC3. + */ +@export +enum FrontendAtsc3Modulation : uint32_t { + UNDEFINED = 0, + MOD_QPSK = 1 << 0, + MOD_16QAM = 1 << 1, + MOD_64QAM = 1 << 2, + MOD_256QAM = 1 << 3, + MOD_1024QAM = 1 << 4, + MOD_4096QAM = 1 << 5, +}; + +/** + * Bandwidth for ATSC3. + */ +@export +enum FrontendAtsc3Bandwidth : uint32_t { + UNDEFINED = 0, + BANDWIDTH_8MHZ = 1 << 0, + BANDWIDTH_7MHZ = 1 << 1, + BANDWIDTH_6MHZ = 1 << 2, +}; + +/** + * Time Interleave Mode for ATSC3. + */ +@export +enum FrontendAtsc3TimeInterleaveMode : uint32_t { + UNDEFINED, + CTI, + HTI, +}; + +/** + * Code Rate for ATSC3. + */ +@export +enum FrontendAtsc3CodeRate : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Coderate automatically */ + AUTO = 1 << 0, + CODERATE_2_15 = 1 << 1, + CODERATE_3_15 = 1 << 2, + CODERATE_4_15 = 1 << 3, + CODERATE_5_15 = 1 << 4, + CODERATE_6_15 = 1 << 5, + CODERATE_7_15 = 1 << 6, + CODERATE_8_15 = 1 << 7, + CODERATE_9_15 = 1 << 8, + CODERATE_10_15 = 1 << 9, + CODERATE_11_15 = 1 << 10, + CODERATE_12_15 = 1 << 11, + CODERATE_13_15 = 1 << 12, +}; + +/** + * Forward Error Correction (FEC) for ATSC3. + */ +@export +enum FrontendAtsc3Fec : uint32_t { + UNDEFINED, + BCH_LDPC_16K, + BCH_LDPC_64K, + CRC_LDPC_16K, + CRC_LDPC_64K, + LDPC_16K, + LDPC_64K, +}; + +/** + * Signal Settings for an ATSC3 Frontend. + */ +struct FrontendAtsc3Settings { + /** Signal frequency in Hertz */ + uint32_t frequency; + FrontendAtsc3Bandwidth bandwidth; + FrontendAtsc3TimeInterleaveMode interleaveMode; + FrontendAtsc3CodeRate codeRate; + FrontendAtsc3Fec fec; + vec plpIdList; +}; + +/** + * Capabilities for ATSC3 Frontend. + */ +struct FrontendAtsc3Capabilities { + /** Modulation capability */ + bitfield modulationCap; + /** Bandwidth capability */ + bitfield bandwidthCap; +}; + +/** + * Modulation Type for DVBS. + */ +@export +enum FrontendDvbsModulation : int32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Modulation automatically */ + AUTO = 1 << 0, + MOD_QPSK = 1 << 1, + MOD_8PSK = 1 << 2, + MOD_16QAM = 1 << 3, + MOD_16PSK = 1 << 4, + MOD_32PSK = 1 << 5, + MOD_ACM = 1 << 6, + MOD_8APSK = 1 << 7, + MOD_16APSK = 1 << 8, + MOD_32APSK = 1 << 9, + MOD_64APSK = 1 << 10, + MOD_128APSK = 1 << 11, + MOD_256APSK = 1 << 12, + /** Reserved for Proprietary modulation */ + MOD_RESERVED = 1 << 13, +}; + +/** + * Roll Off value for DVBS. + */ +@export +enum FrontendDvbsRolloff : uint32_t { + UNDEFINED, + ROLLOFF_0_35, + ROLLOFF_0_25, + ROLLOFF_0_20, + ROLLOFF_0_15, + ROLLOFF_0_10, + ROLLOFF_0_5, +}; + +/** + * Pilot mode for DVBS. + */ +@export +enum FrontendDvbsPilot : uint32_t { + UNDEFINED, + ON, + OFF, + AUTO, +}; + +/** + * Code Rate for DVBS. + */ +struct FrontendDvbsCodeRate { + FrontendInnerFec fec; + bool isLinear; + /* true if enable short frame */ + bool isShortFrames; + /* bits number in 1000 symbol. 0 if use the default. */ + uint32_t bitsPer1000Symbol; +}; + +/** + * Sub standards in DVBS. + */ +@export +enum FrontendDvbsStandard : uint8_t { + AUTO = 1 << 0, + S = 1 << 1, + S2 = 1 << 2, + S2X = 1 << 3, +}; + +/** + * Signal Settings for an DVBS Frontend. + */ +struct FrontendDvbsSettings { + /** Signal frequency in Hertz */ + uint32_t frequency; + FrontendDvbsModulation modulation; + FrontendDvbsCodeRate coderate; + /** Symbols per second */ + uint32_t symbolRate; + FrontendDvbsRolloff rolloff; + FrontendDvbsPilot pilot; + uint32_t inputStreamId; + FrontendDvbsStandard standard; +}; + +/** + * Capabilities for DVBS Frontend. + */ +struct FrontendDvbsCapabilities { + bitfield modulationCap; + bitfield innerfecCap; + bitfield standard; +}; + +/** + * Modulation Type for DVBC. + */ +@export +enum FrontendDvbcModulation : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Modulation automatically */ + AUTO = 1 << 0, + MOD_16QAM = 1 << 1, + MOD_32QAM = 1 << 2, + MOD_64QAM = 1 << 3, + MOD_128QAM = 1 << 4, + MOD_256QAM = 1 << 5, +}; + +/** + * Outer Forward Error Correction (FEC) Type for DVBC. + */ +@export +enum FrontendDvbcOuterFec : uint32_t { + UNDEFINED = 0, + OUTER_FEC_NONE, + OUTER_FEC_RS, +}; + +/** + * Annex Type for DVBC. + */ +@export +enum FrontendDvbcAnnex : uint8_t { + UNDEFINED = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, +}; + +/** + * Spectral Inversion Type for DVBC. + */ +@export +enum FrontendDvbcSpectralInversion : uint32_t { + UNDEFINED, + NORMAL, + INVERTED, +}; + +/** + * Signal Settings for an DVBC Frontend. + */ +struct FrontendDvbcSettings { + /** Signal frequency in Hertz */ + uint32_t frequency; + FrontendDvbcModulation modulation; + FrontendInnerFec fec; + /** Symbols per second */ + uint32_t symbolRate; + FrontendDvbcOuterFec outerFec; + FrontendDvbcAnnex annex; + FrontendDvbcSpectralInversion spectralInversion; +}; + +/** + * Capabilities for DVBC Frontend. + */ +struct FrontendDvbcCapabilities { + bitfield modulationCap; + bitfield fecCap; + bitfield annexCap; +}; + +/** + * Bandwidth Type for DVBT. + */ +@export +enum FrontendDvbtBandwidth : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Bandwidth automatically */ + AUTO = 1 << 0, + BANDWIDTH_8MHZ = 1 << 1, + BANDWIDTH_7MHZ = 1 << 2, + BANDWIDTH_6MHZ = 1 << 3, + BANDWIDTH_5MHZ = 1 << 4, + BANDWIDTH_1_7MHZ = 1 << 5, + BANDWIDTH_10MHZ = 1 << 6, +}; + +/** + * Constellation Type for DVBT. + */ +@export +enum FrontendDvbtConstellation : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Constellation automatically */ + AUTO = 1 << 0, + CONSTELLATION_QPSK = 1 << 1, + CONSTELLATION_16QAM = 1 << 2, + CONSTELLATION_64QAM = 1 << 3, + CONSTELLATION_256QAM = 1 << 4, +}; + +/** + * Hierarchy Type for DVBT. + */ +@export +enum FrontendDvbtHierarchy : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Hierarchy automatically */ + AUTO = 1 << 0, + HIERARCHY_NON_NATIVE = 1 << 1, + HIERARCHY_1_NATIVE = 1 << 2, + HIERARCHY_2_NATIVE = 1 << 3, + HIERARCHY_4_NATIVE = 1 << 4, + HIERARCHY_NON_INDEPTH = 1 << 5, + HIERARCHY_1_INDEPTH = 1 << 6, + HIERARCHY_2_INDEPTH = 1 << 7, + HIERARCHY_4_INDEPTH = 1 << 8, +}; + +/** + * Hierarchy Type for DVBT. + */ +@export +enum FrontendDvbtCoderate : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Hierarchy automatically */ + AUTO = 1 << 0, + CODERATE_1_2 = 1 << 1, + CODERATE_2_3 = 1 << 2, + CODERATE_3_4 = 1 << 3, + CODERATE_5_6 = 1 << 4, + CODERATE_7_8 = 1 << 5, + CODERATE_3_5 = 1 << 6, + CODERATE_4_5 = 1 << 7, + CODERATE_6_7 = 1 << 8, + CODERATE_8_9 = 1 << 9, +}; + +/** + * Guard Interval Type for DVBT. + */ +@export +enum FrontendDvbtGuardInterval : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Guard Interval automatically */ + AUTO = 1 << 0, + INTERVAL_1_32 = 1 << 1, + INTERVAL_1_16 = 1 << 2, + INTERVAL_1_8 = 1 << 3, + INTERVAL_1_4 = 1 << 4, + INTERVAL_1_128 = 1 << 5, + INTERVAL_19_128 = 1 << 6, + INTERVAL_19_256 = 1 << 7, +}; + +/** + * Transmission Mode for DVBT. + */ +@export +enum FrontendDvbtTransmissionMode : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Transmission Mode automatically */ + AUTO = 1 << 0, + MODE_2K = 1 << 1, + MODE_8K = 1 << 2, + MODE_4K = 1 << 3, + MODE_1K = 1 << 4, + MODE_16K = 1 << 5, + MODE_32K = 1 << 6, +}; + +/** + * Physical Layer Pipe (PLP) Mode for DVBT. + */ +enum FrontendDvbtPlpMode : uint32_t { + UNDEFINED, + AUTO, + MANUAL, +}; + +/** + * Sub standards in DVBT. + */ +@export +enum FrontendDvbtStandard : uint8_t { + AUTO = 1 << 0, + T = 1 << 1, + T2 = 1 << 2, +}; + /** * Signal Setting for DVBT Frontend. */ struct FrontendDvbtSettings { /** Signal frequencey in Herhz */ uint32_t frequency; - FrontendAtscModulation modulation; - FrontendInnerFec fec; + FrontendDvbtTransmissionMode transmissionMode; + FrontendDvbtBandwidth bandwidth; + FrontendDvbtConstellation constellation; + FrontendDvbtHierarchy hierarchy; + /** Code Rate for High Priority level */ + FrontendDvbtCoderate hpCoderate; + /** Code Rate for Low Priority level */ + FrontendDvbtCoderate lpCoderate; + FrontendDvbtGuardInterval guardInterval; + bool isHighPriority; + FrontendDvbtStandard standard; + bool isMiso; + FrontendDvbtPlpMode plpMode; + /** Physical Layer Pipe (PLP) Id */ + uint8_t plpId; + /** Group Id for Physical Layer Pipe (PLP) */ + uint8_t plpGroupId; }; /** - * Modulation Type for ATSC. + * Capabilities for DVBT Frontend. + */ +struct FrontendDvbtCapabilities { + bitfield transmissionModeCap; + bitfield bandwidthCap; + bitfield constellationCap; + bitfield coderateCap; + bitfield hierarchyCap; + bitfield guardIntervalCap; + bool isT2Supported; + bool isMisoSupported; +}; + +/** + * Roll Off Type for ISDBS. + */ +@export +enum FrontendIsdbsRolloff : uint32_t { + UNDEFINED, + ROLLOFF_0_35, +}; + +/** + * Modulaltion Type for ISDBS. + */ +@export +enum FrontendIsdbsModulation : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Modulation automatically */ + AUTO = 1 << 0, + MOD_BPSK = 1 << 1, + MOD_QPSK = 1 << 2, + MOD_TC8PSK = 1 << 3, +}; + +/** + * Code Rate Type for ISDBS. + */ +@export +enum FrontendIsdbsCoderate : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Code Rate automatically */ + AUTO = 1 << 0, + CODERATE_1_2 = 1 << 1, + CODERATE_2_3 = 1 << 2, + CODERATE_3_4 = 1 << 3, + CODERATE_5_6 = 1 << 4, + CODERATE_7_8 = 1 << 5, +}; + +/** + * Stream Id Type for ISDBS. + */ +@export +enum FrontendIsdbsStreamIdType : uint32_t { + STREAM_ID, + RELATIVE_STREAM_ID, +}; + +/** + * Signal Setting for ISDBS Frontend. + */ +struct FrontendIsdbsSettings { + /** Signal frequency in Hertz */ + uint32_t frequency; + uint16_t streamId; + FrontendIsdbsStreamIdType streamIdType; + FrontendIsdbsModulation modulation; + FrontendIsdbsCoderate coderate; + /** Symbols per second */ + uint32_t symbolRate; + FrontendIsdbsRolloff rolloff; +}; + +/** + * Capabilities for ISDBS Frontend. + */ +struct FrontendIsdbsCapabilities { + bitfield modulationCap; + bitfield coderateCap; +}; + +/** + * Roll of Type for ISDBS3. + */ +@export +enum FrontendIsdbs3Rolloff : uint32_t { + UNDEFINED, + ROLLOFF_0_03, +}; + +/** + * Modulaltion Type for ISDBS3. + */ +@export +enum FrontendIsdbs3Modulation : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Modulation automatically */ + AUTO = 1 << 5, + MOD_BPSK = 1 << 1, + MOD_QPSK = 1 << 2, + MOD_8PSK = 1 << 3, + MOD_16APSK = 1 << 4, + MOD_32APSK = 1 << 5, +}; + +/** + * Code Rate Type for ISDBS3. + */ +@export +enum FrontendIsdbs3Coderate : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Code Rate automatically */ + AUTO = 1 << 0, + CODERATE_1_3 = 1 << 1, + CODERATE_2_5 = 1 << 2, + CODERATE_1_2 = 1 << 3, + CODERATE_3_5 = 1 << 4, + CODERATE_2_3 = 1 << 5, + CODERATE_3_4 = 1 << 6, + CODERATE_7_9 = 1 << 7, + CODERATE_4_5 = 1 << 8, + CODERATE_5_6 = 1 << 9, + CODERATE_7_8 = 1 << 10, + CODERATE_9_10 = 1 << 11, +}; + +/** + * Signal Setting for ISDBS3 Frontend. + */ +struct FrontendIsdbs3Settings { + /** Signal frequency in Hertz */ + uint32_t frequency; + uint16_t streamId; + FrontendIsdbsStreamIdType streamIdType; + FrontendIsdbs3Modulation modulation; + FrontendIsdbs3Coderate coderate; + /** Symbols per second */ + uint32_t symbolRate; + FrontendIsdbs3Rolloff rolloff; +}; + +/** + * Capabilities for ISDBS3 Frontend. + */ +struct FrontendIsdbs3Capabilities { + bitfield modulationCap; + bitfield coderateCap; +}; + +/** + * Mode for ISDBT. + */ +@export +enum FrontendIsdbtMode : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Mode automatically */ + AUTO = 1 << 0, + MODE_1 = 1 << 1, + MODE_2 = 1 << 2, + MODE_3 = 1 << 3, +}; + +/** + * Bandwidth for ISDBT. + */ +@export +enum FrontendIsdbtBandwidth : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Bandwidth automatically */ + AUTO = 1 << 0, + BANDWIDTH_8MHZ = 1 << 1, + BANDWIDTH_7MHZ = 1 << 2, + BANDWIDTH_6MHZ = 1 << 3, +}; + +/** + * Modulation for ISDBT. + */ +@export +enum FrontendIsdbtModulation : uint32_t { + UNDEFINED = 0, + /** hardware is able to detect and set Modulation automatically */ + AUTO = 1 << 0, + MOD_DQPSK = 1 << 1, + MOD_QPSK = 1 << 2, + MOD_16QAM = 1 << 3, + MOD_64QAM = 1 << 4, +}; + +/** Code Rate for ISDBT. */ +typedef FrontendDvbtCoderate FrontendIsdbtCoderate; + +/** Guard Interval for ISDBT. */ +typedef FrontendDvbtGuardInterval FrontendIsdbtGuardInterval; + +/** + * Signal Setting for ISDBT Frontend. + */ +struct FrontendIsdbtSettings { + /** Signal frequency in Hertz */ + uint32_t frequency; + FrontendIsdbtModulation modulation; + FrontendIsdbtBandwidth bandwidth; + FrontendIsdbtMode mode; + FrontendIsdbtCoderate coderate; + FrontendIsdbtGuardInterval guardInterval; + uint32_t serviceAreaId; +}; + +/** + * Capabilities for ISDBT Frontend. + */ +struct FrontendIsdbtCapabilities { + bitfield modeCap; + bitfield bandwidthCap; + bitfield constellationCap; + bitfield coderateCap; + bitfield guardIntervalCap; +}; + +/** + * Signal Type for Analog Frontend. + */ +@export +enum FrontendAnalogType : uint32_t { + UNDEFINED = 0, + PAL = 1 << 0, + SECAM = 1 << 1, + NTSC = 1 << 2, +}; + +/** + * Standard Interchange Format (SIF) for Analog Frontend. + */ +@export +enum FrontendAnalogSifStandard : uint32_t { + UNDEFINED = 0, + BG = 1 << 0, + BG_A2 = 1 << 1, + BG_NICAM = 1 << 2, + I = 1 << 3, + DK = 1 << 4, + DK1 = 1 << 5, + DK2 = 1 << 6, + DK3 = 1 << 7, + DK_NICAM = 1 << 8, + L = 1 << 9, + M = 1 << 10, + M_BTSC = 1 << 11, + M_A2 = 1 << 12, + M_EIA_J = 1 << 13, + I_NICAM = 1 << 14, + L_NICAM = 1 << 15, +}; + +/** + * Signal Setting for Analog Frontend. + */ +struct FrontendAnalogSettings { + /** Signal frequency in Hertz */ + uint32_t frequency; + FrontendAnalogType type; + FrontendAnalogSifStandard sifStandard; +}; + +/** + * Capabilities for Analog Frontend. + */ +struct FrontendAnalogCapabilities { + bitfield typeCap; + bitfield sifStandardCap; +}; + +/** + * Signal Setting for Frontend. */ safe_union FrontendSettings { + FrontendAnalogSettings analog; FrontendAtscSettings atsc; + FrontendAtsc3Settings atsc3; + FrontendDvbsSettings dvbs; + FrontendDvbcSettings dvbc; FrontendDvbtSettings dvbt; + FrontendIsdbsSettings isdbs; + FrontendIsdbs3Settings isdbs3; + FrontendIsdbtSettings isdbt; +}; + +/** + * Scan type for Frontend. + */ +enum FrontendScanType : uint32_t { + SCAN_UNDEFINED = 0, + SCAN_AUTO = 1 << 0, + SCAN_BLIND = 1 << 1, +}; + +/** + * Scan Message Type for Frontend. + */ +enum FrontendScanMessageType : uint32_t { + /** Scan locked the signal. */ + LOCKED, + /** Scan stopped. */ + END, + /** Scan progress report. */ + PROGRESS_PERCENT, + /** Locked frequency report. */ + FREQUENCY, + /** Locked symbol rate. */ + SYMBOL_RATE, + /** Locked Plp Ids for DVBT2 frontend. */ + PLP_IDS, + /** Locked group Ids for DVBT2 frontend. */ + GROUP_IDS, + /** Locked the number of the Plps. */ + INPUT_STREAM_IDS, + /** Locked signal stardard. */ + STANDARD, +}; + +/** + * Scan Message for Frontend. + */ +safe_union FrontendScanMessage { + bool islocked; + bool isEnd; + /** scan progress percent (0..100) */ + uint8_t progressPercent; + /** Signal frequency in Hertz */ + uint32_t frequency; + /** Symbols per second */ + uint32_t symbolRate; + vec plpIds; + vec groupIds; + vec inputStreamIds; + safe_union standard { + FrontendDvbsStandard sStd; + FrontendDvbtStandard tStd; + } std; }; /** @@ -136,8 +954,174 @@ enum FrontendEventType : uint32_t { * event. */ LOST_LOCK, + /** + * If frontend detect that incoming Diseqc message is overflow. + */ + DISEQC_RX_OVERFLOW, + /** + * If frontend detect that outgoing Diseqc message isn't delivered on time. + */ + DISEQC_RX_TIMEOUT, + /** + * If frontend detect that the incoming Diseqc message has parity error. + */ + DISEQC_RX_PARITY_ERROR, + /** + * If frontend detect that the LNB is overload. + */ + LNB_OVERLOAD, }; +/** + * Frontend Status Type. + */ +@export +enum FrontendStatusType : uint32_t { + /** Lock status for RF or Demod. */ + LOCK, + /** Signal to Noise Ratio. */ + SNR, + /** Bit Error Ratio. */ + BER, + /** Packages Error Ratio. */ + PER, + /** Bit Error Ratio befor FEC. */ + PRE_BER, + /* + * Signal Quality (0..100). Good data over total data in percent can be + * used as a way to present Signal Quality. + */ + SIGNAL_QUALITY, + /** Signal Strength. */ + SIGGAL_STRENGTH, + /** Symbol Rate. */ + SYMBOL_RATE, + /** Forward Error Correction Type. */ + FEC, + /** Modulation Type. */ + MODULATION, + /** Spectral Inversion Type. */ + SPECTRAL, + /** LNB Voltage. */ + LNB_VOLTAGE, + /** Physical Layer Pipe ID. */ + PLP_ID, + /** Status for Emergency Warning Broadcasting System. */ + EWBS, +}; + +/** + * Modulation Type for Frontend's status. + */ +safe_union FrontendModulationStatus { + FrontendDvbsModulation dvbs; + FrontendAtsc3Modulation atsc3; +}; + +/** + * The status for Frontend. + */ +safe_union FrontendStatus { + bool isLocked; + /** SNR value measured by 0.001 dB. */ + int32_t snr; + /** The number of error bit per 1 billion bits. */ + uint32_t ber; + /** The number of error package per 1 billion packages. */ + uint32_t per; + /** The number of error bit per 1 billion bits before FEC. */ + uint32_t preBer; + /** Signal Quality in percent. */ + uint32_t signalQuality; + /** Signal Strength measured by 0.001 dBm. */ + int32_t signalStrength; + /** Symbols per second */ + uint32_t symbolRate; + FrontendInnerFec innerFec; + FrontendModulationStatus modulation; + FrontendDvbcSpectralInversion inversion; + FrontendLnbVoltage lnbVoltage; + uint8_t plpId; + bool isEWBS; +}; + +/** + * Information for the Frontend. + */ +struct FrontendInfo { + FrontendType type; + /** Frequency in Hertz */ + uint32_t minFrequency; + /** Frequency in Hertz */ + uint32_t maxFrequency; + /** Minimum symbols per second */ + uint32_t minSymbolRate; + /** Maximum symbols per second */ + uint32_t maxSymbolRate; + /** Range in Hertz */ + uint32_t acquireRange; + /* + * Frontends are assigned with the same exclusiveGroupId if they can't + * function at same time. For instance, they share same hardware module. + */ + uint32_t exclusiveGroupId; + /** A list of supported status types which client can inquiry */ + vec statusCaps; + safe_union FrontendCapabilities { + FrontendAnalogCapabilities analogCaps; + FrontendAtscCapabilities atscCaps; + FrontendAtsc3Capabilities atsc3Caps; + FrontendDvbsCapabilities dvbsCaps; + FrontendDvbcCapabilities dvbcCaps; + FrontendDvbtCapabilities dvbtCaps; + FrontendIsdbsCapabilities isdbsCaps; + FrontendIsdbs3Capabilities isdbs3Caps; + FrontendIsdbtCapabilities isdbtCaps; + } frontendCaps; +}; + +/* + * Low-Noise Block downconverter (LNB) ID is used to associate with a hardware + * LNB module. + */ +typedef uint32_t LnbId; + +/** + * Power Voltage Type for LNB. + */ +@export +enum FrontendLnbVoltage : uint32_t { + NONE, + VOLTAGE_5V, + VOLTAGE_11V, + VOLTAGE_12V, + VOLTAGE_13V, + VOLTAGE_14V, + VOLTAGE_15V, + VOLTAGE_18V, + VOLTAGE_19V, +}; + +/** + * Tone Type for LNB. + */ +@export +enum FrontendLnbTone : int32_t { + NONE, + CONTINUOUS, +}; + +/** + * The Position of LNB. + */ +@export +enum FrontendLnbPosition : int32_t { + UNDEFINED, + POSITION_A, + POSITION_B, +}; + + /* Demux ID is used to associate with a hardware demux resource. */ typedef uint32_t DemuxId; @@ -248,7 +1232,7 @@ struct DemuxFilterSectionSettings { /* Version number for Section Filter */ uint16_t version; /* true if the filter checks CRC and discards data with wrong CRC */ - bool checkCrc; + bool isCheckCrc; /* true if the filter repeats the data with the same version */ bool isRepeat; /* true if the filter output raw data */ @@ -265,7 +1249,7 @@ struct DemuxFilterPesDataSettings { DemuxTpid tpid; DemuxStreamId streamId; /* true if the filter output raw data */ - bool bIsRaw; + bool isRaw; }; /** @@ -283,7 +1267,7 @@ struct DemuxFilterAudioSettings { /** * true if the filter output goes to decoder directly in pass through mode. */ - bool bPassthrough; + bool isPassthrough; }; /** @@ -294,7 +1278,7 @@ struct DemuxFilterVideoSettings { /** * true if the filter output goes to decoder directly in pass through mode. */ - bool bPassthrough; + bool isPassthrough; }; /** diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index d272d710f3..7256cc4478 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #define WAIT_TIMEOUT 3000000000 @@ -72,6 +73,8 @@ using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; using android::hardware::tv::tuner::V1_0::FrontendEventType; using android::hardware::tv::tuner::V1_0::FrontendId; using android::hardware::tv::tuner::V1_0::FrontendInnerFec; +using android::hardware::tv::tuner::V1_0::FrontendScanMessage; +using android::hardware::tv::tuner::V1_0::FrontendScanMessageType; using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::IDemux; using android::hardware::tv::tuner::V1_0::IDemuxCallback; @@ -159,12 +162,21 @@ class FrontendCallback : public IFrontendCallback { return Void(); } + virtual Return onScanMessage(FrontendScanMessageType /* type */, + const FrontendScanMessage& /* message */) override { + android::Mutex::Autolock autoLock(mMsgLock); + mScanMessageReceived = true; + mMsgCondition.signal(); + return Void(); + }; + void testOnEvent(sp& frontend, FrontendSettings settings); void testOnDiseqcMessage(sp& frontend, FrontendSettings settings); private: bool mEventReceived = false; bool mDiseqcMessageReceived = false; + bool mScanMessageReceived = false; FrontendEventType mEventType; hidl_vec mEventMessage; android::Mutex mMsgLock; @@ -205,8 +217,8 @@ class DemuxCallback : public IDemuxCallback { ALOGW("[VTS] FILTER EVENT %d", filterEvent.filterId); android::Mutex::Autolock autoLock(mMsgLock); mFilterEventReceived = true; - // maybe assemble here?? - mFilterEvent = filterEvent; + mFilterIdToEvent[filterEvent.filterId] = filterEvent; + startFilterEventThread(filterEvent); mMsgCondition.signal(); return Void(); } @@ -236,11 +248,19 @@ class DemuxCallback : public IDemuxCallback { void testOnFilterEvent(uint32_t filterId); void testOnSectionFilterEvent(sp& demux, uint32_t filterId, MQDesc& filterMQDescriptor, MQDesc& inputMQDescriptor); - void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor); - bool readAndCompareSectionEventData(); + void testFilterDataOutput(); + // Legacy + bool readAndCompareSectionEventData(uint32_t filterId); + void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor); + void startFilterEventThread(DemuxFilterEvent event); static void* __threadLoopInput(void* threadArgs); + static void* __threadLoopFilter(void* threadArgs); void inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ, MQDesc& inputMQDescriptor); + void filterThreadLoop(DemuxFilterEvent& event); + + void updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor); + void updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile); private: struct InputThreadArgs { @@ -249,22 +269,34 @@ class DemuxCallback : public IDemuxCallback { bool* keepWritingInputFMQ; MQDesc& inputMQDesc; }; - bool mFilterEventReceived = false; - std::vector mDataOutputBuffer; - std::unique_ptr mFilterMQ; - std::unique_ptr mInputMQ; + struct FilterThreadArgs { + DemuxCallback* user; + DemuxFilterEvent& event; + }; uint16_t mDataLength = 0; - DemuxFilterEvent mFilterEvent; - android::Mutex mMsgLock; - android::Mutex mReadLock; - android::Condition mMsgCondition; - EventFlag* mFilterMQEventFlag; + std::vector mDataOutputBuffer; + + bool mFilterEventReceived; + std::map mFilterIdToGoldenOutput; + std::map mFilterIdToEvent; + + std::map> mFilterIdToMQ; + std::unique_ptr mInputMQ; + std::map mFilterIdToMQEventFlag; EventFlag* mInputMQEventFlag; + + android::Mutex mMsgLock; + android::Mutex mFilterOutputLock; + android::Condition mMsgCondition; + android::Condition mFilterOutputCondition; + bool mKeepWritingInputFMQ; bool mInputThreadRunning; pthread_t mInputThread; + pthread_t mFilterThread; }; +// Legacy void DemuxCallback::testOnFilterEvent(uint32_t filterId) { android::Mutex::Autolock autoLock(mMsgLock); while (!mFilterEventReceived) { @@ -276,7 +308,7 @@ void DemuxCallback::testOnFilterEvent(uint32_t filterId) { // Reset the filter event recieved flag mFilterEventReceived = false; // Check if filter id match - EXPECT_TRUE(filterId == mFilterEvent.filterId) << "filter id match"; + EXPECT_TRUE(filterId == mFilterIdToEvent[filterId].filterId) << "filter id match"; } void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor) { @@ -291,28 +323,42 @@ void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputM pthread_setname_np(mInputThread, "test_playback_input_loop"); } -/*void DemuxCallback::testPlaybackDataFlow(bool* keepWritingInputFMQ) { - // timeout logic here +void DemuxCallback::startFilterEventThread(DemuxFilterEvent event) { + struct FilterThreadArgs* threadArgs = + (struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs)); + threadArgs->user = this; + threadArgs->event = event; - // assemble logic here + pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs); + pthread_setname_np(mFilterThread, "test_playback_input_loop"); +} +void DemuxCallback::testFilterDataOutput() { + android::Mutex::Autolock autoLock(mFilterOutputLock); + while (!mFilterIdToMQ.empty()) { + if (-ETIMEDOUT == mFilterOutputCondition.waitRelative(mFilterOutputLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "filter output does not match golden output within timeout"; + return; + } + } +} -}*/ - +// Legacy void DemuxCallback::testOnSectionFilterEvent(sp& demux, uint32_t filterId, MQDesc& filterMQDescriptor, MQDesc& inputMQDescriptor) { Result status; // Create MQ to read the output into the local buffer - mFilterMQ = std::make_unique(filterMQDescriptor, true /* resetPointers */); - EXPECT_TRUE(mFilterMQ); + mFilterIdToMQ[filterId] = + std::make_unique(filterMQDescriptor, true /* resetPointers */); + EXPECT_TRUE(mFilterIdToMQ[filterId]); // Get the MQ to write the input to the HAL mInputMQ = std::make_unique(inputMQDescriptor, true /* resetPointers */); EXPECT_TRUE(mInputMQ); // Create the EventFlag that is used to signal the HAL impl that data have been // read the Filter FMQ - EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) == - android::OK); + EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ[filterId]->getEventFlagWord(), + &mFilterIdToMQEventFlag[filterId]) == android::OK); // Create the EventFlag that is used to signal the HAL impl that data have been // written into the Input FMQ EXPECT_TRUE(EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &mInputMQEventFlag) == @@ -329,21 +375,24 @@ void DemuxCallback::testOnSectionFilterEvent(sp& demux, uint32_t filterI mInputMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_READY)); testOnFilterEvent(filterId); // checksum of mDataOutputBuffer and Input golden input - if (readAndCompareSectionEventData() && i < SECTION_READ_COUNT - 1) { - mFilterMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); + if (readAndCompareSectionEventData(filterId) && i < SECTION_READ_COUNT - 1) { + mFilterIdToMQEventFlag[filterId]->wake( + static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); } } } -bool DemuxCallback::readAndCompareSectionEventData() { +// Legacy +bool DemuxCallback::readAndCompareSectionEventData(uint32_t filterId) { bool result = false; - for (int i = 0; i < mFilterEvent.events.size(); i++) { - DemuxFilterSectionEvent event = mFilterEvent.events[i].section(); + DemuxFilterEvent filterEvent = mFilterIdToEvent[filterId]; + for (int i = 0; i < filterEvent.events.size(); i++) { + DemuxFilterSectionEvent event = filterEvent.events[i].section(); mDataLength = event.dataLength; EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not match"; mDataOutputBuffer.resize(mDataLength); - result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength); + result = mFilterIdToMQ[filterId]->read(mDataOutputBuffer.data(), mDataLength); EXPECT_TRUE(result) << "can't read from Filter MQ"; for (int i = 0; i < mDataLength; i++) { @@ -353,6 +402,18 @@ bool DemuxCallback::readAndCompareSectionEventData() { return result; } +void DemuxCallback::updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor) { + mFilterIdToMQ[filterId] = + std::make_unique(filterMQDescriptor, true /* resetPointers */); + EXPECT_TRUE(mFilterIdToMQ[filterId]); + EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ[filterId]->getEventFlagWord(), + &mFilterIdToMQEventFlag[filterId]) == android::OK); +} + +void DemuxCallback::updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile) { + mFilterIdToGoldenOutput[filterId] = goldenOutputFile; +} + void* DemuxCallback::__threadLoopInput(void* threadArgs) { DemuxCallback* const self = static_cast(((struct InputThreadArgs*)threadArgs)->user); @@ -413,6 +474,26 @@ void DemuxCallback::inputThreadLoop(InputConf inputConf, bool* keepWritingInputF inputData.close(); } +void* DemuxCallback::__threadLoopFilter(void* threadArgs) { + DemuxCallback* const self = + static_cast(((struct FilterThreadArgs*)threadArgs)->user); + self->filterThreadLoop(((struct FilterThreadArgs*)threadArgs)->event); + return 0; +} + +void DemuxCallback::filterThreadLoop(DemuxFilterEvent& /*event*/) { + android::Mutex::Autolock autoLock(mFilterOutputLock); + // Read from MQ[event.filterId] per event and filter type + + // Assemble to filterOutput[filterId] + + // check if filterOutput[filterId] matches goldenOutput[filterId] + + // If match, remove filterId entry from MQ map + + // end thread +} + // Test environment for Tuner HIDL HAL. class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { public: @@ -462,16 +543,19 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId); ::testing::AssertionResult getInputMQDescriptor(); ::testing::AssertionResult addInputToDemux(DemuxInputSettings setting); - ::testing::AssertionResult addSectionFilterToDemux(); ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting); ::testing::AssertionResult getFilterMQDescriptor(const uint32_t filterId); ::testing::AssertionResult closeDemux(); ::testing::AssertionResult createDescrambler(); ::testing::AssertionResult closeDescrambler(); - ::testing::AssertionResult readSectionFilterDataOutput(); ::testing::AssertionResult playbackDataFlowTest(vector filterConf, - InputConf inputConf, string goldenOutput); + InputConf inputConf, + vector goldenOutputFiles); + + // Legacy + ::testing::AssertionResult addSectionFilterToDemux(); + ::testing::AssertionResult readSectionFilterDataOutput(); }; ::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) { @@ -507,8 +591,6 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { FrontendDvbtSettings frontendDvbtSettings{ .frequency = 0, - .modulation = FrontendAtscModulation::UNDEFINED, - .fec = FrontendInnerFec::FEC_UNDEFINED, }; frontendSettings.dvbt(frontendDvbtSettings); mFrontendCallback->testOnEvent(mFrontend, frontendSettings); @@ -650,6 +732,7 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { return ::testing::AssertionResult(status == Result::SUCCESS); } +// Legacy ::testing::AssertionResult TunerHidlTest::addSectionFilterToDemux() { Result status; @@ -717,6 +800,7 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { return ::testing::AssertionResult(status == Result::SUCCESS); } +// Legacy ::testing::AssertionResult TunerHidlTest::readSectionFilterDataOutput() { // Filter Configuration Module DemuxInputSettings setting{ @@ -744,7 +828,7 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { ::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(vector filterConf, InputConf inputConf, - string /*goldenOutput*/) { + vector goldenOutputFiles) { Result status; // Filter Configuration Module for (int i = 0; i < filterConf.size(); i++) { @@ -754,6 +838,12 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) { return ::testing::AssertionFailure(); } + mDemuxCallback->updateFilterMQ(mFilterId, mFilterMQDescriptor); + mDemuxCallback->updateGoldenOutputMap(mFilterId, goldenOutputFiles[i]); + status = mDemux->startFilter(mFilterId); + if (status != Result::SUCCESS) { + return ::testing::AssertionFailure(); + } } // Playback Input Module @@ -769,12 +859,9 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { } // Data Verify Module - // golden output, created FMQ to read and EventFlags to DATA_CONSUMED - // Maintain each filter's real output (and how to assemble?????) - // mDemuxCallback->testPlaybackDataFlow(); + mDemuxCallback->testFilterDataOutput(); // Clean Up Module - // TODO what about remove input, remove filters return closeDemux(); }