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