trunk 20080912
[gitenigma.git] / lib / dvb / frontend.cpp
blobc5000a84bfcdd5567021a260ef3edb8c7e075512
1 #include <lib/dvb/frontend.h>
3 #include <config.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/ioctl.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <error.h>
12 #include <cmath>
14 #include <lib/base/ebase.h>
15 #include <lib/dvb/edvb.h>
16 #include <lib/dvb/esection.h>
17 #include <lib/dvb/decoder.h>
18 #include <lib/system/econfig.h>
19 #include <lib/system/info.h>
20 #include <lib/driver/rc.h>
22 // need this to check if currently a dvb service running..
23 // for lostlock/retune handling..
24 // when no dvb service is running or needed we call savePower..
25 #include <lib/dvb/service.h>
26 // for check if in background a recording is running
27 #include <lib/dvb/edvb.h>
28 #include <lib/system/math.h>
30 eFrontend* eFrontend::frontend;
32 eFrontend::eFrontend(int type, const char *demod, const char *sec)
33 :type(type),
34 curRotorPos(10000), transponder(0), rotorTimer1(eApp),
35 rotorTimer2(eApp),
36 #if HAVE_DVB_API_VERSION >= 3
37 timeout(eApp),
38 #endif
39 checkRotorLockTimer(eApp), checkLockTimer(eApp),
40 updateTransponderTimer(eApp), sn(0), noRotorCmd(0)
42 CONNECT(rotorTimer1.timeout, eFrontend::RotorStartLoop );
43 CONNECT(rotorTimer2.timeout, eFrontend::RotorRunningLoop );
44 CONNECT(checkRotorLockTimer.timeout, eFrontend::checkRotorLock );
45 CONNECT(checkLockTimer.timeout, eFrontend::checkLock );
46 CONNECT(updateTransponderTimer.timeout, eFrontend::updateTransponder );
48 #if HAVE_DVB_API_VERSION >= 3
49 CONNECT(timeout.timeout, eFrontend::tuneFailed);
50 #endif
52 fd=::open(demod, O_RDWR|O_NONBLOCK);
53 if (fd<0)
55 type=eSystemInfo::feUnknown;
56 fd=-1;
57 #if HAVE_DVB_API_VERSION < 3
58 secfd=-1;
59 #endif
60 perror(demod);
61 return;
64 #if HAVE_DVB_API_VERSION < 3
65 FrontendEvent ev;
66 #else
67 dvb_frontend_event ev;
68 #endif
69 while ( !::ioctl(fd, FE_GET_EVENT, &ev) )
70 eDebug("[FE] clear FE_EVENT queue");
72 sn=new eSocketNotifier(eApp, fd, eSocketNotifier::Read);
73 CONNECT(sn->activated, eFrontend::readFeEvent );
74 #if HAVE_DVB_API_VERSION < 3
75 if (type==eSystemInfo::feSatellite)
77 secfd=::open(sec, O_RDWR);
78 if (secfd<0)
80 perror(sec);
81 return;
83 } else
85 secfd=-1;
86 if (type == eSystemInfo::feTerrestrial)
88 int antenna_5v_disabled=0;
89 eConfig::getInstance()->getKey("/elitedvb/DVB/config/disable_5V", antenna_5v_disabled);
90 setTerrestrialAntennaVoltage(antenna_5v_disabled);
93 #else
94 curContTone = curVoltage = -1;
95 #endif
96 needreset = 2;
99 void eFrontend::checkLock()
101 if (!Locked())
103 if (++lostlockcount > 2)
104 setFrontend();
105 else
106 checkLockTimer.start(750,true);
108 else
110 lostlockcount=0;
111 checkLockTimer.start(750,true);
115 void eFrontend::checkRotorLock()
117 if (!transponder)
118 return;
119 if (type==eSystemInfo::feSatellite)
121 eSatellite * sat = eTransponderList::getInstance()->findSatellite(transponder->satellite.orbital_position);
122 if (sat)
124 eLNB *lnb = sat->getLNB();
125 if (lnb && lnb->getDiSEqC().DiSEqCMode == eDiSEqC::V1_2 && curRotorPos>=11000 )
127 int snr = SNR();
128 eDebug("[FE] checkRotorLock SNR is %d... old was %d", snr, curRotorPos-=11000 );
129 if ( Locked() && abs(curRotorPos - snr) < 5000 )
131 eDebug("[FE] rotor has stopped..");
132 curRotorPos=newPos;
133 /*emit*/ tunedIn(transponder, 0);
134 // eDebug("!!!!!!!!!!!!!!!! TUNED IN OK 1 !!!!!!!!!!!!!!!!");
135 if ( !eDVB::getInstance()->getScanAPI() )
137 eDebug("[FE] start update transponder data timer");
138 updateTransponderTimer.start(2000,true);
139 checkLockTimer.start(750,true);
140 // eDebug("ROTOR STOPPED 2");
141 s_RotorStopped();
143 return;
145 else
147 eDebug("[FE] rotor already running");
148 curRotorPos=11000;
149 if ( eDVB::getInstance()->getScanAPI() )
151 // eDebug("!!!!!!!!!!!!!!!! TUNED IN EAGAIN 1 !!!!!!!!!!!!!!!!");
152 /*emit*/ tunedIn(transponder, -EAGAIN);
154 else
155 setFrontend();
156 return;
163 int eFrontend::setFrontend()
165 if (type == eSystemInfo::feUnknown)
166 return -1;
167 if (ioctl(fd, FE_SET_FRONTEND, &front)<0)
169 eDebug("FE_SET_FRONTEND failed (%m)");
170 return -1;
172 eDebug("FE_SET_FRONTEND OK");
173 #if HAVE_DVB_API_VERSION >= 3
174 // API V3 drivers have no working TIMEDOUT event..
175 timeout.start(3000,true);
176 #endif
177 return 0;
180 void eFrontend::tuneOK()
182 #if HAVE_DVB_API_VERSION >= 3
183 // stop userspace lock timeout
184 timeout.stop();
185 #endif
186 if (!transponder || type == eSystemInfo::feUnknown)
187 return;
188 if (type==eSystemInfo::feSatellite)
190 eSatellite * sat = eTransponderList::getInstance()->findSatellite(transponder->satellite.orbital_position);
191 if (sat)
193 eLNB *lnb = sat->getLNB();
194 if (lnb && lnb->getDiSEqC().DiSEqCMode == eDiSEqC::V1_2)
196 if (curRotorPos==5000) // rotor running in input power mode
198 eDebug("[FE] ignore .. rotor is running");
199 return;
201 if (curRotorPos==11000)
203 curRotorPos+=SNR();
204 checkRotorLockTimer.start(2000,true); // check SNR in 2 sek
205 eDebug("[FE] start check locktimer cur snr is %d", curRotorPos );
206 return;
211 if ( !eDVB::getInstance()->getScanAPI() )
213 eDebug("[FE] start update transponder data timer");
214 updateTransponderTimer.start(2000,true);
215 checkLockTimer.start(750,true);
217 // eDebug("!!!!!!!!!!!!!!!! TUNED IN OK 2 !!!!!!!!!!!!!!!!");
218 /*emit*/ tunedIn(transponder, 0);
219 return;
222 void eFrontend::tuneFailed()
224 if (!transponder || type == eSystemInfo::feUnknown)
225 return;
226 if (type==eSystemInfo::feSatellite)
228 eSatellite * sat = eTransponderList::getInstance()->findSatellite(transponder->satellite.orbital_position);
229 if (sat)
231 eLNB *lnb = sat->getLNB();
232 if ( lnb && lnb->getDiSEqC().DiSEqCMode == eDiSEqC::V1_2 )
234 if (curRotorPos==5000) // rotor running in input power mode
236 eDebug("[FE] ignore .. rotor is running");
237 return;
239 if ( curRotorPos==11000 )
241 eDebug("[FE] RotorPos uninitialized (%d)", tries);
242 // check every transponder two times..
243 if (eDVB::getInstance()->getScanAPI() && ++tries > 1)
245 tries=0;
246 eDebug("[FE] don't set this TP to error");
247 // eDebug("!!!!!!!!!!!!!!!! TUNED IN EAGAIN 2 !!!!!!!!!!!!!!!!");
248 /*emit*/ tunedIn(transponder, -EAGAIN); // nextTransponder
249 return;
251 setFrontend();
252 return;
257 // eDebug("!!!!!!!!!!!!!!!! TUNED IN ETIMEDOUT 1 !!!!!!!!!!!!!!!!");
258 if ( !eDVB::getInstance()->getScanAPI() )
260 if (++lostlockcount > 5)
262 needreset=2;
263 lostlockcount=0;
264 transponder->tune();
266 else
267 setFrontend();
269 /*emit*/ tunedIn(transponder, -ETIMEDOUT);
270 return;
273 void eFrontend::readFeEvent(int what)
275 #if HAVE_DVB_API_VERSION < 3
276 FrontendEvent ev;
277 memset(&ev, 0, sizeof(FrontendEvent));
278 #else
279 dvb_frontend_event ev;
280 memset(&ev, 0, sizeof(dvb_frontend_event));
281 #endif
282 if ( ::ioctl(fd, FE_GET_EVENT, &ev) < 0 )
284 eDebug("FE_GET_EVENT failed(%m)");
285 return;
287 if ( !transponder )
289 eDebug("[FE] no transponder .. ignore FE Events");
290 return;
292 #if HAVE_DVB_API_VERSION < 3
293 switch (ev.type)
295 case FE_COMPLETION_EV:
296 #else
297 if ( ev.status & FE_HAS_LOCK )
298 #endif
300 eDebug("[FE] evt. locked");
301 tuneOK();
302 return;
304 #if HAVE_DVB_API_VERSION < 3
305 case FE_FAILURE_EV:
307 eDebug("[FE] evt. failure");
308 tuneFailed();
309 return;
311 #else
312 else if ( ev.status & FE_TIMEDOUT )
313 eDebug("[FE].");
314 #endif
315 #if HAVE_DVB_API_VERSION < 3
316 default:
317 eDebug("[FE] unhandled event (type %d)", ev.type);
319 #else
320 else if ( ev.status )
321 eDebug("[FE] unhandled event (status %d)", ev.status);
322 #endif
325 void eFrontend::InitDiSEqC()
327 lastcsw = lastSmatvFreq = lastRotorCmd = lastucsw = lastToneBurst = -1;
328 lastLNB=0;
329 transponder=0;
330 std::list<eLNB> &lnbs = eTransponderList::getInstance()->getLNBs();
331 for (std::list<eLNB>::iterator it(lnbs.begin()); it != lnbs.end(); ++it)
332 if ( it->getDiSEqC().DiSEqCMode != eDiSEqC::NONE &&
333 ( it->getDiSEqC().DiSEqCParam != eDiSEqC::SENDNO ||
334 it->getDiSEqC().uncommitted_cmd ) )
336 // DiSEqC Reset
337 sendDiSEqCCmd( 0, 0 );
338 // peripheral power supply on
339 sendDiSEqCCmd( 0, 3 );
340 usleep(150000);
341 break;
345 eFrontend::~eFrontend()
347 delete sn;
348 if (fd>=0)
349 ::close(fd);
350 #if HAVE_DVB_API_VERSION < 3
351 if (secfd>=0)
352 ::close(secfd);
353 #endif
354 frontend=0;
357 int eFrontend::Status()
359 if (!transponder || type == eSystemInfo::feUnknown)
360 return 0;
361 #if HAVE_DVB_API_VERSION < 3
362 FrontendStatus status=0;
363 #else
364 fe_status_t status;
365 #endif
366 if ( ioctl(fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
367 eDebug("FE_READ_STATUS failed (%m)");
368 return status;
371 uint32_t eFrontend::BER()
373 if (!transponder || type == eSystemInfo::feUnknown)
374 return 0;
375 uint32_t ber=0;
376 if (ioctl(fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
377 eDebug("FE_READ_BER failed (%m)");
378 return ber;
381 int eFrontend::SignalStrength()
383 if (!transponder || type == eSystemInfo::feUnknown)
384 return 0;
385 uint16_t strength=0;
386 if (ioctl(fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
387 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
388 #if 0
389 if ((strength<0) || (strength>65535))
391 eWarning("buggy SignalStrength driver (or old version) (%08x)", strength);
392 strength=0;
394 #endif
395 return strength;
398 int eFrontend::SNR()
400 if (!transponder || type == eSystemInfo::feUnknown)
401 return 0;
402 uint16_t snr=0;
403 if (ioctl(fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
404 eDebug("FE_READ_SNR failed (%m)");
405 #if 0
406 if ((snr<0) || (snr>65535))
408 eWarning("buggy SNR driver (or old version) (%08x)", snr);
409 snr=0;
411 #endif
412 return snr;
415 uint32_t eFrontend::UncorrectedBlocks()
417 if (!transponder || type == eSystemInfo::feUnknown)
418 return 0;
419 uint32_t ublocks=0;
420 if (ioctl(fd, FE_READ_UNCORRECTED_BLOCKS, &ublocks) < 0 && errno != ERANGE)
421 eDebug("FE_READ_UNCORRECTED_BLOCKS failed (%m)");
422 return ublocks;
425 static CodeRate etsiToDvbApiFEC(int fec)
427 switch (fec)
429 case -1:
430 case 15:
431 return FEC_NONE;
432 case 0:
433 return FEC_AUTO;
434 case 1:
435 return FEC_1_2;
436 case 2:
437 return FEC_2_3;
438 case 3:
439 return FEC_3_4;
440 case 4:
441 return FEC_5_6;
442 case 5:
443 return FEC_7_8;
444 default:
445 break;
447 return FEC_AUTO;
450 static Modulation etsiToDvbApiModulation(int mod)
452 switch (mod)
454 case 1:
455 return QAM_16;
456 case 2:
457 return QAM_32;
458 case 3:
459 return QAM_64;
460 case 4:
461 return QAM_128;
462 case 5:
463 return QAM_256;
464 default:
465 return QAM_64;
469 // conversions etsi -> API for DVB-T
470 static Modulation etsiToDvbApiConstellation(int mod)
472 switch (mod)
474 case 0:
475 return QPSK;
476 case 1:
477 return QAM_16;
478 case 2:
479 return QAM_64;
480 default:
481 break;
483 return (Modulation)QAM_AUTO;
486 static CodeRate etsiToDvbApiCodeRate(int rate)
488 switch(rate)
490 case 0:
491 return FEC_1_2;
492 case 1:
493 return FEC_2_3;
494 case 2:
495 return FEC_3_4;
496 case 3:
497 return FEC_5_6;
498 case 4:
499 return FEC_7_8;
500 default:
501 break;
503 return (CodeRate)FEC_AUTO;
506 static BandWidth etsiToDvbApiBandwidth(int bwidth)
508 switch(bwidth)
510 case 0:
511 return BANDWIDTH_8_MHZ;
512 case 1:
513 return BANDWIDTH_7_MHZ;
514 case 2:
515 return BANDWIDTH_6_MHZ;
516 default:
517 break;
519 return (BandWidth)BANDWIDTH_AUTO;
522 static GuardInterval etsiToDvbApiGuardInterval( int interval )
524 switch(interval)
526 case 0:
527 return GUARD_INTERVAL_1_32;
528 case 1:
529 return GUARD_INTERVAL_1_16;
530 case 2:
531 return GUARD_INTERVAL_1_8;
532 case 3:
533 return GUARD_INTERVAL_1_4;
534 default:
535 break;
537 return (GuardInterval)GUARD_INTERVAL_AUTO;
540 static TransmitMode etsiToDvbApiTransmitMode( int mode )
542 switch(mode)
544 case 0:
545 return TRANSMISSION_MODE_2K;
546 case 1:
547 return TRANSMISSION_MODE_8K;
548 default:
549 break;
551 return (TransmitMode)TRANSMISSION_MODE_AUTO;
554 static Hierarchy etsiToDvbApiHierarchyInformation( int hierarchy )
556 switch(hierarchy)
558 case 0:
559 return HIERARCHY_NONE;
560 case 1:
561 return HIERARCHY_1;
562 case 2:
563 return HIERARCHY_2;
564 case 3:
565 return HIERARCHY_4;
566 default:
567 break;
569 return (Hierarchy)HIERARCHY_AUTO;
572 static int dvbApiToEtsiCodeRate(CodeRate cr)
574 switch (cr) {
575 case FEC_1_2:
576 return 0;
577 case FEC_2_3:
578 return 1;
579 case FEC_3_4:
580 return 2;
581 case FEC_5_6:
582 return 3;
583 case FEC_7_8:
584 return 4;
585 default:
586 break;
588 return -1;
591 static int dvbApiToEtsiConstellation(Modulation mod)
593 switch(mod)
595 case QPSK:
596 return 0;
597 case QAM_16:
598 return 1;
599 case QAM_64:
600 return 2;
601 default:
602 break;
604 return 3;
607 static int dvbApiToEtsiBandWidth(BandWidth bw)
609 switch(bw)
611 case BANDWIDTH_8_MHZ:
612 return 0;
613 case BANDWIDTH_7_MHZ:
614 return 1;
615 case BANDWIDTH_6_MHZ:
616 return 2;
617 default:
618 break;
620 return 3;
623 static int dvbApiToEtsiGuardInterval( GuardInterval interval )
625 switch(interval)
627 case GUARD_INTERVAL_1_32:
628 return 0;
629 case GUARD_INTERVAL_1_16:
630 return 1;
631 case GUARD_INTERVAL_1_8:
632 return 2;
633 case GUARD_INTERVAL_1_4:
634 return 3;
635 default:
636 break;
638 return 4;
641 static int dvbApiToEtsiTransmitMode( TransmitMode mode )
643 switch(mode)
645 case TRANSMISSION_MODE_2K:
646 return 0;
647 case TRANSMISSION_MODE_8K:
648 return 1;
649 default:
650 break;
652 return 2;
655 static int dvbApiToEtsiHierarchyInformation( Hierarchy hierarchy )
657 switch(hierarchy)
659 case HIERARCHY_NONE:
660 return 0;
661 case HIERARCHY_1:
662 return 1;
663 case HIERARCHY_2:
664 return 2;
665 case HIERARCHY_4:
666 return 3;
667 default:
668 break;
670 return 4;
674 int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
676 int eFrontend::readInputPower()
678 int power=0;
679 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() )
681 switch ( eSystemInfo::getInstance()->getHwType() )
683 case eSystemInfo::DM7000:
684 case eSystemInfo::DM7020:
686 // open front prozessor
687 int fp=::open("/dev/dbox/fp0", O_RDWR);
688 if (fp < 0)
690 eDebug("couldn't open fp");
691 return -1;
693 #define FP_IOCTL_GET_ID 0
694 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
695 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
697 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
698 return -1;
700 ::close(fp);
701 break;
703 default:
704 eDebug("Inputpower read for platform %d not yet implemented", eSystemInfo::getInstance()->getHwType());
707 return power;
710 #if HAVE_DVB_API_VERSION < 3
711 int eFrontend::sendDiSEqCCmd( int addr, int Cmd, eString params, int frame )
713 if (type != eSystemInfo::feSatellite)
714 return -1;
716 secCmdSequence seq;
717 secCommand cmd;
719 int cnt=0;
720 for ( unsigned int i=0; i < params.length() && i < 6; i+=2 )
721 cmd.u.diseqc.params[cnt++] = strtol( params.mid(i, 2).c_str(), 0, 16 );
723 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
724 cmd.u.diseqc.cmdtype = frame;
725 cmd.u.diseqc.addr = addr;
726 cmd.u.diseqc.cmd = Cmd;
727 cmd.u.diseqc.numParams = cnt;
729 // debug output..
730 #if 0
731 eString parms;
732 for (int i=0; i < cnt; i++)
733 parms+=eString().sprintf("0x%02x ",cmd.u.diseqc.params[i]);
734 #endif
736 if ( transponder && lastLNB )
738 // eDebug("hold current voltage and continuous tone");
739 // set Continuous Tone ( 22 Khz... low - high band )
740 if ( transponder->satellite.frequency > lastLNB->getLOFThreshold() )
741 seq.continuousTone = SEC_TONE_ON;
742 else
743 seq.continuousTone = SEC_TONE_OFF;
744 // set voltage
745 if ( transponder->satellite.polarisation == polVert )
746 seq.voltage = SEC_VOLTAGE_13;
747 else
748 seq.voltage = SEC_VOLTAGE_18;
750 else
752 eDebug("set continuous tone OFF and voltage to 13V");
753 seq.continuousTone = SEC_TONE_OFF;
754 seq.voltage = SEC_VOLTAGE_13;
757 // eDebug("cmdtype = %02x, addr = %02x, cmd = %02x, numParams = %02x, params=%s", frame, addr, Cmd, cnt, parms.c_str() );
758 seq.miniCommand = SEC_MINI_NONE;
759 seq.commands=&cmd;
760 seq.numCommands=1;
762 if ( ioctl(secfd, SEC_SEND_SEQUENCE, &seq) < 0 )
764 eDebug("SEC_SEND_SEQUENCE failed ( %m )");
765 return -1;
767 /* else
768 eDebug("cmd send");*/
770 lastcsw = lastucsw = -1;
772 return 0;
774 #else
775 int eFrontend::sendDiSEqCCmd( int addr, int Cmd, eString params, int frame )
777 if (type != eSystemInfo::feSatellite)
778 return -1;
779 struct dvb_diseqc_master_cmd cmd;
781 cmd.msg[0]=frame;
782 cmd.msg[1]=addr;
783 cmd.msg[2]=Cmd;
784 cmd.msg_len=3;
786 for (uint8_t i = 0; i < params.length() && i < 6; i += 2)
787 cmd.msg[cmd.msg_len++] = strtol( params.mid(i, 2).c_str(), 0, 16 );
789 if ( curVoltage == -1 && (::ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) < 0) )
790 eDebug("FE_SET_VOLTAGE (18) failed (%m)");
792 if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) < 0)
794 eDebug("FE_SET_TONE failed (%m)");
795 return -1;
797 curContTone = eSecCmdSequence::TONE_OFF;
799 if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
801 eDebug("FE_DISEQC_SEND_MASTER_CMD failed (%m)");
802 return -1;
805 lastcsw = lastucsw = -1;
807 return 0;
809 #endif
811 #if HAVE_DVB_API_VERSION < 3
812 int eFrontend::SendSequence( const eSecCmdSequence &s )
814 if (type != eSystemInfo::feSatellite)
815 return -1;
816 secCmdSequence seq;
817 memset( &seq, 0, sizeof(seq) );
818 seq.commands = s.commands;
819 seq.numCommands = s.numCommands;
820 seq.continuousTone = s.continuousTone;
821 seq.miniCommand = s.toneBurst;
822 switch ( s.voltage )
824 case eSecCmdSequence::VOLTAGE_13:
825 seq.voltage=s.increasedVoltage?SEC_VOLTAGE_13_5:SEC_VOLTAGE_13;
826 break;
827 case eSecCmdSequence::VOLTAGE_18:
828 seq.voltage=s.increasedVoltage?SEC_VOLTAGE_18_5:SEC_VOLTAGE_18;
829 break;
830 case eSecCmdSequence::VOLTAGE_OFF:
831 default:
832 seq.voltage=SEC_VOLTAGE_OFF;
833 break;
835 return ::ioctl(secfd, SEC_SEND_SEQUENCE, &seq);
837 #else
838 int eFrontend::SendSequence( const eSecCmdSequence &seq )
840 if (type != eSystemInfo::feSatellite)
841 return -1;
843 int i=0, ret=0, wait=0;
844 dvb_diseqc_master_cmd *scommands;
846 // set Tone
847 // eDebug("curContTone = %d, newTone = %d", curContTone, seq.continuousTone );
848 if ( curContTone != eSecCmdSequence::TONE_OFF &&
849 ( seq.continuousTone == eSecCmdSequence::TONE_OFF
850 // diseqc command or minidiseqc command to sent ?
851 || seq.numCommands || seq.toneBurst != eSecCmdSequence::NONE ) )
853 // eDebug("disable cont Tone");
854 ret = ioctl(fd, FE_SET_TONE, SEC_TONE_OFF);
855 if ( ret < 0 )
857 eDebug("FE_SET_TONE failed (%m)");
858 return ret;
860 curContTone = eSecCmdSequence::TONE_OFF;
861 wait=1;
864 if (seq.increasedVoltage)
866 // eDebug("enable high voltage");
867 ret = ioctl(fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 1);
868 if ( ret < 0 )
870 eDebug("FE_ENABLE_HIGH_LNB_VOLTAGE failed (%m)");
871 return ret;
874 // eDebug("curVoltage = %d, new Voltage = %d", curContTone, seq.voltage);
875 if ( seq.voltage != curVoltage )
877 ret = ioctl(fd, FE_SET_VOLTAGE, seq.voltage);
878 if ( ret < 0 )
880 eDebug("FE_SET_VOLTAGE failed (%m)");
881 return ret;
883 curVoltage = seq.voltage;
884 // eDebug("set voltage to %s", seq.voltage==eSecCmdSequence::VOLTAGE_13?"13 V":seq.voltage==eSecCmdSequence::VOLTAGE_18?"18 V":"unknown ... bug!!");
885 wait=1;
888 if ( wait )
890 // eDebug("delay 30 ms");
891 usleep(30*1000);
892 wait=0;
895 while (true && seq.numCommands)
897 scommands = &seq.commands[i];
899 ret = ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, scommands);
900 if ( ret < 0)
902 eDebug("FE_DISEQC_SEND_MASTER_CMD failed (%m)");
903 return ret;
905 // eDebug("DiSEqC Cmd sent %02x %02x %02x %02x", scommands->msg[0], scommands->msg[1], scommands->msg[2], scommands->msg[3] );
907 if ( scommands->msg[0] & 1 )
909 if ( scommands->msg[2] == 0x39 )
911 eDebug("(%d)uncommited repeat command sent", i);
913 else
915 eDebug("(%d)commited repeat command sent", i);
918 else
920 if ( scommands->msg[2] == 0x39 )
922 eDebug("(%d)uncommited command sent", i);
924 else
926 eDebug("(%d)commited command sent", i);
930 i++;
931 if ( i < seq.numCommands ) // another command is to send...
933 if (wait && seq.commands[i].msg[0] & 1)
935 usleep(wait*1000);
936 // eDebug("delay %dms",wait);
938 if ( seq.commands[i].msg[2] == scommands->msg[2]
939 && seq.commands[i].msg[3] == scommands->msg[3] )
940 // send repeat without uncommitted switch in gap... wait 120 ms
942 usleep(120*1000);
943 // eDebug("delay 120ms");
945 else if ( seq.commands[i].msg[0] & 1 // repeat
946 || (i+1 < seq.numCommands &&
947 seq.commands[i-1].msg[2] == seq.commands[i+1].msg[2] ))
949 if (!wait)
951 // we calc prev message length
952 int mlength = (scommands->msg_len * 8 + scommands->msg_len) * 15;
953 // eDebug("messageLength = %dms", mlength / 10 );
954 wait = ( ( (1200 - mlength) / 20) );
955 // half time we wait before next cmd
956 usleep(wait*1000);
957 // eDebug("delay %dms",wait);
959 else
960 wait = 0;
961 } // MSG[1] ??? or MSG
962 else if ( seq.commands[i].msg[1] == 0x58 ) // handle SMATV Cmd
964 // eDebug("delay 10ms"); // Standard > 6ms
965 usleep( 10*1000 );
967 else // we calc the delay between two cmds with difference types.. switch..rotor
969 usleep( 120*1000 ); // wait after msg
970 // eDebug("delay 120ms");
971 wait=0;
974 else
975 break;
978 if (seq.numCommands) // When DiSEqC Commands was sent.. then wait..
980 // eDebug("delay 30ms after send last diseqc command"); // Standard > 15ms
981 usleep(30*1000);
984 // send minidiseqc
985 if (seq.toneBurst != eSecCmdSequence::NONE)
987 ret = ioctl(fd, FE_DISEQC_SEND_BURST, seq.toneBurst);
988 if ( ret < 0)
990 eDebug("FE_DISEQC_SEND_BURST failed (%m)");
991 return ret;
993 // eDebug("toneBurst sent\n");
995 usleep(30*1000); // after send toneburst we wait...
996 // eDebug("delay 30ms");
999 // eDebug("curTone = %d, newTone = %d", curContTone, seq.continuousTone );
1000 if ( seq.continuousTone == eSecCmdSequence::TONE_ON && curContTone != SEC_TONE_ON )
1002 // eDebug("enable continuous Tone");
1003 ret = ioctl(fd, FE_SET_TONE, SEC_TONE_ON);
1004 if ( ret < 0 )
1006 eDebug("FE_SET_TONE failed (%m)");
1007 return ret;
1009 else
1011 curContTone = eSecCmdSequence::TONE_ON;
1012 usleep(10*1000);
1013 // eDebug("delay 10ms");
1016 /////////////////////////////////////////
1017 return 0;
1019 #endif
1021 int eFrontend::RotorUseTimeout(eSecCmdSequence& seq, eLNB *lnb )
1023 #if HAVE_DVB_API_VERSION < 3
1024 secCommand *commands = seq.commands;
1025 #else
1026 dvb_diseqc_master_cmd *commands = seq.commands;
1027 #endif
1028 // we send first the normal DiSEqC Switch Cmds
1029 // and then the Rotor CMD
1030 seq.numCommands--;
1032 int secTone = seq.continuousTone;
1033 // send DiSEqC Sequence ( normal diseqc switches )
1034 seq.continuousTone = eSecCmdSequence::TONE_OFF;
1035 if ( SendSequence(seq) < 0 )
1037 eDebug("SendSequence failed (%m)");
1038 return -1;
1040 else if ( lnb->getDiSEqC().SeqRepeat ) // Sequence Repeat selected ?
1042 usleep( 100000 ); // between seq repeats we wait 75ms
1043 SendSequence(seq); // then repeat the command
1045 if ( lastLNB != lnb )
1046 usleep( 1000000 ); // wait 1sek
1047 else
1048 usleep( 100000 ); // wait 100ms
1050 // send DiSEqC Sequence (Rotor)
1051 seq.commands=&commands[seq.numCommands]; // last command is rotor cmd... see above...
1052 seq.numCommands=1; // only rotor cmd
1053 seq.toneBurst = eSecCmdSequence::NONE;
1054 seq.continuousTone=secTone;
1056 if ( SendSequence(seq) < 0 )
1058 eDebug("SendSequence failed (%m)");
1059 return -1;
1061 else
1062 eDebug("Rotor Cmd is sent");
1064 tries=0;
1065 return 0;
1068 int eFrontend::RotorUseInputPower(eSecCmdSequence& seq, eLNB *lnb )
1070 #if HAVE_DVB_API_VERSION < 3
1071 secCommand *commands = seq.commands;
1072 #else
1073 dvb_diseqc_master_cmd *commands = seq.commands;
1074 #endif
1075 idlePowerInput=0;
1076 runningPowerInput=0;
1077 int secTone = seq.continuousTone;
1079 // we send first the normal DiSEqC Switch Cmds
1080 // and then the Rotor CMD
1081 seq.numCommands--;
1083 // eDebug("sent normal diseqc switch cmd");
1084 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x, numParams=%d, numcmds=%d", seq.commands[0].u.diseqc.cmdtype, seq.commands[0].u.diseqc.addr, seq.commands[0].u.diseqc.cmd, seq.commands[0].u.diseqc.params[0], seq.numCommands, seq.commands[0].u.diseqc.numParams );
1085 // send DiSEqC Sequence ( normal diseqc switches )
1087 seq.continuousTone=SEC_TONE_OFF;
1088 if ( SendSequence(seq) < 0 )
1090 eDebug("SendSequence failed (%m)");
1091 return -2;
1093 else if ( lnb->getDiSEqC().SeqRepeat ) // Sequence Repeat selected ?
1095 usleep( 100000 ); // between seq repeats we wait 100ms
1096 SendSequence(seq); // then repeat the cmd
1099 if ( lastLNB != lnb )
1101 usleep( 1000*1000 ); // wait 1sek
1102 // eDebug("sleep 1sek");
1104 else
1106 usleep( 100*1000 ); // wait 100ms
1107 // eDebug("sleep 100ms");
1110 // get power input of Rotor on idle not work on dbox yet .. only dreambox
1111 idlePowerInput = readInputPower();
1112 if ( idlePowerInput < 0 )
1113 return idlePowerInput;
1114 // eDebug("idle power input = %dmA", idlePowerInput );
1116 // send DiSEqC Sequence (Rotor)
1117 seq.commands=&commands[seq.numCommands]; // last command is rotor cmd... see above...
1118 seq.numCommands=1; // only rotor cmd
1119 seq.toneBurst = eSecCmdSequence::NONE;
1121 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x,0x%02x", seq.commands[0].u.diseqc.cmdtype, seq.commands[0].u.diseqc.addr, seq.commands[0].u.diseqc.cmd, seq.commands[0].u.diseqc.params[0], seq.commands[0].u.diseqc.params[1]);
1122 seq.continuousTone=secTone;
1123 if ( SendSequence(seq) < 0 )
1125 eDebug("SendSequence failed (%m)");
1126 return -2;
1128 // set rotor start timeout // 2 sek..
1129 gettimeofday(&rotorTimeout,0);
1130 rotorTimeout+=2000;
1131 RotorStartLoop();
1132 return 0;
1135 void eFrontend::RotorStartLoop()
1137 // timeouted ??
1138 timeval now;
1139 gettimeofday(&now,0);
1140 if ( rotorTimeout < now )
1142 eDebug("rotor has timeoutet :( ");
1143 /* emit */ s_RotorTimeout();
1144 RotorFinish();
1146 else
1148 runningPowerInput = readInputPower();
1149 if ( runningPowerInput < 0 )
1150 return;
1151 // eDebug("running %d mA", runningPowerInput);
1152 // eDebug("delta %d mA", DeltaA);
1154 if ( abs(runningPowerInput-idlePowerInput ) >= (DeltaA&0xFF) ) // rotor running ?
1156 if ( (DeltaA & 0x200) == 0x200 )
1158 eDebug("Rotor is Running");
1160 if ( !eDVB::getInstance()->getScanAPI() )
1162 // eDebug("ROTOR RUNNING EMIT");
1163 /* emit */ s_RotorRunning( newPos );
1166 // set rotor running timeout // 360 sek
1167 gettimeofday(&rotorTimeout,0);
1168 rotorTimeout+=360000;
1169 RotorRunningLoop();
1170 return;
1172 else
1173 DeltaA+=0x100;
1175 else
1176 DeltaA &= ~0xF00;
1177 rotorTimer1.start(50,true); // restart timer
1181 void eFrontend::RotorRunningLoop()
1183 timeval now;
1184 gettimeofday(&now,0);
1185 if ( rotorTimeout < now )
1187 eDebug("Rotor timeouted :-(");
1188 /* emit */ s_RotorTimeout();
1190 else
1192 runningPowerInput = readInputPower();
1193 if ( runningPowerInput < 0 )
1194 return;
1195 // eDebug("running %d mA", runningPowerInput);
1197 if ( abs( idlePowerInput-runningPowerInput ) <= (DeltaA&0xFF) ) // rotor stoped ?
1199 if ( (DeltaA & 0x200) == 0x200 )
1201 eDebug("Rotor Stopped");
1202 /* emit */ s_RotorStopped();
1203 RotorFinish();
1204 return;
1206 else
1207 DeltaA+=0x100;
1209 else
1210 DeltaA &= ~0xF00;
1211 rotorTimer2.start(50,true); // restart timer
1215 void eFrontend::RotorFinish(bool tune)
1217 if (type != eSystemInfo::feSatellite)
1218 return;
1219 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() == 1 )
1221 if ( voltage != eSecCmdSequence::VOLTAGE_18 )
1222 #if HAVE_DVB_API_VERSION < 3
1223 if (ioctl(secfd, SEC_SET_VOLTAGE, increased ? SEC_VOLTAGE_13_5 : SEC_VOLTAGE_13) < 0 )
1224 eDebug("SEC_SET_VOLTAGE failed (%m)");
1225 #else
1226 if ( ioctl(fd, FE_SET_VOLTAGE, voltage) < 0 )
1227 eDebug("FE_SET_VOLTAGE failed (%m)");
1228 curVoltage = voltage;
1229 #endif
1231 else // can only measure with lower lnb voltage ( 13V )
1233 if ( voltage != eSecCmdSequence::VOLTAGE_13 )
1234 #if HAVE_DVB_API_VERSION < 3
1235 if (ioctl(secfd, SEC_SET_VOLTAGE, increased ? SEC_VOLTAGE_18_5 : SEC_VOLTAGE_18) < 0 )
1236 eDebug("SEC_SET_VOLTAGE failed (%m)");
1237 #else
1238 if ( ioctl(fd, FE_SET_VOLTAGE, voltage) < 0 )
1239 eDebug("FE_SET_VOLTAGE failed (%m)");
1240 curVoltage = voltage;
1241 #endif
1243 curRotorPos=newPos;
1244 if ( tune && transponder )
1245 transponder->tune();
1248 double calcElevation( double SatLon, double SiteLat, double SiteLon, int Height_over_ocean = 0 )
1250 double a0=0.58804392,
1251 a1=-0.17941557,
1252 a2=0.29906946E-1,
1253 a3=-0.25187400E-2,
1254 a4=0.82622101E-4,
1256 f = 1.00 / 298.257, // Earth flattning factor
1258 r_sat=42164.57, // Distance from earth centre to satellite
1260 r_eq=6378.14, // Earth radius
1262 sinRadSiteLat=SIN(Radians(SiteLat)),
1263 cosRadSiteLat=COS(Radians(SiteLat)),
1265 Rstation = r_eq / ( std::sqrt( 1.00 - f*(2.00-f)*sinRadSiteLat*sinRadSiteLat ) ),
1267 Ra = (Rstation+Height_over_ocean)*cosRadSiteLat,
1268 Rz= Rstation*(1.00-f)*(1.00-f)*sinRadSiteLat,
1270 alfa_rx=r_sat*COS(Radians(SatLon-SiteLon)) - Ra,
1271 alfa_ry=r_sat*SIN(Radians(SatLon-SiteLon)),
1272 alfa_rz=-Rz,
1274 alfa_r_north=-alfa_rx*sinRadSiteLat + alfa_rz*cosRadSiteLat,
1275 alfa_r_zenith=alfa_rx*cosRadSiteLat + alfa_rz*sinRadSiteLat,
1277 El_geometric=Deg(ATAN( alfa_r_zenith/std::sqrt(alfa_r_north*alfa_r_north+alfa_ry*alfa_ry))),
1279 x = std::fabs(El_geometric+0.589),
1280 refraction=std::fabs(a0+a1*x+a2*x*x+a3*x*x*x+a4*x*x*x*x),
1281 El_observed = 0.00;
1283 if (El_geometric > 10.2)
1284 El_observed = El_geometric+0.01617*(COS(Radians(std::fabs(El_geometric)))/SIN(Radians(std::fabs(El_geometric))) );
1285 else
1287 El_observed = El_geometric+refraction ;
1290 if (alfa_r_zenith < -3000)
1291 El_observed=-99;
1293 return El_observed;
1296 double calcAzimuth(double SatLon, double SiteLat, double SiteLon, int Height_over_ocean=0)
1298 double f = 1.00 / 298.257, // Earth flattning factor
1300 r_sat=42164.57, // Distance from earth centre to satellite
1302 r_eq=6378.14, // Earth radius
1304 sinRadSiteLat=SIN(Radians(SiteLat)),
1305 cosRadSiteLat=COS(Radians(SiteLat)),
1307 Rstation = r_eq / ( std::sqrt( 1 - f*(2-f)*sinRadSiteLat*sinRadSiteLat ) ),
1308 Ra = (Rstation+Height_over_ocean)*cosRadSiteLat,
1309 Rz = Rstation*(1-f)*(1-f)*sinRadSiteLat,
1311 alfa_rx = r_sat*COS(Radians(SatLon-SiteLon)) - Ra,
1312 alfa_ry = r_sat*SIN(Radians(SatLon-SiteLon)),
1313 alfa_rz = -Rz,
1315 alfa_r_north = -alfa_rx*sinRadSiteLat + alfa_rz*cosRadSiteLat,
1317 Azimuth = 0.00;
1319 if (alfa_r_north < 0)
1320 Azimuth = 180+Deg(ATAN(alfa_ry/alfa_r_north));
1321 else
1322 Azimuth = Rev(360+Deg(ATAN(alfa_ry/alfa_r_north)));
1324 return Azimuth;
1327 double calcDeclination( double SiteLat, double Azimuth, double Elevation)
1329 return Deg( ASIN(SIN(Radians(Elevation)) *
1330 SIN(Radians(SiteLat)) +
1331 COS(Radians(Elevation)) *
1332 COS(Radians(SiteLat)) +
1333 COS(Radians(Azimuth))
1338 double calcSatHourangle( double Azimuth, double Elevation, double Declination, double Lat )
1340 double a = - COS(Radians(Elevation)) *
1341 SIN(Radians(Azimuth)),
1343 b = SIN(Radians(Elevation)) *
1344 COS(Radians(Lat)) -
1345 COS(Radians(Elevation)) *
1346 SIN(Radians(Lat)) *
1347 COS(Radians(Azimuth)),
1349 // Works for all azimuths (northern & sourhern hemisphere)
1350 returnvalue = 180 + Deg(ATAN(a/b));
1352 (void)Declination;
1354 if ( Azimuth > 270 )
1356 returnvalue = ( (returnvalue-180) + 360 );
1357 if (returnvalue>360)
1358 returnvalue = 360 - (returnvalue-360);
1361 if ( Azimuth < 90 )
1362 returnvalue = ( 180 - returnvalue );
1364 return returnvalue;
1367 void eFrontend::updateTransponder()
1369 if (type == eSystemInfo::feUnknown)
1370 return;
1371 if (!transponder)
1372 return;
1373 if (!eSystemInfo::getInstance()->canUpdateTransponder())
1374 return;
1375 if (!Locked())
1376 return;
1378 #if HAVE_DVB_API_VERSION < 3
1379 FrontendParameters front;
1380 #else
1381 struct dvb_frontend_parameters front;
1382 #endif
1383 if (ioctl(fd, FE_GET_FRONTEND, &front)<0) {
1384 eDebug("FE_GET_FRONTEND (%m)");
1385 return;
1388 if ((type==eSystemInfo::feSatellite) && (transponder->satellite.valid))
1390 unsigned int freq, inv, sr;
1391 #if HAVE_DVB_API_VERSION < 3
1392 freq = front.Frequency;
1393 inv = front.Inversion;
1394 sr = front.u.qpsk.SymbolRate;
1395 #else
1396 freq = front.frequency;
1397 inv = front.inversion;
1398 sr = front.u.qpsk.symbol_rate;
1399 #endif
1400 eDebug("[FE] update transponder data");
1401 eSatellite * sat = eTransponderList::getInstance()->findSatellite(transponder->satellite.orbital_position);
1402 if (sat)
1404 eLNB *lnb = sat->getLNB();
1405 if (lnb)
1407 int lof = transponder->satellite.frequency > lnb->getLOFThreshold() ?
1408 lnb->getLOFHi() : lnb->getLOFLo();
1409 int tuned_freq = transponder->satellite.frequency - lof;
1410 if ( tuned_freq < 0 ) // c-band
1411 transponder->satellite.frequency = abs(freq-lof);
1412 else
1413 transponder->satellite.frequency = freq+lof;
1416 /* transponder->satellite.fec = front.u.qpsk.FEC_inner; */
1417 transponder->satellite.inversion = inv;
1418 transponder->satellite.symbol_rate = sr;
1420 else if ((type==eSystemInfo::feCable) && (transponder->cable.valid)) {
1421 #if HAVE_DVB_API_VERSION < 3
1422 // FIXME
1423 #else
1424 // FIXME
1425 #endif
1427 else if ((type==eSystemInfo::feTerrestrial) && (transponder->terrestrial.valid)) {
1428 #if HAVE_DVB_API_VERSION < 3
1429 transponder->terrestrial.centre_frequency = front.Frequency;
1430 transponder->terrestrial.bandwidth = dvbApiToEtsiBandWidth(front.u.ofdm.bandWidth);
1431 transponder->terrestrial.code_rate_hp = dvbApiToEtsiCodeRate(front.u.ofdm.HP_CodeRate);
1432 transponder->terrestrial.code_rate_lp = dvbApiToEtsiCodeRate(front.u.ofdm.LP_CodeRate);
1433 transponder->terrestrial.constellation = dvbApiToEtsiConstellation(front.u.ofdm.Constellation);
1434 transponder->terrestrial.transmission_mode = dvbApiToEtsiTransmitMode(front.u.ofdm.TransmissionMode);
1435 transponder->terrestrial.guard_interval = dvbApiToEtsiGuardInterval(front.u.ofdm.guardInterval);
1436 transponder->terrestrial.hierarchy_information = dvbApiToEtsiHierarchyInformation(front.u.ofdm.HierarchyInformation);
1437 #else
1438 // FIXME
1439 #endif
1443 void eFrontend::tune_all(eTransponder *trans) // called from within tune_qpsk, tune_qam, tune_ofdm
1445 tries=0;
1446 eSection::abortAll();
1447 lostlockcount=0;
1448 updateTransponderTimer.stop();
1449 transponder = trans;
1452 int eFrontend::tune_qpsk(eTransponder *trans,
1453 uint32_t Frequency, // absolute frequency in kHz
1454 int polarisation, // polarisation (polHor, polVert, ...)
1455 uint32_t SymbolRate, // symbolrate in symbols/s (e.g. 27500000)
1456 uint8_t FEC_inner, // FEC_inner (-1 for none, 0 for auto, but please don't use that)
1457 int Inversion, // spectral inversion, INVERSION_OFF / _ON / _AUTO (but please...)
1458 eSatellite &sat) // Satellite Data.. LNB, DiSEqC, switch..
1460 if (type != eSystemInfo::feSatellite)
1461 return -1;
1462 tune_all(trans);
1463 int finalTune=1;
1464 // eDebug("op = %d", trans->satellite.orbital_position );
1465 checkRotorLockTimer.stop();
1466 checkLockTimer.stop();
1468 if ( curRotorPos > 11000 )
1469 curRotorPos = 11000;
1471 // eDebug("ROTOR STOPPED 1");
1472 /* emit */ s_RotorStopped();
1474 if ( rotorTimer1.isActive() || rotorTimer2.isActive() )
1476 eDebug("Switch ... but running rotor... send stop..");
1477 rotorTimer1.stop();
1478 rotorTimer2.stop();
1479 // ROTOR STOP
1480 sendDiSEqCCmd( 0x31, 0x60 );
1481 sendDiSEqCCmd( 0x31, 0x60 );
1482 lastRotorCmd=-1;
1483 curRotorPos=10000;
1486 if (needreset > 1)
1488 #if HAVE_DVB_API_VERSION < 3
1489 ioctl(fd, FE_SET_POWER_STATE, FE_POWER_ON);
1490 usleep(150000);
1491 #else
1492 curContTone = curVoltage = -1;
1493 #endif
1494 InitDiSEqC();
1495 needreset=0;
1498 transponder=trans;
1500 eSwitchParameter &swParams = sat.getSwitchParams();
1501 eLNB *lnb = sat.getLNB();
1502 // Variables to detect if DiSEqC must sent .. or not
1503 int csw = lnb->getDiSEqC().DiSEqCParam,
1504 ucsw = (lnb->getDiSEqC().uncommitted_cmd ?
1505 lnb->getDiSEqC().uncommitted_cmd : lastucsw),
1506 ToneBurst = (lnb->getDiSEqC().MiniDiSEqCParam ?
1507 lnb->getDiSEqC().MiniDiSEqCParam : lastToneBurst),
1508 RotorCmd = lastRotorCmd,
1509 sendRotorCmd=0;
1510 // SmatvFreq = -1;
1512 if ( !transponder->satellite.useable( lnb ) )
1514 // eDebug("!!!!!!!!!!!!!!!! TUNED IN ETIMEDOUT 2 !!!!!!!!!!!!!!!!");
1515 /*emit*/ tunedIn(transponder, -ETIMEDOUT);
1516 return 0;
1519 eSecCmdSequence seq;
1520 #if HAVE_DVB_API_VERSION < 3
1521 #define SEC_12V_OUT_OFF 0x10
1522 #define SEC_12V_OUT_ON 0x11
1523 if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 &&
1524 ioctl(secfd, SEC_SET_VOLTAGE, lnb->get12VOut() ? SEC_12V_OUT_ON : SEC_12V_OUT_OFF) < 0 )
1525 eDebug("SEC_SET_VOLTAGE (12V Out) failed (%m)");
1526 secCommand *commands=0; // pointer to all sec commands
1527 #else
1528 dvb_diseqc_master_cmd *commands=0;
1529 #endif
1531 // num command counter
1532 int cmdCount=0;
1534 if (csw <= eDiSEqC::SENDNO) // use AA/AB/BA/BB/SENDNO
1536 // eDebug("csw=%d, csw<<2=%d", csw, csw << 2);
1537 if ( csw != eDiSEqC::SENDNO )
1538 csw = 0xF0 | ( csw << 2 );
1539 if ( polarisation==polHor)
1541 csw |= 2; // Horizontal
1542 eDebug("Horizontal");
1544 else
1545 eDebug("Vertikal");
1547 if ( Frequency > lnb->getLOFThreshold() )
1549 csw |= 1; // 22 Khz enabled
1550 eDebug("Hi Band");
1552 else
1553 eDebug("Low Band");
1555 //else we sent directly the cmd 0xF0..0xFF
1557 if ( csw != eDiSEqC::SENDNO )
1558 eDebug("DiSEqC Switch cmd = %04x", csw);
1559 else
1560 eDebug("send no committed diseqc cmd !");
1562 // Rotor Support
1563 if ( lnb->getDiSEqC().DiSEqCMode == eDiSEqC::V1_2 && !noRotorCmd )
1565 bool useGotoXX=false;
1568 std::map<int,int,Orbital_Position_Compare>::iterator it =
1569 lnb->getDiSEqC().RotorTable.find( sat.getOrbitalPosition() );
1571 if (it != lnb->getDiSEqC().RotorTable.end()) // position for selected sat found ?
1572 RotorCmd=it->second;
1573 else // entry not in table found
1575 eDebug("Entry for %d,%d° not in Rotor Table found... i try gotoXX°", sat.getOrbitalPosition() / 10, sat.getOrbitalPosition() % 10 );
1577 useGotoXX=true;
1578 int pos = sat.getOrbitalPosition();
1579 int satDir = pos < 0 ? eDiSEqC::WEST : eDiSEqC::EAST;
1581 double SatLon = abs(pos)/10.00,
1582 SiteLat = lnb->getDiSEqC().gotoXXLatitude,
1583 SiteLon = lnb->getDiSEqC().gotoXXLongitude;
1585 if ( lnb->getDiSEqC().gotoXXLaDirection == eDiSEqC::SOUTH )
1586 SiteLat = -SiteLat;
1588 if ( lnb->getDiSEqC().gotoXXLoDirection == eDiSEqC::WEST )
1589 SiteLon = 360 - SiteLon;
1591 if (satDir == eDiSEqC::WEST )
1592 SatLon = 360 - SatLon;
1594 eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon );
1595 double azimuth=calcAzimuth(SatLon, SiteLat, SiteLon );
1596 double elevation=calcElevation( SatLon, SiteLat, SiteLon );
1597 double declination=calcDeclination( SiteLat, azimuth, elevation );
1598 double satHourAngle=calcSatHourangle( azimuth, elevation, declination, SiteLat );
1599 eDebug("azimuth=%lf, elevation=%lf, declination=%lf, PolarmountHourAngle=%lf", azimuth, elevation, declination, satHourAngle );
1602 // xphile: USALS fix for southern hemisphere
1604 if (SiteLat >= 0)
1607 // Northern Hemisphere
1609 int tmp=(int)round( fabs( 180 - satHourAngle ) * 10.0 );
1610 RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
1612 if (satHourAngle < 180) // the east
1613 RotorCmd |= 0xE000;
1614 else // west
1615 RotorCmd |= 0xD000;
1617 else
1620 // Southern Hemisphere
1622 if (satHourAngle < 180) // the east
1624 int tmp=(int)round( fabs( satHourAngle ) * 10.0 );
1625 RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
1626 RotorCmd |= 0xD000;
1628 else
1629 { // west
1630 int tmp=(int)round( fabs( 360 - satHourAngle ) * 10.0 );
1631 RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
1632 RotorCmd |= 0xE000;
1636 eDebug("RotorCmd = %04x", RotorCmd);
1639 if ( RotorCmd != lastRotorCmd || (RotorCmd && curRotorPos == 10000) ) // rotorCmd must sent?
1641 cmdCount=1; // this is the RotorCmd
1642 if ( ucsw != lastucsw )
1643 cmdCount++;
1644 if ( csw != lastcsw && csw & 0xF0) // NOT SENDNO
1645 cmdCount++;
1646 cmdCount += (cmdCount-1)*lnb->getDiSEqC().DiSEqCRepeats;
1648 #if HAVE_DVB_API_VERSION < 3
1649 // allocate memory for all DiSEqC commands
1650 commands = new secCommand[cmdCount];
1651 commands[cmdCount-1].type = SEC_CMDTYPE_DISEQC_RAW;
1652 commands[cmdCount-1].u.diseqc.addr=0x31; // normal positioner
1653 commands[cmdCount-1].u.diseqc.cmdtype=0xE0; // no replay... first transmission
1654 #else
1655 commands = new dvb_diseqc_master_cmd[cmdCount];
1656 commands[cmdCount-1].msg[0]=0xE0;
1657 commands[cmdCount-1].msg[1]=0x31;
1658 #endif
1659 if ( useGotoXX )
1661 eDebug("Rotor DiSEqC Param = %04x (useGotoXX)", RotorCmd);
1662 #if HAVE_DVB_API_VERSION < 3
1663 commands[cmdCount-1].u.diseqc.cmd=0x6E; // gotoXX Drive Motor to Angular Position
1664 commands[cmdCount-1].u.diseqc.numParams=2;
1665 commands[cmdCount-1].u.diseqc.params[0]=((RotorCmd & 0xFF00) / 0x100);
1666 commands[cmdCount-1].u.diseqc.params[1]=RotorCmd & 0xFF;
1667 #else
1668 commands[cmdCount-1].msg[2]=0x6E;
1669 commands[cmdCount-1].msg[3]=((RotorCmd & 0xFF00) / 0x100);
1670 commands[cmdCount-1].msg[4]=RotorCmd & 0xFF;
1671 commands[cmdCount-1].msg_len=5;
1672 #endif
1674 else
1676 eDebug("Rotor DiSEqC Param = %02x (use stored position)", RotorCmd);
1677 #if HAVE_DVB_API_VERSION < 3
1678 commands[cmdCount-1].u.diseqc.cmd=0x6B; // goto stored sat position
1679 commands[cmdCount-1].u.diseqc.numParams=1;
1680 commands[cmdCount-1].u.diseqc.params[0]=RotorCmd;
1681 #else
1682 commands[cmdCount-1].msg[2]=0x6B;
1683 commands[cmdCount-1].msg[3]=RotorCmd;
1684 commands[cmdCount-1].msg_len=4;
1685 #endif
1687 sendRotorCmd++;
1691 if ( curRotorPos > 10000 && !sendRotorCmd )
1693 eDebug("reset Rotor cmd");
1694 curRotorPos = 10000;
1697 #if 0
1698 else if ( lnb->getDiSEqC().DiSEqCMode == eDiSEqC::SMATV )
1700 SmatvFreq=Frequency;
1701 if ( lastSmatvFreq != SmatvFreq )
1703 if ( lnb->getDiSEqC().uncommitted_cmd && lastucsw != ucsw)
1704 cmdCount=3;
1705 else
1706 cmdCount=2;
1707 cmdCount += (cmdCount-1)*lnb->getDiSEqC().DiSEqCRepeats;
1709 // allocate memory for all DiSEqC commands
1710 commands = new secCommand[cmdCount];
1712 commands[cmdCount-1].type = SEC_CMDTYPE_DISEQC_RAW;
1713 commands[cmdCount-1].u.diseqc.addr = 0x71; // intelligent slave interface for multi-master bus
1714 commands[cmdCount-1].u.diseqc.cmd = 0x58; // write channel frequency
1715 commands[cmdCount-1].u.diseqc.cmdtype = 0xE0;
1716 commands[cmdCount-1].u.diseqc.numParams = 3;
1717 commands[cmdCount-1].u.diseqc.params[0] = (((Frequency / 10000000) << 4) & 0xF0) | ((Frequency / 1000000) & 0x0F);
1718 commands[cmdCount-1].u.diseqc.params[1] = (((Frequency / 100000) << 4) & 0xF0) | ((Frequency / 10000) & 0x0F);
1719 commands[cmdCount-1].u.diseqc.params[2] = (((Frequency / 1000) << 4) & 0xF0) | ((Frequency / 100) & 0x0F);
1722 #endif
1723 if ( lnb->getDiSEqC().DiSEqCMode >= eDiSEqC::V1_0 )
1725 // eDebug("ucsw=%d lastucsw=%d csw=%d lastcsw=%d", ucsw, lastucsw, csw, lastcsw);
1726 if ( ucsw != lastucsw || csw != lastcsw || (ToneBurst && ToneBurst != lastToneBurst) )
1728 // eDebug("cmdCount=%d", cmdCount);
1729 int loops;
1730 if ( cmdCount ) // Smatv or Rotor is avail...
1731 loops = cmdCount - 1; // do not overwrite rotor cmd
1732 else // no rotor or smatv
1734 // DiSEqC Repeats and uncommitted switches only when DiSEqC >= V1_1
1735 if ( lnb->getDiSEqC().DiSEqCMode >= eDiSEqC::V1_1 && ucsw != lastucsw )
1736 cmdCount++;
1737 if ( csw != lastcsw && csw & 0xF0 )
1738 cmdCount++;
1739 cmdCount += cmdCount*lnb->getDiSEqC().DiSEqCRepeats;
1740 loops = cmdCount;
1742 if ( cmdCount )
1743 #if HAVE_DVB_API_VERSION < 3
1744 commands = new secCommand[cmdCount];
1745 #else
1746 commands = new dvb_diseqc_master_cmd[cmdCount];
1747 #endif
1750 for ( int i = 0; i < loops;) // fill commands...
1752 enum { UNCOMMITTED, COMMITTED } cmdbefore = COMMITTED;
1753 #if HAVE_DVB_API_VERSION < 3
1754 commands[i].type = SEC_CMDTYPE_DISEQC_RAW;
1755 commands[i].u.diseqc.cmdtype= i ? 0xE1 : 0xE0; // repeated or not repeated transm.
1756 commands[i].u.diseqc.numParams=1;
1757 commands[i].u.diseqc.addr=0x10;
1758 #else
1759 commands[i].msg[0]= i ? 0xE1 : 0xE0;
1760 commands[i].msg[1]=0x10;
1761 commands[i].msg_len=4;
1762 #endif
1763 if ( ( lnb->getDiSEqC().SwapCmds
1764 && lnb->getDiSEqC().DiSEqCMode > eDiSEqC::V1_0
1765 && ucsw != lastucsw )
1766 || !(csw & 0xF0) )
1768 cmdbefore = UNCOMMITTED;
1769 #if HAVE_DVB_API_VERSION < 3
1770 commands[i].u.diseqc.params[0] = ucsw;
1771 commands[i].u.diseqc.cmd=0x39;
1772 #else
1773 commands[i].msg[2]=0x39;
1774 commands[i].msg[3]=ucsw;
1775 #endif
1777 else
1779 #if HAVE_DVB_API_VERSION < 3
1780 commands[i].u.diseqc.params[0] = csw;
1781 commands[i].u.diseqc.cmd=0x38;
1782 #else
1783 commands[i].msg[2]=0x38;
1784 commands[i].msg[3]=csw;
1785 #endif
1787 // eDebug("normalCmd");
1788 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x", commands[i].u.diseqc.cmdtype, commands[i].u.diseqc.addr, commands[i].u.diseqc.cmd, commands[i].u.diseqc.params[0]);
1789 i++;
1790 if ( i < loops
1791 && ( ( (cmdbefore == COMMITTED) && ucsw )
1792 || ( (cmdbefore == UNCOMMITTED) && csw & 0xF0 ) ) )
1794 memcpy( &commands[i], &commands[i-1], sizeof(commands[i]) );
1795 if ( cmdbefore == COMMITTED )
1797 #if HAVE_DVB_API_VERSION < 3
1798 commands[i].u.diseqc.cmd=0x39;
1799 commands[i].u.diseqc.params[0]=ucsw;
1800 #else
1801 commands[i].msg[2]=0x39;
1802 commands[i].msg[3]=ucsw;
1803 #endif
1805 else
1807 #if HAVE_DVB_API_VERSION < 3
1808 commands[i].u.diseqc.cmd=0x38;
1809 commands[i].u.diseqc.params[0]=csw;
1810 #else
1811 commands[i].msg[2]=0x38;
1812 commands[i].msg[3]=csw;
1813 #endif
1815 // eDebug("0x%02x,0x%02x,0x%02x,0x%02x", commands[i].u.diseqc.cmdtype, commands[i].u.diseqc.addr, commands[i].u.diseqc.cmd, commands[i].u.diseqc.params[0]);
1816 i++;
1821 if ( !cmdCount)
1823 eDebug("send no DiSEqC");
1824 seq.commands=0;
1827 seq.numCommands=cmdCount;
1828 eDebug("%d DiSEqC cmds to send", cmdCount);
1830 seq.toneBurst = eSecCmdSequence::NONE;
1831 if ( ucsw != lastucsw || csw != lastcsw || (ToneBurst && ToneBurst != lastToneBurst) )
1833 if ( lnb->getDiSEqC().MiniDiSEqCParam == eDiSEqC::A )
1835 eDebug("Toneburst A");
1836 seq.toneBurst=eSecCmdSequence::TONEBURST_A;
1838 else if ( lnb->getDiSEqC().MiniDiSEqCParam == eDiSEqC::B )
1840 eDebug("Toneburst B");
1841 seq.toneBurst=eSecCmdSequence::TONEBURST_B;
1843 else
1844 eDebug("no Toneburst (MiniDiSEqC)");
1847 // no DiSEqC related Stuff
1849 // calc Frequency
1850 int local = Frequency - ( Frequency > lnb->getLOFThreshold() ? lnb->getLOFHi() : lnb->getLOFLo() );
1851 #if HAVE_DVB_API_VERSION < 3
1852 front.Frequency = abs(local);
1853 #else
1854 front.frequency = abs(local);
1855 #endif
1857 // set Continuous Tone ( 22 Khz... low - high band )
1858 if ( (swParams.HiLoSignal == eSwitchParameter::ON) || ( (swParams.HiLoSignal == eSwitchParameter::HILO) && (Frequency > lnb->getLOFThreshold()) ) )
1859 seq.continuousTone = eSecCmdSequence::TONE_ON;
1860 else if ( (swParams.HiLoSignal == eSwitchParameter::OFF) || ( (swParams.HiLoSignal == eSwitchParameter::HILO) && (Frequency <= lnb->getLOFThreshold()) ) )
1861 seq.continuousTone = eSecCmdSequence::TONE_OFF;
1863 seq.increasedVoltage = lnb->getIncreasedVoltage();
1865 // Voltage( 0/14/18V vertical/horizontal )
1866 if ( swParams.VoltageMode == eSwitchParameter::_14V || ( polarisation == polVert && swParams.VoltageMode == eSwitchParameter::HV ) )
1867 voltage = eSecCmdSequence::VOLTAGE_13;
1868 else if ( swParams.VoltageMode == eSwitchParameter::_18V || ( polarisation==polHor && swParams.VoltageMode == eSwitchParameter::HV) )
1869 voltage = eSecCmdSequence::VOLTAGE_18;
1870 else
1871 voltage = eSecCmdSequence::VOLTAGE_OFF;
1873 // set cmd ptr in sequence..
1874 seq.commands=commands;
1876 // handle DiSEqC Rotor
1877 if ( sendRotorCmd )
1879 #if 0
1880 eDebug("handle DISEqC Rotor.. cmdCount = %d", cmdCount);
1881 eDebug("0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",
1882 commands[cmdCount-1].u.diseqc.cmdtype,
1883 commands[cmdCount-1].u.diseqc.addr,
1884 commands[cmdCount-1].u.diseqc.cmd,
1885 commands[cmdCount-1].u.diseqc.params[0],
1886 commands[cmdCount-1].u.diseqc.params[1]);
1887 #endif
1889 // drive rotor with 18V when we can measure inputpower
1890 // or we know which orbital pos currently is selected
1891 if ( lnb->getDiSEqC().useRotorInPower&1 )
1893 if ( eSystemInfo::getInstance()->canMeasureLNBCurrent() == 1 ) // can measure with voltage > 13V ?
1894 seq.voltage = eSecCmdSequence::VOLTAGE_18;
1895 else
1896 seq.voltage = eSecCmdSequence::VOLTAGE_13;
1898 else
1899 seq.voltage = voltage;
1901 lastRotorCmd=RotorCmd;
1903 increased = seq.increasedVoltage;
1904 newPos = sat.getOrbitalPosition();
1906 if ( lnb->getDiSEqC().useRotorInPower&1 )
1908 curRotorPos=5000;
1909 DeltaA=(lnb->getDiSEqC().useRotorInPower & 0x0000FF00) >> 8;
1910 RotorUseInputPower(seq, lnb );
1911 finalTune=0;
1913 else
1915 if ( !eDVB::getInstance()->getScanAPI() )
1917 eDebug("ROTOR RUNNING EMIT");
1918 /* emit */ s_RotorRunning( newPos );
1920 RotorUseTimeout(seq, lnb );
1921 curRotorPos=11000; // Rotor cmd sent
1924 else if ( lastucsw != ucsw || ( ToneBurst && lastToneBurst != ToneBurst) )
1926 send:
1927 seq.voltage=voltage;
1928 if ( SendSequence(seq) < 0 )
1930 eDebug("SendSequence failed (%m)");
1931 return -1;
1933 else if ( lnb->getDiSEqC().DiSEqCMode >= eDiSEqC::V1_1 && lnb->getDiSEqC().SeqRepeat ) // Sequence Repeat ?
1935 usleep( 100000 ); // between seq repeats we wait 80ms
1936 SendSequence(seq); // just do it *g*
1939 else if ( lastcsw != csw )
1941 // faster zap workaround... send only diseqc when satpos changed
1942 if ( lnb->getDiSEqC().FastDiSEqC && csw && (csw / 4) == (lastcsw / 4) )
1944 eDebug("Satellite has not changed.. don't send DiSEqC cmd (Fast DiSEqC)");
1945 seq.numCommands=0;
1947 goto send; // jump above...
1949 else
1950 eDebug("no Band or Polarisation changed .. don't send Sequence");
1952 lastcsw = csw;
1953 lastucsw = ucsw;
1954 lastToneBurst = ToneBurst;
1955 lastLNB = lnb; /* important.. for the correct timeout
1956 between normal diseqc cmd and rotor cmd */
1958 // delete allocated memory
1959 delete [] commands;
1961 // fill in Frontend data
1962 #if HAVE_DVB_API_VERSION < 3
1963 front.Inversion=(Inversion == 2 ? INVERSION_AUTO :
1964 (Inversion?INVERSION_ON:INVERSION_OFF) );
1965 front.u.qpsk.FEC_inner=etsiToDvbApiFEC(FEC_inner);
1966 front.u.qpsk.SymbolRate=SymbolRate;
1967 #else
1968 front.inversion=(Inversion == 2 ? INVERSION_AUTO :
1969 (Inversion?INVERSION_ON:INVERSION_OFF) );
1970 front.u.qpsk.fec_inner=etsiToDvbApiFEC(FEC_inner);
1971 front.u.qpsk.symbol_rate=SymbolRate;
1972 #endif
1974 if (finalTune)
1975 return setFrontend();
1977 return 0;
1980 int eFrontend::tune_qam(eTransponder *trans,
1981 uint32_t Frequency, // absolute frequency in kHz
1982 uint32_t SymbolRate, // symbolrate in symbols/s (e.g. 6900000)
1983 uint8_t FEC_inner, // FEC_inner (-1 for none, 0 for auto, but please don't use that). normally -1.
1984 int Inversion, // spectral inversion, INVERSION_OFF / _ON / _AUTO (but please...)
1985 int QAM) // Modulation, QAM_xx
1987 eDebug("Cable Frontend detected");
1988 tune_all(trans);
1990 if (needreset > 1)
1992 #if HAVE_DVB_API_VERSION < 3
1993 ioctl(fd, FE_SET_POWER_STATE, FE_POWER_ON);
1994 usleep(150000);
1995 #endif
1996 needreset=0;
1999 #if HAVE_DVB_API_VERSION < 3
2000 front.Inversion=(Inversion == 2 ? INVERSION_AUTO :
2001 (Inversion?INVERSION_ON:INVERSION_OFF) );
2002 front.Frequency=Frequency;
2003 front.u.qam.QAM=etsiToDvbApiModulation(QAM);
2004 front.u.qam.FEC_inner=etsiToDvbApiFEC(FEC_inner);
2005 front.u.qam.SymbolRate=SymbolRate;
2006 #else
2007 front.inversion=(Inversion == 2 ? INVERSION_AUTO :
2008 (Inversion?INVERSION_ON:INVERSION_OFF) );
2009 front.frequency = Frequency*1000; // dbox2 v3 drivers need frequency as Hz
2010 front.u.qam.modulation=etsiToDvbApiModulation(QAM);
2011 front.u.qam.fec_inner=etsiToDvbApiFEC(FEC_inner);
2012 front.u.qam.symbol_rate=SymbolRate;
2013 #endif
2014 return setFrontend();
2017 int eFrontend::tune_ofdm(eTransponder *trans,
2018 int centre_frequency,
2019 int bandwidth,
2020 int constellation,
2021 int hierarchy_information,
2022 int code_rate_hp,
2023 int code_rate_lp,
2024 int guard_interval,
2025 int transmission_mode,
2026 int inversion)
2028 eDebug("DVB-T Frontend detected");
2029 tune_all(trans);
2031 if (needreset > 1)
2033 #if HAVE_DVB_API_VERSION < 3
2034 ioctl(fd, FE_SET_POWER_STATE, FE_POWER_ON);
2035 usleep(150000);
2036 #endif
2037 needreset=0;
2040 #if HAVE_DVB_API_VERSION < 3
2041 front.Inversion=(inversion == 2 ? INVERSION_AUTO :
2042 (inversion?INVERSION_ON:INVERSION_OFF) );
2043 front.Frequency = centre_frequency;
2044 front.u.ofdm.bandWidth=etsiToDvbApiBandwidth(bandwidth);
2045 front.u.ofdm.HP_CodeRate=etsiToDvbApiCodeRate(code_rate_hp);
2046 front.u.ofdm.LP_CodeRate=etsiToDvbApiCodeRate(code_rate_lp);
2047 front.u.ofdm.Constellation=etsiToDvbApiConstellation(constellation);
2048 front.u.ofdm.TransmissionMode=etsiToDvbApiTransmitMode(transmission_mode);
2049 front.u.ofdm.guardInterval=etsiToDvbApiGuardInterval(guard_interval);
2050 front.u.ofdm.HierarchyInformation=etsiToDvbApiHierarchyInformation(hierarchy_information);
2051 #else
2052 front.inversion=(inversion == 2 ? INVERSION_AUTO :
2053 (inversion?INVERSION_ON:INVERSION_OFF) );
2054 front.frequency = centre_frequency;
2055 front.u.ofdm.bandwidth=etsiToDvbApiBandwidth(bandwidth);
2056 front.u.ofdm.code_rate_HP=etsiToDvbApiCodeRate(code_rate_hp);
2057 front.u.ofdm.code_rate_LP=etsiToDvbApiCodeRate(code_rate_lp);
2058 front.u.ofdm.constellation=etsiToDvbApiConstellation(constellation);
2059 front.u.ofdm.transmission_mode=etsiToDvbApiTransmitMode(transmission_mode);
2060 front.u.ofdm.guard_interval=etsiToDvbApiGuardInterval(guard_interval);
2061 front.u.ofdm.hierarchy_information=etsiToDvbApiHierarchyInformation(hierarchy_information);
2062 #endif
2063 return setFrontend();
2066 int eFrontend::savePower()
2068 if (type == eSystemInfo::feUnknown)
2069 return -1;
2070 transponder=0;
2071 checkLockTimer.stop();
2072 checkRotorLockTimer.stop();
2073 updateTransponderTimer.stop();
2074 rotorTimer1.stop();
2075 rotorTimer2.stop();
2076 #if HAVE_DVB_API_VERSION < 3
2077 if (secfd != -1)
2079 eSecCmdSequence seq;
2080 seq.commands=0;
2081 seq.numCommands=0;
2082 seq.voltage= eSecCmdSequence::VOLTAGE_OFF;
2083 seq.continuousTone = eSecCmdSequence::TONE_OFF;
2084 seq.toneBurst = eSecCmdSequence::NONE;
2085 if (SendSequence(seq) < 0 )
2087 eDebug("SendSequence failed (%m)");
2088 return -1;
2091 if ( ioctl(fd, FE_SET_POWER_STATE, FE_POWER_OFF) < 0 )
2092 eDebug("FE_SET_POWER_STATE failed (%m)");
2093 #else
2094 if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF) < 0)
2095 eDebug("FE_SET_VOLTAGE (off) failed (%m)");
2096 if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) < 0)
2097 eDebug("FE_SET_TONE (off) failed (%m)");
2098 #endif
2099 transponder=0;
2100 needreset = 2;
2101 return 0;
2104 void eFrontend::setTerrestrialAntennaVoltage(bool state)
2106 if (type != eSystemInfo::feTerrestrial)
2107 return;
2108 #if HAVE_DVB_API_VERSION < 3
2109 int secfd=::open(SEC_DEV, O_RDWR);
2110 if (secfd<0)
2112 eDebug("open secfd failed(%m)");
2113 return;
2115 if ( ::ioctl(secfd, SEC_SET_VOLTAGE, state ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_13) < 0 )
2116 eDebug("SEC_SET_VOLTAGE (-T) failed (%m)");
2117 ::close(secfd);
2118 #endif