implement SDT scan on enter transponder (on normale zapping)
[enigma2.git] / lib / dvb / pmt.cpp
index 5ea47467a5a596e60513d2f6271545b3a0c803cf..74042ed09ceb951fb0986459e52ab14e90d3c9de 100644 (file)
@@ -5,6 +5,8 @@
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb_ci/dvbci.h>
 #include <lib/dvb/epgcache.h>
+#include <lib/dvb/scan.h>
+#include <dvbsi++/ca_descriptor.h>
 #include <dvbsi++/ca_program_map_section.h>
 #include <dvbsi++/teletext_descriptor.h>
 #include <dvbsi++/descriptor_tag.h>
@@ -12,7 +14,7 @@
 #include <dvbsi++/stream_identifier_descriptor.h>
 
 eDVBServicePMTHandler::eDVBServicePMTHandler()
-       :m_ca_servicePtr(0), m_decode_demux_num(0xFF)
+       :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
 {
        m_use_decode_demux = 0;
        m_pmt_pid = -1;
@@ -134,6 +136,76 @@ void eDVBServicePMTHandler::PATready(int)
                serviceEvent(eventNoPAT);
 }
 
+PyObject *eDVBServicePMTHandler::getCaIds()
+{
+       PyObject *ret=0;
+
+       ePtr<eTable<ProgramMapSection> > ptr;
+
+       if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
+       {
+               uint16_t caids[255];
+               memset(caids, 0, sizeof(caids));
+               std::vector<ProgramMapSection*>::const_iterator i = ptr->getSections().begin();
+               for (; i != ptr->getSections().end(); ++i)
+               {
+                       const ProgramMapSection &pmt = **i;
+                       ElementaryStreamInfoConstIterator es = pmt.getEsInfo()->begin();
+                       for (; es != pmt.getEsInfo()->end(); ++es)
+                       {
+                               for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+                                               desc != (*es)->getDescriptors()->end(); ++desc)
+                               {
+                                       switch ((*desc)->getTag())
+                                       {
+                                               case CA_DESCRIPTOR:
+                                               {
+                                                       const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
+                                                       uint16_t caid = cadescr->getCaSystemId();
+                                                       int idx=0;
+                                                       while (caids[idx] && caids[idx] != caid)
+                                                               ++idx;
+                                                       caids[idx]=caid;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
+                               desc != pmt.getDescriptors()->end(); ++desc)
+                       {
+                               switch ((*desc)->getTag())
+                               {
+                                       case CA_DESCRIPTOR:
+                                       {
+                                               const CaDescriptor *cadescr = (const CaDescriptor*)*desc;
+                                               uint16_t caid = cadescr->getCaSystemId();
+                                               int idx=0;
+                                               while (caids[idx] && caids[idx] != caid)
+                                                       ++idx;
+                                               caids[idx]=caid;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               int cnt=0;
+               while (caids[cnt])
+                       ++cnt;
+               if (cnt)
+               {
+                       ret=PyList_New(cnt);
+                       while(cnt--)
+                               PyList_SET_ITEM(ret, cnt, PyInt_FromLong(caids[cnt]));
+               }
+       }
+
+       if (!ret)
+               ret=PyList_New(0);
+
+       return ret;
+}
+
 int eDVBServicePMTHandler::getProgramInfo(struct program &program)
 {
        ePtr<eTable<ProgramMapSection> > ptr;
@@ -369,6 +441,39 @@ int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
                return -1;
 }
 
+void eDVBServicePMTHandler::SDTScanEvent(int event)
+{
+       eDebug("scan event %d!", event);
+
+       switch (event)
+       {
+               case eDVBScan::evtFinish:
+               {
+                       ePtr<iDVBChannelList> db;
+                       int err;
+                       if ((err = m_resourceManager->getChannelList(db)) != 0)
+                               eDebug("no channel list");
+                       else
+                       {
+                               m_dvb_scan->insertInto(db);
+                               eDebug("scan done!");
+                       }
+                       break;
+               }
+
+               case eDVBScan::evtNewService:
+                       eDebug("scan new service");
+                       break;
+
+               case eDVBScan::evtFail:
+                       eDebug("scan failed.");
+                       break;
+
+               default:
+                       break;
+       }
+}
+
 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
 {
        RESULT res;
@@ -429,6 +534,13 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux,
                m_channel->connectEvent(
                        slot(*this, &eDVBServicePMTHandler::channelEvent), 
                        m_channelEvent_connection);
+
+               if (ref.path.empty())
+               {
+                       delete m_dvb_scan;
+                       m_dvb_scan = new eDVBScan(m_channel);
+                       m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection);
+               }
        } else
        {
                serviceEvent(eventTuneFailed);
@@ -446,6 +558,10 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux,
 
 void eDVBServicePMTHandler::free()
 {
+       eDVBScan *tmp = m_dvb_scan;
+       m_dvb_scan = 0;
+       delete m_dvb_scan;
+
        if (m_ca_servicePtr)
        {
                int demuxes[2] = {0,0};