if( (slot = getSlot(slotid)) == 0 )
return -1;
-
+
+ eDVBCISession::deleteSessions(slot);
+
return slot->reset();
}
+int eDVBCIInterfaces::enableTS(int slotid, int enable)
+{
+ eDVBCISlot *slot;
+
+ if( (slot = getSlot(slotid)) == 0 )
+ return -1;
+
+ int tunernum = 0;
+ if (enable)
+ {
+ PMTHandlerList::iterator it = m_pmt_handlers.begin();
+ while (it != m_pmt_handlers.end())
+ {
+ if ( it->cislot == slot )
+ {
+ eDVBServicePMTHandler *pmthandler = it->pmthandler;
+ eUsePtr<iDVBChannel> channel;
+ if (!pmthandler->getChannel(channel))
+ {
+ ePtr<iDVBFrontend> frontend;
+ if (!channel->getFrontend(frontend))
+ {
+ eDVBFrontend *fe = (eDVBFrontend*) &(*frontend);
+ tunernum = fe->getID();
+ }
+ }
+ break;
+ }
+ ++it;
+ }
+ }
+ return slot->enableTS(enable, tunernum);
+}
+
int eDVBCIInterfaces::initialize(int slotid)
{
eDVBCISlot *slot;
if( (slot = getSlot(slotid)) == 0 )
return -1;
-
+
+ slot->resetPrevSentCAPMTVersion();
+ PMTHandlerList::iterator it = m_pmt_handlers.begin();
+ while (it != m_pmt_handlers.end())
+ {
+ if ( it->cislot == slot )
+ {
+ slot->sendCAPMT(it->pmthandler); // send capmt
+ break;
+ }
+ ++it;
+ }
+
return slot->initialize();
}
+int eDVBCIInterfaces::sendCAPMT(int slotid)
+{
+ eDVBCISlot *slot;
+
+ if( (slot = getSlot(slotid)) == 0 )
+ return -1;
+
+ slot->resetPrevSentCAPMTVersion();
+ PMTHandlerList::iterator it = m_pmt_handlers.begin();
+ while (it != m_pmt_handlers.end())
+ {
+ if ( it->cislot == slot )
+ {
+ slot->sendCAPMT(it->pmthandler); // send capmt
+ return 0;
+ }
+ ++it;
+ }
+
+ return -1;
+}
+
int eDVBCIInterfaces::startMMI(int slotid)
{
eDVBCISlot *slot;
return slot->answerText(answer);
}
-int eDVBCIInterfaces::answerEnq(int slotid, int answer, char *value)
+int eDVBCIInterfaces::answerEnq(int slotid, char *value)
+{
+ eDVBCISlot *slot;
+
+ if( (slot = getSlot(slotid)) == 0 )
+ return -1;
+
+ return slot->answerEnq(value);
+}
+
+int eDVBCIInterfaces::cancelEnq(int slotid)
{
eDVBCISlot *slot;
if( (slot = getSlot(slotid)) == 0 )
return -1;
- return slot->answerEnq(answer, value);
+ return slot->cancelEnq();
}
void eDVBCIInterfaces::addPMTHandler(eDVBServicePMTHandler *pmthandler)
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();
}
- m_pmt_handlers.insert(new_handler);
+
+ 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.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;
- eDVBServicePMTHandler *pmthandler = it->pmthandler;
+ 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)
if(what == eSocketNotifier::Priority) {
if(state != stateRemoved) {
state = stateRemoved;
+ enableTS(0);
printf("ci removed\n");
+ eDVBCISession::deleteSessions(this);
notifier->setRequested(eSocketNotifier::Read);
//HACK
eDVBCI_UI::getInstance()->setState(0,0);
application_manager = 0;
mmi_session = 0;
ca_manager = 0;
+ use_count = 0;
slotid = nr;
eDVBCISlot::~eDVBCISlot()
{
+ enableTS(0);
+}
+
+void eDVBCISlot::setAppManager( eDVBCIApplicationManagerSession *session )
+{
+ application_manager=session;
+}
+
+void eDVBCISlot::setMMIManager( eDVBCIMMISession *session )
+{
+ mmi_session = session;
+}
+
+void eDVBCISlot::setCAManager( eDVBCICAManagerSession *session )
+{
+ ca_manager = session;
}
int eDVBCISlot::getSlotID()
{
printf("edvbcislot: reset requested\n");
+ enableTS(0);
+
ioctl(fd, 0);
return 0;
return 0;
}
-int eDVBCISlot::answerEnq(int answer, char *value)
+int eDVBCISlot::answerEnq(char *value)
{
- printf("edvbcislot: answerMMI(%d,%s)\n", answer, value);
+ printf("edvbcislot: answerENQ(%s)\n", value);
+
+ if(mmi_session)
+ mmi_session->answerEnq(value);
+
+ return 0;
+}
+
+int eDVBCISlot::cancelEnq()
+{
+ printf("edvbcislot: cancelENQ\n");
+
+ if(mmi_session)
+ mmi_session->cancelEnq();
+
return 0;
}
int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector<uint16_t> &ids)
{
- const std::vector<uint16_t> &caids = ids.empty() && ca_manager ? ca_manager->getCAIDs() : ids;
+ if (!ca_manager)
+ {
+ eDebug("no ca_manager (no CI plugged?)");
+ return -1;
+ }
+ const std::vector<uint16_t> &caids = ids.empty() ? ca_manager->getCAIDs() : ids;
ePtr<eTable<ProgramMapSection> > ptr;
if (pmthandler->getPMT(ptr))
return -1;
int i=0;
int lenbytes = raw_data[3] & ~0x80;
while(i < lenbytes)
- wp |= (raw_data[4+i] << (8 * i++));
+ wp = (wp << 8) | raw_data[4 + i++];
wp+=4;
wp+=lenbytes;
hlen = 4 + lenbytes;
hlen = 4;
}
// end calc capmt length
- if (!ca_manager)
- eDebug("no ca_manager !!! dump unfiltered capmt:");
- else
- eDebug("ca_manager %p dump capmt:", ca_manager);
+ eDebug("ca_manager %p dump capmt:", ca_manager);
for(int i=0;i<wp;i++)
eDebugNoNewLine("%02x ", raw_data[i]);
eDebug("");
#endif
- if (ca_manager)
- {
- //dont need tag and lenfield
- ca_manager->sendCAPMT(raw_data + hlen, wp - hlen);
- prev_sent_capmt_version = pmt_version;
- }
+ //dont need tag and lenfield
+ ca_manager->sendCAPMT(raw_data + hlen, wp - hlen);
+ prev_sent_capmt_version = pmt_version;
}
}
-
+ return 0;
+}
+
+int eDVBCISlot::enableTS(int enable, int tuner)
+{
+ printf("eDVBCISlot::enableTS(%d %d)\n", enable, tuner);
+
+ FILE *input0, *input1, *ci;
+ if((input0 = fopen("/proc/stb/tsmux/input0", "wb")) == NULL) {
+ printf("cannot open /proc/stb/tsmux/input0\n");
+ return 0;
+ }
+ if((input1 = fopen("/proc/stb/tsmux/input1", "wb")) == NULL) {
+ printf("cannot open /proc/stb/tsmux/input1\n");
+ return 0;
+ }
+ if((ci = fopen("/proc/stb/tsmux/input2", "wb")) == NULL) {
+ printf("cannot open /proc/stb/tsmux/input2\n");
+ return 0;
+ }
+
+ fprintf(ci, "%s", tuner==0 ? "A" : "B"); // configure CI data source (TunerA, TunerB)
+ fprintf(input0, "%s", tuner==0 && enable ? "CI" : "A"); // configure ATI input 0 data source
+ fprintf(input1, "%s", tuner==1 && enable ? "CI" : "B"); // configure ATI input 1 data source
+
+ fclose(input0);
+ fclose(input1);
+ fclose(ci);
+ return 0;
+}
+
+void eDVBCISlot::resendCAPMT()
+{
+ eDVBCIInterfaces::getInstance()->sendCAPMT(slotid);
}
eAutoInitP0<eDVBCIInterfaces> init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");