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