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