diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/gui/scan_setup.cpp neutrino-tangos/src/gui/scan_setup.cpp --- neutrino-tangos.org/src/gui/scan_setup.cpp 2020-05-29 09:02:24.980699917 +0200 +++ neutrino-tangos/src/gui/scan_setup.cpp 2020-05-31 10:50:46.467279131 +0200 @@ -364,14 +364,16 @@ { UNCOMMITED_FIRST, LOCALE_SATSETUP_DISEQC_UNCOM_COM } }; -#define SATSETUP_FRONTEND_MODE_COUNT 5 +#define SATSETUP_FRONTEND_MODE_COUNT 7 const CMenuOptionChooser::keyval SATSETUP_FRONTEND_MODE[SATSETUP_FRONTEND_MODE_COUNT] = { { CFrontend::FE_MODE_UNUSED, LOCALE_SATSETUP_FE_MODE_UNUSED }, { CFrontend::FE_MODE_INDEPENDENT, LOCALE_SATSETUP_FE_MODE_INDEPENDENT }, { CFrontend::FE_MODE_MASTER, LOCALE_SATSETUP_FE_MODE_MASTER }, { CFrontend::FE_MODE_LINK_LOOP, LOCALE_SATSETUP_FE_MODE_LINK_LOOP }, - { CFrontend::FE_MODE_LINK_TWIN, LOCALE_SATSETUP_FE_MODE_LINK_TWIN } + { CFrontend::FE_MODE_LINK_TWIN, LOCALE_SATSETUP_FE_MODE_LINK_TWIN }, + { CFrontend::FE_MODE_MASTER_FBC, LOCALE_SATSETUP_FE_MODE_MASTER }, + { CFrontend::FE_MODE_LINK_FBC, LOCALE_SATSETUP_FE_MODE_LINK_LOOP } }; #define FRONTEND_FORCE_MODE_COUNT 3 @@ -782,7 +784,10 @@ lmode = LOCALE_SATSETUP_FE_MODE_LINK_LOOP; else if (mode == CFrontend::FE_MODE_LINK_TWIN) lmode = LOCALE_SATSETUP_FE_MODE_LINK_TWIN; - + else if (mode == CFrontend::FE_MODE_MASTER_FBC) + lmode = LOCALE_SATSETUP_FE_MODE_MASTER; + else if (mode == CFrontend::FE_MODE_LINK_FBC) + lmode = LOCALE_SATSETUP_FE_MODE_LINK_LOOP; return lmode; } @@ -997,7 +1002,7 @@ mode_count = 3; for (int i = 0; i < fecount; i++) { CFrontend * testfe = CFEManager::getInstance()->getFE(i); - if (i != fenumber && (fe->getSupportedDeliverySystems() == testfe->getSupportedDeliverySystems()) && (testfe->getMode() == CFrontend::FE_MODE_MASTER)) { + if (i != fenumber && (fe->getSupportedDeliverySystems() == testfe->getSupportedDeliverySystems()) && ((testfe->getMode() == CFrontend::FE_MODE_MASTER) || (testfe->getMode() == CFrontend::FE_MODE_MASTER_FBC))) { int num = testfe->getNumber(); snprintf(fename[select_count], sizeof(fename[select_count]), "%d: %s", num+1, testfe->getName()); feselect[select_count].key = num; diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/system/proc_tools.cpp neutrino-tangos/src/system/proc_tools.cpp --- neutrino-tangos.org/src/system/proc_tools.cpp 2020-04-17 09:31:07.697852083 +0200 +++ neutrino-tangos/src/system/proc_tools.cpp 2020-05-31 10:29:36.291540120 +0200 @@ -96,6 +96,22 @@ return ret; } +int proc_get(const char* path) +{ + int ret = -1; + FILE *fp = fopen(path,"r"); + if(fp) + { + fscanf(fp, "%d", &ret); + fclose(fp); + } + else + { + return ret; + } + return ret; +} + unsigned int proc_get_hex(const char *path) { unsigned int n, ret = 0; diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/system/proc_tools.h neutrino-tangos/src/system/proc_tools.h --- neutrino-tangos.org/src/system/proc_tools.h 2020-04-17 09:31:07.697852083 +0200 +++ neutrino-tangos/src/system/proc_tools.h 2020-05-31 10:26:22.168664551 +0200 @@ -19,5 +19,6 @@ int proc_put(const char *path, unsigned long long value); int proc_put(const char *path, bool state); int proc_get(const char *path, char *value, const int len); +int proc_get(const char *path); unsigned int proc_get_hex(const char *path); #endif diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/zapit/include/zapit/femanager.h neutrino-tangos/src/zapit/include/zapit/femanager.h --- neutrino-tangos.org/src/zapit/include/zapit/femanager.h 2020-04-17 09:31:07.701852056 +0200 +++ neutrino-tangos/src/zapit/include/zapit/femanager.h 2020-05-29 10:00:57.527409048 +0200 @@ -160,5 +164,7 @@ bool terrOnly() { return (have_terr && !have_sat && ! have_cable); } void Lock() { mutex.lock(); } void Unlock() { mutex.unlock(); } + void SetupFBC(); + int setProcFBCID(int fe_id, int fbc_connect, bool is_linked); }; #endif /* __femanager_h__ */ diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/zapit/include/zapit/frontend_c.h neutrino-tangos/src/zapit/include/zapit/frontend_c.h --- neutrino-tangos.org/src/zapit/include/zapit/frontend_c.h 2020-04-17 09:31:07.701852056 +0200 +++ neutrino-tangos/src/zapit/include/zapit/frontend_c.h 2020-05-31 10:11:26.577853608 +0200 @@ -100,7 +100,9 @@ FE_MODE_INDEPENDENT, FE_MODE_MASTER, FE_MODE_LINK_LOOP, - FE_MODE_LINK_TWIN + FE_MODE_LINK_TWIN, + FE_MODE_MASTER_FBC, + FE_MODE_LINK_FBC } fe_work_mode_t; private: @@ -114,6 +116,8 @@ int adapter; bool locked; /* information about the used frontend type */ + bool fbc_tuner_master; + bool fbc_tuner_slave; struct dvb_frontend_info info; /* current 22kHz tone mode */ fe_sec_tone_mode_t currentToneMode; @@ -286,10 +290,10 @@ void setMode(int mode) {femode = (fe_work_mode_t) mode; } int getMaster() { return masterkey; } void setMaster(int key) { masterkey = key; } - bool hasLinks() { return (femode == FE_MODE_MASTER) && (linkmap.size() > 1); } + bool hasLinks() { return ((femode == FE_MODE_MASTER) || (femode == FE_MODE_MASTER_FBC)) && (linkmap.size() > 1); } static bool linked(int mode) { - if ((mode == FE_MODE_LINK_LOOP) || (mode == FE_MODE_LINK_TWIN)) + if ((mode == FE_MODE_LINK_LOOP) || (mode == FE_MODE_LINK_TWIN) || (mode == FE_MODE_LINK_FBC)) return true; return false; } @@ -301,6 +305,10 @@ bool hasSat(void); bool hasTerr(void); bool isHybrid(void); + bool isFBC_Tuner_slave(void); + void setFBC_Tuner_slave(bool slave); + bool isFBC_Tuner_master(void); + void setFBC_Tuner_master(bool master); bool supportsDelivery(delivery_system_t); bool forcedDelivery(delivery_system_t); delivery_system_t getCurrentDeliverySystem(void); diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/zapit/src/femanager.cpp neutrino-tangos/src/zapit/src/femanager.cpp --- neutrino-tangos.org/src/zapit/src/femanager.cpp 2020-05-29 09:02:24.984699892 +0200 +++ neutrino-tangos/src/zapit/src/femanager.cpp 2020-05-31 10:58:25.868248674 +0200 @@ -41,6 +41,8 @@ #include #include +#include + static int fedebug = 0; static int unused_demux; static int noSameFE = 0; @@ -54,6 +56,25 @@ __LINE__ , ## args); \ } while (0) +static void loadConnectChoices(const char* filename, bool *connect_choices) +{ + FILE *fp = fopen(filename,"r"); + if(fp) + { + int c; + while(EOF != (c = fgetc(fp))) + { + if(isdigit(c)) + connect_choices[c - '0'] = true; + } + fclose(fp); + } + else + { + DBG("[*][CFrontend::LoadFbcRootChoices] open failed, %s: %m", filename); + } +} + CFeDmx::CFeDmx(int i) { num = i; @@ -433,6 +454,9 @@ for(unsigned i = 0; i < MAX_DMX_UNITS; i++) demuxes[i] = 0; demuxes[0] = 1; + + SetupFBC(); + for(fe_map_iterator_t it = femap.begin(); it != femap.end(); it++) { CFrontend * fe = it->second; int femode = fe->getMode(); @@ -440,7 +464,7 @@ fe->have_loop = false; fe->have_rotor = false; fe->linkmap.clear(); - if (femode == CFrontend::FE_MODE_MASTER) { + if ((femode == CFrontend::FE_MODE_MASTER) || (femode == CFrontend::FE_MODE_MASTER_FBC)) { fe->linkmap.push_back(fe); /* fe is master, find all linked */ for(fe_map_iterator_t it2 = femap.begin(); it2 != femap.end(); it2++) { @@ -454,6 +478,9 @@ if (fe2->getMode() == CFrontend::FE_MODE_LINK_LOOP) { INFO("Frontend #%d: link to master %d as LOOP", fe2->fenumber, fe->fenumber); fe->have_loop = true; + } else if (fe2->getMode() == CFrontend::FE_MODE_LINK_FBC) { + INFO("Frontend #%d: link to master %d as FBC loop", fe2->fenumber, fe->fenumber); + fe->have_loop = true; } else { INFO("Frontend #%d: link to master %d as TWIN", fe2->fenumber, fe->fenumber); } @@ -472,7 +499,10 @@ INFO("Frontend #%d: is LOOP, master %d", fe->fenumber, fe->getMaster()); if (init) fe->setMasterSlave(true); - //fe->slave = true; + } else if (femode == CFrontend::FE_MODE_LINK_FBC) { + INFO("Frontend #%d: is FBC loop, master %d", fe->fenumber, fe->getMaster()); + if (init) + fe->setMasterSlave(true); } else if (femode == CFrontend::FE_MODE_LINK_TWIN) { INFO("Frontend #%d: is TWIN, master %d", fe->fenumber, fe->getMaster()); } else if (femode == CFrontend::FE_MODE_INDEPENDENT) { @@ -606,7 +670,7 @@ continue; } - if (mfe->getMode() == CFrontend::FE_MODE_MASTER) { + if ((mfe->getMode() == CFrontend::FE_MODE_MASTER) || (mfe->getMode() == CFrontend::FE_MODE_MASTER_FBC)) { bool have_loop = mfe->have_loop; CFrontend * free_frontend = NULL; CFrontend * free_twin = NULL; @@ -871,3 +935,82 @@ OpenThreads::ScopedLock m_lock(mutex); return enabled_count; } + +void CFEManager::SetupFBC() +{ + bool isRoot; + int fbcSetID = -2; + int fbcIndex = 0; + int initFbcId = -1; + int prevFbcSetID = -1; + char procFileName[128]; + std::string proc_fe; + bool connect_choices[32] = {false}; + + for(fe_map_iterator_t it = femap.begin(); it != femap.end(); it++) + { + CFrontend * mfe = it->second; + + if (!mfe->isSat((delivery_system_t)mfe->deliverySystemMask)) + continue; + + snprintf(procFileName, sizeof(procFileName), "/proc/stb/frontend/%d/fbc_set_id", mfe->fenumber); + fbcSetID = proc_get(procFileName); + if (fbcSetID != -1) + { + if (prevFbcSetID != fbcSetID) + { + prevFbcSetID = fbcSetID; + memset(connect_choices, 0, sizeof(connect_choices)); + snprintf(procFileName, sizeof(procFileName), "/proc/stb/frontend/%d/fbc_connect_choices", mfe->fenumber); + loadConnectChoices(procFileName, connect_choices); + fbcIndex = 0; // reset + } + + isRoot = false; + if (fbcIndex < sizeof(connect_choices)/sizeof(connect_choices[0])) + { + isRoot = connect_choices[fbcIndex]; + } + + initFbcId = isRoot ? fbcIndex : 0; + + //FBC_TUNER elem = {fbcSetID, fbcIndex, isRoot, initFbcId}; + //m_fbc_tuners[mfe->fenumber] = elem; + + /* set default fbc ID */ + setProcFBCID(mfe->fenumber, initFbcId, false); + + /* set link status */ + if (!(mfe->getDiseqcType() == DISEQC_UNICABLE ) && !(mfe->getDiseqcType() == DISEQC_UNICABLE2 )) + if (isRoot) { + mfe->setMode(CFrontend::FE_MODE_MASTER_FBC); + mfe->setFBC_Tuner_master(isRoot); + } else { + mfe->setMode(CFrontend::FE_MODE_LINK_FBC); + mfe->setFBC_Tuner_slave(isRoot); + mfe->setMaster(initFbcId); + } + else + mfe->setMode(CFrontend::FE_MODE_INDEPENDENT); + fbcIndex++; + } + } + Init(); +} + +int CFEManager::setProcFBCID(int fe_id, int fbc_connect, bool is_linked) +{ + INFO("[CFEManager::setProcFBCID] %d -> %d\n", fe_id, fbc_connect); + char filename[128]; + + /* set root */ + sprintf(filename, "/proc/stb/frontend/%d/fbc_connect", fe_id); + proc_put(filename, fbc_connect); + + /* set linked */ + sprintf(filename, "/proc/stb/frontend/%d/fbc_link", fe_id); + proc_put(filename, (int)is_linked); + + return 0; +} diff -Nur '--exclude-from=/home/tango/DDT/helpers/diff-exclude' neutrino-tangos.org/src/zapit/src/frontend.cpp neutrino-tangos/src/zapit/src/frontend.cpp --- neutrino-tangos.org/src/zapit/src/frontend.cpp 2020-05-29 09:02:24.984699892 +0200 +++ neutrino-tangos/src/zapit/src/frontend.cpp 2020-05-31 10:10:34.682154444 +0200 @@ -271,6 +277,8 @@ deliverySystemMask = UNKNOWN_DS; isMultistream = false; + fbc_tuner_master = false; + fbc_tuner_slave = false; } CFrontend::~CFrontend(void) @@ -2724,6 +2772,26 @@ return false; } +bool CFrontend::isFBC_Tuner_slave(void) +{ + return fbc_tuner_slave; +} + +void CFrontend::setFBC_Tuner_slave(bool slave) +{ + fbc_tuner_slave = slave; +} + +bool CFrontend::isFBC_Tuner_master(void) +{ + return fbc_tuner_master; +} + +void CFrontend::setFBC_Tuner_master(bool master) +{ + fbc_tuner_master = master; +} + bool CFrontend::supportsDelivery(delivery_system_t delsys) { return (deliverySystemMask & delsys) != 0;