From bef98c2e9155fc36568fc23a50fd7b638c5008fe Mon Sep 17 00:00:00 2001 From: max10 Date: Fri, 8 Jul 2016 12:13:23 +0200 Subject: [PATCH] add two-same-cip (thx DboxOldie) --- common/ca.h | 1 + common/ca_ci.cpp | 164 ++++++++++++++++++++++++++------------- common/ca_ci.h | 8 +- libdvbci/dvbci_ccmgr.cpp | 2 +- 4 files changed, 116 insertions(+), 59 deletions(-) diff --git a/common/ca.h b/common/ca.h index 3c653a8..46e18ee 100644 --- a/common/ca.h +++ b/common/ca.h @@ -118,6 +118,7 @@ public: void MenuClose(enum CA_SLOT_TYPE, uint32_t Slot); void SetTSClock(u32 /*Speed*/) { return; }; bool checkChannelID(u64 /*chanID*/) { return false; }; + void setCheckLiveSlot(int /*check*/) { return; }; virtual ~cCA(); }; diff --git a/common/ca_ci.cpp b/common/ca_ci.cpp index 5ca8c8e..6badcdd 100644 --- a/common/ca_ci.cpp +++ b/common/ca_ci.cpp @@ -37,7 +37,7 @@ #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_CA, this, args) static const char * FILENAME = "[ca_ci]"; -static unsigned int LiveSlot = 0; +static bool checkLiveSlot = false; static bool CertChecked = false; static bool Cert_OK = false; static uint8_t NullPMT[50]={0x9F,0x80,0x32,0x2E,0x03,0x6E,0xA7,0x37,0x00,0x00,0x1B,0x15,0x7D,0x00,0x00,0x03,0x15,0x7E,0x00,0x00,0x03,0x15,0x7F,0x00, @@ -585,7 +585,8 @@ void cCA::ModuleReset(enum CA_SLOT_TYPE, uint32_t slot) (*it)->cam_caids.clear(); (*it)->newCapmt = false; - (*it)->inUse = false; + (*it)->recordUse = false; + (*it)->liveUse = false; (*it)->tpid = 0; (*it)->pmtlen = 0; (*it)->source = TUNER_A; @@ -619,60 +620,97 @@ int cCA::GetCAIDS(CaIdVector &Caids) return 0; } -bool cCA::StopRecordCI( u64 tpid, u8 source, u32 calen) +bool cCA::StopLiveCI( u64 tpid, u8 source, u32 calen) { printf("%s -> %s\n", FILENAME, __func__); std::list::iterator it; for (it = slot_data.begin(); it != slot_data.end(); ++it) { - if ((*it)->inUse && (*it)->tpid == tpid && (*it)->source == source && !calen) + if ((*it)->liveUse && (*it)->tpid == tpid && (*it)->source == source && !calen) { - (*it)->inUse = false; + (*it)->liveUse = false; return true; } } return false; } -SlotIt cCA::FindFreeSlot(ca_map_t camap, unsigned char scrambled) +bool cCA::StopRecordCI( u64 tpid, u8 source, u32 calen) +{ + printf("%s -> %s\n", FILENAME, __func__); + std::list::iterator it; + for (it = slot_data.begin(); it != slot_data.end(); ++it) + { + if ((*it)->recordUse && (*it)->tpid == tpid && (*it)->source == source && !calen) + { + (*it)->recordUse = false; + return true; + } + } + return false; +} + +SlotIt cCA::FindFreeSlot(u64 tpid, u8 source, ca_map_t camap, unsigned char scrambled) { printf("%s -> %s\n", FILENAME, __func__); std::list::iterator it; ca_map_iterator_t caIt; unsigned int i; + for (it = slot_data.begin(); it != slot_data.end(); ++it) { - if ((*it)->camIsReady && (*it)->hasCAManager && (*it)->hasAppManager && !(*it)->inUse) + if (!scrambled) { continue; } + + if ((*it)->tpid == tpid && (*it)->source == source) + return it; + } + + for (it = slot_data.begin(); it != slot_data.end(); ++it) + { + if (!scrambled) { continue; } + + if ((*it)->bsids.size()) { -#if x_debug - printf("Slot Caids: %d > ", (*it)->cam_caids.size()); - for (i = 0; i < (*it)->cam_caids.size(); i++) - printf("%04x ", (*it)->cam_caids[i]); - printf("\n"); -#endif - (*it)->scrambled = scrambled; - if (scrambled) - { - for (i = 0; i < (*it)->cam_caids.size(); i++) - { - caIt = camap.find((*it)->cam_caids[i]); - if (caIt != camap.end()) - { - printf("Found: %04x\n", *caIt); - return it; - } - else - { - (*it)->scrambled = 0; - } - } - } - else - { - return it; - } + for (i = 0; i < (*it)->bsids.size(); i++) + if ((*it)->bsids[i] == (u16)(tpid & 0xFFFF)) {goto OUT;} + if (i == (*it)->bsids.size()) {(*it)->SidBlackListed = false;} } + if ((*it)->camIsReady && (*it)->hasCAManager && (*it)->hasAppManager && !(*it)->recordUse) + { + if (!checkLiveSlot || (!(*it)->liveUse || ((*it)->liveUse && (*it)->tpid == tpid))) + { +#if x_debug + printf("Slot Caids: %d > ", (*it)->cam_caids.size()); + for (i = 0; i < (*it)->cam_caids.size(); i++) + printf("%04x ", (*it)->cam_caids[i]); + printf("\n"); +#endif + (*it)->scrambled = scrambled; + if (scrambled) + { + for (i = 0; i < (*it)->cam_caids.size(); i++) + { + caIt = camap.find((*it)->cam_caids[i]); + if (caIt != camap.end()) + { + printf("Found: %04x\n", *caIt); + return it; + } + else + { + (*it)->scrambled = 0; + } + } + } + else + { + return it; + } + } + } +OUT: + usleep(0); } return it; } @@ -694,36 +732,48 @@ bool cCA::SendCAPMT(u64 tpid, u8 source_demux, u8 camask, const unsigned char * printf("Mode: %d\n", mode); printf("Enabled: %s\n", enabled ? "START" : "STOP"); #endif - if (mode && scrambled && !enabled) + if (scrambled && !enabled) { - if (StopRecordCI(tpid, source_demux, calen)) - printf("CI set free\n"); + if (mode) + { + if (StopRecordCI(tpid, source_demux, calen)) + printf("Record CI set free\n"); + } + else + { + if (StopLiveCI(tpid, source_demux, calen)) + printf("Live CI set free\n"); + } } if (calen == 0) return true; - SlotIt It = FindFreeSlot(cm, scrambled); + SlotIt It = FindFreeSlot(tpid, source_demux, cm, scrambled); if ((*It)) { printf("Slot: %d\n", (*It)->slot); if (scrambled || (!scrambled && (*It)->source == source_demux)) { - if ((*It)->bsids.size()) + + if (scrambled && enabled && !(*It)->SidBlackListed) { - for (i = 0; i < (*It)->bsids.size(); i++) - if ((*It)->bsids[i] == SID) {(*It)->SidBlackListed = true; break;} - if (i == (*It)->bsids.size()) {(*It)->SidBlackListed = false;} + if (mode) + { + if(!checkLiveSlot) + (*It)->liveUse = false; + (*It)->recordUse = true; + } + else + (*It)->liveUse = true; } - if (mode && scrambled && enabled && !(*It)->SidBlackListed) - (*It)->inUse = true; SlotIt It2 = GetSlot(!(*It)->slot); if ((*It2)) { if (source_demux == (*It2)->source) { - if ((*It2)->inUse) + if ((*It2)->recordUse) (*It)->SidBlackListed = true; else { @@ -733,9 +783,8 @@ bool cCA::SendCAPMT(u64 tpid, u8 source_demux, u8 camask, const unsigned char * } } } - LiveSlot = (*It)->slot; - if ((*It)->tpid != tpid) + if ((*It)->tpid != tpid || (*It)->source != source_demux) { (*It)->tpid = tpid; (*It)->source = source_demux; @@ -743,7 +792,7 @@ bool cCA::SendCAPMT(u64 tpid, u8 source_demux, u8 camask, const unsigned char * for (i = 0; i < calen; i++) (*It)->pmtdata[i] = cabuf[i]; (*It)->newCapmt = true; - } else if ((*It)->ccmgr_ready && (*It)->hasCCManager && (*It)->scrambled && !(*It)->inUse && !(*It)->SidBlackListed) + } else if ((*It)->ccmgr_ready && (*It)->hasCCManager && (*It)->scrambled && !(*It)->SidBlackListed) (*It)->ccmgrSession->resendKey((tSlot*)(*It)); } } @@ -804,7 +853,8 @@ cCA::cCA(int Slots) slot->mmiOpened = false; slot->newCapmt = false; - slot->inUse = false; + slot->recordUse = false; + slot->liveUse = false; slot->tpid = 0; slot->pmtlen = 0; slot->source = TUNER_A; @@ -1118,7 +1168,8 @@ void cCA::slot_pollthread(void *c) slot->cam_caids.clear(); slot->newCapmt = false; - slot->inUse = false; + slot->recordUse = false; + slot->liveUse = false; slot->tpid = 0; slot->pmtlen = 0; slot->source = TUNER_A; @@ -1218,11 +1269,6 @@ bool cCA::SendCaPMT(tSlot* slot) return true; } -unsigned int cCA::GetLiveSlot(void) -{ - return LiveSlot; -} - bool cCA::Init(void) { printf("%s %s\n", FILENAME, __FUNCTION__); @@ -1296,3 +1342,11 @@ bool cCA::checkChannelID(u64 chanID) } return false; } + +void cCA::setCheckLiveSlot(int check) +{ + if (check) + checkLiveSlot = true; + else + checkLiveSlot = false; +} diff --git a/common/ca_ci.h b/common/ca_ci.h index 6f21eed..22dd38a 100644 --- a/common/ca_ci.h +++ b/common/ca_ci.h @@ -194,7 +194,8 @@ typedef struct char name[512]; bool newCapmt; - bool inUse; + bool recordUse; + bool liveUse; u64 tpid; u32 pmtlen; u8 source; @@ -285,7 +286,8 @@ public: unsigned char scrambled = 0, ca_map_t camap = std::set(), int mode = 0, bool enabled = false); bool StopRecordCI( u64 tpid, u8 source, u32 calen); - SlotIt FindFreeSlot(ca_map_t camap, unsigned char scrambled); + bool StopLiveCI( u64 tpid, u8 source, u32 calen); + SlotIt FindFreeSlot(u64 tpid, u8 source, ca_map_t camap, unsigned char scrambled); SlotIt GetSlot(unsigned int slot); bool SendDateTime(void); bool SendCaPMT(tSlot* slot); @@ -295,7 +297,7 @@ public: void process_tpdu(tSlot* slot, unsigned char tpdu_tag, __u8* data, int asn_data_length, int con_id); bool checkChannelID(u64 chanID); - unsigned int GetLiveSlot(void); + void setCheckLiveSlot(int check); bool SendNullPMT(tSlot* slot); bool CheckCerts(void); void Test(int slot, CaIdVector caids); diff --git a/libdvbci/dvbci_ccmgr.cpp b/libdvbci/dvbci_ccmgr.cpp index de0d6c2..9b87df6 100644 --- a/libdvbci/dvbci_ccmgr.cpp +++ b/libdvbci/dvbci_ccmgr.cpp @@ -1337,7 +1337,7 @@ int eDVBCIContentControlManagerSession::doAction() void eDVBCIContentControlManagerSession::resendKey(tSlot *tslot) { - if (!tslot->SidBlackListed && (tslot->inUse || tslot->slot == cCA::GetInstance()->GetLiveSlot())) + if (!tslot->SidBlackListed && (tslot->recordUse || tslot->liveUse)) descrambler_set_key((int)tslot->source, tslot->lastParity, tslot->lastKey); }