eDVBResourceManager::getInstance(m_resourceManager);
CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
- eDVBCIInterfaces::getInstance()->addPMTHandler(this);
eDebug("new PMT handler record: %d", m_record);
}
ePtr<eTable<ProgramMapSection> > ptr;
m_PMT.getCurrent(ptr);
eDVBCAService::unregister_service(m_reference, demux_num, ptr);
+ eDVBCIInterfaces::getInstance()->removePMTHandler(this);
}
- eDVBCIInterfaces::getInstance()->removePMTHandler(this);
}
void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
serviceEvent(eventNewProgramInfo);
if (!m_pvr_channel)
{
- eDVBCIInterfaces::getInstance()->gotPMT(this);
if(!m_ca_servicePtr) // don't send campmt to camd.socket for playbacked services
{
uint8_t demux_num;
m_demux->getCADemuxID(demux_num);
eDVBCAService::register_service(m_reference, demux_num, m_ca_servicePtr);
+ eDVBCIInterfaces::getInstance()->addPMTHandler(this);
}
+ eDVBCIInterfaces::getInstance()->gotPMT(this);
}
if (m_ca_servicePtr)
{
eServiceReferenceDVB service;
pmthandler->getService(service);
- PMTHandlerSet::iterator it = m_pmt_handlers.begin();
- while (it != m_pmt_handlers.end())
+ eDebug("[eDVBCIInterfaces] addPMTHandler %s", service.toString().c_str());
+
+ // HACK the first service get the CI..
+ eSmartPtrList<eDVBCISlot>::iterator ci_it(m_slots.begin());
+ for (; ci_it != m_slots.end(); ++ci_it)
{
- eServiceReferenceDVB ref;
- it->pmthandler->getService(ref);
- if ( service == ref && it->usedby )
- new_handler.usedby = it->usedby;
- break;
+ if (ci_it->use_count)
+ continue;
+ ci_it->use_count=1;
+ new_handler.cislot = ci_it;
+ new_handler.cislot->resetPrevSentCAPMTVersion();
+ }
+
+ if (ci_it == m_slots.end())
+ {
+ PMTHandlerList::iterator it = m_pmt_handlers.begin();
+ while (it != m_pmt_handlers.end())
+ {
+ eServiceReferenceDVB ref;
+ it->pmthandler->getService(ref);
+ if ( service == ref && it->cislot )
+ {
+ new_handler.cislot = it->cislot;
+ ++new_handler.cislot->use_count;
+ break;
+ }
+ ++it;
+ }
}
- m_pmt_handlers.insert(new_handler);
+
+ m_pmt_handlers.push_back(new_handler);
}
void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler)
{
- PMTHandlerSet::iterator it=m_pmt_handlers.find(pmthandler);
+ PMTHandlerList::iterator it=std::find(m_pmt_handlers.begin(),m_pmt_handlers.end(),pmthandler);
if (it != m_pmt_handlers.end())
{
- eDVBCISlot *slot = it->usedby;
+ eDVBCISlot *slot = it->cislot;
eDVBServicePMTHandler *pmthandler = it->pmthandler;
m_pmt_handlers.erase(it);
- if (slot)
+ if (slot && !--slot->use_count)
{
- eServiceReferenceDVB removed_service;
- pmthandler->getService(removed_service);
- PMTHandlerSet::iterator it=m_pmt_handlers.begin();
+#if 0
+ eDebug("[eDVBCIInterfaces] remove last pmt handler for service %s send empty capmt");
+ std::vector<uint16_t> caids;
+ caids.push_back(0xFFFF);
+ slot->resetPrevSentCAPMTVersion();
+ slot->sendCAPMT(pmthandler, caids);
+#endif
+ // check if another service is running
+ it = m_pmt_handlers.begin();
while (it != m_pmt_handlers.end())
{
- eServiceReferenceDVB ref;
- it->pmthandler->getService(ref);
- if (ref == removed_service)
+ if ( !it->cislot )
+ {
+ it->cislot = slot;
+ ++slot->use_count;
+ slot->resetPrevSentCAPMTVersion();
+ slot->sendCAPMT(it->pmthandler);
break;
+ }
++it;
}
- if ( it == m_pmt_handlers.end() && slot->getPrevSentCAPMTVersion() != 0xFF )
- {
- std::vector<uint16_t> caids;
- caids.push_back(0xFFFF);
- slot->sendCAPMT(pmthandler, caids);
- }
}
}
}
void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler)
{
eDebug("[eDVBCIInterfaces] gotPMT");
- PMTHandlerSet::iterator it=m_pmt_handlers.find(pmthandler);
+ PMTHandlerList::iterator it=std::find(m_pmt_handlers.begin(), m_pmt_handlers.end(), pmthandler);
eServiceReferenceDVB service;
- if ( it != m_pmt_handlers.end() )
- {
- eDebug("[eDVBCIInterfaces] usedby %p", it->usedby);
- if (!it->usedby)
- {
- // HACK this assigns ALL RUNNING SERVICES to the first free CI !!!
- for (eSmartPtrList<eDVBCISlot>::iterator ci_it(m_slots.begin()); ci_it != m_slots.end(); ++ci_it)
- {
-/* eDVBCISlot **usedby = &it->usedby;
- *usedby = ci_it;
- (*usedby)->resetPrevSentCAPMTVersion();
- break;
- */
- }
- }
- if (it->usedby)
- it->usedby->sendCAPMT(pmthandler);
- }
+ if ( it != m_pmt_handlers.end() && it->cislot)
+ it->cislot->sendCAPMT(pmthandler);
}
int eDVBCIInterfaces::getMMIState(int slotid)
application_manager = 0;
mmi_session = 0;
ca_manager = 0;
+ use_count = 0;
slotid = nr;
class eDVBCICAManagerSession;
class eDVBCIMMISession;
class eDVBServicePMTHandler;
+class eDVBCISlot;
class eDVBCISlot: public iObject, public Object
{
enum {stateRemoved, stateInserted};
uint8_t prev_sent_capmt_version;
public:
+ int use_count;
+
eDVBCISlot(eMainloop *context, int nr);
~eDVBCISlot();
struct CIPmtHandler
{
eDVBServicePMTHandler *pmthandler;
- eDVBCISlot *usedby;
+ eDVBCISlot *cislot;
CIPmtHandler()
- :pmthandler(NULL), usedby(NULL)
+ :pmthandler(NULL), cislot(NULL)
{}
CIPmtHandler( const CIPmtHandler &x )
- :pmthandler(x.pmthandler), usedby(x.usedby)
+ :pmthandler(x.pmthandler), cislot(x.cislot)
{}
CIPmtHandler( eDVBServicePMTHandler *ptr )
- :pmthandler(ptr), usedby(NULL)
+ :pmthandler(ptr), cislot(NULL)
{}
- bool operator<(const CIPmtHandler &x) const { return x.pmthandler < pmthandler; }
+ bool operator==(const CIPmtHandler &x) const { return x.pmthandler == pmthandler; }
};
-typedef std::set<CIPmtHandler> PMTHandlerSet;
+typedef std::list<CIPmtHandler> PMTHandlerList;
class eDVBCIInterfaces
{
eSmartPtrList<eDVBCISlot> m_slots;
eDVBCISlot *getSlot(int slotid);
- PMTHandlerSet m_pmt_handlers;
+ PMTHandlerList m_pmt_handlers;
public:
eDVBCIInterfaces();
~eDVBCIInterfaces();