Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/dvb/cahandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,25 @@ int eDVBCAHandler::unregisterService(const eServiceReferenceDVB &ref, int adapte
{
if (!used_demux_slots) // no more used.. so we remove it
{
/*
* Send CMD_NOT_SELECTED to tell the softcam to stop
* descrambling this service before we delete it.
* Without this, switching from an encrypted channel
* to FTA/IPTV would leave the softcam in descrambling
* state (e.g. ecm.info not removed).
*/
if (m_protocol3_established && caservice->getCAPMTVersion() >= 0)
{
for (ePtrList<ePMTClient>::iterator client_it = clients.begin(); client_it != clients.end(); ++client_it)
{
if (client_it->state() == eSocket::Connection)
{
eDebug("[eDVBCAHandler] sending CMD_NOT_SELECTED for service %s", caservice->toString().c_str());
caservice->writeCAPMTObject(*client_it, LIST_UPDATE, CMD_NOT_SELECTED);
}
}
}

delete it->second;
services.erase(it);

Expand Down
22 changes: 19 additions & 3 deletions lib/dvb/csasession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,18 @@ void eDVBCSASession::startECMMonitor(iDVBDemux *demux, uint16_t ecm_pid, uint16_

if (info.is_csa_alt && !m_active)
{
eDebug("[eDVBCSASession] ECM Monitor: Activating from cache (CSA-ALT)");
m_ecm_analyzed = true;
m_csa_alt = true;
setActive(true);
if (shouldSuppressActivation && shouldSuppressActivation())
{
eDebug("[eDVBCSASession] ECM Monitor: CSA-ALT cached but activation suppressed (CI module)");
stopECMMonitor();
}
else
{
eDebug("[eDVBCSASession] ECM Monitor: Activating from cache (CSA-ALT)");
setActive(true);
}
}
}

Expand Down Expand Up @@ -235,7 +243,15 @@ void eDVBCSASession::ecmDataReceived(const uint8_t *data)
eDebug("[eDVBCSASession] CSA-ALT detected from ECM! Activating software descrambling");
if (!m_active)
{
setActive(true);
if (shouldSuppressActivation && shouldSuppressActivation())
{
eDebug("[eDVBCSASession] Activation suppressed (CI module handles decryption)");
stopECMMonitor();
}
else
{
setActive(true);
}
}
}
else
Expand Down
5 changes: 5 additions & 0 deletions lib/dvb/csasession.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <lib/dvb/idvb.h>
#include <lib/base/ebase.h>
#include <sigc++/sigc++.h>
#include <functional>

class eDVBCSAEngine;
class eDVBCAHandler;
Expand Down Expand Up @@ -91,6 +92,10 @@ class eDVBCSASession : public iServiceScrambled, public sigc::trackable
// Signal when first CW is received (for decoder start timing)
sigc::signal<void()> firstCwReceived;

// Optional callback to check if activation should be suppressed
// (e.g. CI module handles decryption). Return true to suppress.
std::function<bool()> shouldSuppressActivation;

private:
eServiceReferenceDVB m_service_ref;
ePtr<eDVBCSAEngine> m_engine;
Expand Down
2 changes: 0 additions & 2 deletions lib/dvb/pmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ void eDVBServicePMTHandler::PMTready(int error)
{
eDVBCIInterfaces::getInstance()->recheckPMTHandlers();
eDVBCIInterfaces::getInstance()->gotPMT(this);
if (isCiConnected())
serviceEvent(eventCIConnected);
}
}
if (m_ca_servicePtr)
Expand Down
1 change: 0 additions & 1 deletion lib/dvb/pmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ class eDVBServicePMTHandler: public eDVBPMTParser
eventStartPvrDescramble, // start PVR Descramble Convert
eventChannelAllocated,
eventStreamCorrupt,
eventCIConnected, // a CI slot was assigned to this service after recheckPMTHandlers
};
#ifndef SWIG
sigc::signal<void(int)> serviceEvent;
Expand Down
13 changes: 5 additions & 8 deletions lib/service/servicedvb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,14 +1384,6 @@ void eDVBServicePlay::serviceEvent(int event)
case eDVBServicePMTHandler::eventHBBTVInfo:
m_event((iPlayableService*)this, evHBBTVInfo);
break;
case eDVBServicePMTHandler::eventCIConnected:
if (m_csa_session && m_csa_session->isActive())
{
eDebug("[eDVBServicePlay] CI module connected - deactivating SoftCSA to save resources");
m_csa_session->stopECMMonitor();
m_csa_session->forceDeactivate();
}
break;
}
}

Expand Down Expand Up @@ -4379,6 +4371,11 @@ void eDVBServicePlay::setupSpeculativeDescrambling()
m_soft_decoder->m_audio_pid_selected.connect(
sigc::mem_fun(*this, &eDVBServicePlay::onSoftDecoderAudioPidSelected));

// Suppress SoftCSA activation when CI module handles decryption
m_csa_session->shouldSuppressActivation = [this]() {
return m_service_handler.isCiConnected();
};

// Connect to session's activated signal for decoder handover
m_csa_session->activated.connect(
sigc::mem_fun(*this, &eDVBServicePlay::onSessionActivated));
Expand Down
5 changes: 5 additions & 0 deletions lib/service/servicedvbfcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,11 @@ void eDVBServiceFCCPlay::setupSpeculativeDescrambling()
m_soft_decoder->m_audio_pid_selected.connect(
[this](int pid) { this->onSoftDecoderAudioPidSelected(pid); });

// Suppress SoftCSA activation when CI module handles decryption
m_csa_session->shouldSuppressActivation = [this]() {
return m_service_handler.isCiConnected();
};

// Connect to session's activated signal - use FCC-specific callback!
// This is the key difference from base class: we use onFCCSessionActivated
// which handles FCC decoder stop/start properly
Expand Down
Loading