Merge remote branch 'origin/bug_347_adenin_unicable_xml'
authorghost <andreas.monzner@multimedia-labs.de>
Wed, 6 Oct 2010 10:47:10 +0000 (12:47 +0200)
committerghost <andreas.monzner@multimedia-labs.de>
Wed, 6 Oct 2010 10:47:10 +0000 (12:47 +0200)
1  2 
lib/dvb/frontend.cpp
lib/dvb/idvb.h
lib/python/Components/NimManager.py
lib/python/Components/config.py
lib/python/Screens/Satconfig.py

diff --combined lib/dvb/frontend.cpp
@@@ -582,7 -582,7 +582,7 @@@ int eDVBFrontend::openFrontend(
        return 0;
  }
  
- int eDVBFrontend::closeFrontend(bool force)
+ int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
  {
        if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
        {
                eDebugNoSimulate("close frontend %d", m_dvbid);
                if (m_data[SATCR] != -1)
                {
-                       turnOffSatCR(m_data[SATCR]);
+                       if (!no_delayed)
+                       {
+                               m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
+                               m_tuneTimer->start(0, true);
+                               if(!m_tuneTimer->isActive())
+                               {
+                                       int timeout=0;
+                                       eDebug("[turnOffSatCR] no mainloop");
+                                       while(true)
+                                       {
+                                               timeout = tuneLoopInt();
+                                               if (timeout == -1)
+                                                       break;
+                                               usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
+                                       }
+                               }
+                               else
+                                       eDebug("[turnOffSatCR] running mainloop");
+                               return 0;
+                       }
+                       else
+                               m_data[ROTOR_CMD] = -1;
                }
                setTone(iDVBFrontend::toneOff);
                setVoltage(iDVBFrontend::voltageOff);
                m_tuneTimer->stop();
                if (m_sec && !m_simulate)
                        m_sec->setRotorMoving(m_slotid, false);
                if (!::close(m_fd))
@@@ -1053,7 -1076,6 +1076,7 @@@ static void fillDictWithSatelliteData(e
        case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
        default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
        }
 +      PutToDict(dict, "fec_inner", tmp);
  
        switch (p[0].u.data)
        {
@@@ -1102,7 -1124,7 +1125,7 @@@ static void fillDictWithSatelliteData(e
        PutToDict(dict, "orbital_position", orb_pos);
        PutToDict(dict, "polarization", polarization);
  
 -      switch(parm_u_qpsk_fec_inner)
 +      switch((int)parm_u_qpsk_fec_inner)
        {
        case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
        case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
@@@ -1436,11 -1458,9 +1459,11 @@@ int eDVBFrontend::readInputpower(
                return 0;
        int power=m_slotid;  // this is needed for read inputpower from the correct tuner !
        char proc_name[64];
 -      sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
 -      FILE *f=fopen(proc_name, "r");
 -      if (f)
 +      char proc_name2[64];
 +      sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
 +      sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
 +      FILE *f;
 +      if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
        {
                if (fscanf(f, "%d", &power) != 1)
                        eDebug("read %s failed!! (%m)", proc_name);
@@@ -1489,9 -1509,14 +1512,14 @@@ bool eDVBFrontend::setSecSequencePos(in
        return true;
  }
  
- void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
+ void eDVBFrontend::tuneLoop()
+ {
+       tuneLoopInt();
+ }
+ int eDVBFrontend::tuneLoopInt()  // called by m_tuneTimer
  {
-       int delay=0;
+       int delay=-1;
        eDVBFrontend *sec_fe = this;
        eDVBRegisteredFrontend *regFE = 0;
        long tmp = m_data[LINKED_PREV_PTR];
        {
                long *sec_fe_data = sec_fe->m_data;
  //            eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
+               delay = 0;
                switch (m_sec_sequence.current()->cmd)
                {
                        case eSecCommand::SLEEP:
                                ++m_sec_sequence.current();
                                break;
                        }
+                       case eSecCommand::DELAYED_CLOSE_FRONTEND:
+                       {
+                               eDebugNoSimulate("[SEC] delayed close frontend");
+                               closeFrontend(false, true);
+                               ++m_sec_sequence.current();
+                               break;
+                       }
                        default:
                                eDebugNoSimulate("[SEC] unhandled sec command %d",
                                        ++m_sec_sequence.current()->cmd);
                regFE->dec_use();
        if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
                tuneLoop();
+       return delay;
  }
  
  void eDVBFrontend::setFrontend(bool recvEvents)
@@@ -2594,9 -2628,12 +2631,12 @@@ RESULT eDVBFrontend::setSEC(iDVBSatelli
        return 0;
  }
  
- RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
+ RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
  {
-       m_sec_sequence = list;
+       if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
+               m_sec_sequence.push_back(list);
+       else
+               m_sec_sequence = list;
        return 0;
  }
  
@@@ -2673,42 -2710,3 +2713,3 @@@ arg_error
                "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
        return false;
  }
- RESULT eDVBFrontend::turnOffSatCR(int satcr)
- {
-       eSecCommandList sec_sequence;
-       // check if voltage is disabled
-       eSecCommand::pair compare;
-       compare.steps = +9;     //nothing to do
-       compare.voltage = iDVBFrontend::voltageOff;
-       sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );
-       eDVBDiseqcCommand diseqc;
-       memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
-       diseqc.len = 5;
-       diseqc.data[0] = 0xE0;
-       diseqc.data[1] = 0x10;
-       diseqc.data[2] = 0x5A;
-       diseqc.data[3] = satcr << 5;
-       diseqc.data[4] = 0x00;
-       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50+20+14*diseqc.len) );
-       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
-       setSecSequence(sec_sequence);
-       return 0;
- }
- RESULT eDVBFrontend::ScanSatCR()
- {
-       setFrontend();
-       usleep(20000);
-       setTone(iDVBFrontend::toneOff);
-       return 0;
- }
diff --combined lib/dvb/idvb.h
@@@ -459,7 -459,7 +459,7 @@@ class iDVBFrontend: public iDVBFrontend
  public:
        virtual RESULT getFrontendType(int &SWIG_OUTPUT)=0;
        virtual RESULT tune(const iDVBFrontendParameters &where)=0;
-       virtual int closeFrontend(bool force = false)=0;
+       virtual int closeFrontend(bool force = false, bool no_delayed = false)=0;
        virtual void reopenFrontend()=0;
  #ifndef SWIG
        virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
        virtual RESULT sendToneburst(int burst)=0;
  #ifndef SWIG
        virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
-       virtual RESULT setSecSequence(const eSecCommandList &list)=0;
+       virtual RESULT setSecSequence(eSecCommandList &list)=0;
  #endif
        virtual int readFrontendData(int type)=0;
        virtual void getFrontendStatus(SWIG_PYOBJECT(ePyObject) dest)=0;
@@@ -491,6 -491,7 +491,7 @@@ class iDVBSatelliteEquipmentControl: pu
  {
  public:
        virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int frontend_id, unsigned int timeout)=0;
+       virtual void prepareTurnOffSatCR(iDVBFrontend &frontend, int satcr)=0;
        virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id, int *highest_score_lnb=0)=0;
        virtual void setRotorMoving(int slotid, bool)=0;
  };
@@@ -508,7 -509,6 +509,7 @@@ public
                /* direct frontend access for raw channels and/or status inquiries. */
        virtual SWIG_VOID(RESULT) getFrontend(ePtr<iDVBFrontend> &SWIG_OUTPUT)=0;
        virtual RESULT requestTsidOnid(SWIG_PYOBJECT(ePyObject) callback) { return -1; }
 +      virtual int reserveDemux() { return -1; }
  #ifndef SWIG
        enum
        {
@@@ -16,6 -16,9 +16,9 @@@ from time import localtime, mktim
  from datetime import datetime
  from Tools.BoundFunction import boundFunction
  
+ from Tools import Directories
+ import xml.etree.cElementTree
  def getConfigSatlist(orbpos, satlist):
        default_orbpos = None
        for x in satlist:
@@@ -234,6 -237,20 +237,20 @@@ class SecConfigure
                print "sec config completed"
  
        def updateAdvanced(self, sec, slotid):
+               try:
+                       if config.Nims[slotid].advanced.unicableconnected is not None:
+                               if config.Nims[slotid].advanced.unicableconnected.value == True:
+                                       config.Nims[slotid].advanced.unicableconnectedTo.save_forced = True
+                                       self.linkNIMs(sec, slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
+                                       connto = self.getRoot(slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value))
+                                       if not self.linked.has_key(connto):
+                                               self.linked[connto] = []
+                                       self.linked[connto].append(slotid)
+                               else:
+                                       config.Nims[slotid].advanced.unicableconnectedTo.save_forced = False
+               except:
+                       pass
                lnbSat = {}
                for x in range(1,37):
                        lnbSat[x] = []
                                        sec.setLNBLOFH(10600000)
                                        sec.setLNBThreshold(11700000)
                                elif currLnb.lof.value == "unicable":
-                                       sec.setLNBLOFL(9750000)
-                                       sec.setLNBLOFH(10600000)
-                                       sec.setLNBThreshold(11700000)
+                                       def setupUnicable(configManufacturer, ProductDict):
+                                               manufacturer_name = configManufacturer.value
+                                               manufacturer = ProductDict[manufacturer_name]
+                                               product_name = manufacturer.product.value
+                                               sec.setLNBSatCR(manufacturer.scr[product_name].index)
+                                               sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
+                                               sec.setLNBSatCRpositions(manufacturer.positions[product_name][0].value)
+                                               sec.setLNBLOFL(manufacturer.lofl[product_name][0].value * 1000)
+                                               sec.setLNBLOFH(manufacturer.lofh[product_name][0].value * 1000)
+                                               sec.setLNBThreshold(manufacturer.loft[product_name][0].value * 1000)
+                                               configManufacturer.save_forced = True
+                                               manufacturer.product.save_forced = True
+                                               manufacturer.vco[product_name][manufacturer.scr[product_name].index].save_forced = True
                                        if currLnb.unicable.value == "unicable_user":
+ #TODO satpositions for satcruser
+                                               sec.setLNBLOFL(currLnb.lofl.value * 1000)
+                                               sec.setLNBLOFH(currLnb.lofh.value * 1000)
+                                               sec.setLNBThreshold(currLnb.threshold.value * 1000)
                                                sec.setLNBSatCR(currLnb.satcruser.index)
                                                sec.setLNBSatCRvco(currLnb.satcrvcouser[currLnb.satcruser.index].value*1000)
+                                               sec.setLNBSatCRpositions(1)     #HACK
                                        elif currLnb.unicable.value == "unicable_matrix":
-                                               manufacturer_name = currLnb.unicableMatrixManufacturer.value
-                                               manufacturer = currLnb.unicableMatrix[manufacturer_name]
-                                               product_name = manufacturer.product.value
-                                               sec.setLNBSatCR(manufacturer.scr[product_name].index)
-                                               sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
+                                               setupUnicable(currLnb.unicableMatrixManufacturer, currLnb.unicableMatrix)
                                        elif currLnb.unicable.value == "unicable_lnb":
-                                               manufacturer_name = currLnb.unicableLnbManufacturer.value
-                                               manufacturer = currLnb.unicableLnb[manufacturer_name]
-                                               product_name = manufacturer.product.value
-                                               sec.setLNBSatCR(manufacturer.scr[product_name].index)
-                                               sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
+                                               setupUnicable(currLnb.unicableLnbManufacturer, currLnb.unicableLnb)
                                elif currLnb.lof.value == "c_band":
                                        sec.setLNBLOFL(5150000)
                                        sec.setLNBLOFH(5150000)
@@@ -988,55 -1013,57 +1013,57 @@@ def InitNimManager(nimmgr)
  
        lnb_choices_default = "universal_lnb"
  
-       unicablelnbproducts = {
-               "Humax": {"150 SCR":("1210","1420","1680","2040")},
-               "Inverto": {"IDLP-40UNIQD+S":("1680","1420","2040","1210")},
-               "Kathrein": {"UAS481":("1400","1516","1632","1748")},
-               "Kreiling": {"KR1440":("1680","1420","2040","1210")},
-               "Radix": {"Unicable LNB":("1680","1420","2040","1210")},
-               "Wisi": {"OC 05":("1210","1420","1680","2040")}}
+       unicablelnbproducts = {}
+       unicablematrixproducts = {}
+       doc = xml.etree.cElementTree.parse("/usr/share/enigma2/unicable.xml")
+       root = doc.getroot()
+       entry = root.find("lnb")
+       for manufacturer in entry.getchildren():
+               m={}
+               for product in manufacturer.getchildren():
+                       scr=[]
+                       lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
+                       for i in range(len(lscr)):
+                               scr.append(product.get(lscr[i],"0"))
+                       for i in range(len(lscr)):
+                               if scr[len(lscr)-i-1] == "0":
+                                       scr.pop()
+                               else:
+                                       break;
+                       lof=[]
+                       lof.append(int(product.get("positions",1)))
+                       lof.append(int(product.get("lofl",9750)))
+                       lof.append(int(product.get("lofh",10600)))
+                       lof.append(int(product.get("threshold",11700)))
+                       scr.append(tuple(lof))
+                       m.update({product.get("name"):tuple(scr)})
+               unicablelnbproducts.update({manufacturer.get("name"):m})
+       entry = root.find("matrix")
+       for manufacturer in entry.getchildren():
+               m={}
+               for product in manufacturer.getchildren():
+                       scr=[]
+                       lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8")
+                       for i in range(len(lscr)):
+                               scr.append(product.get(lscr[i],"0"))
+                       for i in range(len(lscr)):
+                               if scr[len(lscr)-i-1] == "0":
+                                       scr.pop()
+                               else:
+                                       break;
+                       lof=[]
+                       lof.append(int(product.get("positions",1)))
+                       lof.append(int(product.get("lofl",9750)))
+                       lof.append(int(product.get("lofh",10600)))
+                       lof.append(int(product.get("threshold",11700)))
+                       scr.append(tuple(lof))
+                       m.update({product.get("name"):tuple(scr)})
+               unicablematrixproducts.update({manufacturer.get("name"):m})
        UnicableLnbManufacturers = unicablelnbproducts.keys()
        UnicableLnbManufacturers.sort()
-       unicablematrixproducts = {
-               "Ankaro": {
-                       "UCS 51440":("1400","1632","1284","1516"),
-                       "UCS 51820":("1400","1632","1284","1516","1864","2096","1748","1980"),
-                       "UCS 51840":("1400","1632","1284","1516","1864","2096","1748","1980"),
-                       "UCS 52240":("1400","1632"),
-                       "UCS 52420":("1400","1632","1284","1516"),
-                       "UCS 52440":("1400","1632","1284","1516"),
-                       "UCS 91440":("1400","1632","1284","1516"),
-                       "UCS 91820":("1400","1632","1284","1516","1864","2096","1748","1980"),
-                       "UCS 91840":("1400","1632","1284","1516","1864","2096","1748","1980"),
-                       "UCS 92240":("1400","1632"),
-                       "UCS 92420":("1400","1632","1284","1516"),
-                       "UCS 92440":("1400","1632","1284","1516")},
-               "DCT Delta": {
-                       "SUM518":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "SUM918":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "SUM928":("1284","1400","1516","1632","1748","1864","1980","2096")},
-               "Inverto": {
-                       "IDLP-UST11O-CUO1O-8PP":("1076","1178","1280","1382","1484","1586","1688","1790")},
-               "Kathrein": {
-                       "EXR501":("1400","1516","1632","1748"),
-                       "EXR551":("1400","1516","1632","1748"),
-                       "EXR552":("1400","1516")},
-               "ROTEK": {
-                       "EKL2/1":("1400","1516"),
-                       "EKL2/1E":("0","0","1632","1748")},
-               "Smart": {
-                       "DPA 51":("1284","1400","1516","1632","1748","1864","1980","2096")},
-               "Technisat": {
-                       "TechniRouter 5/1x8 G":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "TechniRouter 5/1x8 K":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "TechniRouter 5/2x4 G":("1284","1400","1516","1632"),
-                       "TechniRouter 5/2x4 K":("1284","1400","1516","1632")},
-               "Telstar": {
-                       "SCR 5/1x8 G":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "SCR 5/1x8 K":("1284","1400","1516","1632","1748","1864","1980","2096"),
-                       "SCR 5/2x4 G":("1284","1400","1516","1632"),
-                       "SCR 5/2x4 K":("1284","1400","1516","1632")}}
        UnicableMatrixManufacturers = unicablematrixproducts.keys()
        UnicableMatrixManufacturers.sort()
  
                                else:
                                        section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user")
  
-                               if lnb < 3:
-                                       section.unicableMatrix = ConfigSubDict()
-                                       section.unicableMatrixManufacturer = ConfigSelection(choices = UnicableMatrixManufacturers, default = UnicableMatrixManufacturers[0])
-                                       for y in unicablematrixproducts:
-                                               products = unicablematrixproducts[y].keys()
+                               def fillUnicableConf(sectionDict, unicableproducts, vco_null_check):
+                                       for y in unicableproducts:
+                                               products = unicableproducts[y].keys()
                                                products.sort()
                                                tmp = ConfigSubsection()
                                                tmp.product = ConfigSelection(choices = products, default = products[0])
                                                tmp.scr = ConfigSubDict()
                                                tmp.vco = ConfigSubDict()
+                                               tmp.lofl = ConfigSubDict()
+                                               tmp.lofh = ConfigSubDict()
+                                               tmp.loft = ConfigSubDict()
+                                               tmp.positions = ConfigSubDict()
                                                for z in products:
                                                        scrlist = []
-                                                       vcolist = unicablematrixproducts[y][z]
+                                                       vcolist = unicableproducts[y][z]
                                                        tmp.vco[z] = ConfigSubList()
-                                                       for cnt in range(1,1+len(vcolist)):
+                                                       for cnt in range(1,1+len(vcolist)-1):
                                                                vcofreq = int(vcolist[cnt-1])
-                                                               if vcofreq == 0:
+                                                               if vcofreq == 0 and vco_null_check:
                                                                        scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
                                                                else:
                                                                        scrlist.append(("%d" %cnt,"SCR %d" %cnt))
                                                                tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
-                                                       tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
-                                               section.unicableMatrix[y] = tmp
+                                                               tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
+                                                               positions = int(vcolist[len(vcolist)-1][0])
+                                                               tmp.positions[z] = ConfigSubList()
+                                                               tmp.positions[z].append(ConfigInteger(default=positions, limits = (positions, positions)))
+                                                               lofl = vcolist[len(vcolist)-1][1]
+                                                               tmp.lofl[z] = ConfigSubList()
+                                                               tmp.lofl[z].append(ConfigInteger(default=lofl, limits = (lofl, lofl)))
+                                                               lofh = int(vcolist[len(vcolist)-1][2])
+                                                               tmp.lofh[z] = ConfigSubList()
+                                                               tmp.lofh[z].append(ConfigInteger(default=lofh, limits = (lofh, lofh)))
+                                                               loft = int(vcolist[len(vcolist)-1][3])
+                                                               tmp.loft[z] = ConfigSubList()
+                                                               tmp.loft[z].append(ConfigInteger(default=loft, limits = (loft, loft)))
+                                               sectionDict[y] = tmp
+                               if lnb < 3:
+                                       print "MATRIX"
+                                       section.unicableMatrix = ConfigSubDict()
+                                       section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
+                                       fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True)
  
                                if lnb < 2:
+                                       print "LNB"
                                        section.unicableLnb = ConfigSubDict()
                                        section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
-                                       for y in unicablelnbproducts:
-                                               products = unicablelnbproducts[y].keys()
-                                               products.sort()
-                                               tmp = ConfigSubsection()
-                                               tmp.product = ConfigSelection(choices = products, default = products[0])
-                                               tmp.scr = ConfigSubDict()
-                                               tmp.vco = ConfigSubDict()
-                                               for z in products:
-                                                       scrlist = []
-                                                       vcolist = unicablelnbproducts[y][z]
-                                                       tmp.vco[z] = ConfigSubList()
-                                                       for cnt in range(1,1+len(vcolist)):
-                                                               scrlist.append(("%d" %cnt,"SCR %d" %cnt))
-                                                               vcofreq = int(vcolist[cnt-1])
-                                                               tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
-                                                       tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
-                                               section.unicableLnb[y] = tmp
+                                       fillUnicableConf(section.unicableLnb, unicablelnbproducts, False)
  
+ #TODO satpositions for satcruser
                                section.satcruser = ConfigSelection(advanced_lnb_satcruser_choices, default="1")
                                tmp = ConfigSubList()
-                               tmp.append(ConfigInteger(default=1284, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1400, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1516, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1632, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1748, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1864, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=1980, limits = (0, 9999)))
-                               tmp.append(ConfigInteger(default=2096, limits = (0, 9999)))
+                               tmp.append(ConfigInteger(default=1284, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1400, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1516, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1632, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1748, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1864, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=1980, limits = (950, 2150)))
+                               tmp.append(ConfigInteger(default=2096, limits = (950, 2150)))
                                section.satcrvcouser = tmp 
  
+                               nim.advanced.unicableconnected = ConfigYesNo(default=False)
+                               nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
+       
        def configDiSEqCModeChanged(configElement):
                section = configElement.section
                if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing):
                        section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
                        section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
                        section.powerMeasurement = ConfigYesNo(default=True)
 -                      section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
 +                      section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
                        section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
                        section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
                        section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
@@@ -29,6 -29,7 +29,7 @@@ from time import localtime, strftim
  class ConfigElement(object):
        def __init__(self):
                self.saved_value = None
+               self.save_forced = False
                self.last_value = None
                self.save_disabled = False
                self.__notifiers = None
@@@ -83,7 -84,7 +84,7 @@@
  
        # you need to override this if str(self.value) doesn't work
        def save(self):
-               if self.save_disabled or self.value == self.default:
+               if self.save_disabled or (self.value == self.default and not self.save_forced):
                        self.saved_value = None
                else:
                        self.saved_value = self.tostring(self.value)
@@@ -178,7 -179,7 +179,7 @@@ class choicesList(object): # XXX: we mi
  
        def __list__(self):
                if self.type == choicesList.LIST_TYPE_LIST:
 -                      ret = [not isinstance(x, tuple) and x or x[0] for x in self.choices]
 +                      ret = [not isinstance(x, tuple) and x or len(x) > 0 and x[0] or len(x) == 0 and x for x in self.choices]
                else:
                        ret = self.choices.keys()
                return ret or [""]
@@@ -95,6 -95,7 +95,7 @@@ class NimSetup(Screen, ConfigListScreen
                self.advancedType = None
                self.advancedManufacturer = None
                self.advancedSCR = None
+               self.advancedConnected = None
                
                if self.nim.isMultiType():
                        multiType = self.nimConfig.multiType
                checkList = (self.configMode, self.diseqcModeEntry, self.advancedSatsEntry, \
                        self.advancedLnbsEntry, self.advancedDiseqcMode, self.advancedUsalsEntry, \
                        self.advancedLof, self.advancedPowerMeasurement, self.turningSpeed, \
-                       self.advancedType, self.advancedSCR, self.advancedManufacturer, self.advancedUnicable, \
+                       self.advancedType, self.advancedSCR, self.advancedManufacturer, self.advancedUnicable, self.advancedConnected, \
                        self.uncommittedDiseqcCommand, self.cableScanType, self.multiType)
                if self["config"].getCurrent() == self.multiType:
                        from Components.NimManager import InitNimManager
                                        self.list.append(self.advancedType)
                                        self.list.append(self.advancedSCR)
                                        self.list.append(getConfigListEntry(_("Frequency"), manufacturer.vco[product_name][manufacturer.scr[product_name].index])) 
+                               choices = []
+                               connectable = nimmanager.canConnectTo(self.slotid)
+                               for id in connectable:
+                                       choices.append((str(id), nimmanager.getNimDescription(id)))
+                               if len(choices):
+                                       self.advancedConnected = getConfigListEntry(_("connected"), self.nimConfig.advanced.unicableconnected)
+                                       self.list.append(self.advancedConnected)
+                                       if self.nimConfig.advanced.unicableconnected.value == True:
+                                               self.nimConfig.advanced.unicableconnectedTo.setChoices(choices)
+                                               self.list.append(getConfigListEntry(_("Connected to"),self.nimConfig.advanced.unicableconnectedTo))
                        else:   #kein Unicable
                                self.list.append(getConfigListEntry(_("Voltage mode"), Sat.voltage))
                                self.list.append(getConfigListEntry(_("Increased voltage"), currLnb.increased_voltage))
                new_configured_sats = nimmanager.getConfiguredSats()
                self.unconfed_sats = old_configured_sats - new_configured_sats
                self.satpos_to_remove = None
 -              self.restoreService(_("Zap back to service before tuner setup?"))
                self.deleteConfirmed((None, "no"))
  
        def deleteConfirmed(self, confirmed):
                        if confirmed[1] == "yestoall" or confirmed[1] == "notoall":
                                self.deleteConfirmed(confirmed)
                        break
 -              
 +              else:
 +                      self.restoreService(_("Zap back to service before tuner setup?"))
 +
        def __init__(self, session, slotid):
                Screen.__init__(self, session)
                self.list = [ ]