add ability to choose "Multiple service support (auto/no/yes)" in Ci Setup
[vuplus_dvbapp] / lib / dvb_ci / dvbci.cpp
index 1be4232..f646262 100644 (file)
@@ -6,6 +6,7 @@
 #include <lib/base/ebase.h>
 
 #include <lib/base/eerror.h>
+#include <lib/base/nconfig.h> // access to python config
 #include <lib/dvb/pmt.h>
 #include <lib/dvb_ci/dvbci.h>
 #include <lib/dvb_ci/dvbci_session.h>
@@ -66,6 +67,16 @@ eDVBCISlot *eDVBCIInterfaces::getSlot(int slotid)
        return 0;
 }
 
+int eDVBCIInterfaces::getSlotState(int slotid)
+{
+       eDVBCISlot *slot;
+
+       if( (slot = getSlot(slotid)) == 0 )
+               return eDVBCISlot::stateInvalid;
+
+       return slot->getState();
+}
+
 int eDVBCIInterfaces::reset(int slotid)
 {
        eDVBCISlot *slot;
@@ -207,6 +218,24 @@ void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot)
        }
 }
 
+static bool canDescrambleMultipleServices(int slotid)
+{
+       char configStr[255];
+       snprintf(configStr, 255, "config.ci%d.canDescrambleMultipleServices", slotid);
+       std::string str;
+       ePythonConfigQuery::getConfigValue(configStr, str);
+       eDebug("str is %s", str.empty()?"empty" : str.c_str());
+       if ( str == "auto" )
+       {
+               std::string appname = eDVBCI_UI::getInstance()->getAppName(slotid);
+               if (appname.find("AlphaCrypt") != std::string::npos)
+                       return true;
+       }
+       else if (str == "yes")
+               return true;
+       return false;
+}
+
 void eDVBCIInterfaces::recheckPMTHandlers()
 {
 //     eDebug("recheckPMTHAndlers()");
@@ -240,9 +269,6 @@ void eDVBCIInterfaces::recheckPMTHandlers()
                {
                        for (eSmartPtrList<eDVBCISlot>::iterator ci_it(m_slots.begin()); ci_it != m_slots.end(); ++ci_it)
                        {
-                               if (ci_it->getState() == eDVBCISlot::stateInvalid)
-                                       ci_it->reset();
-
                                bool useThis=false;
                                eDVBCICAManagerSession *ca_manager = ci_it->getCAManager();
                                if (ca_manager)
@@ -271,7 +297,6 @@ void eDVBCIInterfaces::recheckPMTHandlers()
                                                {
                                                        if ( tmp->cislot )
                                                        {
-                                                               bool canHandleMultipleServices=false;
                                                                eServiceReferenceDVB ref2;
                                                                tmp->pmthandler->getServiceReference(ref2);
                                                                eDVBChannelID s1, s2;
@@ -279,15 +304,8 @@ void eDVBCIInterfaces::recheckPMTHandlers()
                                                                {
                                                                        ref.getChannelID(s1);
                                                                        ref2.getChannelID(s2);
-                                                                       // FIXME .. build a "ci can handle multiple services" config entry
-                                                                       // Yes / No / Auto
-                                                                       if ( eDVBCI_UI::getInstance()->getAppName(ci_it->getSlotID()) == "AlphaCrypt" )
-                                                                       {
-                                                                               canHandleMultipleServices = true;
-                                                                               eDebug("Alphacrypt can handle multiple services");
-                                                                       }
                                                                }
-                                                               if (ref == ref2 || (s1 == s2 && canHandleMultipleServices) )
+                                                               if (ref == ref2 || (s1 == s2 && canDescrambleMultipleServices(ci_it->getSlotID())))
                                                                {
                                                                        it->cislot = tmp->cislot;
                                                                        ++it->cislot->use_count;
@@ -348,18 +366,21 @@ void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler)
                bool sameServiceExist=false;
                for (PMTHandlerList::iterator i=m_pmt_handlers.begin(); i != m_pmt_handlers.end(); ++i)
                {
-                       eServiceReferenceDVB ref;
-                       i->pmthandler->getServiceReference(ref);
-                       if ( ref == service_to_remove )
+                       if (i->cislot)
                        {
-                               sameServiceExist=true;
-                               break;
+                               eServiceReferenceDVB ref;
+                               i->pmthandler->getServiceReference(ref);
+                               if ( ref == service_to_remove )
+                               {
+                                       sameServiceExist=true;
+                                       break;
+                               }
                        }
                }
 
                if (slot && !sameServiceExist)
                {
-                       if (slot->getNumOfServices() > 1) // fixme make it dependend of "ci can handle more than one service"
+                       if (slot->getNumOfServices() > 1)
                        {
                                eDebug("[eDVBCIInterfaces] remove last pmt handler for service %s send empty capmt",
                                        service_to_remove.toString().c_str());
@@ -423,8 +444,6 @@ int eDVBCISlot::send(const unsigned char *data, size_t len)
 
 void eDVBCISlot::data(int what)
 {
-       if (state == stateInvalid)
-               return;
        if(what == eSocketNotifier::Priority) {
                if(state != stateRemoved) {
                        state = stateRemoved;
@@ -437,17 +456,18 @@ void eDVBCISlot::data(int what)
                        eDVBCIInterfaces::getInstance()->ciRemoved(this);
                        eDVBCISession::deleteSessions(this);
                        notifier->setRequested(eSocketNotifier::Read);
-                       //HACK
-                       eDVBCI_UI::getInstance()->setState(0,0);
+                       eDVBCI_UI::getInstance()->setState(getSlotID(),0);
                }
                return;
        }
 
+       if (state == stateInvalid)
+               reset();
+
        if(state != stateInserted) {
                eDebug("ci inserted");
                state = stateInserted;
-//             HACK
-               eDVBCI_UI::getInstance()->setState(0,1);
+               eDVBCI_UI::getInstance()->setState(getSlotID(),1);
                notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority);
                /* enable PRI to detect removal or errors */
        }