implement SDT scan on enter transponder (on normale zapping)
[vuplus_dvbapp] / lib / dvb / pmt.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/dvb/pmt.h>
3 #include <lib/dvb/specs.h>
4 #include <lib/dvb/dvb.h>
5 #include <lib/dvb/metaparser.h>
6 #include <lib/dvb_ci/dvbci.h>
7 #include <lib/dvb/epgcache.h>
8 #include <lib/dvb/scan.h>
9 #include <dvbsi++/ca_descriptor.h>
10 #include <dvbsi++/ca_program_map_section.h>
11 #include <dvbsi++/teletext_descriptor.h>
12 #include <dvbsi++/descriptor_tag.h>
13 #include <dvbsi++/iso639_language_descriptor.h>
14 #include <dvbsi++/stream_identifier_descriptor.h>
15
16 eDVBServicePMTHandler::eDVBServicePMTHandler()
17         :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
18 {
19         m_use_decode_demux = 0;
20         m_pmt_pid = -1;
21         eDVBResourceManager::getInstance(m_resourceManager);
22         CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
23         CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
24 }
25
26 eDVBServicePMTHandler::~eDVBServicePMTHandler()
27 {
28         free();
29 }
30
31 void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
32 {
33         int state;
34         channel->getState(state);
35         
36         if ((m_last_channel_state != iDVBChannel::state_ok)
37                 && (state == iDVBChannel::state_ok) && (!m_demux))
38         {
39                 if (m_channel)
40                         if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
41                                 eDebug("Allocating %s-decoding a demux for now tuned-in channel failed.", m_use_decode_demux ? "" : "non-");
42                 
43                 serviceEvent(eventTuned);
44                 
45                 if (m_demux)
46                 {
47                         eDebug("ok ... now we start!!");
48
49                         if (m_pmt_pid == -1)
50                                 m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
51                         else
52                                 m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux);
53
54                         if ( m_service && !m_service->cacheEmpty() )
55                                 serviceEvent(eventNewProgramInfo);
56                 }
57         } else if ((m_last_channel_state != iDVBChannel::state_failed) && 
58                         (state == iDVBChannel::state_failed))
59         {
60                 eDebug("tune failed.");
61                 serviceEvent(eventTuneFailed);
62         }
63 }
64
65 void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event)
66 {
67         switch (event)
68         {
69         case iDVBChannel::evtEOF:
70                 serviceEvent(eventEOF);
71                 break;
72         case iDVBChannel::evtSOF:
73                 serviceEvent(eventSOF);
74                 break;
75         default:
76                 break;
77         }
78 }
79
80 void eDVBServicePMTHandler::PMTready(int error)
81 {
82         if (error)
83                 serviceEvent(eventNoPMT);
84         else
85         {
86                 serviceEvent(eventNewProgramInfo);
87                 eEPGCache::getInstance()->PMTready(this);
88                 if (!m_pvr_channel)
89                 {
90                         if(!m_ca_servicePtr)   // don't send campmt to camd.socket for playbacked services
91                         {
92                                 int demuxes[2] = {0,0};
93                                 uint8_t tmp;
94                                 m_demux->getCADemuxID(tmp);
95                                 demuxes[0]=tmp;
96                                 if (m_decode_demux_num != 0xFF)
97                                         demuxes[1]=m_decode_demux_num;
98                                 else
99                                         demuxes[1]=demuxes[0];
100                                 eDVBCAService::register_service(m_reference, demuxes, m_ca_servicePtr);
101                                 eDVBCIInterfaces::getInstance()->addPMTHandler(this);
102                         }
103                         eDVBCIInterfaces::getInstance()->gotPMT(this);
104                 }
105                 if (m_ca_servicePtr)
106                 {
107                         ePtr<eTable<ProgramMapSection> > ptr;
108                         if (!m_PMT.getCurrent(ptr))
109                                 m_ca_servicePtr->buildCAPMT(ptr);
110                         else
111                                 eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
112                 }
113         }
114 }
115
116 void eDVBServicePMTHandler::PATready(int)
117 {
118         ePtr<eTable<ProgramAssociationSection> > ptr;
119         if (!m_PAT.getCurrent(ptr))
120         {
121                 int pmtpid = -1;
122                 std::vector<ProgramAssociationSection*>::const_iterator i;
123                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
124                 {
125                         const ProgramAssociationSection &pat = **i;
126                         ProgramAssociationConstIterator program;
127                         for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
128                                 if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
129                                         pmtpid = (*program)->getProgramMapPid();
130                 }
131                 if (pmtpid == -1)
132                         serviceEvent(eventNoPATEntry);
133                 else
134                         m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
135         } else
136                 serviceEvent(eventNoPAT);
137 }
138
139 PyObject *eDVBServicePMTHandler::getCaIds()
140 {
141         PyObject *ret=0;
142
143         ePtr<eTable<ProgramMapSection> > ptr;
144
145         if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
146         {
147                 uint16_t caids[255];
148                 memset(caids, 0, sizeof(caids));
149                 std::vector<ProgramMapSection*>::const_iterator i = ptr->getSections().begin();
150                 for (; i != ptr->getSections().end(); ++i)
151                 {
152                         const ProgramMapSection &pmt = **i;
153                         ElementaryStreamInfoConstIterator es = pmt.getEsInfo()->begin();
154                         for (; es != pmt.getEsInfo()->end(); ++es)
155                         {
156                                 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
157                                                 desc != (*es)->getDescriptors()->end(); ++desc)
158                                 {
159                                         switch ((*desc)->getTag())
160                                         {
161                                                 case CA_DESCRIPTOR:
162                                                 {
163                                                         const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
164                                                         uint16_t caid = cadescr->getCaSystemId();
165                                                         int idx=0;
166                                                         while (caids[idx] && caids[idx] != caid)
167                                                                 ++idx;
168                                                         caids[idx]=caid;
169                                                         break;
170                                                 }
171                                         }
172                                 }
173                         }
174                         for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
175                                 desc != pmt.getDescriptors()->end(); ++desc)
176                         {
177                                 switch ((*desc)->getTag())
178                                 {
179                                         case CA_DESCRIPTOR:
180                                         {
181                                                 const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
182                                                 uint16_t caid = cadescr->getCaSystemId();
183                                                 int idx=0;
184                                                 while (caids[idx] && caids[idx] != caid)
185                                                         ++idx;
186                                                 caids[idx]=caid;
187                                                 break;
188                                         }
189                                 }
190                         }
191                 }
192                 int cnt=0;
193                 while (caids[cnt])
194                         ++cnt;
195                 if (cnt)
196                 {
197                         ret=PyList_New(cnt);
198                         while(cnt--)
199                                 PyList_SET_ITEM(ret, cnt, PyInt_FromLong(caids[cnt]));
200                 }
201         }
202
203         if (!ret)
204                 ret=PyList_New(0);
205
206         return ret;
207 }
208
209 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
210 {
211         ePtr<eTable<ProgramMapSection> > ptr;
212
213         program.videoStreams.clear();
214         program.audioStreams.clear();
215         program.pcrPid = -1;
216         program.isCrypted = false;
217         program.pmtPid = -1;
218         program.textPid = -1;
219
220         if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
221         {
222                 int cached_apid_ac3 = -1;
223                 int cached_apid_mpeg = -1;
224                 int cached_vpid = -1;
225                 int cached_tpid = -1;
226                 if ( m_service && !m_service->cacheEmpty() )
227                 {
228                         cached_vpid = m_service->getCachePID(eDVBService::cVPID);
229                         cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID);
230                         cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID);
231                         cached_tpid = m_service->getCachePID(eDVBService::cTPID);
232                 }
233                 eDVBTableSpec table_spec;
234                 ptr->getSpec(table_spec);
235                 program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1;
236                 std::vector<ProgramMapSection*>::const_iterator i;
237                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
238                 {
239                         const ProgramMapSection &pmt = **i;
240                         program.pcrPid = pmt.getPcrPid();
241                         
242                         ElementaryStreamInfoConstIterator es;
243                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
244                         {
245                                 int isaudio = 0, isvideo = 0, cadescriptors = 0;
246                                 videoStream video;
247                                 audioStream audio;
248                                 audio.component_tag=-1;
249                                 video.component_tag=-1;
250
251                                 video.pid = (*es)->getPid();
252                                 audio.pid = (*es)->getPid();
253
254                                 switch ((*es)->getType())
255                                 {
256                                 case 0x01: // MPEG 1 video
257                                 case 0x02: // MPEG 2 video
258                                         isvideo = 1;
259                                         //break; fall through !!!
260                                 case 0x03: // MPEG 1 audio
261                                 case 0x04: // MPEG 2 audio:
262                                         if (!isvideo)
263                                         {
264                                                 isaudio = 1;
265                                                 audio.type = audioStream::atMPEG;
266                                         }
267                                         //break; fall through !!!
268                                 case 0x06: // PES Private
269                                                 /* PES private can contain AC-3, DTS or lots of other stuff.
270                                                    check descriptors to get the exact type. */
271                                         for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
272                                                         desc != (*es)->getDescriptors()->end(); ++desc)
273                                         {
274                                                 switch ((*desc)->getTag())
275                                                 {
276                                                 case TELETEXT_DESCRIPTOR:
277                                                         if ( program.textPid == -1 || (*es)->getPid() == cached_tpid )
278                                                                 program.textPid = (*es)->getPid();
279                                                         break;
280                                                 case AC3_DESCRIPTOR:
281                                                         if (!isvideo)
282                                                         {
283                                                                 isaudio = 1;
284                                                                 audio.type = audioStream::atAC3;
285                                                         }
286                                                         break;
287                                                 case ISO_639_LANGUAGE_DESCRIPTOR:
288                                                         if (!isvideo)
289                                                         {
290                                                                 const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
291                                                                         /* use last language code */
292                                                                 for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i)
293                                                                         audio.language_code = (*i)->getIso639LanguageCode();
294                                                         }
295                                                         break;
296                                                 case STREAM_IDENTIFIER_DESCRIPTOR:
297                                                         audio.component_tag =
298                                                                 video.component_tag =
299                                                                         ((StreamIdentifierDescriptor*)*desc)->getComponentTag();
300                                                         break;
301                                                 case CA_DESCRIPTOR:
302                                                         ++cadescriptors;
303                                                         break;
304                                                 }
305                                         }
306                                         break;
307                                 }
308                                 if (isaudio)
309                                 {
310                                         if ( !program.audioStreams.empty() &&
311                                                 ( audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) )
312                                         {
313                                                 program.audioStreams.push_back(program.audioStreams[0]);
314                                                 program.audioStreams[0] = audio;
315                                         }
316                                         else
317                                                 program.audioStreams.push_back(audio);
318                                 }
319                                 else if (isvideo)
320                                 {
321                                         if ( !program.videoStreams.empty() && video.pid == cached_vpid )
322                                         {
323                                                 program.videoStreams.push_back(program.videoStreams[0]);
324                                                 program.videoStreams[0] = video;
325                                         }
326                                         else
327                                                 program.videoStreams.push_back(video);
328                                 }
329                                 else
330                                         continue;
331                                 if ( cadescriptors > 0 )
332                                         program.isCrypted=true;
333                         }
334                         if ( !program.isCrypted )
335                         {
336                                 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
337                                         desc != pmt.getDescriptors()->end(); ++desc)
338                                 {
339                                         switch ((*desc)->getTag())
340                                         {
341                                         case CA_DESCRIPTOR:
342                                                 program.isCrypted=true;
343                                                 break;
344                                         }
345                                 }
346                                 break;
347                         }
348                 }
349                 return 0;
350         } else if ( m_service && !m_service->cacheEmpty() )
351         {
352                 int vpid = m_service->getCachePID(eDVBService::cVPID),
353                         apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID),
354                         apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
355                         pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
356                         tpid = m_service->getCachePID(eDVBService::cTPID),
357                         cnt=0;
358                 if ( vpid != -1 )
359                 {
360                         videoStream s;
361                         s.pid = vpid;
362                         program.videoStreams.push_back(s);
363                         ++cnt;
364                 }
365                 if ( apid_ac3 != -1 )
366                 {
367                         audioStream s;
368                         s.type = audioStream::atAC3;
369                         s.pid = apid_ac3;
370                         program.audioStreams.push_back(s);
371                         ++cnt;
372                 }
373                 if ( apid_mpeg != -1 )
374                 {
375                         audioStream s;
376                         s.type = audioStream::atMPEG;
377                         s.pid = apid_mpeg;
378                         program.audioStreams.push_back(s);
379                         ++cnt;
380                 }
381                 if ( pcrpid != -1 )
382                 {
383                         ++cnt;
384                         program.pcrPid = pcrpid;
385                 }
386                 if ( tpid != -1 )
387                 {
388                         ++cnt;
389                         program.textPid = tpid;
390                 }
391                 if ( cnt )
392                         return 0;
393         }
394         return -1;
395 }
396
397 int eDVBServicePMTHandler::getChannel(eUsePtr<iDVBChannel> &channel)
398 {
399         channel = m_channel;
400         if (channel)
401                 return 0;
402         else
403                 return -1;
404 }
405
406 int eDVBServicePMTHandler::getDataDemux(ePtr<iDVBDemux> &demux)
407 {
408         demux = m_demux;
409         if (demux)
410                 return 0;
411         else
412                 return -1;
413 }
414
415 int eDVBServicePMTHandler::getDecodeDemux(ePtr<iDVBDemux> &demux)
416 {
417         int ret=0;
418                 /* if we're using the decoding demux as data source
419                    (for example in pvr playbacks), return that one. */
420         if (m_use_decode_demux)
421         {
422                 demux = m_demux;
423                 return ret;
424         }
425         
426         ASSERT(m_channel); /* calling without a previous ::tune is certainly bad. */
427
428         ret = m_channel->getDemux(demux, iDVBChannel::capDecode);
429         if (!ret)
430                 demux->getCADemuxID(m_decode_demux_num);
431
432         return ret;
433 }
434
435 int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
436 {
437         pvr_channel = m_pvr_channel;
438         if (pvr_channel)
439                 return 0;
440         else
441                 return -1;
442 }
443
444 void eDVBServicePMTHandler::SDTScanEvent(int event)
445 {
446         eDebug("scan event %d!", event);
447
448         switch (event)
449         {
450                 case eDVBScan::evtFinish:
451                 {
452                         ePtr<iDVBChannelList> db;
453                         int err;
454                         if ((err = m_resourceManager->getChannelList(db)) != 0)
455                                 eDebug("no channel list");
456                         else
457                         {
458                                 m_dvb_scan->insertInto(db);
459                                 eDebug("scan done!");
460                         }
461                         break;
462                 }
463
464                 case eDVBScan::evtNewService:
465                         eDebug("scan new service");
466                         break;
467
468                 case eDVBScan::evtFail:
469                         eDebug("scan failed.");
470                         break;
471
472                 default:
473                         break;
474         }
475 }
476
477 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
478 {
479         RESULT res;
480         m_reference = ref;
481         
482         m_use_decode_demux = use_decode_demux;
483         
484                 /* is this a normal (non PVR) channel? */
485         if (ref.path.empty())
486         {
487                 eDVBChannelID chid;
488                 ref.getChannelID(chid);
489                 res = m_resourceManager->allocateChannel(chid, m_channel);
490                 eDebug("allocate Channel: res %d", res);
491         } else
492         {
493                 eDVBMetaParser parser;
494                 
495                 if (parser.parseFile(ref.path))
496                 {
497                         eWarning("no .meta file found, trying to find PMT pid");
498                         eDVBTSTools tstools;
499                         if (tstools.openFile(ref.path.c_str()))
500                                 eWarning("failed to open file");
501                         else
502                         {
503                                 int service_id, pmt_pid;
504                                 if (!tstools.findPMT(pmt_pid, service_id))
505                                 {
506                                         eDebug("PMT pid found on pid %04x, service id %d", pmt_pid, service_id);
507                                         m_reference.setServiceID(service_id);
508                                         m_pmt_pid = pmt_pid;
509                                 }
510                         }
511                 } else
512                         m_reference = parser.m_ref;
513                 
514                 eDebug("alloc PVR");
515                         /* allocate PVR */
516                 res = m_resourceManager->allocatePVRChannel(m_pvr_channel);
517                 if (res)
518                         eDebug("allocatePVRChannel failed!\n");
519                 m_channel = m_pvr_channel;
520         }
521
522         ePtr<iDVBChannelList> db;
523         if (!m_resourceManager->getChannelList(db))
524                 db->getService((eServiceReferenceDVB&)m_reference, m_service);
525
526         if (m_channel)
527         {
528                 m_channel->connectStateChange(
529                         slot(*this, &eDVBServicePMTHandler::channelStateChanged), 
530                         m_channelStateChanged_connection);
531                 m_last_channel_state = -1;
532                 channelStateChanged(m_channel);
533
534                 m_channel->connectEvent(
535                         slot(*this, &eDVBServicePMTHandler::channelEvent), 
536                         m_channelEvent_connection);
537
538                 if (ref.path.empty())
539                 {
540                         delete m_dvb_scan;
541                         m_dvb_scan = new eDVBScan(m_channel);
542                         m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection);
543                 }
544         } else
545         {
546                 serviceEvent(eventTuneFailed);
547                 return res;
548         }
549
550         if (m_pvr_channel)
551         {
552                 m_pvr_channel->setCueSheet(cue);
553                 m_pvr_channel->playFile(ref.path.c_str());
554         }
555
556         return res;
557 }
558
559 void eDVBServicePMTHandler::free()
560 {
561         eDVBScan *tmp = m_dvb_scan;
562         m_dvb_scan = 0;
563         delete m_dvb_scan;
564
565         if (m_ca_servicePtr)
566         {
567                 int demuxes[2] = {0,0};
568                 uint8_t tmp;
569                 m_demux->getCADemuxID(tmp);
570                 demuxes[0]=tmp;
571                 if (m_decode_demux_num != 0xFF)
572                         demuxes[1]=m_decode_demux_num;
573                 else
574                         demuxes[1]=demuxes[0];
575                 ePtr<eTable<ProgramMapSection> > ptr;
576                 m_PMT.getCurrent(ptr);
577                 eDVBCAService::unregister_service(m_reference, demuxes, ptr);
578                 eDVBCIInterfaces::getInstance()->removePMTHandler(this);
579                 m_ca_servicePtr = 0;
580         }
581
582         if (m_pvr_channel)
583         {
584                 m_pvr_channel->stopFile();
585                 m_pvr_channel->setCueSheet(0);
586         }
587         m_PMT.stop();
588         m_PAT.stop();
589         m_service = 0;
590         m_channel = 0;
591         m_pvr_channel = 0;
592         m_demux = 0;
593 }
594
595 std::map<eServiceReferenceDVB, eDVBCAService*> eDVBCAService::exist;
596
597 eDVBCAService::eDVBCAService()
598         :m_prev_build_hash(0), m_sendstate(0), m_retryTimer(eApp)
599 {
600         memset(m_used_demux, 0xFF, sizeof(m_used_demux));
601         CONNECT(m_retryTimer.timeout, eDVBCAService::sendCAPMT);
602         Connect();
603 }
604
605 eDVBCAService::~eDVBCAService()
606 {
607         eDebug("[eDVBCAService] free service %s", m_service.toString().c_str());
608         ::close(m_sock);
609 }
610
611 RESULT eDVBCAService::register_service( const eServiceReferenceDVB &ref, int demux_nums[2], eDVBCAService *&caservice )
612 {
613         CAServiceMap::iterator it = exist.find(ref);
614         if ( it != exist.end() )
615                 caservice = it->second;
616         else
617         {
618                 caservice = (exist[ref]=new eDVBCAService());
619                 caservice->m_service = ref;
620                 eDebug("[eDVBCAService] new service %s", ref.toString().c_str() );
621         }
622
623         int loops = demux_nums[0] != demux_nums[1] ? 2 : 1;
624         for (int i=0; i < loops; ++i)
625         {
626 // search free demux entry
627                 int iter=0, max_demux_slots = sizeof(caservice->m_used_demux);
628
629                 while ( iter < max_demux_slots && caservice->m_used_demux[iter] != 0xFF )
630                         ++iter;
631
632                 if ( iter < max_demux_slots )
633                 {
634                         caservice->m_used_demux[iter] = demux_nums[i] & 0xFF;
635                         eDebug("[eDVBCAService] add demux %d to slot %d service %s", caservice->m_used_demux[iter], iter, ref.toString().c_str());
636                 }
637                 else
638                 {
639                         eDebug("[eDVBCAService] no more demux slots free for service %s!!", ref.toString().c_str());
640                         return -1;
641                 }
642         }
643         return 0;
644 }
645
646 RESULT eDVBCAService::unregister_service( const eServiceReferenceDVB &ref, int demux_nums[2], eTable<ProgramMapSection> *ptr )
647 {
648         CAServiceMap::iterator it = exist.find(ref);
649         if ( it == exist.end() )
650         {
651                 eDebug("[eDVBCAService] try to unregister non registered %s", ref.toString().c_str());
652                 return -1;
653         }
654         else
655         {
656                 eDVBCAService *caservice = it->second;
657                 int loops = demux_nums[0] != demux_nums[1] ? 2 : 1;
658                 for (int i=0; i < loops; ++i)
659                 {
660                         bool freed = false;
661                         int iter = 0,
662                                 used_demux_slots = 0,
663                                 max_demux_slots = sizeof(caservice->m_used_demux)/sizeof(int);
664                         while ( iter < max_demux_slots )
665                         {
666                                 if ( caservice->m_used_demux[iter] != 0xFF )
667                                 {
668                                         if ( !freed && caservice->m_used_demux[iter] == demux_nums[i] )
669                                         {
670                                                 eDebug("[eDVBCAService] free slot %d demux %d for service %s", iter, caservice->m_used_demux[iter], caservice->m_service.toString().c_str() );
671                                                 caservice->m_used_demux[iter] = 0xFF;
672                                                 freed=true;
673                                         }
674                                         else
675                                                 ++used_demux_slots;
676                                 }
677                                 ++iter;
678                         }
679                         if (!freed)
680                                 eDebug("[eDVBCAService] couldn't free demux slot for demux %d", demux_nums[i]);
681                         if (i || loops == 1)
682                         {
683                                 if (!used_demux_slots)  // no more used.. so we remove it
684                                 {
685                                         delete it->second;
686                                         exist.erase(it);
687                                 }
688                                 else
689                                 {
690                                         if (ptr)
691                                                 it->second->buildCAPMT(ptr);
692                                         else
693                                                 eDebug("[eDVBCAService] can not send updated demux info");
694                                 }
695                         }
696                 }
697         }
698         return 0;
699 }
700
701 void eDVBCAService::Connect()
702 {
703         memset(&m_servaddr, 0, sizeof(struct sockaddr_un));
704         m_servaddr.sun_family = AF_UNIX;
705         strcpy(m_servaddr.sun_path, "/tmp/camd.socket");
706         m_clilen = sizeof(m_servaddr.sun_family) + strlen(m_servaddr.sun_path);
707         m_sock = socket(PF_UNIX, SOCK_STREAM, 0);
708         connect(m_sock, (struct sockaddr *) &m_servaddr, m_clilen);
709         fcntl(m_sock, F_SETFL, O_NONBLOCK);
710         int val=1;
711         setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4);
712 }
713
714 void eDVBCAService::buildCAPMT(eTable<ProgramMapSection> *ptr)
715 {
716         if (!ptr)
717                 return;
718
719         eDVBTableSpec table_spec;
720         ptr->getSpec(table_spec);
721
722         int pmtpid = table_spec.pid,
723                 pmt_version = table_spec.version;
724
725         uint8_t demux_mask = 0;
726         int data_demux = -1;
727
728         int iter=0, max_demux_slots = sizeof(m_used_demux);
729         while ( iter < max_demux_slots )
730         {
731                 if ( m_used_demux[iter] != 0xFF )
732                 {
733                         if ( m_used_demux[iter] > data_demux )
734                                 data_demux = m_used_demux[iter];
735                         demux_mask |= (1 << m_used_demux[iter]);
736                 }
737                 ++iter;
738         }
739
740         if ( data_demux == -1 )
741         {
742                 eDebug("[eDVBCAService] no data demux found for service %s", m_service.toString().c_str() );
743                 return;
744         }
745
746         eDebug("demux %d mask %02x prevhash %08x", data_demux, demux_mask, m_prev_build_hash);
747
748         unsigned int build_hash = (pmtpid << 16);
749         build_hash |= (demux_mask << 8);
750         build_hash |= (pmt_version&0xFF);
751
752         if ( build_hash == m_prev_build_hash )
753         {
754                 eDebug("[eDVBCAService] don't build/send the same CA PMT twice");
755                 return;
756         }
757
758         std::vector<ProgramMapSection*>::const_iterator i=ptr->getSections().begin();
759         if ( i != ptr->getSections().end() )
760         {
761                 CaProgramMapSection capmt(*i++, m_prev_build_hash ? 0x05 /*update*/ : 0x03 /*only*/, 0x01 );
762
763                 while( i != ptr->getSections().end() )
764                 {
765 //                      eDebug("append");
766                         capmt.append(*i++);
767                 }
768
769                 // add our private descriptors to capmt
770                 uint8_t tmp[10];
771
772                 tmp[0]=0x84;  // pmt pid
773                 tmp[1]=0x02;
774                 tmp[2]=pmtpid>>8;
775                 tmp[3]=pmtpid&0xFF;
776                 capmt.injectDescriptor(tmp, false);
777
778                 tmp[0] = 0x82; // demux
779                 tmp[1] = 0x02;
780                 tmp[2] = demux_mask;    // descramble bitmask
781                 tmp[3] = data_demux&0xFF; // read section data from demux number
782                 capmt.injectDescriptor(tmp, false);
783
784                 tmp[0] = 0x81; // dvbnamespace
785                 tmp[1] = 0x08;
786                 tmp[2] = m_service.getDVBNamespace().get()>>24;
787                 tmp[3]=(m_service.getDVBNamespace().get()>>16)&0xFF;
788                 tmp[4]=(m_service.getDVBNamespace().get()>>8)&0xFF;
789                 tmp[5]=m_service.getDVBNamespace().get()&0xFF;
790                 tmp[6]=m_service.getTransportStreamID().get()>>8;
791                 tmp[7]=m_service.getTransportStreamID().get()&0xFF;
792                 tmp[8]=m_service.getOriginalNetworkID().get()>>8;
793                 tmp[9]=m_service.getOriginalNetworkID().get()&0xFF;
794                 capmt.injectDescriptor(tmp, false);
795
796                 capmt.writeToBuffer(m_capmt);
797         }
798
799         m_prev_build_hash = build_hash;
800
801         if ( m_sendstate != 0xFFFFFFFF )
802                 m_sendstate=0;
803         sendCAPMT();
804 }
805
806 void eDVBCAService::sendCAPMT()
807 {
808         if ( m_sendstate && m_sendstate != 0xFFFFFFFF ) // broken pipe retry
809         {
810                 ::close(m_sock);
811                 Connect();
812         }
813
814         int wp=0;
815         if ( m_capmt[3] & 0x80 )
816         {
817                 int i=0;
818                 int lenbytes = m_capmt[3] & ~0x80;
819                 while(i < lenbytes)
820                         wp = (wp << 8) | m_capmt[4 + i++];
821                 wp+=4;
822                 wp+=lenbytes;
823         }
824         else
825         {
826                 wp = m_capmt[3];
827                 wp+=4;
828         }
829
830         if ( write(m_sock, m_capmt, wp) == wp )
831         {
832                 m_sendstate=0xFFFFFFFF;
833                 eDebug("[eDVBCAService] send %d bytes",wp);
834 #if 1
835                 for(int i=0;i<wp;i++)
836                         eDebugNoNewLine("%02x ", m_capmt[i]);
837                 eDebug("");
838 #endif
839         }
840         else
841         {
842                 switch(m_sendstate)
843                 {
844                         case 0xFFFFFFFF:
845                                 ++m_sendstate;
846                                 m_retryTimer.start(0,true);
847 //                              eDebug("[eDVBCAService] send failed .. immediate retry");
848                                 break;
849                         default:
850                                 m_retryTimer.start(5000,true);
851 //                              eDebug("[eDVBCAService] send failed .. retry in 5 sec");
852                                 break;
853                 }
854                 ++m_sendstate;
855         }
856 }