X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/f01b61f8a3c92f43132fdc078e5d3ab0b1345c4a..2b0cb23445858adf81b34500883c842ffd26f4f8:/lib/dvb/sec.cpp diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index 4d6558da..86f549c2 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -2,16 +2,12 @@ #include #include +#include + #if HAVE_DVB_API_VERSION < 3 -#define INVERSION Inversion #define FREQUENCY Frequency -#define FEC_INNER FEC_inner -#define SYMBOLRATE SymbolRate #else -#define INVERSION inversion #define FREQUENCY frequency -#define FEC_INNER fec_inner -#define SYMBOLRATE symbol_rate #endif #include @@ -31,7 +27,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList::iterator sit = lnb_param.m_satellites.find(sat.orbital_position); if ( sit != lnb_param.m_satellites.end()) { int band=0, - linked_to=-1, // linked tuner - satpos_depends_to=-1, + linked_prev_ptr=-1, + linked_next_ptr=-1, + satpos_depends_ptr=-1, csw = di_param.m_committed_cmd, ucsw = di_param.m_uncommitted_cmd, toneburst = di_param.m_toneburst_param, curRotorPos; - fe->getData(6, curRotorPos); - fe->getData(7, linked_to); - fe->getData(8, satpos_depends_to); + fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos); + fe->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); + fe->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); + fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr); if ( sat.frequency > lnb_param.m_lof_threshold ) band |= 1; - if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal) + if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical)) band |= 2; bool rotor=false; @@ -142,35 +142,29 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite csw |= band; if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 ) // ROTOR - { - rotor=true; - if ( curRotorPos == sat.orbital_position ) - ret=20; // rotor on correct orbpos = prio 20 - else - ret=10; // rotor must turn to correct orbpos = prio 10 - } - else - ret = 30; // no rotor = prio 30 + rotor = true; + + ret = 1000; } else { csw = band; - ret = 40; // no diseqc = prio 40 + ret = 2000; } - if (linked_to != -1) // check for linked tuners.. + while (linked_prev_ptr != -1) // check for linked tuners.. { - eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_to; + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr; if (linked_fe->m_inuse) { int ocsw = -1, oucsw = -1, oToneburst = -1, oRotorPos = -1; - linked_fe->m_frontend->getData(0, ocsw); - linked_fe->m_frontend->getData(1, oucsw); - linked_fe->m_frontend->getData(2, oToneburst); - linked_fe->m_frontend->getData(6, oRotorPos); + linked_fe->m_frontend->getData(eDVBFrontend::CSW, ocsw); + linked_fe->m_frontend->getData(eDVBFrontend::UCSW, oucsw); + linked_fe->m_frontend->getData(eDVBFrontend::TONEBURST, oToneburst); + linked_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, oRotorPos); #if 0 eDebug("compare csw %02x == lcsw %02x", csw, ocsw); @@ -187,85 +181,88 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite { // eDebug("can not tune this transponder with linked tuner in use!!"); ret=0; + break; } // else // eDebug("OK .. can tune this transponder with linked tuner in use :)"); } + linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); } - if (satpos_depends_to != -1) // check for linked tuners.. - { - eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_to; - if ( satpos_depends_to_fe->m_inuse ) - { - int oRotorPos = -1; - satpos_depends_to_fe->m_frontend->getData(6, oRotorPos); - if (!rotor || oRotorPos != sat.orbital_position) - { -// eDebug("can not tune this transponder ... rotor on other tuner is positioned to %d", oRotorPos); - ret=0; - } - } -// else -// eDebug("OK .. can tune this transponder satpos is correct :)"); - } if (ret) - { - static int lofs[] = { 3650000, 5150000, 9750000, 10600000 }; - int lof = sat.frequency > lnb_param.m_lof_threshold ? - lnb_param.m_lof_hi : lnb_param.m_lof_lo; - int diff = 0x7FFFFFFF; - unsigned int num_lofs = sizeof(lofs) / sizeof(int); - int used_band = -1; - for (int i=0; i < num_lofs; ++i) + while (linked_next_ptr != -1) // check for linked tuners.. { - int lof_diff = abs(lof - lofs[i]); - if ( lof_diff < diff ) + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr; + if (linked_fe->m_inuse) { - diff = lof_diff; - used_band = i; + int ocsw = -1, + oucsw = -1, + oToneburst = -1, + oRotorPos = -1; + linked_fe->m_frontend->getData(eDVBFrontend::CSW, ocsw); + linked_fe->m_frontend->getData(eDVBFrontend::UCSW, oucsw); + linked_fe->m_frontend->getData(eDVBFrontend::TONEBURST, oToneburst); + linked_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, oRotorPos); +#if 0 + eDebug("compare csw %02x == lcsw %02x", + csw, ocsw); + if ( diseqc ) + eDebug("compare ucsw %02x == lucsw %02x\ncompare toneburst %02x == oToneburst %02x", + ucsw, oucsw, toneburst, oToneburst); + if ( rotor ) + eDebug("compare pos %d == current pos %d", + sat.orbital_position, oRotorPos); +#endif + if ( (csw != ocsw) || + ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) || + ( rotor && oRotorPos != sat.orbital_position ) ) + { +// eDebug("can not tune this transponder with linked tuner in use!!"); + ret=0; + break; + } +// else +// eDebug("OK .. can tune this transponder with linked tuner in use :)"); } + linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); } - if ( used_band != -1 ) + + if (ret) + if (satpos_depends_ptr != -1) { - if ( diff > 50000 ) + eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr; + if ( satpos_depends_to_fe->m_inuse ) { - eDebug("could not detect used lnb freq range .. disable range check !!!"); - used_band = -1; + int oRotorPos = -1; + satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, oRotorPos); + if (!rotor || oRotorPos != sat.orbital_position) + { +// eDebug("can not tune this transponder ... rotor on other tuner is positioned to %d", oRotorPos); + ret=0; + } } +// else +// eDebug("OK .. can tune this transponder satpos is correct :)"); } - if ( used_band != -1 ) + + if (ret) + { + int lof = sat.frequency > lnb_param.m_lof_threshold ? + lnb_param.m_lof_hi : lnb_param.m_lof_lo; + int tuner_freq = abs(sat.frequency - lof); +// eDebug("tuner freq %d", tuner_freq); + if (tuner_freq < 900000 || tuner_freq > 2200000) { - int range[2]; - switch(used_band) - { - case 0: // s-band - range[0] = 2500000; - range[1] = 2700000; - break; - case 1: // c-band - range[0] = 3400000; - range[1] = 4200000; - break; - case 2: // ku-band low - range[0] = 10700000; - range[1] = 11750000; - break; - case 3: // ku-band high - range[0] = 11750000; - range[1] = 12750000; - break; - } - // check frequency in range ( +/- 75Mhz ) - if ( (sat.frequency+75000) < range[0] ) - ret=0; - if ( (sat.frequency-75000) > range[1] ) - ret=0; + ret=0; +// eDebug("Transponder not tuneable with this lnb... %d Khz out of tuner range", +// tuner_freq); } } } } } + if (ret && satcount) + ret -= (satcount-1); return ret; } @@ -290,9 +287,11 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA { eDVBSatelliteSwitchParameters &sw_param = sit->second; bool doSetVoltageToneFrontend = true; + bool doSetFrontend = true; int band=0, - linked_to=-1, // linked tuner - satpos_depends_to=-1, + linked_prev_ptr=-1, // linked tuner + linked_next_ptr=-1, // linked tuner + satpos_depends_ptr=-1, voltage = iDVBFrontend::voltageOff, tone = iDVBFrontend::toneOff, csw = di_param.m_committed_cmd, @@ -304,27 +303,43 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA lastRotorCmd = -1, curRotorPos = -1; - frontend.getData(0, lastcsw); - frontend.getData(1, lastucsw); - frontend.getData(2, lastToneburst); - frontend.getData(5, lastRotorCmd); - frontend.getData(6, curRotorPos); - frontend.getData(7, linked_to); - frontend.getData(8, satpos_depends_to); + frontend.getData(eDVBFrontend::CSW, lastcsw); + frontend.getData(eDVBFrontend::UCSW, lastucsw); + frontend.getData(eDVBFrontend::TONEBURST, lastToneburst); + frontend.getData(eDVBFrontend::ROTOR_CMD, lastRotorCmd); + frontend.getData(eDVBFrontend::ROTOR_POS, curRotorPos); + frontend.getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); + frontend.getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); + frontend.getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr); - if (linked_to != -1) + while (linked_prev_ptr != -1) // check for linked tuners.. { - eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_to; + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr; if (linked_fe->m_inuse) { eDebug("[SEC] frontend is linked with another and the other one is in use.. so we dont do SEC!!"); linked=true; + break; } + linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); } - if (satpos_depends_to != -1) + if (!linked) + while (linked_next_ptr != -1) // check for linked tuners.. + { + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr; + if (linked_fe->m_inuse) + { + eDebug("[SEC] frontend is linked with another and the other one is in use.. so we dont do SEC!!"); + linked=true; + break; + } + linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); + } + + if (satpos_depends_ptr != -1) { - eDVBRegisteredFrontend *satpos_fe = (eDVBRegisteredFrontend*) satpos_depends_to; + eDVBRegisteredFrontend *satpos_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr; if (satpos_fe->m_inuse) { if ( di_param.m_diseqc_mode != eDVBSatelliteDiseqcParameters::V1_2 ) @@ -344,56 +359,17 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA parm.FREQUENCY = abs(parm.FREQUENCY); - if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal) - band |= 2; + frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - parm.FREQUENCY); - switch (sat.inversion) - { - case eDVBFrontendParametersCable::Inversion::On: - parm.INVERSION = INVERSION_ON; - break; - case eDVBFrontendParametersCable::Inversion::Off: - parm.INVERSION = INVERSION_OFF; - break; - default: - case eDVBFrontendParametersCable::Inversion::Unknown: - parm.INVERSION = INVERSION_AUTO; - break; - } - - switch (sat.fec) - { - default: - case eDVBFrontendParametersSatellite::FEC::fNone: - eDebug("no fec set.. assume auto"); - case eDVBFrontendParametersSatellite::FEC::fAuto: - parm.u.qpsk.FEC_INNER = FEC_AUTO; - break; - case eDVBFrontendParametersSatellite::FEC::f1_2: - parm.u.qpsk.FEC_INNER = FEC_1_2; - break; - case eDVBFrontendParametersSatellite::FEC::f2_3: - parm.u.qpsk.FEC_INNER = FEC_2_3; - break; - case eDVBFrontendParametersSatellite::FEC::f3_4: - parm.u.qpsk.FEC_INNER = FEC_3_4; - break; - case eDVBFrontendParametersSatellite::FEC::f5_6: - parm.u.qpsk.FEC_INNER = FEC_5_6; - break; - case eDVBFrontendParametersSatellite::FEC::f7_8: - parm.u.qpsk.FEC_INNER = FEC_7_8; - break; - } - - parm.u.qpsk.SYMBOLRATE = sat.symbol_rate; + if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical)) + band |= 2; if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_14V - || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Vertical + || ( sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV ) ) voltage = VOLTAGE(13); else if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_18V - || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal + || ( !(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical) && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV ) ) voltage = VOLTAGE(18); if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::ON) @@ -480,11 +456,12 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA int RotorCmd=-1; bool useGotoXX = false; - if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 ) + if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 + && !sat.no_rotor_command_on_tune ) { if (depend_satpos_mode || linked) // in this both modes we dont really turn the rotor.... but in canTune we need the satpos - frontend.setData(6, sat.orbital_position); + frontend.setData(eDVBFrontend::ROTOR_POS, sat.orbital_position); else { if (sw_param.m_rotorPosNum) // we have stored rotor pos? @@ -567,8 +544,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); compare.steps = +3; sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) ); - // voltage was disabled..so we wait a longer time .. for normal switches 200ms should be enough - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 200) ); + // voltage was disabled..so we wait a longer time .. for normal switches 750ms should be enough + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 750) ); for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat) { @@ -585,8 +562,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if ( send_mask & 2 ) ++loops; - for ( int i=0; i < di_param.m_repeats; ++i ) - loops *= 2; + loops <<= di_param.m_repeats; for ( int i = 0; i < loops;) // fill commands... { @@ -604,10 +580,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA diseqc.data[2] = 0x38; diseqc.data[3] = csw; } - else + else // no committed command confed.. so send uncommitted.. { - diseqc.data[2] = 0x00; - diseqc.data[3] = 0x00; + diseqc.data[2] = 0x39; + diseqc.data[3] = ucsw; } sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); @@ -621,7 +597,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA cmd=0x38; if (cmd) { - static int delay = (120 - 54) / 2; // standard says 100msek between two repeated commands + int delay = di_param.m_repeats ? (120 - 54) / 2 : 120; // standard says 100msek between two repeated commands sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay) ); diseqc.data[2]=cmd; diseqc.data[3]=(cmd==0x38) ? csw : ucsw; @@ -650,25 +626,28 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if ( RotorCmd != -1 && RotorCmd != lastRotorCmd ) { eSecCommand::pair compare; - compare.voltage = iDVBFrontend::voltageOff; - compare.steps = +4; - // the next is a check if voltage is switched off.. then we first set a voltage :) - // else we set voltage after all diseqc stuff.. - sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) ); - - if (rotor_param.m_inputpower_parameters.m_use) - sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) ); // in normal mode start turning with 13V - else - sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) ); // turn always with 18V + if (!send_mask) + { + compare.voltage = iDVBFrontend::voltageOff; + compare.steps = +4; + // the next is a check if voltage is switched off.. then we first set a voltage :) + // else we set voltage after all diseqc stuff.. + sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) ); - // voltage was disabled..so we wait a longer time .. - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 500) ); - sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +7) ); // no need to send stop rotor cmd + if (rotor_param.m_inputpower_parameters.m_use) + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) ); // in normal mode start turning with 13V + else + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) ); // turn always with 18V - if (send_mask) - sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 750) ); // wait 750ms after send switch cmd + // voltage was disabled..so we wait a longer time .. + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 750) ); + sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +8) ); // no need to send stop rotor cmd and recheck voltage + } else - sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +1) ); + { + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 750) ); // wait 750ms after send switch cmd + sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +8) ); // no need to send stop rotor cmd and recheck voltage + } eDVBDiseqcCommand diseqc; diseqc.len = 3; @@ -752,6 +731,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA else { // use normal turning mode doSetVoltageToneFrontend=false; + doSetFrontend=false; eSecCommand::rotor cmd; eSecCommand::pair compare; compare.voltage = VOLTAGE(13); @@ -786,21 +766,18 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA } sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) ); sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) ); - frontend.setData(3, RotorCmd); - frontend.setData(4, sat.orbital_position); + frontend.setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd); + frontend.setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position); } } else csw = band; - frontend.setData(0, csw); - frontend.setData(1, ucsw); - frontend.setData(2, di_param.m_toneburst_param); - - if ( linked ) - return 0; + frontend.setData(eDVBFrontend::CSW, csw); + frontend.setData(eDVBFrontend::UCSW, ucsw); + frontend.setData(eDVBFrontend::TONEBURST, di_param.m_toneburst_param); - if (doSetVoltageToneFrontend) + if (!linked && doSetVoltageToneFrontend) { eSecCommand::pair compare; compare.voltage = voltage; @@ -811,11 +788,13 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) ); sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) ); + } + if (doSetFrontend) + { sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT) ); sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) ); } - frontend.setSecSequence(sec_sequence); return 0; @@ -828,7 +807,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA RESULT eDVBSatelliteEquipmentControl::clear() { - for (int i=0; i < m_lnbidx; ++i) + for (int i=0; i <= m_lnbidx; ++i) { m_lnbs[i].m_satellites.clear(); m_lnbs[i].tuner_mask = 0; @@ -837,40 +816,19 @@ RESULT eDVBSatelliteEquipmentControl::clear() // clear linked tuner configuration for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it) - it->m_frontend->setData(7, -1); - - return 0; -} - -// helper function for setTunerLinked and setTunerDepends -RESULT eDVBSatelliteEquipmentControl::setDependencyPointers( int tu1, int tu2, int dest_data_byte ) -{ - if (tu1 == tu2) - return -1; - - eDVBRegisteredFrontend *p1=NULL, *p2=NULL; - - int cnt=0; - for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it, ++cnt) - { - if (cnt == tu1) - p1 = *it; - else if (cnt == tu2) - p2 = *it; - } - if (p1 && p2) { - p1->m_frontend->setData(dest_data_byte, (int)p2); // this is evil.. - p2->m_frontend->setData(dest_data_byte, (int)p1); - return 0; + it->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1); } - return -1; + + return 0; } /* LNB Specific Parameters */ RESULT eDVBSatelliteEquipmentControl::addLNB() { - if ( m_lnbidx < (int)(sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters))) + if ( (m_lnbidx+1) < (int)(sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters))) m_curSat=m_lnbs[++m_lnbidx].m_satellites.end(); else { @@ -1117,14 +1075,181 @@ RESULT eDVBSatelliteEquipmentControl::setRotorPosNum(int rotor_pos_num) return 0; } +struct sat_compare +{ + int orb_pos, lofl, lofh; + sat_compare(int o, int lofl, int lofh) + :orb_pos(o), lofl(lofl), lofh(lofh) + {} + sat_compare(const sat_compare &x) + :orb_pos(x.orb_pos), lofl(x.lofl), lofh(x.lofh) + {} + bool operator < (const sat_compare & cmp) const + { + if (orb_pos == cmp.orb_pos) + { + if ( abs(lofl-cmp.lofl) < 200000 ) + { + if (abs(lofh-cmp.lofh) < 200000) + return false; + return lofh::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it, ++cnt) + { + if (cnt == tu1) + p1 = *it; + else if (cnt == tu2) + p2 = *it; + } + + if (p1 && p2) + { + // check for linked tuners + + do + { + int tmp; + p1->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp); + if (tmp != -1) + p1 = (eDVBRegisteredFrontend*)tmp; + else + break; + } + while (true); + + do + { + int tmp; + p2->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp); + if (tmp != -1) + p2 = (eDVBRegisteredFrontend*)tmp; + else + break; + } + while (true); + + if (p1 != p2) + { + int tmp1=-1; + int tmp2=-1; + // check for rotor dependency + p1->m_frontend->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, tmp1); + if (tmp1 != -1) + p1 = (eDVBRegisteredFrontend*)tmp1; + p2->m_frontend->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, tmp2); + if (tmp2 != -1) + p2 = (eDVBRegisteredFrontend*)tmp2; + if (p1 != p2) + { + int tu1_mask = 1 << p1->m_frontend->getID(), + tu2_mask = 1 << p2->m_frontend->getID(); + std::set tu1sats, tu2sats; + std::list tu1difference, tu2difference; + std::insert_iterator > insert1(tu1difference, tu1difference.begin()), + insert2(tu2difference, tu2difference.begin()); + for (int idx=0; idx <= m_lnbidx; ++idx ) + { + eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx]; + for (std::map::iterator sit(lnb_param.m_satellites.begin()); + sit != lnb_param.m_satellites.end(); ++sit) + { + if ( lnb_param.tuner_mask & tu1_mask ) + tu1sats.insert(sat_compare(sit->first, lnb_param.m_lof_lo, lnb_param.m_lof_hi)); + if ( lnb_param.tuner_mask & tu2_mask ) + tu2sats.insert(sat_compare(sit->first, lnb_param.m_lof_lo, lnb_param.m_lof_hi)); + } + } + std::set_difference(tu1sats.begin(), tu1sats.end(), + tu2sats.begin(), tu2sats.end(), + insert1); + std::set_difference(tu2sats.begin(), tu2sats.end(), + tu1sats.begin(), tu1sats.end(), + insert2); + if (!tu1sats.empty() || !tu2sats.empty()) + { + int idx=0; + ret = PyList_New(2+tu1difference.size()+tu2difference.size()); + + PyList_SET_ITEM(ret, idx++, PyInt_FromLong(tu1difference.size())); + for(std::list::iterator it(tu1difference.begin()); it != tu1difference.end(); ++it) + PyList_SET_ITEM(ret, idx++, PyInt_FromLong(it->orb_pos)); + + PyList_SET_ITEM(ret, idx++, PyInt_FromLong(tu2difference.size())); + for(std::list::iterator it(tu2difference.begin()); it != tu2difference.end(); ++it) + PyList_SET_ITEM(ret, idx++, PyInt_FromLong(it->orb_pos)); + } + } + } + } + } + if (!ret) + { + ret = PyList_New(2); + PyList_SET_ITEM(ret, 0, PyInt_FromLong(0)); + PyList_SET_ITEM(ret, 1, PyInt_FromLong(0)); + } + return ret; +} + RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2) { - return setDependencyPointers(tu1, tu2, 7); + if (tu1 == tu2) + return -1; + + eDVBRegisteredFrontend *p1=NULL, *p2=NULL; + + int cnt=0; + for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it, ++cnt) + { + if (cnt == tu1) + p1 = *it; + else if (cnt == tu2) + p2 = *it; + } + if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (int)p2); + p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (int)p1); + return 0; + } } RESULT eDVBSatelliteEquipmentControl::setTunerDepends(int tu1, int tu2) { - return setDependencyPointers(tu1, tu2, 8); + if (tu1 == tu2) + return -1; + + eDVBRegisteredFrontend *p1=NULL, *p2=NULL; + + int cnt=0; + for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it, ++cnt) + { + if (cnt == tu1) + p1 = *it; + else if (cnt == tu2) + p2 = *it; + } + if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (int)p2); + p2->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (int)p1); + return 0; + } + return -1; } bool eDVBSatelliteEquipmentControl::isRotorMoving()