trunk 20080912
[gitenigma.git] / lib / dvb / dvbservice.cpp
blob73563a9b8e2da51699c6500c9ad1b600eae9da5b
1 #include <lib/dvb/dvbservice.h>
3 #include <errno.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
8 #include <lib/dvb/si.h>
9 #include <lib/dvb/decoder.h>
10 #include <lib/dvb/iso639.h>
11 #include <lib/dvb/frontend.h>
12 #ifndef DISABLE_CI
13 #include <lib/dvb/dvbci.h>
14 #endif
15 #include <lib/dvb/service.h>
16 #include <lib/dvb/eaudio.h>
17 #include <lib/system/info.h>
18 #include <lib/dvb/edvb.h>
19 #include <lib/dvb/record.h>
20 #include <lib/dvb/subtitling.h>
21 #include <sstream>
22 #if HAVE_DVB_API_VERSION < 3
23 #include <ost/dmx.h>
24 #define DEMUX1_DEV "/dev/dvb/card0/demux1"
25 #else
26 #include <linux/dvb/dmx.h>
27 #define DEMUX1_DEV "/dev/dvb/adapter0/demux1"
28 #endif
30 std::set<eDVBCaPMTClient*> eDVBCaPMTClientHandler::capmtclients;
32 pthread_mutex_t eDVBServiceController::availCALock =
33 PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
35 PMTEntry *eDVBServiceController::priorityAudio(PMTEntry *audio)
37 PMTEntry *audio2 = 0;
39 char *audiochannelspriority = 0;
40 eConfig::getInstance()->getKey("/extras/audiochannelspriority", audiochannelspriority);
42 if (audiochannelspriority)
44 char *audiochannel = strtok(audiochannelspriority, "#");
45 while (audiochannel && audio2 == 0)
47 for (std::list<eDVBServiceController::audioStream>::iterator it(audioStreams.begin())
48 ;it != audioStreams.end(); ++it)
50 if (strcasecmp(audiochannel, it->text.c_str()) == 0)
52 audio2 = it->pmtentry;
53 break;
56 audiochannel = strtok(NULL, "#");
58 free(audiochannelspriority);
60 if (audio2 != 0)
61 audio = audio2;
62 return audio;
65 eString getISO639Description(char *iso)
67 for (unsigned int i=0; i<sizeof(iso639)/sizeof(*iso639); ++i)
69 if (!strncasecmp(iso639[i].iso639foreign, iso, 3))
70 return iso639[i].description1;
71 if (!strncasecmp(iso639[i].iso639int, iso, 3))
72 return iso639[i].description1;
74 return eString()+iso[0]+iso[1]+iso[2];
76 #ifndef DISABLE_FILE
77 void eDVBServiceController::FillPIDsFromFile(eService *sp)
79 if (service.path)
81 eDebug("fill PIDs for %s", service.path.c_str());
82 int fd=open(service.path.c_str(), O_RDONLY|O_LARGEFILE);
83 if (fd >= 0)
85 __u8 packet[188];
88 if (::read(fd, packet, 188) != 188)
89 break;
90 // i know that THIS is not really a SIT parser :)
91 if ((packet[0] != 0x47) || (packet[1] != 0x40) || (packet[2] != 0x1f) || (packet[3] != 0x10))
92 break;
93 int nameoffset = 6;
94 if (memcmp(packet+0x15, "ENIGMA", 6))
96 //failed so check another
97 if (!memcmp(packet+0x15, "NEUTRINONG", 10))
98 nameoffset = 10;
99 else
100 break;
102 // we found our private descriptor:
103 __u8 *descriptor=packet+0x13;
104 int len=descriptor[1];
105 sp->dvb->service_id = eServiceID((packet[0xf]<<8)|packet[0x10]);
106 len-=nameoffset;
107 descriptor+=2+nameoffset; // skip tag, len, ENIGMA or NEUTRINONG
108 for (int i=0; i<len; i+=descriptor[i+1]+2)
110 int tag=descriptor[i];
111 switch (tag)
113 case eServiceDVB::cVPID:
114 sp->dvb->set(eServiceDVB::cVPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
115 break;
116 case eServiceDVB::cAPID:
117 if (descriptor[i+4] == 0)
118 sp->dvb->set(eServiceDVB::cAPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
119 else
120 sp->dvb->set(eServiceDVB::cAC3PID, (descriptor[i+2]<<8)|(descriptor[i+3]));
121 break;
122 case eServiceDVB::cTPID:
123 sp->dvb->set(eServiceDVB::cTPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
124 break;
125 case eServiceDVB::cPCRPID:
126 sp->dvb->set(eServiceDVB::cPCRPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
127 break;
130 } while (0);
131 close(fd);
135 #endif
137 eDVBServiceController::eDVBServiceController(eDVB &dvb)
138 : eDVBController(dvb)
139 , updateTDTTimer(eApp)
140 , disableFrontendTimer(eApp)
141 #ifndef DISABLE_CI
142 , DVBCI(dvb.DVBCI)
143 , DVBCI2(dvb.DVBCI2)
144 #endif
146 CONNECT(disableFrontendTimer.timeout, eDVBServiceController::disableFrontend);
147 CONNECT(updateTDTTimer.timeout, eDVBServiceController::startTDT);
148 CONNECT(dvb.tPAT.tableReady, eDVBServiceController::PATready);
149 CONNECT(dvb.tPMT.tableReady, eDVBServiceController::PMTready);
150 CONNECT(dvb.tSDT.tableReady, eDVBServiceController::SDTready);
151 CONNECT(dvb.tEIT.tableReady, eDVBServiceController::EITready);
153 initCAlist();
155 timeSet = false;
156 transponder=0;
157 tdt=0;
158 calist.setAutoDelete(true);
160 updateTDTTimer.start(60*60*1000,true); // update time every hour to transponder time
162 eDVBCaPMTClientHandler::registerCaPMTClient(this); // static method...
165 eDVBServiceController::~eDVBServiceController()
167 delete tdt;
168 Decoder::Flush();
169 eDVBCaPMTClientHandler::unregisterCaPMTClient(this); // static method...
172 void eDVBServiceController::handleEvent(const eDVBEvent &event)
174 #ifdef PROFILE
175 static timeval last_event;
177 timeval now;
178 gettimeofday(&now, 0);
180 int diff=(now.tv_sec-last_event.tv_sec)*1000000+(now.tv_usec-last_event.tv_usec);
181 last_event=now;
183 char *what="unknown";
185 switch (event.type)
187 case eDVBServiceEvent::eventTunedIn: what="eventTunedIn"; break;
188 case eDVBServiceEvent::eventServiceSwitch: what="ServiceSwitch"; break;
189 case eDVBServiceEvent::eventServiceTuneOK: what="TuneOK"; break;
190 case eDVBServiceEvent::eventServiceTuneFailed: what="TuneFailed"; break;
191 case eDVBServiceEvent::eventServiceGotPAT: what="GotPAT"; break;
192 case eDVBServiceEvent::eventServiceGotPMT: what="GotPMT"; break;
193 case eDVBServiceEvent::eventServiceNewPIDs: what="NewPIDs"; break;
194 case eDVBServiceEvent::eventServiceGotSDT: what="GotSDT"; break;
195 case eDVBServiceEvent::eventServiceSwitched: what="Switched"; break;
196 case eDVBServiceEvent::eventServiceFailed: what="Failed"; break;
197 default: { static char bug[100]; sprintf(bug, "%d", event.type); what=bug; }
200 eDebug("[PROFILE] [%s] +%dus", what, diff);
201 #endif
202 switch (event.type)
204 case eDVBEvent::eventTunedIn:
205 if (transponder==event.transponder)
206 dvb.event(eDVBServiceEvent(event.err?eDVBServiceEvent::eventServiceTuneFailed: eDVBServiceEvent::eventServiceTuneOK, event.err, event.transponder));
207 break;
208 case eDVBServiceEvent::eventServiceSwitch:
210 if (!service.path.size()) // a normal service, not a replay
212 if (!dvb.settings->getTransponders())
214 eDebug("no tranponderlist");
215 service_state=ENOENT;
216 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
217 return;
219 eTransponder *n=dvb.settings->getTransponders()->searchTS(service.getDVBNamespace(), service.getTransportStreamID(), service.getOriginalNetworkID());
220 if (!n)
222 eDebug("no transponder %x %x", service.getOriginalNetworkID().get(), service.getTransportStreamID().get());
223 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceTuneFailed));
224 break;
226 if ( !(n->state&eTransponder::stateOK) )
228 eDebug("couldn't tune (state is %x)", n->state);
229 service_state=ENOENT;
230 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
231 return;
234 if (n==transponder)
236 // dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceTune));
237 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceTuneOK, 0, n));
238 } else
240 /*emit*/ dvb.leaveTransponder(transponder);
241 transponder=n;
242 if (n->tune())
243 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceTuneFailed));
244 else
245 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceTune));
247 eDebug("<-- tuned");
248 } else
250 eDebug("won't tune, since its a replay.");
251 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceTuneOK, 0, 0));
253 break;
255 case eDVBServiceEvent::eventServiceTuneOK:
257 // eDebug("apid = %04x, vpid = %04x, pcrpid = %04x, tpid = %04x", Decoder::current.apid, Decoder::current.vpid, Decoder::current.pcrpid, Decoder::current.tpid );
258 /*emit*/ dvb.enterTransponder(event.transponder);
259 int nodvb=0;
261 spSID=service.getServiceID().get();
262 // do we haved fixed or cached PID values?
263 eService *sp=eServiceInterface::getInstance()->addRef(service);
264 if (sp)
266 if (sp->dvb)
268 #ifndef DISABLE_FILE
269 FillPIDsFromFile(sp);
270 #endif
271 // VPID
272 Decoder::parms.vpid=sp->dvb->get(eServiceDVB::cVPID);
273 // AC3PID
274 int tmp = sp->dvb->get(eServiceDVB::cAC3PID);
275 if ( tmp != -1)
277 Decoder::parms.audio_type=DECODE_AUDIO_AC3;
278 Decoder::parms.apid=tmp;
280 /* APID*/ else
282 tmp = sp->dvb->get(eServiceDVB::cAPID);
283 if ( tmp != -1)
285 Decoder::parms.audio_type=DECODE_AUDIO_MPEG;
286 Decoder::parms.apid=tmp;
289 // TPID
290 Decoder::parms.tpid=sp->dvb->get(eServiceDVB::cTPID);
291 // PCRPID ... do not set on recorded streams..
292 tmp = sp->dvb->get(eServiceDVB::cPCRPID);
293 if ( tmp != -1 && !service.path.length() )
294 Decoder::parms.pcrpid=tmp;
295 // start yet...
296 Decoder::Set();
298 if (sp->dvb->dxflags & eServiceDVB::dxNoDVB)
299 nodvb=1; // dont use pat/pmt
301 spSID=sp->dvb->service_id.get();
303 eServiceInterface::getInstance()->removeRef(service);
306 if ( service.path ) // replay ?
308 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceGetPAT));
309 dvb.tPAT.start(new PAT());
311 break;
313 if (nodvb) // dont get PAT/PMT and other..
315 dvb.tEIT.start(new EIT(EIT::typeNowNext, spSID, EIT::tsActual));
316 service_state=0;
317 /*emit*/ dvb.enterService(service);
318 /*emit*/ dvb.switchedService(service, -service_state);
319 dvb.setState(eDVBServiceState(eDVBServiceState::stateIdle));
320 break;
322 else if ( spSID )
324 // workaround for zap in background before recordings
325 if ( Decoder::locked == 2 && !dvb.recorder )
327 eDebug("start PAT on demux1");
328 dvb.tPAT.start(new PAT(), DEMUX1_DEV);
330 else
332 eDebug("start PAT on demux0");
333 dvb.tPAT.start(new PAT());
337 startTDT();
339 switch (service.getServiceType())
341 case 1: // digital television service
342 case 2: // digital radio service
343 case 3: // teletext service
344 dvb.tEIT.start(new EIT(EIT::typeNowNext, spSID, EIT::tsActual));
345 case 5: // NVOD time shifted service ( faked )
346 case 6: // mosaic service
347 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceGetPAT));
348 dvb.tPAT.get();
349 break;
350 case 4: // NVOD reference service
351 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceGetSDT));
352 dvb.tEIT.start(new EIT(EIT::typeNowNext, spSID, EIT::tsActual));
353 break;
354 case 7: // linkage ( faked )
355 // start parentEIT
356 dvb.tEIT.start(new EIT(EIT::typeNowNext, parentservice.getServiceID().get(),
357 ( (service.getTransportStreamID()==parentservice.getTransportStreamID())
358 &&(service.getOriginalNetworkID()==parentservice.getOriginalNetworkID())) ? EIT::tsActual:EIT::tsOther ));
359 case -1: // data
360 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceGetPAT));
361 dvb.tPAT.get();
362 break;
363 default:
364 service_state=ENOSYS;
365 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
366 break;
368 break;
370 case eDVBServiceEvent::eventServiceTuneFailed:
371 eDebug("[TUNE] tune failed");
372 service_state=ENOENT;
373 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
374 // transponder=0;
375 break;
376 case eDVBServiceEvent::eventServiceGotPAT:
378 int pmtpid=-1;
379 if (dvb.getState() != eDVBServiceState::stateServiceGetPAT)
380 break;
382 if ( !service.path )
383 dvb.tSDT.start(new SDT());
385 PAT *pat=dvb.tPAT.getCurrent();
386 PATEntry *pe=spSID ? pat->searchService(spSID) : 0;
387 if (!pe)
389 #ifndef DISABLE_FILE
390 if ( service.path ) // recorded ts
392 // we try to find manual the correct sid
393 int fd = open( service.path.c_str(), O_RDONLY|O_LARGEFILE );
394 if ( fd < 0 )
395 eDebug("open %s failed");
396 else
398 eDebug("parse ts file for find the correct pmtpid");
399 unsigned char *buf = new unsigned char[256*1024]; // 256 kbyte
400 int rd=0;
401 while ( pmtpid == -1 && (rd < 1024*1024*5) )
403 std::set<int> pids;
404 int r = ::read( fd, buf, 256*1024 );
405 if ( r <= 0 )
406 break;
407 rd+=r;
408 int cnt=0;
409 while(cnt < r)
411 while ( (buf[cnt] != 0x47) && ((cnt+188) < r) && (buf[cnt+188] != 0x47) )
413 // eDebug("search sync byte %02x %02x, %d %d", buf[cnt], buf[cnt+188], cnt+188, r);
414 cnt++;
416 if ( buf[cnt] == 0x47 )
418 int pid = ((buf[cnt+1]&0x3F) << 8) | buf[cnt+2];
419 // eDebug("addpid %d", pid);
420 pids.insert(pid);
421 cnt+=188;
423 else
424 break;
426 for( std::set<int>::iterator it(pids.begin()); pmtpid==-1 && it != pids.end(); ++it )
428 for ( ePtrList<PATEntry>::iterator i(pat->entries); i != pat->entries.end(); ++i)
429 if ( i->program_map_PID == *it )
431 pmtpid = *it;
432 spSID = i->program_number;
433 eDebug("found pmtpid %04x for sid %d(%04x)", pmtpid, spSID, spSID);
434 break;
438 delete [] buf;
439 close(fd);
442 #endif
444 else
445 pmtpid=pe->program_map_PID;
446 pat->unlock();
447 if (pmtpid==-1)
449 eDebug("[PAT] no pat entry");
450 service_state=ENOENT;
451 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
452 return;
454 dvb.setState(eDVBServiceState(eDVBServiceState::stateServiceGetPMT));
456 // workaround for zap in background before recordings
457 if ( Decoder::locked == 2 && !service.path && !dvb.recorder )
459 eDebug("start PMT on demux1");
460 dvb.tPMT.start(new PMT(pmtpid, spSID), DEMUX1_DEV );
462 else
464 eDebug("start PMT on demux0");
465 dvb.tPMT.start(new PMT(pmtpid, spSID));
467 break;
469 case eDVBServiceEvent::eventServiceGotPMT:
471 service_state=0;
472 PMT *pmt=dvb.tPMT.ready()?dvb.tPMT.getCurrent():0;
473 if (pmt)
475 scanPMT(pmt);
477 if ( !service.path )
478 eDVBCaPMTClientHandler::distribute_gotPMT(service, pmt);
480 /*emit*/ dvb.gotPMT(pmt);
481 pmt->unlock();
482 if ( dvb.tEIT.ready() )
483 EITready(0); // fake call.. to update Audio Descriptions..
485 if (dvb.getState()==eDVBServiceState::stateServiceGetPMT)
486 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceSwitched));
487 else
488 eDebug("nee, doch nicht (state ist %d)", (int)dvb.getState());
489 break;
491 case eDVBServiceEvent::eventServiceGotSDT:
493 if (dvb.getState() != eDVBServiceState::stateServiceGetSDT)
494 break;
496 SDT *sdt=dvb.tSDT.ready()?dvb.tSDT.getCurrent():0;
497 if (sdt)
499 dvb.setState(eDVBServiceState(eDVBServiceState::stateIdle));
500 /*emit*/ dvb.gotSDT(sdt);
501 sdt->unlock();
502 if (service.getServiceType()==4)
503 service_state=ENVOD;
504 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceSwitched));
505 } else
506 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceFailed));
507 break;
509 case eDVBServiceEvent::eventServiceNewPIDs:
510 Decoder::Set();
511 break;
512 case eDVBServiceEvent::eventServiceSwitched:
513 #ifndef DISABLE_FILE
514 if ( service.path )
516 eString filename = service.path;
517 filename.erase(filename.length()-2, 2);
518 filename+="eit";
519 int fd = ::open( filename.c_str(), O_RDONLY );
520 if ( fd > -1 )
522 __u8 buf[4096];
523 int rd = ::read(fd, buf, 4096);
524 ::close(fd);
525 if ( rd > 12 /*EIT_LOOP_SIZE*/ )
527 EIT *e=new EIT();
528 e->ts=EIT::tsFaked;
529 e->type=EIT::typeNowNext;
530 e->version_number=0;
531 e->current_next_indicator=0;
532 e->transport_stream_id=service.getTransportStreamID().get();
533 e->original_network_id=service.getOriginalNetworkID().get();
534 EITEvent *evt = new EITEvent( (eit_event_struct*)buf, (e->transport_stream_id<<16)|e->original_network_id );
535 evt->free_CA_mode=0;
536 e->events.push_back(evt);
537 e->ready=1;
538 dvb.tEIT.inject(e);
542 #endif
543 /*emit*/ dvb.enterService(service);
544 case eDVBServiceEvent::eventServiceFailed:
545 /*emit*/ dvb.switchedService(service, -service_state);
546 dvb.setState(eDVBServiceState(eDVBServiceState::stateIdle));
547 break;
551 void eDVBServiceController::PATready(int error)
553 eDebug("PATready (%d)",error);
554 dvb.event(eDVBServiceEvent(error?eDVBServiceEvent::eventServiceFailed:eDVBServiceEvent::eventServiceGotPAT));
557 void eDVBServiceController::SDTready(int error)
559 eDebug("SDTready (%d)", error);
560 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceGotSDT));
561 if (dvb.settings->getTransponders())
563 SDT *sdt=dvb.tSDT.ready()?dvb.tSDT.getCurrent():0;
564 if (sdt)
566 dvb.settings->getTransponders()->startHandleSDT(sdt, service.getDVBNamespace(), -1, -1, &freeCheckFinishedCallback, transponder->state & eTransponder::stateOnlyFree ? eTransponderList::SDT_SCAN_FREE : eTransponderList::SDT_SCAN );
567 sdt->unlock();
572 void eDVBServiceController::freeCheckFinished()
574 eDebug("freeCheckFinished");
577 void eDVBServiceController::PMTready(int error)
579 eDebug("PMTready (%d)", error);
580 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceGotPMT));
583 void eDVBServiceController::EITready(int error)
585 eDebug("EITready (%d)", error);
586 bool haveAC3=false, changed=false;
587 if (!error)
589 EIT *eit=dvb.getEIT();
591 for (ePtrList<EITEvent>::iterator e(eit->events); e != eit->events.end(); ++e)
593 // eDebug("running_status = %d", e->running_status );
594 if ((e->running_status>=2) || (!e->running_status) ) // currently running service
596 for (ePtrList<Descriptor>::iterator d(e->descriptor); d != e->descriptor.end(); ++d)
598 if (d->Tag()==DESCR_COMPONENT)
600 for (std::list<audioStream>::iterator it(audioStreams.begin())
601 ;it != audioStreams.end(); ++it )
603 if (((ComponentDescriptor*)*d)->component_tag == it->component_tag )
605 changed=true;
606 eString tmp = ((ComponentDescriptor*)*d)->text;
607 if (tmp)
609 it->text=tmp;
610 if ( it->isAC3 )
611 it->text+=" (AC3)";
612 else if ( it->isDTS )
613 it->text+=" (DTS)";
616 if ( !haveAC3 && (it->isAC3 || it->isDTS) )
617 haveAC3=true;
621 break;
625 if ( service.getServiceType() == 4 ) // NVOD Service
627 delete dvb.parentEIT;
628 dvb.parentEIT = new EIT( eit );
629 dvb.parentEIT->events.setAutoDelete(true);
630 eit->events.setAutoDelete(false);
632 /*emit*/ dvb.gotEIT(eit, 0);
633 eit->unlock();
635 else
636 /*emit*/ dvb.gotEIT(0, error);
638 if ( changed && !(haveAC3 && eAudio::getInstance()->getAC3default()) )
640 PMTEntry *audio = 0;
641 audio = priorityAudio(audio);
642 if (audio)
644 setPID(audio);
645 setDecoder();
650 // defines for DM7000 / DM7020
651 #define FP_IOCTL_SET_RTC 0x101
652 #define FP_IOCTL_GET_RTC 0x102
654 static time_t prev_time;
656 void setRTC(time_t time)
658 int fd = open("/dev/dbox/fp0", O_RDWR);
659 if ( fd >= 0 )
661 if ( ::ioctl(fd, FP_IOCTL_SET_RTC, (void*)&time ) < 0 )
662 eDebug("FP_IOCTL_SET_RTC failed(%m)");
663 else
664 prev_time = time;
665 close(fd);
669 time_t getRTC()
671 time_t rtc_time=0;
672 int fd = open("/dev/dbox/fp0", O_RDWR);
673 if ( fd >= 0 )
675 if ( ::ioctl(fd, FP_IOCTL_GET_RTC, (void*)&rtc_time ) < 0 )
676 eDebug("FP_IOCTL_GET_RTC failed(%m)");
677 close(fd);
679 return rtc_time != prev_time ? rtc_time : 0;
682 void eDVBServiceController::TDTready(int error)
684 eDebug("TDTready %d", error);
685 // receive new TDT every 60 minutes
686 updateTDTTimer.start(60*60*1000,true);
687 if (!error && transponder)
689 std::map<tsref,int> &tOffsMap = eTransponderList::getInstance()->TimeOffsetMap;
690 std::map< tsref, int >::iterator it( tOffsMap.find( *transponder ) );
692 // current linux time
693 time_t linuxTime = time(0);
695 // current enigma time
696 time_t nowTime=linuxTime+dvb.time_difference;
698 // difference between current enigma time and transponder time
699 int enigma_diff = tdt->UTC_time-nowTime;
701 int new_diff=0;
703 if (timeSet) // ref time ready?
705 // difference between reference time (current enigma time)
706 // and the transponder time
707 eDebug("[TIME] diff is %d", enigma_diff);
708 if ( abs(enigma_diff) < 120 )
710 eDebug("[TIME] diff < 120 .. use Transponder Time");
711 tOffsMap[*transponder] = 0;
712 new_diff = enigma_diff;
714 else if ( it != tOffsMap.end() ) // correction saved?
716 eDebug("[TIME] we have correction %d", it->second);
717 time_t CorrectedTpTime = tdt->UTC_time+it->second;
718 int ddiff = CorrectedTpTime-nowTime;
719 eDebug("[TIME] diff after add correction is %d", ddiff);
720 if ( abs(it->second) < 300 ) // stored correction < 5 min
722 eDebug("[TIME] use stored correction(<5 min)");
723 new_diff = ddiff;
725 else if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 &&
726 getRTC() )
728 time_t rtc=getRTC();
729 tOffsMap[*transponder] = rtc-tdt->UTC_time;
730 new_diff = rtc-nowTime; // set enigma time to rtc
731 eDebug("[TIME] update stored correction to %d (calced against RTC time)", rtc-tdt->UTC_time );
733 else if ( abs(ddiff) <= 120 )
735 // with stored correction calced time difference is lower 2 min
736 // this don't help when a transponder have a clock running to slow or to fast
737 // then its better to have a DM7020 with always running RTC
738 eDebug("[TIME] use stored correction(corr < 2 min)");
739 new_diff = ddiff;
741 else // big change in calced correction.. hold current time and update correction
743 eDebug("[TIME] update stored correction to %d", -enigma_diff);
744 tOffsMap[*transponder] = -enigma_diff;
747 else
749 eDebug("[TIME] no correction found... store calced correction(%d)",-enigma_diff);
750 tOffsMap[*transponder] = -enigma_diff;
753 else // no time setted yet
755 if ( it != tOffsMap.end() )
757 enigma_diff += it->second;
758 eDebug("[TIME] we have correction (%d)... use", it->second );
760 else
761 eDebug("[TIME] dont have correction.. set Transponder Diff");
762 new_diff=enigma_diff;
765 time_t t = nowTime+new_diff;
766 lastTpTimeDifference=tdt->UTC_time-t;
768 if (!new_diff)
770 eDebug("[TIME] not changed");
771 return;
774 tm now = *localtime(&t);
775 eDebug("[TIME] time update to %02d:%02d:%02d",
776 now.tm_hour,
777 now.tm_min,
778 now.tm_sec);
780 dvb.time_difference = t - linuxTime; // calc our new linux_time -> enigma_time correction
781 eDebug("[TIME] time_difference is %d", dvb.time_difference );
783 if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 )
784 setRTC(t);
786 if ( abs(dvb.time_difference) > 59 )
788 eDebug("[TIME] set Linux Time");
789 timeval tnow;
790 gettimeofday(&tnow,0);
791 tnow.tv_sec=t;
792 settimeofday(&tnow,0);
793 for (ePtrList<eMainloop>::iterator it(eMainloop::existing_loops)
794 ;it != eMainloop::existing_loops.end(); ++it)
795 it->setTimerOffset(dvb.time_difference);
796 dvb.time_difference=1;
798 else if ( !dvb.time_difference )
799 dvb.time_difference=1;
801 timeSet = true;
803 /*emit*/ dvb.timeUpdated();
805 else if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 ||
806 ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7000
807 && eSystemInfo::getInstance()->hasStandbyWakeupTimer() ) )
809 eDebug("[TIME] no transponder tuned... or no TDT/TOT avail .. try to use RTC :)");
810 time_t rtc_time = getRTC();
811 if ( rtc_time ) // RTC Ready?
813 tm now = *localtime(&rtc_time);
814 eDebug("[TIME] RTC time is %02d:%02d:%02d",
815 now.tm_hour,
816 now.tm_min,
817 now.tm_sec);
818 time_t linuxTime=time(0);
819 time_t nowTime=linuxTime+dvb.time_difference;
820 now = *localtime(&nowTime);
821 eDebug("[TIME] Receiver time is %02d:%02d:%02d",
822 now.tm_hour,
823 now.tm_min,
824 now.tm_sec);
825 dvb.time_difference = rtc_time - linuxTime;
826 eDebug("[TIME] RTC to Receiver time difference is %d seconds", nowTime - rtc_time );
827 if ( abs(dvb.time_difference) > 59 )
829 eDebug("[TIME] set Linux Time to RTC Time");
830 timeval tnow;
831 gettimeofday(&tnow,0);
832 tnow.tv_sec=rtc_time;
833 settimeofday(&tnow,0);
834 for (ePtrList<eMainloop>::iterator it(eMainloop::existing_loops)
835 ;it != eMainloop::existing_loops.end(); ++it)
836 it->setTimerOffset(dvb.time_difference);
837 dvb.time_difference=1;
839 else if ( !dvb.time_difference )
840 dvb.time_difference=1;
841 else
842 eDebug("[TIME] set to RTC time");
843 /*emit*/ dvb.timeUpdated();
845 else
846 eDebug("[TIME] shit RTC not ready :(");
850 void eDVBServiceController::scanPMT( PMT *pmt )
852 Decoder::parms.pmtpid=pmt->pid;
854 usedCASystems.clear();
856 PMTEntry *audio=0, *ac3_audio=0, *video=0, *teletext=0;
858 int audiopid=-1, videopid=-1, ac3pid=-1, tpid=-1;
860 int sac3default=eAudio::getInstance()->getAC3default();
862 if ( Decoder::parms.pcrpid != pmt->PCR_PID && !service.path.size() )
863 Decoder::parms.pcrpid = pmt->PCR_PID;
865 // get last selected audio / video pid from pid cache
866 eService *sp=eServiceInterface::getInstance()->addRef(service);
867 if (sp)
869 if (sp->dvb)
871 #ifndef DISABLE_FILE
872 FillPIDsFromFile(sp);
873 #endif
874 videopid=sp->dvb->get(eServiceDVB::cVPID);
875 audiopid=sp->dvb->get(eServiceDVB::cAPID);
876 ac3pid=sp->dvb->get(eServiceDVB::cAC3PID);
877 sp->dvb->set(eServiceDVB::cPCRPID, Decoder::parms.pcrpid);
881 int isca=checkCA(calist, pmt->program_info, pmt->program_number);
883 audioStreams.clear();
884 videoStreams.clear();
885 subtitleStreams.clear();
887 int content_pid=-1;
889 ePtrList<PMTEntry>::iterator TTXIt=pmt->streams.end();
890 for (ePtrList<PMTEntry>::iterator i(pmt->streams); i != pmt->streams.end(); ++i)
892 PMTEntry *pe=*i;
893 bool isAudio=false;
894 int tmp=0;
896 switch (pe->stream_type)
898 case 1: // ISO/IEC 11172 Video
899 case 2: // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
900 if ( (!video) || (pe->elementary_PID == videopid) )
901 video=pe;
902 isca+=checkCA(calist, pe->ES_info, pmt->program_number);
903 videoStreams.push_back(pe);
904 break;
905 case 3: // ISO/IEC 11172 Audio
906 case 4: // ISO/IEC 13818-3 Audio
907 isAudio=true;
908 case 6:
910 isca+=checkCA(calist, pe->ES_info, pmt->program_number);
911 audioStream stream(pe);
912 for (ePtrList<Descriptor>::iterator ii(pe->ES_info); ii != pe->ES_info.end(); ++ii)
914 switch( ii->Tag() )
916 case DESCR_AC3:
917 stream.isAC3=1;
918 break;
919 case DESCR_REGISTRATION:
920 if (!memcmp(((RegistrationDescriptor*)*ii)->format_identifier, "DTS", 3))
921 stream.isDTS=1;
922 break;
923 case DESCR_TELETEXT:
924 if ( (!teletext) || (pe->elementary_PID == tpid) )
926 TTXIt = i;
927 teletext=pe;
929 break;
930 case DESCR_SUBTITLING:
931 subtitleStreams.push_back(pe);
932 break;
933 case DESCR_ISO639_LANGUAGE:
934 stream.text=getISO639Description(((ISO639LanguageDescriptor*)*ii)->language_code);
935 break;
936 case DESCR_STREAM_ID:
937 stream.component_tag=((StreamIdentifierDescriptor*)*ii)->component_tag;
938 break;
939 case DESCR_LESRADIOS:
941 LesRadiosDescriptor *d = (LesRadiosDescriptor*)*ii;
942 if ( (stream.component_tag >= 0 || d->id) && d->name )
943 stream.text.sprintf("%d.) %s", d->id, d->name.c_str());
944 else
945 isAudio=false;
946 break;
948 default:
949 break;
953 if (stream.isAC3)
955 stream.text+=" (AC3)";
956 isAudio=true;
957 if ( (!ac3_audio) || (pe->elementary_PID == ac3pid) )
958 ac3_audio=pe;
960 else if (stream.isDTS)
962 stream.text+=" (DTS)";
963 isAudio=true;
964 if ( (!ac3_audio) || (pe->elementary_PID == ac3pid) )
965 ac3_audio=pe;
967 else if (isAudio && ( (!audio) || (pe->elementary_PID == audiopid) ) )
968 audio=pe;
970 if (!stream.text)
971 stream.text.sprintf("PID %04x", pe->elementary_PID);
973 if (isAudio)
974 audioStreams.push_back(stream);
976 case 5: // private section
978 if ( content_pid != -1)
979 continue;
980 for (ePtrList<Descriptor>::iterator ii(pe->ES_info); ii != pe->ES_info.end(); ++ii)
982 switch( ii->Tag() )
984 case DESCR_PRIV_DATA_SPEC:
985 if ( ((PrivateDataSpecifierDescriptor*)*ii)->private_data_specifier == 190 )
986 tmp |= 1;
987 break;
988 case 0x90:
990 UnknownDescriptor *descr = (UnknownDescriptor*) *ii;
991 if ( descr->length() == 4 && !descr->data[0] && !descr->data[1] && descr->data[2] == 0xFF && descr->data[3] == 0xFF )
992 tmp |= 2;
994 default:
995 break;
998 if ( tmp == 3 )
999 content_pid = pe->elementary_PID;
1001 default:
1002 break;
1006 if ( content_pid != -1 )
1007 /*emit*/ dvb.gotContentPid(content_pid);
1009 // get audio priority channel
1010 audio = priorityAudio(audio);
1012 ePtrList<PMTEntry>::iterator tmp = pmt->streams.end();
1013 if (TTXIt != tmp)
1015 // move teletext to the end of the list
1016 --tmp;
1017 if ( tmp != TTXIt )
1018 std::iter_swap(tmp, TTXIt);
1021 int needAC3Workaround=0;
1022 switch (eSystemInfo::getInstance()->getHwType())
1024 case eSystemInfo::dbox2Nokia:
1025 case eSystemInfo::dbox2Philips:
1026 case eSystemInfo::dbox2Sagem:
1027 needAC3Workaround=1;
1028 default:
1029 break;
1032 if ( !needAC3Workaround && ac3_audio && ( sac3default || (ac3pid != -1) || (!audio) ) )
1034 audiopid = ac3pid;
1035 audio = ac3_audio;
1038 if ( video )
1040 if ( video->elementary_PID != videopid )
1041 setPID(video);
1043 else if (sp && sp->dvb) // handle no more existing vpid
1045 Decoder::parms.vpid = -1;
1046 sp->dvb->set(eServiceDVB::cVPID, -1);
1049 if ( audio )
1051 if ( audiopid != audio->elementary_PID )
1052 setPID(audio);
1054 else if (sp && sp->dvb) // handle no more existing apid
1056 Decoder::parms.apid = -1;
1057 sp->dvb->set(eServiceDVB::cAPID, -1);
1058 sp->dvb->set(eServiceDVB::cAC3PID, -1);
1061 if ( teletext )
1063 if ( tpid != teletext->elementary_PID )
1064 setPID(teletext);
1066 else if (sp && sp->dvb) // handle no more existing tpid
1068 Decoder::parms.tpid = -1;
1069 sp->dvb->set(eServiceDVB::cTPID, -1);
1072 /*emit*/ dvb.scrambled(isca);
1074 int hideerror=0;
1075 eConfig::getInstance()->getKey("/elitedvb/extra/hideerror", hideerror);
1076 if ( hideerror || (dvb.recorder && service.path) )
1078 else if (isca && !service.path && !calist )
1080 eDebug("NO CASYS");
1081 service_state=ENOCASYS;
1084 if ((Decoder::parms.vpid==-1) && (Decoder::parms.apid==-1))
1085 service_state=ENOSTREAM;
1087 // for (ePtrList<CA>::iterator i(calist); i != calist.end(); ++i)
1088 // eDebug("CA %04x ECMPID %04x", i->casysid, i->ecmpid);
1090 setDecoder();
1092 // AC3 DBOX2 Workaround... buggy drivers...
1093 if ( needAC3Workaround && ac3_audio && ( sac3default || (ac3pid != -1) || (!audio) ) )
1095 setPID(ac3_audio);
1096 setDecoder();
1099 if (sp)
1100 eServiceInterface::getInstance()->removeRef(service);
1103 int eDVBServiceController::switchService(const eServiceReferenceDVB &newservice)
1105 if (newservice == service)
1107 eDebug("is same service..");
1108 return 0;
1111 Decoder::Flush(1);
1113 #ifndef DISABLE_FILE
1114 eServiceReferenceDVB recRef =
1115 dvb.recorder && dvb.recorder->recRef ?
1116 dvb.recorder->recRef : eServiceReferenceDVB();
1117 recRef.data[0] = service.getServiceType();
1118 #endif
1120 if ( service
1121 #ifndef DISABLE_FILE
1122 // && !service.path
1123 && Decoder::locked != 2 // leave service for (timer) zap in Background
1124 && service != recRef
1125 #endif
1128 // must replace faked service types.. for capmt handlers
1129 eServiceReferenceDVB ref=service;
1130 switch(ref.getServiceType())
1132 case 4:
1133 case 7:
1134 ref.data[0]=1; // TV
1135 break;
1137 eDVBCaPMTClientHandler::distribute_leaveService(ref); // capmt handler call..
1140 /*emit*/ dvb.leaveService(service);
1142 // Linkage service handling..
1143 if ( newservice.getServiceType()==7 && prevservice )
1145 parentservice = prevservice;
1146 prevservice = eServiceReferenceDVB();
1149 if ( !newservice )
1151 if ( service.getServiceType() != 7 )
1152 prevservice=service; // save currentservice
1153 // when in 15 seconds no other dvb service is running disable frontend
1154 disableFrontendTimer.start(15*1000, true);
1156 /////////////////////////////////
1158 service=newservice;
1160 dvb.tEIT.start(0); // clear eit
1161 dvb.tPAT.start(0); // clear tables.
1162 dvb.tPMT.start(0);
1163 dvb.tSDT.start(0);
1165 if (service)
1167 if ( service && !service.path )
1168 eDVBCaPMTClientHandler::distribute_enterService(service); // capmt handler call..
1170 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceSwitch));
1173 switch(newservice.getServiceType())
1175 case 1: // tv service
1176 case 2: // radio service
1177 case 4: // nvod parent service
1178 case 7: // linkage service
1179 delete dvb.parentEIT;
1180 dvb.parentEIT = 0;
1181 break;
1182 case 5: // nvod ref service
1183 // send Parent EIT .. for osd text..
1184 dvb.gotEIT(0,0);
1185 break;
1187 return 1;
1190 #ifndef DISABLE_CI
1191 void eDVBServiceController::handlePMT(const eServiceReferenceDVB &ref, PMT *pmt)
1193 if ( CIServices.find(ref) != CIServices.end() )
1195 int prevPMTVersion = CIServices[ref];
1196 if ( prevPMTVersion == pmt->version )
1198 eDebug("[eDVBCIHandler] dont send pmt with self pmt version");
1199 return;
1202 else
1204 eDebug("[eDVBCIHandler] get PMT for unknown service");
1205 return;
1208 int sid= pmt->program_number;
1210 if ( eSystemInfo::getInstance()->hasCI() )
1211 calist.clear();
1213 if ( DVBCI )
1214 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTsetVersion, pmt->program_number, pmt->version, -1 ));
1215 if ( DVBCI2 )
1216 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTsetVersion, pmt->program_number, pmt->version, -1 ));
1218 for (ePtrList<Descriptor>::const_iterator i(pmt->program_info);
1219 i != pmt->program_info.end(); ++i)
1221 if (i->Tag()==9) // CADescriptor
1223 CADescriptor *ca=(CADescriptor*)*i;
1224 if ( DVBCI )
1226 unsigned char *buf=new unsigned char[ca->data[1]+2];
1227 memcpy(buf, ca->data, ca->data[1]+2);
1228 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddDescriptor, sid, buf));
1230 if ( DVBCI2 )
1232 unsigned char *buf2=new unsigned char[ca->data[1]+2];
1233 memcpy(buf2, ca->data, ca->data[1]+2);
1234 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddDescriptor, sid, buf2));
1239 for (ePtrList<PMTEntry>::iterator i(pmt->streams);
1240 i != pmt->streams.end(); ++i)
1242 PMTEntry *pe=*i;
1244 if ( DVBCI )
1245 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddPID, pmt->program_number, pe->elementary_PID, pe->stream_type));
1246 if ( DVBCI2 )
1247 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddPID, pmt->program_number, pe->elementary_PID, pe->stream_type));
1249 switch (pe->stream_type)
1251 case 1: // ISO/IEC 11172 Video
1252 case 2: // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
1253 case 3: // ISO/IEC 11172 Audio
1254 case 4: // ISO/IEC 13818-3 Audio
1255 case 6:
1257 for (ePtrList<Descriptor>::const_iterator i(pe->ES_info);
1258 i != pe->ES_info.end(); ++i)
1260 if (i->Tag()==9) // CADescriptor
1262 CADescriptor *ca=(CADescriptor*)*i;
1263 if ( DVBCI )
1265 unsigned char *buf=new unsigned char[ca->data[1]+2];
1266 memcpy(buf, ca->data, ca->data[1]+2);
1267 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddDescriptor, sid, buf));
1269 if ( DVBCI2 )
1271 unsigned char *buf2=new unsigned char[ca->data[1]+2];
1272 memcpy(buf2, ca->data, ca->data[1]+2);
1273 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTaddDescriptor, sid, buf2));
1277 break;
1281 if ( DVBCI )
1282 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::go));
1283 if ( DVBCI2 )
1284 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::go));
1285 CIServices[ref]=pmt->version;
1288 void eDVBServiceController::enterService( const eServiceReferenceDVB &service)
1290 if (!service)
1291 return;
1292 if ( CIServices.find(service) == CIServices.end() )
1294 // eDebug("[eDVBCIHandler] new service %s", service.toString().c_str() );
1295 CIServices[service]=-1;
1299 void eDVBServiceController::leaveService( const eServiceReferenceDVB &service)
1301 if (!service)
1302 return;
1303 std::map<eServiceReferenceDVB,int>::iterator it = CIServices.find(service);
1304 if ( it != CIServices.end() )
1306 // eDebug("[eDVBCIHandler] leave service %s", service.toString().c_str() );
1307 CIServices.erase(it);
1308 if ( DVBCI )
1309 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTflush, service.getServiceID().get() ));
1310 if ( DVBCI2 )
1311 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::PMTflush, service.getServiceID().get() ));
1314 #endif
1316 void eDVBServiceController::setPID(const PMTEntry *entry)
1318 if (entry)
1320 int isvideo=0, isaudio=0, isteletext=0, isAC3=0;
1321 switch (entry->stream_type)
1323 case 1: // ISO/IEC 11172 Video
1324 case 2: // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
1325 isvideo=1;
1326 break;
1327 case 3: // ISO/IEC 11172 Audio
1328 case 4: // ISO/IEC 13818-3 Audio
1329 isaudio=1;
1330 break;
1331 case 6:
1333 for (ePtrList<Descriptor>::const_iterator i(entry->ES_info);
1334 i != entry->ES_info.end(); ++i)
1336 if (i->Tag()==DESCR_AC3)
1338 isaudio=1;
1339 isAC3=1;
1341 else if (i->Tag() == DESCR_REGISTRATION)
1343 RegistrationDescriptor *reg=(RegistrationDescriptor*)*i;
1344 if (!memcmp(reg->format_identifier, "DTS", 3))
1346 isaudio=1;
1347 isAC3=1;
1349 } else if (i->Tag()==DESCR_TELETEXT)
1350 isteletext=1;
1355 eService *sp=eServiceInterface::getInstance()->addRef(service);
1356 if (isaudio)
1358 if (isAC3)
1360 Decoder::parms.audio_type=DECODE_AUDIO_AC3;
1361 Decoder::parms.apid=entry->elementary_PID;
1362 if (sp && sp->dvb)
1364 sp->dvb->set(eServiceDVB::cAC3PID, entry->elementary_PID);
1365 sp->dvb->set(eServiceDVB::cAPID, -1);
1367 } else
1369 Decoder::parms.audio_type=DECODE_AUDIO_MPEG;
1370 Decoder::parms.apid=entry->elementary_PID;
1371 if (sp && sp->dvb)
1373 sp->dvb->set(eServiceDVB::cAC3PID, -1);
1374 sp->dvb->set(eServiceDVB::cAPID, entry->elementary_PID);
1378 else if (isvideo)
1380 Decoder::parms.vpid=entry->elementary_PID;
1381 if (sp && sp->dvb)
1382 sp->dvb->set(eServiceDVB::cVPID, entry->elementary_PID);
1384 else if (isteletext)
1386 Decoder::parms.tpid=entry->elementary_PID;
1387 if (sp && sp->dvb)
1388 sp->dvb->set(eServiceDVB::cTPID, entry->elementary_PID);
1391 if (sp)
1392 eServiceInterface::getInstance()->removeRef(service);
1396 void eDVBServiceController::setDecoder()
1398 dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceNewPIDs));
1402 int eDVBServiceController::checkCA(ePtrList<CA> &list, const ePtrList<Descriptor> &descriptors, int sid)
1404 int found=0;
1405 for (ePtrList<Descriptor>::const_iterator i(descriptors);
1406 i != descriptors.end(); ++i)
1408 if (i->Tag()==9) // CADescriptor
1410 found++;
1411 CADescriptor *ca=(CADescriptor*)*i;
1413 #if 0
1414 // this is old unneeded code for camd call..
1415 // now we do this in eDVBCAHandler..
1416 Decoder::addCADescriptor((__u8*)(ca->data));
1417 #endif
1419 int avail=0;
1421 singleLock s(availCALock);
1422 if (availableCASystems.find(ca->CA_system_ID) != availableCASystems.end())
1423 avail++;
1426 usedCASystems.insert(ca->CA_system_ID);
1428 if (avail)
1430 for (ePtrList<CA>::iterator a = list.begin();
1431 a != list.end(); a++)
1433 if (a->casysid==ca->CA_system_ID)
1435 avail=0;
1436 break;
1439 if (avail)
1441 CA *n=new CA;
1442 n->ecmpid=ca->CA_PID;
1443 n->casysid=ca->CA_system_ID;
1444 n->emmpid=-1;
1445 list.push_back(n);
1450 return found;
1453 void eDVBServiceController::initCAlist()
1455 singleLock s(availCALock);
1456 availableCASystems=eSystemInfo::getInstance()->getCAIDs();
1459 void eDVBServiceController::clearCAlist()
1462 singleLock s(availCALock);
1463 availableCASystems.clear();
1465 initCAlist();
1466 #ifndef DISABLE_CI
1467 if (DVBCI)
1468 DVBCI->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::getcaids));
1469 if (DVBCI2)
1470 DVBCI2->messages.send(eDVBCI::eDVBCIMessage(eDVBCI::eDVBCIMessage::getcaids));
1471 #endif
1474 void eDVBServiceController::disableFrontend()
1476 if ( transponder && (!service || service.path) &&
1477 #ifndef DISABLE_FILE
1478 !dvb.recorder &&
1479 #endif
1480 !dvb.getScanAPI() ) // no more service need the frontend..
1482 eDebug("no more dvb service running.. disable Frontend");
1483 transponder=0;
1484 eFrontend::getInstance()->savePower();
1485 if ( eDVB::getInstance()->time_difference && // have valid time?
1486 eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7000
1487 && eSystemInfo::getInstance()->hasStandbyWakeupTimer() )
1489 eDebug("set RTC when frontend is disabled..");
1490 time_t nowTime=time(0)+eDVB::getInstance()->time_difference;
1491 setRTC(nowTime);
1496 void eDVBServiceController::startTDT()
1498 delete tdt;
1499 tdt=0;
1500 tdt=new TDT();
1501 CONNECT(tdt->tableReady, eDVBServiceController::TDTready);
1502 if ( (Decoder::locked == 2 && !dvb.recorder) ||
1503 (dvb.recorder && eSystemInfo::getInstance()->canTimeshift()
1504 && eServiceInterface::getInstance()->service.path ) )
1506 tdt->start(DEMUX1_DEV);
1507 eDebug("start TDT on demux1");
1509 else
1511 tdt->start();
1512 eDebug("start TDT on demux0");