small fix
[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 <dvbsi++/ca_program_map_section.h>
8 #include <dvbsi++/descriptor_tag.h>
9 #include <dvbsi++/iso639_language_descriptor.h>
10 #include <dvbsi++/component_descriptor.h>
11
12 eDVBServicePMTHandler::eDVBServicePMTHandler(int record)
13         :m_ca_servicePtr(0)
14 {
15         m_record = record;
16         eDVBResourceManager::getInstance(m_resourceManager);
17         CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
18         CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
19         eDebug("new PMT handler record: %d", m_record);
20 }
21
22 eDVBServicePMTHandler::~eDVBServicePMTHandler()
23 {
24         eDebug("delete PMT handler record: %d", m_record);
25         if (m_ca_servicePtr)
26         {
27                 eDebug("unregister caservice");
28                 uint8_t demux_num;
29                 m_demux->getCADemuxID(demux_num);
30                 ePtr<eTable<ProgramMapSection> > ptr;
31                 m_PMT.getCurrent(ptr);
32                 eDVBCAService::unregister_service(m_reference, demux_num, ptr);
33                 eDVBCIInterfaces::getInstance()->removePMTHandler(this);
34         }
35 }
36
37 void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
38 {
39         int state;
40         channel->getState(state);
41         
42         if ((m_last_channel_state != iDVBChannel::state_ok)
43                 && (state == iDVBChannel::state_ok) && (!m_demux))
44         {
45                 if (m_channel)
46                         if (m_channel->getDemux(m_demux, m_record ? 0 : iDVBChannel::capDecode))
47                                 eDebug("Allocating a demux for now tuned-in channel failed.");
48                 
49                 serviceEvent(eventTuned);
50                 
51                 if (m_demux)
52                 {
53                         eDebug("ok ... now we start!!");
54
55                         /* emit */ m_resourceManager->m_channelRunning(channel);
56
57                         m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
58
59                         if ( m_service && !m_service->cacheEmpty() )
60                                 serviceEvent(eventNewProgramInfo);
61                 }
62         } else if ((m_last_channel_state != iDVBChannel::state_failed) && 
63                         (state == iDVBChannel::state_failed))
64         {
65                 eDebug("tune failed.");
66                 serviceEvent(eventTuneFailed);
67         }
68 }
69
70 void eDVBServicePMTHandler::PMTready(int error)
71 {
72         if (error)
73                 serviceEvent(eventNoPMT);
74         else
75         {
76                 serviceEvent(eventNewProgramInfo);
77                 if (!m_pvr_channel)
78                 {
79                         if(!m_ca_servicePtr)   // don't send campmt to camd.socket for playbacked services
80                         {
81                                 uint8_t demux_num;
82                                 m_demux->getCADemuxID(demux_num);
83                                 eDVBCAService::register_service(m_reference, demux_num, m_ca_servicePtr);
84                                 eDVBCIInterfaces::getInstance()->addPMTHandler(this);
85                         }
86                         eDVBCIInterfaces::getInstance()->gotPMT(this);
87                 }
88                 if (m_ca_servicePtr)
89                 {
90                         ePtr<eTable<ProgramMapSection> > ptr;
91                         if (!m_PMT.getCurrent(ptr))
92                                 m_ca_servicePtr->buildCAPMT(ptr);
93                         else
94                                 eDebug("eDVBServicePMTHandler cannot call buildCAPMT");
95                 }
96         }
97 }
98
99 void eDVBServicePMTHandler::PATready(int)
100 {
101         eDebug("got PAT");
102         ePtr<eTable<ProgramAssociationSection> > ptr;
103         if (!m_PAT.getCurrent(ptr))
104         {
105                 int pmtpid = -1;
106                 std::vector<ProgramAssociationSection*>::const_iterator i;
107                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
108                 {
109                         const ProgramAssociationSection &pat = **i;
110                         ProgramAssociationConstIterator program;
111                         for (program = pat.getPrograms()->begin(); program != pat.getPrograms()->end(); ++program)
112                                 if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
113                                         pmtpid = (*program)->getProgramMapPid();
114                 }
115                 if (pmtpid == -1)
116                         serviceEvent(eventNoPATEntry);
117                 else
118                         m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
119         } else
120                 serviceEvent(eventNoPAT);
121 }
122
123 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
124 {
125         ePtr<eTable<ProgramMapSection> > ptr;
126
127         program.videoStreams.clear();
128         program.audioStreams.clear();
129         program.pcrPid = -1;
130
131         if (!m_PMT.getCurrent(ptr))
132         {
133                 eDVBTableSpec table_spec;
134                 ptr->getSpec(table_spec);
135                 program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1;
136                 std::vector<ProgramMapSection*>::const_iterator i;
137                 for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
138                 {
139                         const ProgramMapSection &pmt = **i;
140                         program.pcrPid = pmt.getPcrPid();
141                         
142                         ElementaryStreamInfoConstIterator es;
143                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
144                         {
145                                 int isaudio = 0, isvideo = 0;
146                                 videoStream video;
147                                 audioStream audio;
148                                 
149                                 video.pid = (*es)->getPid();
150                                 audio.pid = (*es)->getPid();
151                                 
152                                 switch ((*es)->getType())
153                                 {
154                                 case 0x01: // MPEG 1 video
155                                 case 0x02: // MPEG 2 video
156                                         isvideo = 1;
157                                         break;
158                                 case 0x03: // MPEG 1 audio
159                                 case 0x04: // MPEG 2 audio:
160                                         isaudio = 1;
161                                         audio.type = audioStream::atMPEG;
162                                         break;
163                                 case 0x06: // PES Private
164                                                 /* PES private can contain AC-3, DTS or lots of other stuff.
165                                                    check descriptors to get the exact type. */
166                                         for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
167                                                         desc != (*es)->getDescriptors()->end(); ++desc)
168                                         {
169                                                 switch ((*desc)->getTag())
170                                                 {
171                                                 case AC3_DESCRIPTOR:
172                                                         isaudio = 1;
173                                                         audio.type = audioStream::atAC3;
174                                                         break;
175                                                 }
176                                         }
177                                         break;
178                                 }
179                                 if (isaudio)
180                                 {
181                                         for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
182                                                         desc != (*es)->getDescriptors()->end(); ++desc)
183                                         {
184                                                 switch ((*desc)->getTag())
185                                                 {
186                                                 case ISO_639_LANGUAGE_DESCRIPTOR:
187                                                 {
188                                                         const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages();
189                                                         
190                                                                 /* use last language code */
191                                                         for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i)
192                                                                 audio.language_code = (*i)->getIso639LanguageCode();
193
194                                                         break;
195                                                 }
196                                                 case COMPONENT_DESCRIPTOR:
197                                                         audio.component_tag = ((ComponentDescriptor*)*desc)->getComponentTag();
198                                                         break;
199                                                 }
200                                         }
201
202                                         program.audioStreams.push_back(audio);
203                                 }
204                                 if (isvideo)
205                                         program.videoStreams.push_back(video);
206                         }
207                 }
208                 return 0;
209         }
210         else if ( m_service && !m_service->cacheEmpty() )
211         {
212                 int vpid = m_service->getCachePID(eDVBService::cVPID),
213                         apid_ac3 = m_service->getCachePID(eDVBService::cAPID),
214                         apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID),
215                         pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
216                         cnt=0;
217                 if ( vpid != -1 )
218                 {
219                         videoStream s;
220                         s.pid = vpid;
221                         program.videoStreams.push_back(s);
222                         ++cnt;
223                 }
224                 if ( apid_ac3 != -1 )
225                 {
226                         audioStream s;
227                         s.type = audioStream::atAC3;
228                         s.pid = apid_ac3;
229                         program.audioStreams.push_back(s);
230                         ++cnt;
231                 }
232                 if ( apid_mpeg != -1 )
233                 {
234                         audioStream s;
235                         s.type = audioStream::atMPEG;
236                         s.pid = apid_mpeg;
237                         program.audioStreams.push_back(s);
238                         ++cnt;
239                 }
240                 if ( pcrpid != -1 )
241                 {
242                         ++cnt;
243                         program.pcrPid = pcrpid;
244                 }
245                 if ( cnt )
246                         return 0;
247         }
248         return -1;
249 }
250
251 int eDVBServicePMTHandler::getChannel(eUsePtr<iDVBChannel> &channel)
252 {
253         channel = m_channel;
254         if (channel)
255                 return 0;
256         else
257                 return -1;
258 }
259
260 int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
261 {
262         demux = m_demux;
263         if (demux)
264                 return 0;
265         else
266                 return -1;
267 }
268
269 int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
270 {
271         pvr_channel = m_pvr_channel;
272         if (pvr_channel)
273                 return 0;
274         else
275                 return -1;
276 }
277
278 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
279 {
280         RESULT res;
281         m_reference = ref;
282         
283                 /* is this a normal (non PVR) channel? */
284         if (ref.path.empty())
285         {
286                 eDVBChannelID chid;
287                 ref.getChannelID(chid);
288                 res = m_resourceManager->allocateChannel(chid, m_channel);
289                 eDebug("allocate Channel: res %d", res);
290         } else
291         {
292                 eDVBMetaParser parser;
293                 
294                 if (parser.parseFile(ref.path))
295                         eWarning("no .meta file found, trying original service ref.");
296                 else
297                         m_reference = parser.m_ref;
298                 
299                 eDebug("alloc PVR");
300                         /* allocate PVR */
301                 res = m_resourceManager->allocatePVRChannel(m_pvr_channel);
302                 if (res)
303                         eDebug("allocatePVRChannel failed!\n");
304                 m_channel = m_pvr_channel;
305         }
306         
307         if (m_channel)
308         {
309                 m_channel->connectStateChange(
310                         slot(*this, &eDVBServicePMTHandler::channelStateChanged), 
311                         m_channelStateChanged_connection);
312                 m_last_channel_state = -1;
313                 channelStateChanged(m_channel);
314         } else
315         {
316                 serviceEvent(eventTuneFailed);
317                 return res;
318         }
319
320         if (m_pvr_channel)
321                 m_pvr_channel->playFile(ref.path.c_str());
322
323         ePtr<iDVBChannelList> db;
324         if (!m_resourceManager->getChannelList(db))
325                 db->getService((eServiceReferenceDVB&)m_reference, m_service);
326
327         return res;
328 }
329
330 std::map<eServiceReferenceDVB, eDVBCAService*> eDVBCAService::exist;
331
332 eDVBCAService::eDVBCAService()
333         :m_prev_build_hash(0), m_sendstate(0), m_retryTimer(eApp)
334 {
335         memset(m_used_demux, 0xFF, sizeof(m_used_demux));
336         CONNECT(m_retryTimer.timeout, eDVBCAService::sendCAPMT);
337         Connect();
338 }
339
340 eDVBCAService::~eDVBCAService()
341 {
342         eDebug("[eDVBCAService] free service %s", m_service.toString().c_str());
343         ::close(m_sock);
344 }
345
346 RESULT eDVBCAService::register_service( const eServiceReferenceDVB &ref, int demux_num, eDVBCAService *&caservice )
347 {
348         CAServiceMap::iterator it = exist.find(ref);
349         if ( it != exist.end() )
350                 caservice = it->second;
351         else
352         {
353                 caservice = (exist[ref]=new eDVBCAService());
354                 caservice->m_service = ref;
355                 eDebug("[eDVBCAHandler] new service %s", ref.toString().c_str() );
356         }
357 // search free demux entry
358         int iter=0, max_demux_slots = sizeof(caservice->m_used_demux);
359
360         while ( iter < max_demux_slots && caservice->m_used_demux[iter] != 0xFF )
361                 ++iter;
362
363         if ( iter < max_demux_slots )
364         {
365                 caservice->m_used_demux[iter] = demux_num & 0xFF;
366                 eDebug("[eDVBCAHandler] add demux %d to slot %d service %s", demux_num, iter, ref.toString().c_str());
367         }
368         else
369         {
370                 eDebug("[eDVBCAHandler] no more demux slots free for service %s!!", ref.toString().c_str());
371                 return -1;
372         }
373         return 0;
374 }
375
376 RESULT eDVBCAService::unregister_service( const eServiceReferenceDVB &ref, int demux_num, eTable<ProgramMapSection> *ptr )
377 {
378         CAServiceMap::iterator it = exist.find(ref);
379         if ( it == exist.end() )
380         {
381                 eDebug("[eDVBCAHandler] try to unregister non registered %s", ref.toString().c_str());
382                 return -1;
383         }
384         else
385         {
386                 eDVBCAService *caservice = it->second;
387                 bool freed = false;
388                 int iter = 0,
389                         used_demux_slots = 0,
390                         max_demux_slots = sizeof(caservice->m_used_demux)/sizeof(int);
391                 while ( iter < max_demux_slots )
392                 {
393                         if ( caservice->m_used_demux[iter] != 0xFF )
394                         {
395                                 if ( !freed && caservice->m_used_demux[iter] == demux_num )
396                                 {
397                                         eDebug("[eDVBCAService] free slot %d demux %d for service %s", iter, caservice->m_used_demux[iter], caservice->m_service.toString().c_str() );
398                                         caservice->m_used_demux[iter] = 0xFF;
399                                         freed=true;
400                                 }
401                                 else
402                                         ++used_demux_slots;
403                         }
404                         ++iter;
405                 }
406                 if (!freed)
407                 {
408                         eDebug("[eDVBCAService] couldn't free demux slot for demux %d", demux_num);
409                         return -1;
410                 }
411                 if (!used_demux_slots)  // no more used.. so we remove it
412                 {
413                         delete it->second;
414                         exist.erase(it);
415                 }
416                 else
417                 {
418                         if (ptr)
419                                 it->second->buildCAPMT(ptr);
420                         else
421                                 eDebug("[eDVBCAHandler] can not send updated demux info");
422                 }
423         }
424         return 0;
425 }
426
427 void eDVBCAService::Connect()
428 {
429         memset(&m_servaddr, 0, sizeof(struct sockaddr_un));
430         m_servaddr.sun_family = AF_UNIX;
431         strcpy(m_servaddr.sun_path, "/tmp/camd.socket");
432         m_clilen = sizeof(m_servaddr.sun_family) + strlen(m_servaddr.sun_path);
433         m_sock = socket(PF_UNIX, SOCK_STREAM, 0);
434         connect(m_sock, (struct sockaddr *) &m_servaddr, m_clilen);
435         fcntl(m_sock, F_SETFL, O_NONBLOCK);
436         int val=1;
437         setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4);
438 }
439
440 void eDVBCAService::buildCAPMT(eTable<ProgramMapSection> *ptr)
441 {
442         if (!ptr)
443                 return;
444
445         eDVBTableSpec table_spec;
446         ptr->getSpec(table_spec);
447
448         int pmtpid = table_spec.pid,
449                 pmt_version = table_spec.version;
450
451         uint8_t demux_mask = 0;
452         uint8_t first_demux_num = 0xFF;
453
454 #if 1
455         int iter=0, max_demux_slots = sizeof(m_used_demux);
456         while ( iter < max_demux_slots )
457         {
458                 if ( m_used_demux[iter] != 0xFF )
459                 {
460                         if ( first_demux_num == 0xFF )
461                                 first_demux_num = m_used_demux[iter];
462                         demux_mask |= (1 << m_used_demux[iter]);
463                 }
464                 ++iter;
465         }
466 #else
467         demux_mask = 3;
468         first_demux_num = 0;
469 #endif
470
471         if ( first_demux_num == 0xFF )
472         {
473                 eDebug("[eDVBCAService] no demux found for service %s", m_service.toString().c_str() );
474                 return;
475         }
476
477         eDebug("demux %d mask %02x prevhash %08x", first_demux_num, demux_mask, m_prev_build_hash);
478
479         unsigned int build_hash = (pmtpid << 16);
480         build_hash |= (demux_mask << 8);
481         build_hash |= (pmt_version&0xFF);
482
483         if ( build_hash == m_prev_build_hash )
484         {
485                 eDebug("[eDVBCAService] don't build/send the same CA PMT twice");
486                 return;
487         }
488
489         std::vector<ProgramMapSection*>::const_iterator i=ptr->getSections().begin();
490         if ( i != ptr->getSections().end() )
491         {
492                 CaProgramMapSection capmt(*i++, m_prev_build_hash ? 0x05 /*update*/ : 0x03 /*only*/, 0x01 );
493
494                 while( i != ptr->getSections().end() )
495                 {
496 //                      eDebug("append");
497                         capmt.append(*i++);
498                 }
499
500                 // add our private descriptors to capmt
501                 uint8_t tmp[10];
502
503                 tmp[0]=0x84;  // pmt pid
504                 tmp[1]=0x02;
505                 tmp[2]=pmtpid>>8;
506                 tmp[3]=pmtpid&0xFF;
507                 capmt.injectDescriptor(tmp, false);
508
509                 tmp[0] = 0x82; // demux
510                 tmp[1] = 0x02;
511                 tmp[2] = demux_mask;    // descramble bitmask
512                 tmp[3] = first_demux_num; // read section data from demux number
513                 capmt.injectDescriptor(tmp, false);
514
515                 tmp[0] = 0x81; // dvbnamespace
516                 tmp[1] = 0x08;
517                 tmp[2] = m_service.getDVBNamespace().get()>>24;
518                 tmp[3]=(m_service.getDVBNamespace().get()>>16)&0xFF;
519                 tmp[4]=(m_service.getDVBNamespace().get()>>8)&0xFF;
520                 tmp[5]=m_service.getDVBNamespace().get()&0xFF;
521                 tmp[6]=m_service.getTransportStreamID().get()>>8;
522                 tmp[7]=m_service.getTransportStreamID().get()&0xFF;
523                 tmp[8]=m_service.getOriginalNetworkID().get()>>8;
524                 tmp[9]=m_service.getOriginalNetworkID().get()&0xFF;
525                 capmt.injectDescriptor(tmp, false);
526
527                 capmt.writeToBuffer(m_capmt);
528         }
529
530         m_prev_build_hash = build_hash;
531
532         if ( m_sendstate != 0xFFFFFFFF )
533                 m_sendstate=0;
534         sendCAPMT();
535 }
536
537 void eDVBCAService::sendCAPMT()
538 {
539         if ( m_sendstate && m_sendstate != 0xFFFFFFFF ) // broken pipe retry
540         {
541                 ::close(m_sock);
542                 Connect();
543         }
544
545         int wp=0;
546         if ( m_capmt[3] & 0x80 )
547         {
548                 int i=0;
549                 int lenbytes = m_capmt[3] & ~0x80;
550                 while(i < lenbytes)
551                         wp = (wp << 8) | m_capmt[4 + i++];
552                 wp+=4;
553                 wp+=lenbytes;
554         }
555         else
556         {
557                 wp = m_capmt[3];
558                 wp+=4;
559         }
560
561         if ( write(m_sock, m_capmt, wp) == wp )
562         {
563                 m_sendstate=0xFFFFFFFF;
564                 eDebug("[eDVBCAHandler] send %d bytes",wp);
565 #if 1
566                 for(int i=0;i<wp;i++)
567                         eDebugNoNewLine("%02x ", m_capmt[i]);
568                 eDebug("");
569 #endif
570         }
571         else
572         {
573                 switch(m_sendstate)
574                 {
575                         case 0xFFFFFFFF:
576                                 ++m_sendstate;
577                                 m_retryTimer.start(0,true);
578 //                              eDebug("[eDVBCAHandler] send failed .. immediate retry");
579                                 break;
580                         default:
581                                 m_retryTimer.start(5000,true);
582 //                              eDebug("[eDVBCAHandler] send failed .. retry in 5 sec");
583                                 break;
584                 }
585                 ++m_sendstate;
586         }
587 }