change default lof threshold for universal lnbs to 11700
[enigma2.git] / lib / dvb / sec.cpp
index 6d11f44e78b0aa9159ea0562f624fbd847a53032..d9a84226484f60375dd3b214ddee2a540f8fa922 100644 (file)
@@ -2,6 +2,8 @@
 #include <lib/dvb/sec.h>
 #include <lib/dvb/rotor_calc.h>
 
+#include <set>
+
 #if HAVE_DVB_API_VERSION < 3
 #define FREQUENCY Frequency
 #else
@@ -25,7 +27,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
        addLNB();
        setLNBTunerMask(3);
        setLNBLOFL(9750000);
-       setLNBThreshold(11750000);
+       setLNBThreshold(11700000);
        setLNBLOFH(10607000);
        setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
        setToneburst(eDVBSatelliteDiseqcParameters::NO);
@@ -42,7 +44,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
        addLNB();
        setLNBTunerMask(3);
        setLNBLOFL(9750000);
-       setLNBThreshold(11750000);
+       setLNBThreshold(11700000);
        setLNBLOFH(10600000);
        setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
        setToneburst(eDVBSatelliteDiseqcParameters::NO);
@@ -59,7 +61,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
        addLNB();
        setLNBTunerMask(3);
        setLNBLOFL(9750000);
-       setLNBThreshold(11750000);
+       setLNBThreshold(11700000);
        setLNBLOFH(10600000);
        setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_2);
        setToneburst(eDVBSatelliteDiseqcParameters::NO);
@@ -93,7 +95,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
 
 int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite &sat, iDVBFrontend *fe, int frontend_id )
 {
-       int ret=0;
+       int ret=0, satcount=0;
 
        for (int idx=0; idx <= m_lnbidx; ++idx )
        {
@@ -102,6 +104,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                {
                        eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
 
+                       satcount += lnb_param.m_satellites.size();
+
                        std::map<int, eDVBSatelliteSwitchParameters>::iterator sit =
                                lnb_param.m_satellites.find(sat.orbital_position);
                        if ( sit != lnb_param.m_satellites.end())
@@ -136,20 +140,14 @@ 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..
@@ -205,61 +203,22 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                }
                                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)
-                                       {
-                                               int lof_diff = abs(lof - lofs[i]);
-                                               if ( lof_diff < diff )
-                                               {
-                                                       diff = lof_diff;
-                                                       used_band = i;
-                                               }
-                                       }
-                                       if ( used_band != -1 )
-                                       {
-                                               if ( diff > 50000 )
-                                               {
-                                                       eDebug("could not detect used lnb freq range .. disable range check !!!");
-                                                       used_band = -1;
-                                               }
-                                       }
-                                       if ( used_band != -1 )
+                                       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;
 }
 
@@ -284,6 +243,7 @@ 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,
@@ -435,7 +395,8 @@ 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
@@ -541,7 +502,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        ++loops;
 
                                                for ( int i=0; i < di_param.m_repeats; ++i )
-                                               loops *= 2;
+                                                       loops *= 2;
 
                                                for ( int i = 0; i < loops;)  // fill commands...
                                                {
@@ -559,10 +520,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) );
 
@@ -707,6 +668,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);
@@ -752,10 +714,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        frontend.setData(1, ucsw);
                        frontend.setData(2, di_param.m_toneburst_param);
 
-                       if ( linked )
-                               return 0;
-
-                       if (doSetVoltageToneFrontend)
+                       if (!linked && doSetVoltageToneFrontend)
                        {
                                eSecCommand::pair compare;
                                compare.voltage = voltage;
@@ -766,11 +725,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;
@@ -783,7 +744,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;
@@ -825,7 +786,7 @@ RESULT eDVBSatelliteEquipmentControl::setDependencyPointers( int tu1, int tu2, i
 /* 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
        {
@@ -1072,6 +1033,110 @@ 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<cmp.lofh;
+                       }
+                       return lofl<cmp.lofl;
+               }
+               return orb_pos < cmp.orb_pos;
+       }
+};
+
+PyObject *eDVBSatelliteEquipmentControl::get_exclusive_satellites(int tu1, int tu2)
+{
+       PyObject *ret=0;
+
+       int tu1_mask = 1 << tu1,
+               tu2_mask = 1 << tu2;
+
+       if (tu1 != tu2)
+       {
+               eDVBRegisteredFrontend *p1=NULL, *p2=NULL;
+               int cnt=0;
+               for (eSmartPtrList<eDVBRegisteredFrontend>::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
+                       int tmp1, tmp2;
+                       p1->m_frontend->getData(7, tmp1);
+                       p2->m_frontend->getData(7, tmp2);
+                       if ((void*)tmp1 != p2 && (void*)tmp2 != p1)
+                       {
+                               // check for rotor dependency
+                               p1->m_frontend->getData(8, tmp1);
+                               p2->m_frontend->getData(8, tmp2);
+                               if ((void*)tmp1 != p2 && (void*)tmp2 != p1)
+                               {
+                                       std::set<sat_compare> tu1sats, tu2sats;
+                                       std::list<sat_compare> tu1difference, tu2difference;
+                                       std::insert_iterator<std::list<sat_compare> > 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<int, eDVBSatelliteSwitchParameters>::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<sat_compare>::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<sat_compare>::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);