X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/271b34fd82da86aa15e3da90703c59d822e89826..37b38cb05fc6bc4993f852a78bdba93c7627cf5b:/lib/dvb/sec.cpp diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index 10b2c2c1..2b7f717b 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -36,8 +36,8 @@ void eDVBSatelliteEquipmentControl::setParam(int param, int value) m_params[param]=value; } -eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends) - :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_rotorMoving(false) +eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends, eSmartPtrList &avail_simulate_frontends) + :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(false) { if (!instance) instance = this; @@ -114,9 +114,27 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrListis_simulate(); + bool direct_connected = m_not_linked_slot_mask & slot_id; + int score=0, satcount=0; + + if (highest_score_lnb) + *highest_score_lnb = -1; + + eSecDebugNoSimulate("canTune %d", slot_id); for (int idx=0; idx <= m_lnbidx; ++idx ) { @@ -124,14 +142,18 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx]; if ( lnb_param.slot_mask & slot_id ) // lnb for correct tuner? { + int ret = 0; eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters; + eSecDebugNoSimulate("lnb %d found", idx); + satcount += lnb_param.m_satellites.size(); std::map::iterator sit = lnb_param.m_satellites.find(sat.orbital_position); if ( sit != lnb_param.m_satellites.end()) { + bool diseqc=false; long band=0, linked_prev_ptr=-1, linked_next_ptr=-1, @@ -141,6 +163,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite toneburst = di_param.m_toneburst_param, curRotorPos; + eSecDebugNoSimulate("sat %d found", sat.orbital_position); fe->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr); @@ -149,8 +172,6 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical)) band |= 2; - bool diseqc=false; - if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0) { diseqc=true; @@ -171,11 +192,14 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite ret = 15000; } - if (m_not_linked_slot_mask & slot_id) // frontend with direct connection? + eSecDebugNoSimulate("ret1 %d", ret); + + if (direct_connected) // frontend with direct connection? { long ocsw = -1, oucsw = -1, oToneburst = -1; + eSecDebugNoSimulate("direct"); fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos); fe->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); fe->getData(eDVBFrontend::CSW, ocsw); @@ -195,6 +219,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr); } + eSecDebugNoSimulate("ret2 %d", ret); while (ret && linked_next_ptr != -1) // check for linked tuners.. { eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr; @@ -209,6 +234,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr); } + eSecDebugNoSimulate("ret3 %d", ret); } else // linked frontend.. { @@ -228,6 +254,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite sec_fe->getData(eDVBFrontend::CSW, ocsw); sec_fe->getData(eDVBFrontend::UCSW, oucsw); sec_fe->getData(eDVBFrontend::TONEBURST, oToneburst); + eSecDebug("(%ld != %ld) || \n(%d && (%ld != %ld || %ld != %ld) ) ||\n( %d && %ld != %d ) )", + csw, ocsw, diseqc, ucsw, oucsw, toneburst, oToneburst, rotor, curRotorPos, sat.orbital_position); if ( (csw != ocsw) || ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) || ( rotor && curRotorPos != sat.orbital_position ) ) @@ -237,22 +265,29 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } } } + eSecDebugNoSimulate("ret4 %d", ret); } - if (ret && rotor && curRotorPos != -1) - ret -= abs(curRotorPos-sat.orbital_position); - if (ret) if (satpos_depends_ptr != -1) { + eSecDebugNoSimulate("satpos depends"); eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr; if ( satpos_depends_to_fe->m_inuse ) { + if (!direct_connected) + satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, curRotorPos); if (!rotor || curRotorPos != sat.orbital_position) ret=0; } + eSecDebugNoSimulate("ret5 %d", ret); } + if (ret && rotor && curRotorPos != -1 && (direct_connected || satpos_depends_ptr == -1) ) // direct conntected or loopthrough! + ret -= abs(curRotorPos-sat.orbital_position); + + eSecDebugNoSimulate("ret6 %d", ret); + if (ret) { int lof = sat.frequency > lnb_param.m_lof_threshold ? @@ -261,14 +296,24 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite if (tuner_freq < 900000 || tuner_freq > 2200000) ret=0; } + + eSecDebugNoSimulate("ret %d, score old %d", ret, score); + if (ret > score) + { + score = ret; + if (highest_score_lnb) + *highest_score_lnb = idx; + } + eSecDebugNoSimulate("score new %d", score); } } } - if (ret && satcount) - ret -= (satcount-1); - if (ret && m_not_linked_slot_mask & slot_id) - ret += 5; // increase score for tuners with direct sat connection - return ret; + if (score && satcount) + score -= (satcount-1); + if (score && direct_connected) + score += 5; // increase score for tuners with direct sat connection + eSecDebugNoSimulate("final score %d", score); + return score; } bool need_turn_fast(int turn_speed) @@ -297,13 +342,24 @@ bool need_turn_fast(int turn_speed) #define VOLTAGE(x) (lnb_param.m_increased_voltage ? iDVBFrontend::voltage##x##_5 : iDVBFrontend::voltage##x) +#define eDebugNoSimulate(x...) \ + do { \ + 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) { - for (int idx=0; idx <= m_lnbidx; ++idx ) + bool simulate = ((eDVBFrontend*)&frontend)->is_simulate(); + int lnb_idx = -1; + if (canTune(sat, &frontend, slot_id, &lnb_idx)) { - eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx]; - if (!(lnb_param.slot_mask & slot_id)) // lnb for correct tuner? - continue; + eDVBSatelliteLNBParameters &lnb_param = m_lnbs[lnb_idx]; eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters; eDVBSatelliteRotorParameters &rotor_param = lnb_param.m_rotor_parameters; @@ -314,8 +370,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA eDVBSatelliteSwitchParameters &sw_param = sit->second; bool doSetFrontend = true; bool doSetVoltageToneFrontend = true; - bool allowDiseqc1_2 = true; bool sendDiSEqC = false; + bool forceChanged = false; + bool needDiSEqCReset = false; long band=0, voltage = iDVBFrontend::voltageOff, tone = iDVBFrontend::toneOff, @@ -329,6 +386,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA curRotorPos = -1, satposDependPtr = -1; iDVBFrontend *sec_fe=&frontend; + eDVBRegisteredFrontend *linked_fe = 0; + eDVBSatelliteDiseqcParameters::t_diseqc_mode diseqc_mode = di_param.m_diseqc_mode; frontend.getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satposDependPtr); @@ -338,12 +397,20 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA frontend.getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); while (linked_prev_ptr != -1) { - eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr; + linked_fe = (eDVBRegisteredFrontend*) linked_prev_ptr; sec_fe = linked_fe->m_frontend; sec_fe->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr); } - if (satposDependPtr != -1) - allowDiseqc1_2 = false; + if (satposDependPtr != -1) // we dont need uncommitted switch and rotor cmds on second output of a rotor lnb + diseqc_mode = eDVBSatelliteDiseqcParameters::V1_0; + 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) + int state; + sec_fe->getState(state); + if (!linked_fe->m_inuse && state != eDVBFrontend::stateIdle) + forceChanged = true; + } } sec_fe->getData(eDVBFrontend::CSW, lastcsw); @@ -352,6 +419,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_fe->getData(eDVBFrontend::ROTOR_CMD, lastRotorCmd); sec_fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos); + if (lastcsw == lastucsw && lastToneburst == lastucsw && lastucsw == -1) + needDiSEqCReset = true; + if ( sat.frequency > lnb_param.m_lof_threshold ) band |= 1; @@ -384,7 +454,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA eSecCommandList sec_sequence; - if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0) + if (diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0) { if ( di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO ) csw = 0xF0 | (csw << 2); @@ -394,15 +464,15 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA bool send_csw = (di_param.m_committed_cmd != eDVBSatelliteDiseqcParameters::SENDNO); - bool changed_csw = send_csw && csw != lastcsw; + bool changed_csw = send_csw && (forceChanged || csw != lastcsw); bool send_ucsw = - (di_param.m_uncommitted_cmd && di_param.m_diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0); - bool changed_ucsw = send_ucsw && ucsw != lastucsw; + (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 && toneburst != lastToneburst; + bool changed_burst = send_burst && (forceChanged || toneburst != lastToneburst); int send_mask = 0; /* 1 must send csw @@ -436,7 +506,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA && di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO && (lastcsw & 0xF0) && ((csw / 4) == (lastcsw / 4)) ) - eDebug("dont send committed cmd (fast diseqc)"); + eDebugNoSimulate("dont send committed cmd (fast diseqc)"); else { send_mask |= 1; @@ -460,15 +530,14 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA { int RotorCmd=-1; bool useGotoXX = false; - if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 - && !sat.no_rotor_command_on_tune - && allowDiseqc1_2 ) + 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 { - eDebug("Entry for %d,%d? not in Rotor Table found... i try gotoXX?", sat.orbital_position / 10, sat.orbital_position % 10 ); + 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, @@ -481,10 +550,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST ) SiteLon = 360 - SiteLon; - eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon ); + eDebugNoSimulate("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon ); double satHourAngle = calcSatHourangle( SatLon, SiteLat, SiteLon ); - eDebug("PolarmountHourAngle=%lf", satHourAngle ); + eDebugNoSimulate("PolarmountHourAngle=%lf", satHourAngle ); static int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; @@ -514,7 +583,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA RotorCmd |= 0xE000; } } - eDebug("RotorCmd = %04x", RotorCmd); + eDebugNoSimulate("RotorCmd = %04x", RotorCmd); } } @@ -558,6 +627,23 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA 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] = 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]) ); + } + for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat) { if ( send_mask & 4 ) @@ -633,11 +719,14 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA 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]) ); } sendDiSEqC = true; } - eDebug("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd); + eDebugNoSimulate("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd); if ( RotorCmd != -1 && RotorCmd != lastRotorCmd ) { eSecCommand::pair compare; @@ -805,8 +894,8 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA csw = band; } - if (sendDiSEqC) - sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) ); +// if (sendDiSEqC) + sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) ); sec_fe->setData(eDVBFrontend::NEW_CSW, csw); sec_fe->setData(eDVBFrontend::NEW_UCSW, ucsw); @@ -834,16 +923,25 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) ); } - if (sendDiSEqC) - sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) ); +// if (sendDiSEqC) + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) ); frontend.setSecSequence(sec_sequence); return 0; } } - - eDebug("found no useable satellite configuration for orbital position (%d)", sat.orbital_position ); + eDebugNoSimulate("found no useable satellite configuration for %s freq %d%s %s on orbital position (%d)", + sat.system ? "DVB-S2" : "DVB-S", + sat.frequency, + sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal ? "H" : + eDVBFrontendParametersSatellite::Polarisation::Vertical ? "V" : + eDVBFrontendParametersSatellite::Polarisation::CircularLeft ? "CL" : "CR", + sat.modulation == eDVBFrontendParametersSatellite::Modulation::Auto ? "AUTO" : + eDVBFrontendParametersSatellite::Modulation::QPSK ? "QPSK" : + eDVBFrontendParametersSatellite::Modulation::M8PSK ? "8PSK" : "QAM16", + sat.orbital_position ); return -1; } @@ -881,6 +979,15 @@ RESULT eDVBSatelliteEquipmentControl::clear() it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1); } + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + it->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1); + it->m_frontend->setData(eDVBFrontend::ROTOR_POS, -1); + it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1); + } + return 0; } @@ -1222,6 +1329,20 @@ RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2) fclose(f); } } + } + + p1=p2=NULL; + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + if (it->m_frontend->getSlotID() == tu1) + p1 = *it; + else if (it->m_frontend->getSlotID() == tu2) + p2 = *it; + } + if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)p2); + p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)p1); return 0; } } @@ -1244,11 +1365,26 @@ RESULT eDVBSatelliteEquipmentControl::setTunerDepends(int tu1, int tu2) p2 = *it; } if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p2); + p2->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p1); + } + + p1=p2=NULL; + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + if (it->m_frontend->getSlotID() == tu1) + p1 = *it; + else if (it->m_frontend->getSlotID() == tu2) + p2 = *it; + } + if (p1 && p2) { p1->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p2); p2->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p1); return 0; } + return -1; }