Remove check legacy dvbapi version.
[vuplus_dvbapp] / lib / dvb / sec.cpp
index a2bc886..335c8b1 100644 (file)
@@ -2,15 +2,8 @@
 #include <lib/dvb/sec.h>
 #include <lib/dvb/rotor_calc.h>
 #include <lib/dvb/dvbtime.h>
-
-#include <set>
-
-#if HAVE_DVB_API_VERSION < 3
-#define FREQUENCY Frequency
-#else
-#define FREQUENCY frequency
-#endif
 #include <lib/base/eerror.h>
+#include <set>
 
 //#define SEC_DEBUG
 
@@ -49,18 +42,13 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBR
                if (!simulate) \
                        eSecDebug(x); \
        } while(0)
-//             else \
-//             { \
-//                     eDebugNoNewLine("SIMULATE:"); \
-//                     eDebug(x); \
-//             } \
 
 int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite &sat, iDVBFrontend *fe, int slot_id, int *highest_score_lnb)
 {
        bool simulate = ((eDVBFrontend*)fe)->is_simulate();
        bool direct_connected = m_not_linked_slot_mask & slot_id;
        int score=0, satcount=0;
-       long linked_prev_ptr=-1, linked_next_ptr=-1, linked_csw=-1, linked_ucsw=-1, linked_toneburst=-1,
+       long linked_prev_ptr=-1, linked_next_ptr=-1, linkable_csw=-1, linkable_ucsw=-1, linkable_toneburst=-1,
                fe_satpos_depends_ptr=-1, fe_rotor_pos=-1;
        bool linked_in_use = false;
 
@@ -94,9 +82,9 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
        // when a linked in use tuner is found we get the tuner data...
        if (linked_in_use)
        {
-               fe->getData(eDVBFrontend::CSW, linked_csw);
-               fe->getData(eDVBFrontend::UCSW, linked_ucsw);
-               fe->getData(eDVBFrontend::TONEBURST, linked_toneburst);
+               fe->getData(eDVBFrontend::LINKABLE_CSW, linkable_csw);
+               fe->getData(eDVBFrontend::LINKABLE_UCSW, linkable_ucsw);
+               fe->getData(eDVBFrontend::LINKABLE_TONEBURST, linkable_toneburst);
        }
 
        if (highest_score_lnb)
@@ -169,8 +157,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                if (linked_in_use && !is_unicable)
                                {
                                        // compare tuner data
-                                       if ( (csw != linked_csw) ||
-                                               ( diseqc && (ucsw != linked_ucsw || toneburst != linked_toneburst) ) ||
+                                       if ( (csw != linkable_csw) ||
+                                               ( diseqc && (ucsw != linkable_ucsw || toneburst != linkable_toneburst) ) ||
                                                ( rotor && rotor_pos != sat.orbital_position ) )
                                        {
                                                ret = 0;
@@ -279,11 +267,6 @@ bool need_turn_fast(int turn_speed)
                if (!simulate) \
                        eDebug(x); \
        } while(0)
-//             else \
-//             { \
-//                     eDebugNoNewLine("SIMULATE:"); \
-//                     eDebug(x); \
-//             } \
 
 RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int slot_id, unsigned int tunetimeout)
 {
@@ -324,16 +307,21 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        bool diseqc13V = voltage_mode == eDVBSatelliteSwitchParameters::HV_13;
                        bool is_unicable = lnb_param.SatCR_idx != -1;
 
+                       bool useGotoXX = false;
+                       int RotorCmd=-1;
+                       int send_mask = 0;
+
+                       bool direct_connected = m_not_linked_slot_mask & slot_id;
+
                        lnb_param.guard_offset = 0; //HACK
 
-                       frontend.setData(eDVBFrontend::SATCR, lnb_param.SatCR_idx);
 
                        if (diseqc13V)
                                voltage_mode = eDVBSatelliteSwitchParameters::HV;
 
                        frontend.getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satposDependPtr);
 
-                       if (!(m_not_linked_slot_mask & slot_id))  // frontend with direct connection?
+                       if (!direct_connected)  // frontend with direct connection?
                        {
                                long linked_prev_ptr;
                                frontend.getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
@@ -345,6 +333,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                }
                                if (satposDependPtr != -1)  // we dont need uncommitted switch and rotor cmds on second output of a rotor lnb
                                        diseqc_mode = eDVBSatelliteDiseqcParameters::V1_0;
+#if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
                                else {
                                        // in eDVBFrontend::tuneLoop we call closeFrontend and ->inc_use() in this this condition (to put the kernel frontend thread into idle state)
                                        // so we must resend all diseqc stuff (voltage is disabled when the frontend is closed)
@@ -353,6 +342,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                        if (!linked_fe->m_inuse && state != eDVBFrontend::stateIdle)
                                                forceChanged = true;
                                }
+#endif
                        }
 
                        sec_fe->getData(eDVBFrontend::CSW, lastcsw);
@@ -374,10 +364,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        if(!is_unicable)
                        {
                                // calc Frequency
-                               int local= abs(sat.frequency 
+                               int local= abs(sat.frequency
                                        - lof);
-                               parm.FREQUENCY = ((((local * 2) / 125) + 1) / 2) * 125;
-                               frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - parm.FREQUENCY);
+                               parm.frequency = ((((local * 2) / 125) + 1) / 2) * 125;
+                               frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - parm.frequency);
 
                                if ( voltage_mode == eDVBSatelliteSwitchParameters::_14V
                                        || ( sat.polarisation & eDVBFrontendParametersSatellite::Polarisation_Vertical
@@ -396,21 +386,53 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        }
                        else
                        {
-                               int tmp1 = abs(sat.frequency 
-                                               -lof)
-                                               + lnb_param.SatCRvco
-                                               - 1400000
-                                               + lnb_param.guard_offset;
-                               int tmp2 = ((((tmp1 * 2) / 4000) + 1) / 2) * 4000;
-                               parm.FREQUENCY = lnb_param.SatCRvco - (tmp1-tmp2) + lnb_param.guard_offset;
-                               lnb_param.UnicableTuningWord = ((tmp2 / 4000) 
-                                               | ((band & 1) ? 0x400 : 0)                      //HighLow
-                                               | ((band & 2) ? 0x800 : 0)                      //VertHor
-                                               | ((lnb_param.LNBNum & 1) ? 0 : 0x1000)                 //Umschaltung LNB1 LNB2
-                                               | (lnb_param.SatCR_idx << 13));         //Adresse des SatCR
-                                               eDebug("[prepare] UnicableTuningWord %#04x",lnb_param.UnicableTuningWord);
-                                               eDebug("[prepare] guard_offset %d",lnb_param.guard_offset);
-                               frontend.setData(eDVBFrontend::FREQ_OFFSET, (lnb_param.UnicableTuningWord & 0x3FF) *4000 + 1400000 + lof - (2 * (lnb_param.SatCRvco - (tmp1-tmp2))) );
+                               switch(lnb_param.SatCR_format)
+                               {
+                                       case 1:
+                                               {
+                                                       eDebug("[prepare] JESS");
+
+                                                       int tmp1 = abs(sat.frequency
+                                                               -lof)
+                                                               - 100000;
+                                                       volatile unsigned int tmp2 = (1000 + 2 * tmp1) / (2 *1000); //round to multiple of 1000
+                                                       parm.frequency = lnb_param.SatCRvco - (tmp1 - (1000 * tmp2));
+                                                       frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - lof -(lnb_param.SatCRvco - parm.frequency));
+
+                                                       lnb_param.UnicableTuningWord =
+                                                                 (band & 0x3)                                          //Bit0:HighLow  Bit1:VertHor
+                                                               | (((lnb_param.LNBNum - 1) & 0x3F) << 2)                        //position number (max. 63)
+                                                               | ((tmp2 & 0x7FF)<< 8)                                  //frequency (-100MHz Offset)
+                                                               | ((lnb_param.SatCR_idx & 0x1F) << 19);                 //adresse of SatCR (max. 32)
+
+                                                       eDebug("[prepare] UnicableTuningWord %#06x",lnb_param.UnicableTuningWord);
+                                               }
+                                               break;
+                                       case 0:
+                                       default:
+                                               {
+                                                       eDebug("[prepare] Unicable");
+                                                       int tmp1 = abs(sat.frequency
+                                                               -lof)
+                                                               + lnb_param.SatCRvco
+                                                               - 1400000
+                                                               + lnb_param.guard_offset;
+                                                       volatile unsigned int tmp2 = (4000 + 2 * tmp1) / (2 *4000); //round to multiple of 4000
+
+                                                       parm.frequency = lnb_param.SatCRvco - (tmp1 - (4000 * tmp2)) + lnb_param.guard_offset;
+                                                       lnb_param.UnicableTuningWord = tmp2
+                                                               | ((band & 1) ? 0x400 : 0)                      //HighLow
+                                                               | ((band & 2) ? 0x800 : 0)                      //VertHor
+                                                               | ((lnb_param.LNBNum & 1) ? 0 : 0x1000)                 //Umschaltung LNB1 LNB2
+                                                               | (lnb_param.SatCR_idx << 13);          //Adresse des SatCR
+
+                                                       eDebug("[prepare] UnicableTuningWord %#04x",lnb_param.UnicableTuningWord);
+                                                       eDebug("[prepare] guard_offset %d",lnb_param.guard_offset);
+
+                                                       frontend.setData(eDVBFrontend::FREQ_OFFSET, (lnb_param.UnicableTuningWord & 0x3FF) *4000 + 1400000 + lof - (2 * (lnb_param.SatCRvco - (tmp1 - (4000 * tmp2)))) );
+                                               }
+                               }
+                               voltage = VOLTAGE(13);
                        }
 
                        if (diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
@@ -423,17 +445,24 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
 
                                bool send_csw =
                                        (di_param.m_committed_cmd != eDVBSatelliteDiseqcParameters::SENDNO);
-                               bool changed_csw = send_csw && (forceChanged || csw != lastcsw);
 
                                bool send_ucsw =
                                        (di_param.m_uncommitted_cmd && diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
-                               bool changed_ucsw = send_ucsw && (forceChanged || ucsw != lastucsw);
 
                                bool send_burst =
                                        (di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO);
-                               bool changed_burst = send_burst && (forceChanged || toneburst != lastToneburst);
 
-                               int send_mask = 0; /*
+                               bool changed_csw = false;
+                               bool changed_ucsw = false;
+                               bool changed_burst = false;
+                               if (direct_connected || (linked_fe && (!linked_fe->m_frontend->isLoopTimerActive() || !linked_fe->m_frontend->isScheduledSendDiseqc())))
+                               {
+                                       changed_csw = send_csw && (forceChanged || csw != lastcsw);
+                                       changed_ucsw = send_ucsw && (forceChanged || ucsw != lastucsw);
+                                       changed_burst = send_burst && (forceChanged || toneburst != lastToneburst);
+                               }
+
+                               /* send_mask
                                        1 must send csw
                                        2 must send ucsw
                                        4 send toneburst first
@@ -459,7 +488,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                        if (di_param.m_command_order==4 && send_burst)
                                                send_mask |= 8;
                                }
-                               if (changed_csw) 
+                               if (changed_csw)
                                {
                                        if ( di_param.m_use_fast
                                                && di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO
@@ -485,388 +514,201 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                eDebugNoNewLine("0");
                                eDebug("");
 #endif
-                               if (doSetVoltageToneFrontend)
+                               if ( diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2
+                                       && !sat.no_rotor_command_on_tune )
                                {
-                                       int RotorCmd=-1;
-                                       bool useGotoXX = false;
-                                       if ( diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2
-                                               && !sat.no_rotor_command_on_tune )
+                                       if (sw_param.m_rotorPosNum) // we have stored rotor pos?
+                                               RotorCmd=sw_param.m_rotorPosNum;
+                                       else  // we must calc gotoxx cmd
                                        {
-                                               if (sw_param.m_rotorPosNum) // we have stored rotor pos?
-                                                       RotorCmd=sw_param.m_rotorPosNum;
-                                               else  // we must calc gotoxx cmd
-                                               {
-                                                       eDebugNoSimulate("Entry for %d,%d? not in Rotor Table found... i try gotoXX?", sat.orbital_position / 10, sat.orbital_position % 10 );
-                                                       useGotoXX = true;
-       
-                                                       double  SatLon = abs(sat.orbital_position)/10.00,
-                                                                       SiteLat = rotor_param.m_gotoxx_parameters.m_latitude,
-                                                                       SiteLon = rotor_param.m_gotoxx_parameters.m_longitude;
-       
-                                                       if ( rotor_param.m_gotoxx_parameters.m_la_direction == eDVBSatelliteRotorParameters::SOUTH )
-                                                               SiteLat = -SiteLat;
-       
-                                                       if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST )
-                                                               SiteLon = 360 - SiteLon;
-       
-                                                       eDebugNoSimulate("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon );
-                                                       double satHourAngle =
-                                                               calcSatHourangle( SatLon, SiteLat, SiteLon );
-                                                       eDebugNoSimulate("PolarmountHourAngle=%lf", satHourAngle );
-       
-                                                       static int gotoXTable[10] =
-                                                               { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
-       
-                                                       if (SiteLat >= 0) // Northern Hemisphere
-                                                       {
-                                                               int tmp=(int)round( fabs( 180 - satHourAngle ) * 10.0 );
-                                                               RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
-       
-                                                               if (satHourAngle < 180) // the east
-                                                                       RotorCmd |= 0xE000;
-                                                               else                                    // west
-                                                                       RotorCmd |= 0xD000;
-                                                       }
-                                                       else // Southern Hemisphere
-                                                       {
-                                                               if (satHourAngle < 180) // the east
-                                                               {
-                                                                       int tmp=(int)round( fabs( satHourAngle ) * 10.0 );
-                                                                       RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
-                                                                       RotorCmd |= 0xD000;
-                                                               }
-                                                               else // west
-                                                               {
-                                                                       int tmp=(int)round( fabs( 360 - satHourAngle ) * 10.0 );
-                                                                       RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
-                                                                       RotorCmd |= 0xE000;
-                                                               }
-                                                       }
-                                                       eDebugNoSimulate("RotorCmd = %04x", RotorCmd);
-                                               }
-                                       }
+                                               eDebugNoSimulate("Entry for %d,%d? not in Rotor Table found... i try gotoXX?", sat.orbital_position / 10, sat.orbital_position % 10 );
+                                               useGotoXX = true;
 
-                                       if ( send_mask )
-                                       {
-                                               int diseqc_repeats = diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0 ? di_param.m_repeats : 0;
-                                               int vlt = iDVBFrontend::voltageOff;
-                                               eSecCommand::pair compare;
-                                               compare.steps = +3;
-                                               compare.tone = iDVBFrontend::toneOff;
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
-
-                                               if (diseqc13V)
-                                                       vlt = iDVBFrontend::voltage13;
-                                               else if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
-                                               {
-                                                       if (rotor_param.m_inputpower_parameters.m_use)
-                                                               vlt = VOLTAGE(18);  // in input power mode set 18V for measure input power
-                                                       else
-                                                               vlt = VOLTAGE(13);  // in normal mode start turning with 13V
-                                               }
-                                               else
-                                                       vlt = voltage;
+                                               double  SatLon = abs(sat.orbital_position)/10.00,
+                                                               SiteLat = rotor_param.m_gotoxx_parameters.m_latitude,
+                                                               SiteLon = rotor_param.m_gotoxx_parameters.m_longitude;
 
-                                               // check if voltage is already correct..
-                                               compare.voltage = vlt;
-                                               compare.steps = +7;
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+                                               if ( rotor_param.m_gotoxx_parameters.m_la_direction == eDVBSatelliteRotorParameters::SOUTH )
+                                                       SiteLat = -SiteLat;
 
-                                               // check if voltage is disabled
-                                               compare.voltage = iDVBFrontend::voltageOff;
-                                               compare.steps = +4;
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+                                               if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST )
+                                                       SiteLon = 360 - SiteLon;
 
-                                               // voltage is changed... use DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS]) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
+                                               eDebugNoSimulate("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon );
+                                               double satHourAngle =
+                                                       calcSatHourangle( SatLon, SiteLat, SiteLon );
+                                               eDebugNoSimulate("PolarmountHourAngle=%lf", satHourAngle );
 
-                                               // voltage was disabled.. use DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS]) );
+                                               static int gotoXTable[10] =
+                                                       { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
 
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS) );
-                                               if (needDiSEqCReset)
+                                               if (SiteLat >= 0) // Northern Hemisphere
                                                {
-                                                       eDVBDiseqcCommand diseqc;
-                                                       memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
-                                                       diseqc.len = 3;
-                                                       diseqc.data[0] = 0xE0;
-                                                       diseqc.data[1] = 0;
-                                                       diseqc.data[2] = 0;
-                                                       // diseqc reset
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_DISEQC_RESET_CMD]) );
-                                                       diseqc.data[2] = 3;
-                                                       // diseqc peripherial powersupply on
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD]) );
-                                               }
+                                                       int tmp=(int)round( fabs( 180 - satHourAngle ) * 10.0 );
+                                                       RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
 
-                                               for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat)
+                                                       if (satHourAngle < 180) // the east
+                                                               RotorCmd |= 0xE000;
+                                                       else                                    // west
+                                                               RotorCmd |= 0xD000;
+                                               }
+                                               else // Southern Hemisphere
                                                {
-                                                       if ( send_mask & 4 )
+                                                       if (satHourAngle < 180) // the east
                                                        {
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_TONEBURST]) );
-                                                       }
-
-                                                       int loops=0;
-
-                                                       if ( send_mask & 1 )
-                                                               ++loops;
-                                                       if ( send_mask & 2 )
-                                                               ++loops;
-
-                                                       loops <<= diseqc_repeats;
-
-                                                       for ( int i = 0; i < loops;)  // fill commands...
-                                                       {
-                                                               eDVBDiseqcCommand diseqc;
-                                                               memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
-                                                               diseqc.len = 4;
-                                                               diseqc.data[0] = i ? 0xE1 : 0xE0;
-                                                               diseqc.data[1] = 0x10;
-                                                               if ( (send_mask & 2) && (di_param.m_command_order & 4) )
-                                                               {
-                                                                       diseqc.data[2] = 0x39;
-                                                                       diseqc.data[3] = ucsw;
-                                                               }
-                                                               else if ( send_mask & 1 )
-                                                               {
-                                                                       diseqc.data[2] = 0x38;
-                                                                       diseqc.data[3] = csw;
-                                                               }
-                                                               else  // no committed command confed.. so send uncommitted..
-                                                               {
-                                                                       diseqc.data[2] = 0x39;
-                                                                       diseqc.data[3] = ucsw;
-                                                               }
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-
-                                                               i++;
-                                                               if ( i < loops )
-                                                               {
-                                                                       int cmd=0;
-                                                                       if (diseqc.data[2] == 0x38 && (send_mask & 2))
-                                                                               cmd=0x39;
-                                                                       else if (diseqc.data[2] == 0x39 && (send_mask & 1))
-                                                                               cmd=0x38;
-                                                                       int tmp = m_params[DELAY_BETWEEN_DISEQC_REPEATS];
-                                                                       if (cmd)
-                                                                       {
-                                                                               int delay = diseqc_repeats ? (tmp - 54) / 2 : tmp;  // 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;
-                                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                                                               ++i;
-                                                                               if ( i < loops )
-                                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay ) );
-                                                                               else
-                                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
-                                                                       }
-                                                                       else  // delay 120msek when no command is in repeat gap
-                                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, tmp) );
-                                                               }
-                                                               else
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
+                                                               int tmp=(int)round( fabs( satHourAngle ) * 10.0 );
+                                                               RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+                                                               RotorCmd |= 0xD000;
                                                        }
-
-                                                       if ( send_mask & 8 )  // toneburst at end of sequence
+                                                       else // west
                                                        {
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_TONEBURST]) );
+                                                               int tmp=(int)round( fabs( 360 - satHourAngle ) * 10.0 );
+                                                               RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+                                                               RotorCmd |= 0xE000;
                                                        }
-
-                                                       if (di_param.m_seq_repeat && seq_repeat == 0)
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_BEFORE_SEQUENCE_REPEAT]) );
                                                }
+                                               eDebugNoSimulate("RotorCmd = %04x", RotorCmd);
                                        }
+                               }
 
-                                       eDebugNoSimulate("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd);
-                                       if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
+                               if ( send_mask )
+                               {
+                                       int diseqc_repeats = diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0 ? di_param.m_repeats : 0;
+                                       int vlt = iDVBFrontend::voltageOff;
+                                       eSecCommand::pair compare;
+                                       compare.steps = +3;
+                                       compare.tone = iDVBFrontend::toneOff;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
+
+                                       if (diseqc13V)
+                                               vlt = iDVBFrontend::voltage13;
+                                       else if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
                                        {
-                                               eSecCommand::pair compare;
-                                               if (!send_mask && !is_unicable)
-                                               {
-                                                       compare.steps = +3;
-                                                       compare.tone = iDVBFrontend::toneOff;
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
-
-                                                       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(18)) ); // set 18V for measure input power
-                                                       else
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) ); // in normal mode start turning with 13V
-
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD]) ); // wait 750ms when voltage was disabled
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +9) );  // no need to send stop rotor cmd and recheck voltage
-                                               }
+                                               if (rotor_param.m_inputpower_parameters.m_use && !is_unicable)
+                                                       vlt = VOLTAGE(18);  // in input power mode set 18V for measure input power
                                                else
-                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD]) ); // wait 700ms when diseqc changed
+                                                       vlt = VOLTAGE(13);  // in normal mode start turning with 13V
+                                       }
+                                       else
+                                               vlt = voltage;
 
+                                       // check if voltage is already correct..
+                                       compare.voltage = vlt;
+                                       compare.steps = +7;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+
+                                       // check if voltage is disabled
+                                       compare.voltage = iDVBFrontend::voltageOff;
+                                       compare.steps = +4;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+
+                                       // voltage is changed... use DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS]) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
+
+                                       // voltage was disabled.. use DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, vlt) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS]) );
+
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS) );
+                                       if (needDiSEqCReset)
+                                       {
                                                eDVBDiseqcCommand diseqc;
                                                memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
                                                diseqc.len = 3;
                                                diseqc.data[0] = 0xE0;
-                                               diseqc.data[1] = 0x31;  // positioner
-                                               diseqc.data[2] = 0x60;  // stop
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_ROTORPOS_VALID_GOTO, +5) );
+                                               diseqc.data[1] = 0;
+                                               diseqc.data[2] = 0;
+                                               // diseqc reset
                                                sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_DISEQC_RESET_CMD]) );
+                                               diseqc.data[2] = 3;
+                                               // diseqc peripherial powersupply on
                                                sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                               // wait 150msec after send rotor stop cmd
-                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_MOTOR_STOP_CMD]) );
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_DISEQC_PERIPHERIAL_POWERON_CMD]) );
+                                       }
 
-                                               diseqc.data[0] = 0xE0;
-                                               diseqc.data[1] = 0x31;          // positioner
-                                               if ( useGotoXX )
+                                       for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat)
+                                       {
+                                               if ( send_mask & 4 )
                                                {
-                                                       diseqc.len = 5;
-                                                       diseqc.data[2] = 0x6E;  // drive to angular position
-                                                       diseqc.data[3] = ((RotorCmd & 0xFF00) / 0x100);
-                                                       diseqc.data[4] = RotorCmd & 0xFF;
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_TONEBURST]) );
                                                }
-                                               else
+
+                                               int loops=0;
+
+                                               if ( send_mask & 1 )
+                                                       ++loops;
+                                               if ( send_mask & 2 )
+                                                       ++loops;
+
+                                               loops <<= diseqc_repeats;
+
+                                               for ( int i = 0; i < loops;)  // fill commands...
                                                {
+                                                       eDVBDiseqcCommand diseqc;
+                                                       memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
                                                        diseqc.len = 4;
-                                                       diseqc.data[2] = 0x6B;  // goto stored sat position
-                                                       diseqc.data[3] = RotorCmd;
-                                                       diseqc.data[4] = 0x00;
-                                               }
-//                                             if(!is_unicable)
-                                               {
-                                                       int mrt = m_params[MOTOR_RUNNING_TIMEOUT]; // in seconds!
-                                                       if ( rotor_param.m_inputpower_parameters.m_use && !is_unicable)
-                                                       { // use measure rotor input power to detect rotor state
-                                                               bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
-                                                               eSecCommand::rotor cmd;
-                                                               eSecCommand::pair compare;
-                                                               if (turn_fast)
-                                                                       compare.voltage = VOLTAGE(18);
-                                                               else
-                                                                       compare.voltage = VOLTAGE(13);
-                                                               compare.steps = +3;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
-       // measure idle power values
-                                                               compare.steps = -2;
-                                                               if (turn_fast) {
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) );  // wait 150msec after voltage change
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) );
-                                                                       compare.val = 1;
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) );
-                                                               }
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) );  // wait 150msec before measure
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) );
-                                                               compare.val = 0;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
-       ////////////////////////////
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_DISEQC_RETRYS, m_params[MOTOR_COMMAND_RETRIES]) );  // 2 retries
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) );  // 2 seconds rotor start timout
-       // rotor start loop
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // 50msec delay
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
-                                                               cmd.direction=1;  // check for running rotor
-                                                               cmd.deltaA=rotor_param.m_inputpower_parameters.m_delta;
-                                                               cmd.steps=+5;
-                                                               cmd.okcount=0;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );  // check if rotor has started
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) );  // timeout .. we assume now the rotor is already at the correct position
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // goto loop start
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 10 : 9 ) );  // timeout .. we assume now the rotor is already at the correct position 
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -8) );  // goto loop start
-       ////////////////////
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
-                                                               if (turn_fast)
-                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*20) );  // mrt is in seconds... our SLEEP time is 50ms.. so * 20
-       // rotor running loop
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
-                                                               cmd.direction=0;  // check for stopped rotor
-                                                               cmd.steps=+3;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) );  // timeout ? this should never happen
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // running loop start
-       /////////////////////
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+                                                       diseqc.data[0] = i ? 0xE1 : 0xE0;
+                                                       diseqc.data[1] = 0x10;
+                                                       if ( (send_mask & 2) && (di_param.m_command_order & 4) )
+                                                       {
+                                                               diseqc.data[2] = 0x39;
+                                                               diseqc.data[3] = ucsw;
                                                        }
-                                                       else
-                                                       {  // use normal turning mode
-                                                               if (curRotorPos != -1)
-                                                               {               
-                                                                       mrt = abs(curRotorPos - sat.orbital_position);
-                                                                       if (mrt > 1800)
-                                                                               mrt = 3600 - mrt;
-                                                                       if (mrt % 10)
-                                                                               mrt += 10; // round a little bit
-                                                                       mrt *= 2000;  // (we assume a very slow rotor with just 0.5 degree per second here)
-                                                                       mrt /= 10000;
-                                                                       mrt += 3; // a little bit overhead
+                                                       else if ( send_mask & 1 )
+                                                       {
+                                                               diseqc.data[2] = 0x38;
+                                                               diseqc.data[3] = csw;
+                                                       }
+                                                       else  // no committed command confed.. so send uncommitted..
+                                                       {
+                                                               diseqc.data[2] = 0x39;
+                                                               diseqc.data[3] = ucsw;
+                                                       }
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+
+                                                       i++;
+                                                       if ( i < loops )
+                                                       {
+                                                               int cmd=0;
+                                                               if (diseqc.data[2] == 0x38 && (send_mask & 2))
+                                                                       cmd=0x39;
+                                                               else if (diseqc.data[2] == 0x39 && (send_mask & 1))
+                                                                       cmd=0x38;
+                                                               int tmp = m_params[DELAY_BETWEEN_DISEQC_REPEATS];
+                                                               if (cmd)
+                                                               {
+                                                                       int delay = diseqc_repeats ? (tmp - 54) / 2 : tmp;  // 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;
+                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                                                                       ++i;
+                                                                       if ( i < loops )
+                                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay ) );
+                                                                       else
+                                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
                                                                }
-                                                               doSetVoltageToneFrontend=false;
-                                                               doSetFrontend=false;
-                                                               eSecCommand::rotor cmd;
-                                                               eSecCommand::pair compare;
-                                                               compare.voltage = VOLTAGE(13);
-                                                               compare.steps = +3;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) );  // wait 150msec after voltage change
-       
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); // sleep one second before change voltage or tone
-
-                                                               compare.voltage = voltage;
-                                                               compare.steps = +3;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) );  // wait 2 second before set high voltage
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-
-                                                               compare.tone = tone;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) );
-       
-                                                               cmd.direction=1;  // check for running rotor
-                                                               cmd.deltaA=0;
-                                                               cmd.steps = +3;
-                                                               cmd.okcount=0;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*4) );  // mrt is in seconds... our SLEEP time is 250ms.. so * 4
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );  // 250msec delay
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +5 ) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) );  // goto loop start
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +4) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -5) );
+                                                               else  // delay 120msek when no command is in repeat gap
+                                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, tmp) );
                                                        }
-                                                       eDebug("set rotor timeout to %d seconds", mrt);
-                                                       sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
-                                                       sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
+                                                       else
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
                                                }
+
+                                               if ( send_mask & 8 )  // toneburst at end of sequence
+                                               {
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_TONEBURST]) );
+                                               }
+
+                                               if (di_param.m_seq_repeat && seq_repeat == 0)
+                                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_BEFORE_SEQUENCE_REPEAT]) );
                                        }
                                }
                        }
@@ -879,22 +721,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        sec_fe->setData(eDVBFrontend::NEW_CSW, csw);
                        sec_fe->setData(eDVBFrontend::NEW_UCSW, ucsw);
                        sec_fe->setData(eDVBFrontend::NEW_TONEBURST, di_param.m_toneburst_param);
-
-                       if (doSetVoltageToneFrontend && !is_unicable)
-                       {
-                               eSecCommand::pair compare;
-                               compare.voltage = voltage;
-                               compare.steps = +3;
-                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ?
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_VOLTAGE_CHANGE]) );
-                               compare.tone = tone;
-                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
-                       }
-
-                       sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_SWITCHPARMS) );
+                       sec_fe->setData(eDVBFrontend::LINKABLE_CSW, csw);
+                       sec_fe->setData(eDVBFrontend::LINKABLE_UCSW, ucsw);
+                       sec_fe->setData(eDVBFrontend::LINKABLE_TONEBURST, di_param.m_toneburst_param);
 
                        if(is_unicable)
                        {
@@ -903,27 +732,316 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                compare.steps = +3;
                                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::SET_VOLTAGE, VOLTAGE(13)) );
                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS] ) );
 
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS]) );  // wait 20 ms after voltage change
-       
+
                                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] = lnb_param.UnicableTuningWord >> 8;
-                               diseqc.data[4] = lnb_param.UnicableTuningWord;
+
+                               long oldSatcr, oldPin, oldDiction;
+                               frontend.getData(eDVBFrontend::SATCR, oldSatcr);
+                               frontend.getData(eDVBFrontend::PIN, oldPin);
+                               frontend.getData(eDVBFrontend::DICTION, oldDiction);
+
+                               if((oldSatcr != -1) && (oldSatcr != lnb_param.SatCR_idx))
+                               {
+                                       switch (oldDiction)
+                                       {
+                                               case 1:
+                                                       if(oldPin < 1)
+                                                       {
+                                                               diseqc.len = 4;
+                                                               diseqc.data[0] = 0x70;
+                                                       }
+                                                       else
+                                                       {
+                                                               diseqc.len = 5;
+                                                               diseqc.data[0] = 0x71;
+                                                               diseqc.data[4] = oldPin;
+                                                       }
+                                                       diseqc.data[1] = oldSatcr << 3;
+                                                       diseqc.data[2] = 0x00;
+                                                       diseqc.data[3] = 0x00;
+                                                       break;
+                                               case 0:
+                                               default:
+                                                       if(oldPin < 1)
+                                                       {
+                                                               diseqc.len = 5;
+                                                               diseqc.data[2] = 0x5A;
+                                                       }
+                                                       else
+                                                       {
+                                                               diseqc.len = 6;
+                                                               diseqc.data[2] = 0x5C;
+                                                               diseqc.data[5] = oldPin;
+                                                       }
+                                                       diseqc.data[0] = 0xE0;
+                                                       diseqc.data[1] = 0x10;
+                                                       diseqc.data[3] = oldSatcr << 5;
+                                                       diseqc.data[4] = 0x00;
+                                                       break;
+                                       }
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
+                                       frontend.setData(eDVBFrontend::SATCR, -1);
+                               }
+
+                               frontend.setData(eDVBFrontend::DICTION, lnb_param.SatCR_format);
+//TODO                         frontend.setData(eDVBFrontend::PIN, lnb_param.SatCR_pin);
+
+                               long pin = 0; // hack
+
+                               switch(lnb_param.SatCR_format)
+                               {
+                                       case 1: //JESS
+                                               if(pin < 1)
+                                               {
+                                                       diseqc.len = 4;
+                                                       diseqc.data[0] = 0x70;
+                                                       diseqc.data[1] = lnb_param.UnicableTuningWord >> 16;
+                                                       diseqc.data[2] = lnb_param.UnicableTuningWord >> 8;
+                                                       diseqc.data[3] = lnb_param.UnicableTuningWord;
+                                               }
+                                               else
+                                               {
+                                                       diseqc.len = 5;
+                                                       diseqc.data[0] = 0x71;
+                                                       diseqc.data[4] = pin;
+                                               }
+                                               diseqc.data[1] = lnb_param.UnicableTuningWord >> 16;
+                                               diseqc.data[2] = lnb_param.UnicableTuningWord >> 8;
+                                               diseqc.data[3] = lnb_param.UnicableTuningWord;
+                                               break;
+                                       case 0: //DiSEqC
+                                       default:
+                                               if(pin < 1)
+                                               {
+                                                       diseqc.len = 5;
+                                                       diseqc.data[2] = 0x5A;
+                                               }
+                                               else
+                                               {
+                                                       diseqc.len = 6;
+                                                       diseqc.data[2] = 0x5C;
+                                                       diseqc.data[5] = pin;
+                                               }
+                                               diseqc.data[0] = 0xE0;
+                                               diseqc.data[1] = 0x10;
+                                               diseqc.data[3] = lnb_param.UnicableTuningWord >> 8;
+                                               diseqc.data[4] = lnb_param.UnicableTuningWord;
+                               }
+                               frontend.setData(eDVBFrontend::SATCR, lnb_param.SatCR_idx);
 
                                sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) );
+                               if ( RotorCmd != -1 && RotorCmd != lastRotorCmd && !rotor_param.m_inputpower_parameters.m_use)
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) );  // wait 150msec after voltage change
                        }
 
+                       eDebugNoSimulate("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd);
+                       if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
+                       {
+                               int mrt = m_params[MOTOR_RUNNING_TIMEOUT]; // in seconds!
+                               eSecCommand::pair compare;
+                               if (!send_mask && !is_unicable)
+                               {
+                                       compare.steps = +3;
+                                       compare.tone = iDVBFrontend::toneOff;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
+
+                                       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(18)) ); // set 18V for measure input power
+                                       else
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) ); // in normal mode start turning with 13V
+
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD]) ); // wait 750ms when voltage was disabled
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +9) );  // no need to send stop rotor cmd and recheck voltage
+                               }
+                               else
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_BETWEEN_SWITCH_AND_MOTOR_CMD]) ); // wait 700ms when diseqc changed
+
+                               eDVBDiseqcCommand diseqc;
+                               memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
+                               diseqc.len = 3;
+                               diseqc.data[0] = 0xE0;
+                               diseqc.data[1] = 0x31;  // positioner
+                               diseqc.data[2] = 0x60;  // stop
+                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_ROTORPOS_VALID_GOTO, +5) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                               // wait 150msec after send rotor stop cmd
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_MOTOR_STOP_CMD]) );
+
+                               diseqc.data[0] = 0xE0;
+                               diseqc.data[1] = 0x31;          // positioner
+                               if ( useGotoXX )
+                               {
+                                       diseqc.len = 5;
+                                       diseqc.data[2] = 0x6E;  // drive to angular position
+                                       diseqc.data[3] = ((RotorCmd & 0xFF00) / 0x100);
+                                       diseqc.data[4] = RotorCmd & 0xFF;
+                               }
+                               else
+                               {
+                                       diseqc.len = 4;
+                                       diseqc.data[2] = 0x6B;  // goto stored sat position
+                                       diseqc.data[3] = RotorCmd;
+                                       diseqc.data[4] = 0x00;
+                               }
+
+                       // use measure rotor input power to detect motor state
+                               if ( rotor_param.m_inputpower_parameters.m_use)
+                               {
+                                       bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed) && !is_unicable;
+                                       eSecCommand::rotor cmd;
+                                       eSecCommand::pair compare;
+                                       if (turn_fast)
+                                               compare.voltage = VOLTAGE(18);
+                                       else
+                                               compare.voltage = VOLTAGE(13);
+                                       compare.steps = +3;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
+                       // measure idle power values
+                                       compare.steps = -2;
+                                       if (turn_fast) {
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) );  // wait 150msec after voltage change
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) );
+                                               compare.val = 1;
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) );
+                                       }
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) );  // wait 150msec before measure
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) );
+                                       compare.val = 0;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
+                       ////////////////////////////
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_DISEQC_RETRYS, m_params[MOTOR_COMMAND_RETRIES]) );  // 2 retries
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) );  // 2 seconds rotor start timout
+                       // rotor start loop
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // 50msec delay
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
+                                       cmd.direction=1;  // check for running rotor
+                                       cmd.deltaA=rotor_param.m_inputpower_parameters.m_delta;
+                                       cmd.steps=+5;
+                                       cmd.okcount=0;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );  // check if rotor has started
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) );  // timeout .. we assume now the rotor is already at the correct position
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // goto loop start
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 10 : 9 ) );  // timeout .. we assume now the rotor is already at the correct position 
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -8) );  // goto loop start
+                       ////////////////////
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
+                                       if (turn_fast)
+                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*20) );  // mrt is in seconds... our SLEEP time is 50ms.. so * 20
+                       // rotor running loop
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
+                                       cmd.direction=0;  // check for stopped rotor
+                                       cmd.steps=+3;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) );  // timeout ? this should never happen
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // running loop start
+                       /////////////////////
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+                               }
+                       // use normal motor turning mode
+                               else
+                               {
+                                       if (curRotorPos != -1)
+                                       {
+                                               mrt = abs(curRotorPos - sat.orbital_position);
+                                               if (mrt > 1800)
+                                                       mrt = 3600 - mrt;
+                                               if (mrt % 10)
+                                                       mrt += 10; // round a little bit
+                                               mrt *= 2000;  // (we assume a very slow rotor with just 0.5 degree per second here)
+                                               mrt /= 10000;
+                                               mrt += 3; // a little bit overhead
+                                       }
+                                       doSetVoltageToneFrontend=false;
+                                       doSetFrontend=false;
+                                       eSecCommand::rotor cmd;
+                                       eSecCommand::pair compare;
+                                       compare.voltage = VOLTAGE(13);
+                                       compare.steps = +3;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) );  // wait 150msec after voltage change
+
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); // sleep one second before change voltage or tone
+
+                                       compare.voltage = voltage;
+                                       compare.steps = +3;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) );  // wait 2 second before set high voltage
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
+
+                                       compare.tone = tone;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) );
+
+                                       cmd.direction=1;  // check for running rotor
+                                       cmd.deltaA=0;
+                                       cmd.steps = +3;
+                                       cmd.okcount=0;
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*4) );  // mrt is in seconds... our SLEEP time is 250ms.. so * 4
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );  // 250msec delay
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +5 ) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) );  // goto loop start
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +4) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
+                                       sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -5) );
+                                       eDebug("set rotor timeout to %d seconds", mrt);
+                               }
+                               sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
+                               sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
+                       }
+
+                       if (doSetVoltageToneFrontend && !is_unicable)
+                       {
+                               eSecCommand::pair compare;
+                               compare.voltage = voltage;
+                               compare.steps = +3;
+                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ?
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_VOLTAGE_CHANGE]) );
+                               compare.tone = tone;
+                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
+                       }
+
+                       sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_SWITCHPARMS) );
+
                        if (doSetFrontend)
                        {
                                sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
@@ -952,8 +1070,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
        return -1;
 }
 
-void eDVBSatelliteEquipmentControl::prepareTurnOffSatCR(iDVBFrontend &frontend, int satcr)
+void eDVBSatelliteEquipmentControl::prepareTurnOffSatCR(iDVBFrontend &frontend)
 {
+       long satcr, diction, pin;
        eSecCommandList sec_sequence;
 
        // check if voltage is disabled
@@ -971,12 +1090,48 @@ void eDVBSatelliteEquipmentControl::prepareTurnOffSatCR(iDVBFrontend &frontend,
 
        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;
+       frontend.getData(eDVBFrontend::SATCR, satcr);
+       frontend.getData(eDVBFrontend::DICTION, diction);
+       frontend.getData(eDVBFrontend::PIN, pin);
+
+       switch (diction)
+       {
+               case 1:
+                       if(pin < 1)
+                       {
+                               diseqc.len = 4;
+                               diseqc.data[0] = 0x70;
+                       }
+                       else
+                       {
+                               diseqc.len = 5;
+                               diseqc.data[0] = 0x71;
+                               diseqc.data[4] = pin;
+                       }
+                       diseqc.data[1] = satcr << 3;
+                       diseqc.data[2] = 0x00;
+                       diseqc.data[3] = 0x00;
+                       break;
+               case 0:
+               default:
+                       if(pin < 1)
+                       {
+                               diseqc.len = 5;
+                               diseqc.data[2] = 0x5A;
+                       }
+                       else
+                       {
+                               diseqc.len = 6;
+                               diseqc.data[2] = 0x5C;
+                               diseqc.data[5] = pin;
+                       }
+                       diseqc.data[0] = 0xE0;
+                       diseqc.data[1] = 0x10;
+                       diseqc.data[3] = satcr << 5;
+                       diseqc.data[4] = 0x00;
+                       break;
+       }
+       frontend.setData(eDVBFrontend::SATCR, -1);
 
        sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
        sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
@@ -1008,6 +1163,13 @@ RESULT eDVBSatelliteEquipmentControl::clear()
                it->m_frontend->setData(eDVBFrontend::ROTOR_POS, -1);
                it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1);
                it->m_frontend->setData(eDVBFrontend::SATCR, -1);
+
+               if (it->m_frontend->is_FBCTuner())
+               {
+                       eFBCTunerManager *fbcmng = eFBCTunerManager::getInstance();
+                       if (fbcmng)
+                               fbcmng->setDefaultFBCID(*it);
+               }
        }
 
        for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it)
@@ -1252,6 +1414,18 @@ RESULT eDVBSatelliteEquipmentControl::setInputpowerDelta(int delta)
 }
 
 /* Unicable Specific Parameters */
+RESULT eDVBSatelliteEquipmentControl::setLNBSatCRformat(int SatCR_format)
+{
+       eSecDebug("eDVBSatelliteEquipmentControl::setLNBSatCRformat(%d)", SatCR_format);
+       if(!((SatCR_format >-1) && (SatCR_format < 2)))
+               return -EPERM;
+       if ( currentLNBValid() )
+               m_lnbs[m_lnbidx].SatCR_format = SatCR_format;
+       else
+               return -ENOENT;
+       return 0;
+}
+
 RESULT eDVBSatelliteEquipmentControl::setLNBSatCR(int SatCR_idx)
 {
        eSecDebug("eDVBSatelliteEquipmentControl::setLNBSatCR(%d)", SatCR_idx);
@@ -1297,6 +1471,13 @@ RESULT eDVBSatelliteEquipmentControl::getLNBSatCRpositions()
        return -ENOENT;
 }
 
+RESULT eDVBSatelliteEquipmentControl::getLNBSatCRformat()
+{
+       if ( currentLNBValid() )
+               return m_lnbs[m_lnbidx].SatCR_format;
+       return -ENOENT;
+}
+
 RESULT eDVBSatelliteEquipmentControl::getLNBSatCR()
 {
        if ( currentLNBValid() )
@@ -1433,6 +1614,12 @@ RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2)
                        char c;
                        p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)p2);
                        p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)p1);
+
+                       eFBCTunerManager *fbcmng = eFBCTunerManager::getInstance();
+                       if (p1->m_frontend->is_FBCTuner() && fbcmng)
+                       {
+                               fbcmng->updateFBCID(p1, p2);
+                       }
                }
 
                p1=p2=NULL;