From d78844c80c0fc546186b6cbc52b3f7cb1ea3a680 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 26 Feb 2009 01:51:08 +0100 Subject: some CI fixes --- lib/dvb_ci/dvbci.cpp | 227 ++++++++++++++++++++++++++++++++++++--------------- lib/dvb_ci/dvbci.h | 12 ++- 2 files changed, 172 insertions(+), 67 deletions(-) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 75250404..d088075c 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -18,6 +18,14 @@ #include +#undef CIDEBUG + +#ifdef CIDEBUG + #define eDebugCI(x...) eDebug(x) +#else + #define eDebugCI(x...) +#endif + eDVBCIInterfaces *eDVBCIInterfaces::instance = 0; eDVBCIInterfaces::eDVBCIInterfaces() @@ -101,9 +109,6 @@ int eDVBCIInterfaces::reset(int slotid) if( (slot = getSlot(slotid)) == 0 ) return -1; - eDVBCISession::deleteSessions(slot); - ciRemoved(slot); - return slot->reset(); } @@ -195,11 +200,13 @@ int eDVBCIInterfaces::cancelEnq(int slotid) void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot) { + eDebug("CI Slot %d: removed... usecount %d", slot->getSlotID(), slot->use_count); for (PMTHandlerList::iterator it(m_pmt_handlers.begin()); it != m_pmt_handlers.end(); ++it) { eServiceReferenceDVB ref; it->pmthandler->getServiceReference(ref); + eDebugCI("check %s cislot %p %d\n", ref.toString().c_str(), it->cislot, it->cislot?it->cislot->getSlotID() : -1); slot->removeService(ref.getServiceID().get()); if (slot->use_count && !--slot->use_count) { @@ -209,9 +216,13 @@ void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot) setInputSource(slot->current_tuner, slot->current_source); if (it->cislot == slot) // remove the base slot + { it->cislot = slot->linked_next; + eDebugCI("base removed.. so slot is now %p", it->cislot); + } else { + eDebugCI("not base removed.. %d", it->cislot->getSlotID()); eDVBCISlot *tmp = it->cislot; while(tmp->linked_next != slot) tmp = tmp->linked_next; @@ -222,8 +233,10 @@ void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot) tmp->linked_next = 0; } slot->linked_next=0; + slot->user_mapped=false; } } + recheckPMTHandlers(); } static bool canDescrambleMultipleServices(int slotid) @@ -245,22 +258,39 @@ static bool canDescrambleMultipleServices(int slotid) void eDVBCIInterfaces::recheckPMTHandlers() { -// eDebug("recheckPMTHAndlers()"); + eDebugCI("recheckPMTHAndlers()"); for (PMTHandlerList::iterator it(m_pmt_handlers.begin()); it != m_pmt_handlers.end(); ++it) { CAID_LIST caids; ePtr service; eServiceReferenceDVB ref; + eDVBCISlot *tmp = it->cislot; eDVBServicePMTHandler *pmthandler = it->pmthandler; eDVBServicePMTHandler::program p; pmthandler->getServiceReference(ref); pmthandler->getService(service); + + eDebugCI("recheck %p %s", pmthandler, ref.toString().c_str()); + + // check if this pmt handler has already assigned CI(s) .. and this CI(s) are already running + while(tmp) + { + if (!tmp->running_services.empty()) + break; + tmp=tmp->linked_next; + } + if (tmp) // we dont like to change tsmux for running services + { + eDebugCI("already assigned and running CI!\n"); + continue; + } + if (!pmthandler->getProgramInfo(p)) { int cnt=0; - for (std::set::reverse_iterator x(p.caids.rbegin()); x != p.caids.rend(); ++x, ++cnt) + for (caidSet::reverse_iterator x(p.caids.rbegin()); x != p.caids.rend(); ++x, ++cnt) caids.push_front(*x); if (service && cnt) service->m_ca = caids; @@ -274,15 +304,18 @@ void eDVBCIInterfaces::recheckPMTHandlers() for (eSmartPtrList::iterator ci_it(m_slots.begin()); ci_it != m_slots.end(); ++ci_it) { + eDebugCI("check Slot %d", ci_it->getSlotID()); bool useThis=false; + bool user_mapped=true; eDVBCICAManagerSession *ca_manager = ci_it->getCAManager(); + if (ca_manager) { int mask=0; if (!ci_it->possible_services.empty()) { mask |= 1; - std::set::iterator it = ci_it->possible_services.find(ref); + serviceSet::iterator it = ci_it->possible_services.find(ref); if (it != ci_it->possible_services.end()) { eDebug("'%s' is in service list of slot %d... so use it", ref.toString().c_str(), ci_it->getSlotID()); @@ -291,20 +324,19 @@ void eDVBCIInterfaces::recheckPMTHandlers() } if (!useThis && !ci_it->possible_providers.empty()) { - bool parent=false; + eDVBNamespace ns = ref.getDVBNamespace(); mask |= 2; if (!service) // subservice? { eServiceReferenceDVB parent_ref = ref.getParentServiceReference(); eDVBDB::getInstance()->getService(parent_ref, service); - parent=true; } if (service) { - std::set::iterator it = ci_it->possible_providers.find(service->m_provider_name); + providerSet::iterator it = ci_it->possible_providers.find(providerPair(service->m_provider_name, ns.get())); if (it != ci_it->possible_providers.end()) { - eDebug("'%s' is in provider list of slot %d... so use it", service->m_provider_name.c_str(), ci_it->getSlotID()); + eDebug("'%s/%08x' is in provider list of slot %d... so use it", service->m_provider_name.c_str(), ns.get(), ci_it->getSlotID()); useThis = true; } } @@ -313,11 +345,11 @@ void eDVBCIInterfaces::recheckPMTHandlers() { for (CAID_LIST::iterator ca(caids.begin()); ca != caids.end(); ++ca) { - std::set::iterator it = ci_it->possible_caids.find(*ca); + caidSet::iterator it = ci_it->possible_caids.find(*ca); if (it != ci_it->possible_caids.end()) { eDebug("caid '%04x' is in caid list of slot %d... so use it", *ca, ci_it->getSlotID()); - useThis=true; + useThis = true; break; } } @@ -332,7 +364,8 @@ void eDVBCIInterfaces::recheckPMTHandlers() if ( z != ci_caids.end() && *z == *ca ) { eDebug("The CI in Slot %d has said it can handle caid %04x... so use it", ci_it->getSlotID(), *z); - useThis=true; + useThis = true; + user_mapped = false; break; } } @@ -341,47 +374,74 @@ void eDVBCIInterfaces::recheckPMTHandlers() if (useThis) { + // check if this CI is already assigned to this pmthandler + eDVBCISlot *tmp = it->cislot; + while(tmp) + { + if (tmp == ci_it) + break; + tmp=tmp->linked_next; + } + if (tmp) // ignore already assigned cislots... + { + eDebugCI("already assigned!"); + continue; + } + eDebugCI("current slot %d usecount %d", ci_it->getSlotID(), ci_it->use_count); if (ci_it->use_count) // check if this CI can descramble more than one service { + bool found = false; useThis = false; PMTHandlerList::iterator tmp = m_pmt_handlers.begin(); - while (tmp != m_pmt_handlers.end()) + while (!found && tmp != m_pmt_handlers.end()) { - if ( tmp->cislot == ci_it && it != tmp ) + eDebugCI("."); + eDVBCISlot *tmp_cislot = tmp->cislot; + while (!found && tmp_cislot) { + eDebugCI(".."); eServiceReferenceDVB ref2; tmp->pmthandler->getServiceReference(ref2); - eDVBChannelID s1, s2; - if (ref != ref2) + if ( tmp_cislot == ci_it && it->pmthandler != tmp->pmthandler ) { - ref.getChannelID(s1); - ref2.getChannelID(s2); - } - if (ref == ref2 || (s1 == s2 && canDescrambleMultipleServices(ci_it->getSlotID()))) - { - useThis = true; - break; + eDebugCI("check pmthandler %s for same service/tp", ref2.toString().c_str()); + eDVBChannelID s1, s2; + if (ref != ref2) + { + eDebugCI("different services!"); + ref.getChannelID(s1); + ref2.getChannelID(s2); + } + if (ref == ref2 || (s1 == s2 && canDescrambleMultipleServices(tmp_cislot->getSlotID()))) + { + found = true; + eDebugCI("found!"); + eDVBCISlot *tmpci = it->cislot = tmp->cislot; + while(tmpci) + { + ++tmpci->use_count; + eDebug("(2)CISlot %d, usecount now %d", tmpci->getSlotID(), tmpci->use_count); + tmpci=tmpci->linked_next; + } + } } + tmp_cislot=tmp_cislot->linked_next; } + eDebugCI("..."); ++tmp; } } + if (useThis) { - // check if this CI is already assigned to this pmthandler - eDVBCISlot *tmp = it->cislot; - while(tmp) + if (ci_it->user_mapped) // we dont like to link user mapped CIs { - if (tmp == ci_it) - break; - tmp=tmp->linked_next; - } - - if (tmp) // ignore already assigned cislots... + eDebugCI("user mapped CI already in use... dont link!"); continue; + } ++ci_it->use_count; -// eDebug("usecount now %d", ci_it->use_count); + eDebug("(1)CISlot %d, usecount now %d", ci_it->getSlotID(), ci_it->use_count); data_source ci_source=CI_A; switch(ci_it->getSlotID()) @@ -432,8 +492,15 @@ void eDVBCIInterfaces::recheckPMTHandlers() ci_it->linked_next->setSource(ci_source); } it->cislot = ci_it; + eDebugCI("assigned!"); gotPMT(pmthandler); } + + if (it->cislot && user_mapped) // CI assigned to this pmthandler in this run.. and user mapped? then we break here.. we dont like to link other CIs to user mapped CIs + { + eDebugCI("user mapped CI assigned... dont link CIs!"); + break; + } } } } @@ -520,9 +587,10 @@ void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler) else tmp->linked_next = 0; } - slot->linked_next=0; + slot->linked_next = 0; + slot->user_mapped = false; } -// eDebug("use_count is now %d", slot->use_count); + eDebug("(3) slot %d usecount is now %d", slot->getSlotID(), slot->use_count); slot = next; } // check if another service is waiting for the CI @@ -539,7 +607,9 @@ void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) eDVBCISlot *tmp = it->cislot; while(tmp) { - tmp->sendCAPMT(pmthandler); + eDebugCI("check slot %d %d %d", tmp->getSlotID(), tmp->running_services.empty(), canDescrambleMultipleServices(tmp->getSlotID())); + if (tmp->running_services.empty() || canDescrambleMultipleServices(tmp->getSlotID())) + tmp->sendCAPMT(pmthandler); tmp = tmp->linked_next; } } @@ -551,7 +621,7 @@ int eDVBCIInterfaces::getMMIState(int slotid) if( (slot = getSlot(slotid)) == 0 ) return -1; - + return slot->getMMIState(); } @@ -659,25 +729,28 @@ PyObject *eDVBCIInterfaces::getDescrambleRules(int slotid) ePyObject caid_list = PyList_New(caids); ePyObject service_list = PyList_New(services); ePyObject provider_list = PyList_New(providers); - std::set::iterator caid_it(slot->possible_caids.begin()); + caidSet::iterator caid_it(slot->possible_caids.begin()); while(caids) { --caids; - PyTuple_SET_ITEM(caid_list, caids, PyLong_FromLong(*caid_it)); + PyList_SET_ITEM(caid_list, caids, PyLong_FromLong(*caid_it)); ++caid_it; } - std::set::iterator ref_it(slot->possible_services.begin()); + serviceSet::iterator ref_it(slot->possible_services.begin()); while(services) { --services; - PyTuple_SET_ITEM(service_list, services, PyString_FromString(ref_it->toString().c_str())); + PyList_SET_ITEM(service_list, services, PyString_FromString(ref_it->toString().c_str())); ++ref_it; } - std::set::iterator provider_it(slot->possible_providers.begin()); + providerSet::iterator provider_it(slot->possible_providers.begin()); while(providers) { + ePyObject tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString(provider_it->first.c_str())); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromUnsignedLong(provider_it->second)); --providers; - PyTuple_SET_ITEM(provider_list, providers, PyString_FromString(provider_it->c_str())); + PyList_SET_ITEM(provider_list, providers, tuple); ++provider_it; } PyTuple_SET_ITEM(tuple, 0, service_list); @@ -712,7 +785,7 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) { const char *errstr = "eDVBCIInterfaces::setDescrambleRules not enough entrys in argument tuple!!\n" "first argument should be a pythonlist with possible services\n" - "second argument should be a pythonlist with possible providers\n" + "second argument should be a pythonlist with possible providers/dvbnamespace tuples\n" "third argument should be a pythonlist with possible caids"; PyErr_SetString(PyExc_StandardError, errstr); return -1; @@ -757,19 +830,41 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) while(size) { --size; - ePyObject str = PyList_GET_ITEM(provider_list, size); - if (!PyString_Check(str)) + ePyObject tuple = PyList_GET_ITEM(provider_list, size); + if (!PyTuple_Check(tuple)) { char buf[255]; - snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules entry in provider list is not a string it is '%s'!!", PyObject_TypeStr(str)); + snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules entry in provider list is not a tuple it is '%s'!!", PyObject_TypeStr(tuple)); PyErr_SetString(PyExc_StandardError, buf); return -1; } - char *tmpstr = PyString_AS_STRING(str); + if (PyTuple_Size(tuple) != 2) + { + char buf[255]; + snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules provider tuple has %d instead of 2 entries!!", PyTuple_Size(tuple)); + PyErr_SetString(PyExc_StandardError, buf); + return -1; + } + if (!PyString_Check(PyTuple_GET_ITEM(tuple, 0))) + { + char buf[255]; + snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules 1st entry in provider tuple is not a string it is '%s'", PyObject_TypeStr(PyTuple_GET_ITEM(tuple, 0))); + PyErr_SetString(PyExc_StandardError, buf); + return -1; + } + if (!PyLong_Check(PyTuple_GET_ITEM(tuple, 1))) + { + char buf[255]; + snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules 2nd entry in provider tuple is not a long it is '%s'", PyObject_TypeStr(PyTuple_GET_ITEM(tuple, 1))); + PyErr_SetString(PyExc_StandardError, buf); + return -1; + } + char *tmpstr = PyString_AS_STRING(PyTuple_GET_ITEM(tuple, 0)); + uint32_t orbpos = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(tuple, 1)); if (strlen(tmpstr)) - slot->possible_providers.insert(tmpstr); + slot->possible_providers.insert(std::pair(tmpstr, orbpos)); else - eDebug("eDVBCIInterfaces::setDescrambleRules ignore invalid entry in provider name list!!"); + eDebug("eDVBCIInterfaces::setDescrambleRules ignore invalid entry in provider tuple (string is empty)!!"); }; size = PyList_Size(caid_list); while(size) @@ -820,14 +915,13 @@ void eDVBCISlot::data(int what) if(what == eSocketNotifier::Priority) { if(state != stateRemoved) { state = stateRemoved; - eDebug("ci removed"); while(sendqueue.size()) { delete [] sendqueue.top().data; sendqueue.pop(); } - eDVBCIInterfaces::getInstance()->ciRemoved(this); eDVBCISession::deleteSessions(this); + eDVBCIInterfaces::getInstance()->ciRemoved(this); notifier->setRequested(eSocketNotifier::Read); eDVBCI_UI::getInstance()->setState(getSlotID(),0); } @@ -838,7 +932,7 @@ void eDVBCISlot::data(int what) reset(); if(state != stateInserted) { - eDebug("ci inserted"); + eDebug("ci inserted in slot %d", getSlotID()); state = stateInserted; eDVBCI_UI::getInstance()->setState(getSlotID(),1); notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority); @@ -886,14 +980,19 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) ca_manager = 0; use_count = 0; linked_next = 0; + user_mapped = false; slotid = nr; sprintf(filename, "/dev/ci%d", nr); +// possible_caids.insert(0x1702); +// possible_providers.insert(providerPair("PREMIERE", 0xC00000)); +// possible_services.insert(eServiceReference("1:0:1:2A:4:85:C00000:0:0:0:")); + fd = ::open(filename, O_RDWR | O_NONBLOCK); - eDebug("eDVBCISlot has fd %d", fd); + eDebug("CI Slot %d has fd %d", getSlotID(), fd); state = stateInvalid; if (fd >= 0) @@ -932,7 +1031,7 @@ int eDVBCISlot::getSlotID() int eDVBCISlot::reset() { - eDebug("edvbcislot: reset requested"); + eDebug("CI Slot %d: reset requested", getSlotID()); if (state == stateInvalid) { @@ -955,7 +1054,7 @@ int eDVBCISlot::reset() int eDVBCISlot::startMMI() { - eDebug("edvbcislot: startMMI()"); + eDebug("CI Slot %d: startMMI()", getSlotID()); if(application_manager) application_manager->startMMI(); @@ -965,7 +1064,7 @@ int eDVBCISlot::startMMI() int eDVBCISlot::stopMMI() { - eDebug("edvbcislot: stopMMI()"); + eDebug("CI Slot %d: stopMMI()", getSlotID()); if(mmi_session) mmi_session->stopMMI(); @@ -975,7 +1074,7 @@ int eDVBCISlot::stopMMI() int eDVBCISlot::answerText(int answer) { - eDebug("edvbcislot: answerText(%d)", answer); + eDebug("CI Slot %d: answerText(%d)", getSlotID(), answer); if(mmi_session) mmi_session->answerText(answer); @@ -993,7 +1092,7 @@ int eDVBCISlot::getMMIState() int eDVBCISlot::answerEnq(char *value) { - eDebug("edvbcislot: answerENQ(%s)", value); + eDebug("CI Slot %d: answerENQ(%s)", getSlotID(), value); if(mmi_session) mmi_session->answerEnq(value); @@ -1003,7 +1102,7 @@ int eDVBCISlot::answerEnq(char *value) int eDVBCISlot::cancelEnq() { - eDebug("edvbcislot: cancelENQ"); + eDebug("CI Slot %d: cancelENQ", getSlotID()); if(mmi_session) mmi_session->cancelEnq(); @@ -1146,7 +1245,7 @@ int eDVBCISlot::setSource(data_source source) fprintf(ci, "D"); break; default: - eDebug("setSource %d failed!!!\n", (int)source); + eDebug("CI Slot %d: setSource %d failed!!!\n", getSlotID(), (int)source); break; } fclose(ci); @@ -1161,12 +1260,12 @@ int eDVBCISlot::setSource(data_source source) return 0; } if (source != TUNER_A && source != TUNER_B) - eDebug("setSource %d failed!!!\n", (int)source); + eDebug("CI Slot %d: setSource %d failed!!!\n", getSlotID(), (int)source); else fprintf(ci, "%s", source==TUNER_A ? "A" : "B"); // configure CI data source (TunerA, TunerB) fclose(ci); } - eDebug("eDVBCISlot->setSource(%d)", (int)source); + eDebug("CI Slot %d setSource(%d)", getSlotID(), (int)source); return 0; } diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index 4e3fcce2..c06ae7e3 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -38,6 +38,11 @@ enum data_source TUNER_A, TUNER_B, TUNER_C, TUNER_D, CI_A, CI_B, CI_C, CI_D }; +typedef std::pair providerPair; +typedef std::set providerSet; +typedef std::set caidSet; +typedef std::set serviceSet; + class eDVBCISlot: public iObject, public Object { friend class eDVBCIInterfaces; @@ -51,13 +56,14 @@ class eDVBCISlot: public iObject, public Object eDVBCICAManagerSession *ca_manager; eDVBCIMMISession *mmi_session; std::priority_queue sendqueue; - std::set possible_caids; - std::set possible_services; - std::set possible_providers; + caidSet possible_caids; + serviceSet possible_services; + providerSet possible_providers; int use_count; eDVBCISlot *linked_next; // needed for linked CI handling data_source current_source; int current_tuner; + bool user_mapped; void data(int); public: enum {stateRemoved, stateInserted, stateInvalid, stateResetted}; -- cgit v1.2.3 From 14384e3f5aaf81897d1931a14afd11d855bd6140 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 26 Feb 2009 19:52:00 +0100 Subject: more CI fixes (i.e. fix segfault on e2 shutdown) --- lib/dvb_ci/dvbci.cpp | 36 +++++++++++++++++++++++++----------- lib/dvb_ci/dvbci.h | 1 + 2 files changed, 26 insertions(+), 11 deletions(-) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index d088075c..0227c43c 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -18,7 +18,7 @@ #include -#undef CIDEBUG +//#define CIDEBUG 1 #ifdef CIDEBUG #define eDebugCI(x...) eDebug(x) @@ -268,23 +268,34 @@ void eDVBCIInterfaces::recheckPMTHandlers() eDVBCISlot *tmp = it->cislot; eDVBServicePMTHandler *pmthandler = it->pmthandler; eDVBServicePMTHandler::program p; + bool first_plugged_cis_exist = false; pmthandler->getServiceReference(ref); pmthandler->getService(service); eDebugCI("recheck %p %s", pmthandler, ref.toString().c_str()); + for (eSmartPtrList::iterator ci_it(m_slots.begin()); ci_it != m_slots.end(); ++ci_it) + if (ci_it->first_plugged && ci_it->getCAManager()) + { + eDebug("Slot %d first plugged", ci_it->getSlotID()); + ci_it->first_plugged = false; + first_plugged_cis_exist = true; + } // check if this pmt handler has already assigned CI(s) .. and this CI(s) are already running - while(tmp) - { - if (!tmp->running_services.empty()) - break; - tmp=tmp->linked_next; - } - if (tmp) // we dont like to change tsmux for running services + if (!first_plugged_cis_exist) { - eDebugCI("already assigned and running CI!\n"); - continue; + while(tmp) + { + if (!tmp->running_services.empty()) + break; + tmp=tmp->linked_next; + } + if (tmp) // we dont like to change tsmux for running services + { + eDebugCI("already assigned and running CI!\n"); + continue; + } } if (!pmthandler->getProgramInfo(p)) @@ -912,6 +923,7 @@ int eDVBCISlot::send(const unsigned char *data, size_t len) void eDVBCISlot::data(int what) { + eDebugCI("CISlot %d what %d\n", getSlotID(), what); if(what == eSocketNotifier::Priority) { if(state != stateRemoved) { state = stateRemoved; @@ -981,6 +993,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) use_count = 0; linked_next = 0; user_mapped = false; + first_plugged = true; slotid = nr; @@ -992,7 +1005,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) fd = ::open(filename, O_RDWR | O_NONBLOCK); - eDebug("CI Slot %d has fd %d", getSlotID(), fd); + eDebugCI("CI Slot %d has fd %d", getSlotID(), fd); state = stateInvalid; if (fd >= 0) @@ -1007,6 +1020,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) eDVBCISlot::~eDVBCISlot() { + eDVBCISession::deleteSessions(this); } void eDVBCISlot::setAppManager( eDVBCIApplicationManagerSession *session ) diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index c06ae7e3..7164d25a 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -65,6 +65,7 @@ class eDVBCISlot: public iObject, public Object int current_tuner; bool user_mapped; void data(int); + bool first_plugged; public: enum {stateRemoved, stateInserted, stateInvalid, stateResetted}; eDVBCISlot(eMainloop *context, int nr); -- cgit v1.2.3 From 574d0f07a04f5b9c295e7aa1e4e00a14fa6b2d5e Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 27 Feb 2009 12:12:07 +0100 Subject: add eDVBCiInterfaces::readCICaids --- lib/dvb_ci/dvbci.cpp | 17 +++++++++++++++++ lib/dvb_ci/dvbci.h | 1 + 2 files changed, 18 insertions(+) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 0227c43c..c34ea0c0 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -898,6 +898,23 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) return 0; } +PyObject *eDVBCIInterfaces::readCICaIds(int slotid) +{ + eDVBCISlot *slot = getSlot(slotid); + if (!slot) + { + char tmp[255]; + snprintf(tmp, 255, "eDVBCIInterfaces::readCICaIds try to get CAIds for CI Slot %d... but just %d slots are available", slotid, m_slots.size()); + PyErr_SetString(PyExc_StandardError, tmp); + return 0; + } + int idx=0; + ePyObject list = PyList_New(slot->possible_caids.size()); + for (caidSet::iterator it = slot->possible_caids.begin(); it != slot->possible_caids.end(); ++it) + PyList_SET_ITEM(list, idx++, PyLong_FromLong(*it)); + return list; +} + int eDVBCISlot::send(const unsigned char *data, size_t len) { int res=0; diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index 7164d25a..c11a1203 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -153,6 +153,7 @@ public: int getNumOfSlots() { return m_slots.size(); } PyObject *getDescrambleRules(int slotid); RESULT setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) ); + PyObject *readCICaIds(int slotid); }; #endif -- cgit v1.2.3 From 6f2cf5c74f32e7aa8fea4ce93a6b0963f78fedd5 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 3 Mar 2009 11:50:53 +0100 Subject: take care of subservices --- lib/dvb_ci/dvbci.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index c34ea0c0..a68edea8 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -332,6 +332,20 @@ void eDVBCIInterfaces::recheckPMTHandlers() eDebug("'%s' is in service list of slot %d... so use it", ref.toString().c_str(), ci_it->getSlotID()); useThis = true; } + else // check parent + { + eServiceReferenceDVB parent_ref = ref.getParentServiceReference(); + if (parent_ref) + { + it = ci_it->possible_services.find(ref); + if (it != ci_it->possible_services.end()) + { + eDebug("parent '%s' of '%s' is in service list of slot %d... so use it", + parent_ref.toString().c_str(), ref.toString().c_str(), ci_it->getSlotID()); + useThis = true; + } + } + } } if (!useThis && !ci_it->possible_providers.empty()) { @@ -354,6 +368,7 @@ void eDVBCIInterfaces::recheckPMTHandlers() } if (!useThis && !ci_it->possible_caids.empty()) { + mask |= 4; for (CAID_LIST::iterator ca(caids.begin()); ca != caids.end(); ++ca) { caidSet::iterator it = ci_it->possible_caids.find(*ca); -- cgit v1.2.3 From e57f94d8f1156deee0874d24c33c98d600c9af0d Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 10 Mar 2009 12:04:41 +0100 Subject: fix readCICaIds call --- lib/dvb_ci/dvbci.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index a68edea8..a0166355 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -921,13 +921,18 @@ PyObject *eDVBCIInterfaces::readCICaIds(int slotid) char tmp[255]; snprintf(tmp, 255, "eDVBCIInterfaces::readCICaIds try to get CAIds for CI Slot %d... but just %d slots are available", slotid, m_slots.size()); PyErr_SetString(PyExc_StandardError, tmp); - return 0; } - int idx=0; - ePyObject list = PyList_New(slot->possible_caids.size()); - for (caidSet::iterator it = slot->possible_caids.begin(); it != slot->possible_caids.end(); ++it) - PyList_SET_ITEM(list, idx++, PyLong_FromLong(*it)); - return list; + else + { + int idx=0; + eDVBCICAManagerSession *ca_manager = slot->getCAManager(); + const std::vector &ci_caids = ca_manager->getCAIDs(); + ePyObject list = PyList_New(ci_caids.size()); + for (std::vector::const_iterator it = ci_caids.begin(); it != ci_caids.end(); ++it) + PyList_SET_ITEM(list, idx++, PyLong_FromLong(*it)); + return list; + } + return 0; } int eDVBCISlot::send(const unsigned char *data, size_t len) -- cgit v1.2.3 From 4fc2a70eeb86fa51b783b4a9c034b926db0013a3 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 10 Mar 2009 12:11:18 +0100 Subject: small fix --- lib/dvb_ci/dvbci.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index a0166355..83bbed75 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -926,10 +926,13 @@ PyObject *eDVBCIInterfaces::readCICaIds(int slotid) { int idx=0; eDVBCICAManagerSession *ca_manager = slot->getCAManager(); - const std::vector &ci_caids = ca_manager->getCAIDs(); - ePyObject list = PyList_New(ci_caids.size()); - for (std::vector::const_iterator it = ci_caids.begin(); it != ci_caids.end(); ++it) - PyList_SET_ITEM(list, idx++, PyLong_FromLong(*it)); + const std::vector *ci_caids = ca_manager ? &ca_manager->getCAIDs() : 0; + ePyObject list = PyList_New(ci_caids ? ci_caids->size() : 0); + if (ci_caids) + { + for (std::vector::const_iterator it = ci_caids->begin(); it != ci_caids->end(); ++it) + PyList_SET_ITEM(list, idx++, PyLong_FromLong(*it)); + } return list; } return 0; -- cgit v1.2.3 From 0ffeb4cf114a6706ba629112c070e3d94da98793 Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 11 Mar 2009 08:49:33 +0100 Subject: fix: StandardError: eDVBCIInterfaces::setDescrambleRules entry in caid list is not a long it is 'long'!! --- lib/dvb_ci/dvbci.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/dvb_ci') diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 83bbed75..8fa1bca2 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -897,14 +897,14 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) { --size; ePyObject caid = PyList_GET_ITEM(caid_list, size); - if (!PyInt_Check(caid)) + if (!PyLong_Check(caid)) { char buf[255]; snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules entry in caid list is not a long it is '%s'!!", PyObject_TypeStr(caid)); PyErr_SetString(PyExc_StandardError, buf); return -1; } - int tmpcaid = PyInt_AsLong(caid); + int tmpcaid = PyLong_AsLong(caid); if (tmpcaid > 0 && tmpcaid < 0x10000) slot->possible_caids.insert(tmpcaid); else -- cgit v1.2.3 From a2b81eb390ee9cfb892734251429a062a4fa77e4 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 15 Mar 2009 11:58:52 +0100 Subject: add "High bitrate support" choice in CI Setup (needs new drivers to work) --- data/skin_default.xml | 4 ++-- lib/dvb_ci/dvbci.cpp | 25 +++++++++++++++++++++++++ lib/dvb_ci/dvbci.h | 2 ++ lib/dvb_ci/dvbci_ui.cpp | 5 +++++ lib/dvb_ci/dvbci_ui.h | 2 ++ lib/python/Screens/Ci.py | 21 +++++++++++++++++++-- po/de.po | 3 +++ po/enigma2.pot | 4 ++++ 8 files changed, 62 insertions(+), 4 deletions(-) (limited to 'lib/dvb_ci') diff --git a/data/skin_default.xml b/data/skin_default.xml index f99e1a76..ed3b8a23 100755 --- a/data/skin_default.xml +++ b/data/skin_default.xml @@ -172,9 +172,9 @@ self.instance.move(ePoint((720-wsizex)/2, (576-wsizey)/(count > 7 and 2 or 3) - + - + diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 8fa1bca2..ce1f7d66 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -938,6 +938,14 @@ PyObject *eDVBCIInterfaces::readCICaIds(int slotid) return 0; } +int eDVBCIInterfaces::setCIClockRate(int slotid, int rate) +{ + eDVBCISlot *slot = getSlot(slotid); + if (slot) + return slot->setClockRate(rate); + return -1; +} + int eDVBCISlot::send(const unsigned char *data, size_t len) { int res=0; @@ -1323,4 +1331,21 @@ int eDVBCISlot::setSource(data_source source) return 0; } +int eDVBCISlot::setClockRate(int rate) +{ + char buf[64]; + snprintf(buf, 64, "/proc/stb/tsmux/ci%d_tsclk", slotid); + FILE *ci = fopen(buf, "wb"); + if (ci) + { + if (rate) + fprintf(ci, "high"); + else + fprintf(ci, "normal"); + fclose(ci); + return 0; + } + return -1; +} + eAutoInitP0 init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots"); diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index c11a1203..cdaaf904 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -94,6 +94,7 @@ public: void removeService(uint16_t program_number=0xFFFF); int getNumOfServices() { return running_services.size(); } int setSource(data_source source); + int setClockRate(int); }; struct CIPmtHandler @@ -146,6 +147,7 @@ public: int getMMIState(int slot); int sendCAPMT(int slot); int setInputSource(int tunerno, data_source source); + int setCIClockRate(int slot, int rate); #ifdef SWIG public: #endif diff --git a/lib/dvb_ci/dvbci_ui.cpp b/lib/dvb_ci/dvbci_ui.cpp index af613c43..b1bfdc25 100644 --- a/lib/dvb_ci/dvbci_ui.cpp +++ b/lib/dvb_ci/dvbci_ui.cpp @@ -71,5 +71,10 @@ int eDVBCI_UI::getMMIState(int slot) return eDVBCIInterfaces::getInstance()->getMMIState(slot); } +int eDVBCI_UI::setClockRate(int slot, int rate) +{ + return eDVBCIInterfaces::getInstance()->setCIClockRate(slot, rate); +} + //FIXME: correct "run/startlevel" eAutoInitP0 init_dvbciui(eAutoInitNumbers::rc, "DVB-CI UI"); diff --git a/lib/dvb_ci/dvbci_ui.h b/lib/dvb_ci/dvbci_ui.h index b53ab02d..65b0f95d 100644 --- a/lib/dvb_ci/dvbci_ui.h +++ b/lib/dvb_ci/dvbci_ui.h @@ -13,6 +13,7 @@ class eDVBCI_UI: public eMMI_UI #endif void stateChanged(int val) { ciStateChanged(val); } public: + enum { rateNormal, rateHigh }; PSignal1 ciStateChanged; #ifndef SWIG eDVBCI_UI(); @@ -26,6 +27,7 @@ public: int answerMenu(int slot, int answer); int answerEnq(int slot, char *val); int cancelEnq(int slot); + int setClockRate(int slot, int rate); }; #endif diff --git a/lib/python/Screens/Ci.py b/lib/python/Screens/Ci.py index a997f7fe..19f4d921 100644 --- a/lib/python/Screens/Ci.py +++ b/lib/python/Screens/Ci.py @@ -12,11 +12,21 @@ from enigma import eTimer, eDVBCI_UI, eDVBCIInterfaces MAX_NUM_CI = 4 +def setCIBitrate(configElement): + if configElement.value == "no": + eDVBCI_UI.getInstance().setClockRate(configElement.slotid, eDVBCI_UI.rateNormal) + else: + eDVBCI_UI.getInstance().setClockRate(configElement.slotid, eDVBCI_UI.rateHigh) + def InitCiConfig(): config.ci = ConfigSubList() for slot in range(MAX_NUM_CI): config.ci.append(ConfigSubsection()) config.ci[slot].canDescrambleMultipleServices = ConfigSelection(choices = [("auto", _("Auto")), ("no", _("No")), ("yes", _("Yes"))], default = "auto") + if SystemInfo["CommonInterfaceSupportsHighBitrates"]: + config.ci[slot].canHandleHighBitrates = ConfigSelection(choices = [("no", _("No")), ("yes", _("Yes"))], default = "no") + config.ci[slot].canHandleHighBitrates.slotid = slot + config.ci[slot].canHandleHighBitrates.addNotifier(setCIBitrate) class MMIDialog(Screen): def __init__(self, session, slotid, action, handler = eDVBCI_UI.getInstance(), wait_text = _("wait for ci...") ): @@ -226,7 +236,13 @@ class CiMessageHandler: self.ci = { } self.dlgs = { } eDVBCI_UI.getInstance().ciStateChanged.get().append(self.ciStateChanged) - SystemInfo["CommonInterface"]= eDVBCIInterfaces.getInstance().getNumOfSlots() > 0 + SystemInfo["CommonInterface"] = eDVBCIInterfaces.getInstance().getNumOfSlots() > 0 + try: + file = open("/proc/stb/tsmux/ci0_tsclk", "r") + file.close() + SystemInfo["CommonInterfaceSupportsHighBitrates"] = True + except: + SystemInfo["CommonInterfaceSupportsHighBitrates"] = False def setSession(self, session): self.session = session @@ -285,7 +301,7 @@ class CiSelection(Screen): def selectionChanged(self): cur_idx = self["entries"].getCurrentIndex() - self["text"].setText(_("Slot %d")%((cur_idx / 4)+1)) + self["text"].setText(_("Slot %d")%((cur_idx / 5)+1)) def keyConfigEntry(self, key): try: @@ -315,6 +331,7 @@ class CiSelection(Screen): self.list.append( (appname, ConfigNothing(), 2, slot) ) self.list.append(getConfigListEntry(_("Multiple service support"), config.ci[slot].canDescrambleMultipleServices)) + self.list.append(getConfigListEntry(_("High bitrate support"), config.ci[slot].canHandleHighBitrates)) def updateState(self, slot): state = eDVBCI_UI.getInstance().getState(slot) diff --git a/po/de.po b/po/de.po index 6fc82571..acf7d8a8 100644 --- a/po/de.po +++ b/po/de.po @@ -1541,6 +1541,9 @@ msgstr "Hierarchieinformationen" msgid "Hierarchy mode" msgstr "Hierarchiemodus" +msgid "High bitrate support" +msgstr "Kann hohe Datenraten verarbeiten" + msgid "Horizontal" msgstr "" diff --git a/po/enigma2.pot b/po/enigma2.pot index 0e63744e..e8cc8314 100644 --- a/po/enigma2.pot +++ b/po/enigma2.pot @@ -1828,6 +1828,10 @@ msgstr "" msgid "Hierarchy mode" msgstr "" +#: ../lib/python/Screens/Ci.py:334 +msgid "High bitrate support" +msgstr "" + #: ../lib/python/Tools/Transponder.py:31 msgid "Horizontal" msgstr "" -- cgit v1.2.3