servicemp3.cpp: more simple/flexible streaming detection
[enigma2.git] / lib / dvb_ci / dvbci.cpp
index 037103cfe21a7cec62ec45e283b63e625f4793b2..374672ae1903e5dfa01ba8a36bd6907454f2a045 100644 (file)
@@ -297,8 +297,9 @@ void eDVBCIInterfaces::recheckPMTHandlers()
                if (!pmthandler->getProgramInfo(p))
                {
                        int cnt=0;
-                       for (caidSet::reverse_iterator x(p.caids.rbegin()); x != p.caids.rend(); ++x, ++cnt)
-                               caids.push_front(*x);
+                       std::set<eDVBServicePMTHandler::program::capid_pair> set(p.caids.begin(), p.caids.end());
+                       for (std::set<eDVBServicePMTHandler::program::capid_pair>::reverse_iterator x(set.rbegin()); x != set.rend(); ++x, ++cnt)
+                               caids.push_front(x->caid);
                        if (service && cnt)
                                service->m_ca = caids;
                }
@@ -605,6 +606,8 @@ void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler)
                                        else
                                                tmp->linked_next = 0;
                                }
+                               else // removed old base slot.. update ptr
+                                       base_slot = slot->linked_next;
                                slot->linked_next = 0;
                                slot->user_mapped = false;
                        }
@@ -736,7 +739,7 @@ PyObject *eDVBCIInterfaces::getDescrambleRules(int slotid)
        if (!slot)
        {
                char tmp[255];
-               snprintf(tmp, 255, "eDVBCIInterfaces::getDescrambleRules try to get rules for CI Slot %d... but just %d slots are available", slotid, m_slots.size());
+               snprintf(tmp, 255, "eDVBCIInterfaces::getDescrambleRules try to get rules for CI Slot %d... but just %zd slots are available", slotid, m_slots.size());
                PyErr_SetString(PyExc_StandardError, tmp);
                return 0;
        }
@@ -788,7 +791,7 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject)
        if (!slot)
        {
                char tmp[255];
-               snprintf(tmp, 255, "eDVBCIInterfaces::setDescrambleRules try to set rules for CI Slot %d... but just %d slots are available", slotid, m_slots.size());
+               snprintf(tmp, 255, "eDVBCIInterfaces::setDescrambleRules try to set rules for CI Slot %d... but just %zd slots are available", slotid, m_slots.size());
                PyErr_SetString(PyExc_StandardError, tmp);
                return -1;
        }
@@ -859,7 +862,7 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject)
                if (PyTuple_Size(tuple) != 2)
                {
                        char buf[255];
-                       snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules provider tuple has %d instead of 2 entries!!", PyTuple_Size(tuple));
+                       snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules provider tuple has %zd instead of 2 entries!!", PyTuple_Size(tuple));
                        PyErr_SetString(PyExc_StandardError, buf);
                        return -1;
                }
@@ -911,7 +914,7 @@ PyObject *eDVBCIInterfaces::readCICaIds(int 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());
+               snprintf(tmp, 255, "eDVBCIInterfaces::readCICaIds try to get CAIds for CI Slot %d... but just %zd slots are available", slotid, m_slots.size());
                PyErr_SetString(PyExc_StandardError, tmp);
        }
        else
@@ -1186,10 +1189,11 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector<u
                uint16_t program_number = ref.getServiceID().get();
                std::map<uint16_t, uint8_t>::iterator it =
                        running_services.find(program_number);
+               bool sendEmpty = caids.size() == 1 && caids[0] == 0xFFFF;
 
                if ( it != running_services.end() &&
                        (pmt_version == it->second) &&
-                       !(caids.size() == 1 && caids[0] == 0xFFFF) )
+                       !sendEmpty )
                {
                        eDebug("[eDVBCISlot] dont send self capmt version twice");
                        return -1;
@@ -1214,7 +1218,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector<u
                                capmt.append(*i++);
                        }
                        capmt.writeToBuffer(raw_data);
-#if 1
+
 // begin calc capmt length
                        int wp=0;
                        int hlen;
@@ -1235,19 +1239,22 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector<u
                                hlen = 4;
                        }
 // end calc capmt length
-//                     eDebug("ca_manager %p dump capmt:", ca_manager);
-//                     for(int i=0;i<wp;i++)
-//                             eDebugNoNewLine("%02x ", raw_data[i]);
-//                     eDebug("");
-#endif
-                       if (caids.size() == 1 && caids[0] == 0xFFFF)
+
+                       if (sendEmpty)
                        {
 //                             eDebugNoNewLine("SEND EMPTY CAPMT.. old version is %02x", raw_data[hlen+3]);
+                               if (sendEmpty && running_services.size() == 1)  // check if this is the capmt for the last running service
+                                       raw_data[hlen] = 0x03; // send only instead of update... because of strange effects with alphacrypt
                                raw_data[hlen+3] &= ~0x3E;
                                raw_data[hlen+3] |= ((pmt_version+1) & 0x1F) << 1;
 //                             eDebug(" new version is %02x", raw_data[hlen+3]);
                        }
 
+//                     eDebug("ca_manager %p dump capmt:", ca_manager);
+//                     for(int i=0;i<wp;i++)
+//                             eDebugNoNewLine("%02x ", raw_data[i]);
+//                     eDebug("");
+
                        //dont need tag and lenfield
                        ca_manager->sendCAPMT(raw_data + hlen, wp - hlen);
                        running_services[program_number] = pmt_version;