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