From 91b9bb6c9ec37ea6651fdbf09d24d2012ba0f51d Mon Sep 17 00:00:00 2001 From: max10 Date: Wed, 18 Nov 2015 17:16:23 +0100 Subject: [PATCH] test c** --- common/ca_ci.cpp | 74 +++++++++++++++++++++++++++++++--------- common/ca_ci.h | 3 ++ libdvbci/descrambler.cpp | 65 ++++++++++++++++++++++------------- libdvbci/descrambler.h | 5 ++- libdvbci/dvbci_ccmgr.cpp | 13 ++----- 5 files changed, 109 insertions(+), 51 deletions(-) diff --git a/common/ca_ci.cpp b/common/ca_ci.cpp index e8c26bb..d4dcd53 100644 --- a/common/ca_ci.cpp +++ b/common/ca_ci.cpp @@ -37,6 +37,9 @@ #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_CA, this, args) static const char * FILENAME = "[ca_ci]"; +static unsigned int LiveSlot = 0; +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, +0x00,0x06,0x15,0x80,0x00,0x00,0x06,0x15,0x82,0x00,0x00,0x0B,0x08,0x7B,0x00,0x00,0x05,0x09,0x42,0x00,0x00,0x06,0x15,0x81,0x00,0x00}; /* für callback */ /* nur diese Message wird vom CI aus neutrinoMessages.h benutzt */ @@ -699,15 +702,6 @@ bool cCA::SendCAPMT(u64 tpid, u8 source_demux, u8 camask, const unsigned char * printf("Slot: %d\n", (*It)->slot); if (scrambled || (!scrambled && (*It)->source == source_demux)) { - if ((*It)->tpid != tpid) - { - (*It)->tpid = tpid; - (*It)->source = source_demux; - (*It)->pmtlen = calen; - for (i = 0; i < calen; i++) - (*It)->pmtdata[i] = cabuf[i]; - (*It)->newCapmt = true; - } if ((*It)->bsids.size()) { for (i = 0; i < (*It)->bsids.size(); i++) @@ -716,6 +710,34 @@ bool cCA::SendCAPMT(u64 tpid, u8 source_demux, u8 camask, const unsigned char * } if (mode && scrambled && enabled && !(*It)->SidBlackListed) (*It)->inUse = true; + + SlotIt It2 = GetSlot(!(*It)->slot); + if ((*It2)) + { + if ((*It)->source == (*It2)->source || source_demux == (*It2)->source) + { + if ((*It2)->inUse) + (*It)->SidBlackListed = true; + else + { + SendNullPMT((tSlot*)(*It2)); + (*It2)->tpid = 0; + (*It2)->scrambled = 0; + } + } + } + LiveSlot = (*It)->slot; + + if ((*It)->tpid != tpid) + { + (*It)->tpid = tpid; + (*It)->source = source_demux; + (*It)->pmtlen = calen; + 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) + (*It)->ccmgrSession->resendKey((tSlot*)(*It)); } } else @@ -1154,13 +1176,8 @@ void cCA::slot_pollthread(void *c) { SendCaPMT(slot); slot->newCapmt = false; - if (slot->ccmgr_ready && slot->hasCCManager) - { - if (slot->scrambled) - { - slot->ccmgrSession->resendKey(slot); - } - } + if (slot->ccmgr_ready && slot->hasCCManager && slot->scrambled) + slot->ccmgrSession->resendKey(slot); } } } @@ -1193,6 +1210,11 @@ bool cCA::SendCaPMT(tSlot* slot) return true; } +unsigned int cCA::GetLiveSlot(void) +{ + return LiveSlot; +} + bool cCA::Init(void) { printf("%s %s\n", FILENAME, __FUNCTION__); @@ -1225,3 +1247,23 @@ void cCA::SetInitMask(enum CA_INIT_MASK p) { printf("%s %s param:%d\n", FILENAME, __FUNCTION__, (int)p); } + +SlotIt cCA::GetSlot(unsigned int slot) +{ + std::list::iterator it; + for (it = slot_data.begin(); it != slot_data.end(); ++it) + if ((*it)->slot == slot && (*it)->ccmgr_ready && (*it)->hasCCManager && (*it)->scrambled) + return it; + return it; +} + +bool cCA::SendNullPMT(tSlot* slot) +{ + printf("%s > %s >**\n", FILENAME, __func__); + if ((slot->fd > 0) && (slot->camIsReady) && (slot->hasCAManager)) + { + slot->camgrSession->sendSPDU(0x90, 0, 0, NullPMT, 50); + } + return true; +} + diff --git a/common/ca_ci.h b/common/ca_ci.h index 0739c9f..2e7e470 100644 --- a/common/ca_ci.h +++ b/common/ca_ci.h @@ -286,6 +286,7 @@ public: bool StopRecordCI( u64 tpid, u8 source, u32 calen); SlotIt FindFreeSlot(ca_map_t camap, unsigned char scrambled); + SlotIt GetSlot(unsigned int slot); bool SendDateTime(void); bool SendCaPMT(tSlot* slot); void slot_pollthread(void *c); @@ -293,6 +294,8 @@ public: bool checkQueueSize(tSlot* slot); void process_tpdu(tSlot* slot, unsigned char tpdu_tag, __u8* data, int asn_data_length, int con_id); + unsigned int GetLiveSlot(void); + bool SendNullPMT(tSlot* slot); void Test(int slot, CaIdVector caids); void DelTest(int slot); /// Virtual destructor diff --git a/libdvbci/descrambler.cpp b/libdvbci/descrambler.cpp index ec4828c..ca71db0 100644 --- a/libdvbci/descrambler.cpp +++ b/libdvbci/descrambler.cpp @@ -11,7 +11,9 @@ static const char * FILENAME = "[descrambler]"; -static int desc_fd; +static const char *descrambler_filename = "/dev/dvb/adapter0/ca3"; +static int desc_fd = -1; +static int desc_user_count = 0; /* Byte 0 to 15 are AES Key, Byte 16 to 31 are IV */ @@ -23,22 +25,28 @@ int descrambler_set_key(int index, int parity, unsigned char *data) index |= 0x100; - d.index = index; - d.parity = (ca_descr_parity)parity; - d.data_type = CA_DATA_KEY; - d.length = 32; - d.data = data; - - printf("Index: %d Parity: (%d) -> ", d.index, d.parity); - hexdump(d.data, 32); - - if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d)) + if (descrambler_open()) { - //printf("CA_SET_DESCR_DATA\n"); + d.index = index; + d.parity = (ca_descr_parity)parity; + d.data_type = CA_DATA_KEY; + d.length = 32; + d.data = data; + + printf("Index: %d Parity: (%d) -> ", d.index, d.parity); + hexdump(d.data, 32); + + if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d)) + { + //printf("CA_SET_DESCR_DATA\n"); + } + descrambler_close(); } return 0; } +/* we don't use this for ci cam ! */ +/* int descrambler_set_pid(int index, int enable, int pid) { struct ca_pid p; @@ -54,23 +62,34 @@ int descrambler_set_pid(int index, int enable, int pid) return 0; } +*/ + +bool descrambler_open(void) +{ + desc_fd = open(descrambler_filename, O_RDWR | O_NONBLOCK ); + if (desc_fd <= 0) { + printf("cannot open %s\n", descrambler_filename); + return false; + } + return true; +} + +void descrambler_close(void) +{ + close(desc_fd); + desc_fd = -1; +} int descrambler_init(void) { - const char *filename = "/dev/dvb/adapter0/ca3"; - - printf("%s -> %s\n", FILENAME, __FUNCTION__); - - desc_fd = open(filename, O_RDWR | O_NONBLOCK ); - if (desc_fd <= 0) { - printf("cannot open %s\n", filename); - return -1; - } - + desc_user_count++; + printf("%s -> %s %d\n", FILENAME, __FUNCTION__, desc_user_count); return 0; } void descrambler_deinit(void) { - close(desc_fd); + desc_user_count--; + if (desc_user_count <= 0 && desc_fd > 0) + descrambler_close(); } diff --git a/libdvbci/descrambler.h b/libdvbci/descrambler.h index fd2a89d..1e42aa9 100644 --- a/libdvbci/descrambler.h +++ b/libdvbci/descrambler.h @@ -3,7 +3,10 @@ int descrambler_init(void); void descrambler_deinit(void); +bool descrambler_open(void); +void descrambler_close(void); int descrambler_set_key(int index, int parity, unsigned char *data); -int descrambler_set_pid(int index, int enable, int pid); +/* we don't use this for ci cam ! */ +//int descrambler_set_pid(int index, int enable, int pid); #endif diff --git a/libdvbci/dvbci_ccmgr.cpp b/libdvbci/dvbci_ccmgr.cpp index afc7dd0..e06d942 100644 --- a/libdvbci/dvbci_ccmgr.cpp +++ b/libdvbci/dvbci_ccmgr.cpp @@ -1029,7 +1029,6 @@ bool eDVBCIContentControlManagerSession::data_initialize(tSlot *tslot) printf("%s -> %s\n", FILENAME, __FUNCTION__); -// if (session->private_data) { if (tslot->private_data) { fprintf(stderr, "strange private_data not null!\n"); return false; @@ -1042,7 +1041,6 @@ bool eDVBCIContentControlManagerSession::data_initialize(tSlot *tslot) } /* parent */ -// data->session = session; data->slot = tslot; /* clear storage of credentials */ @@ -1267,15 +1265,8 @@ eDVBCIContentControlManagerSession::~eDVBCIContentControlManagerSession() void eDVBCIContentControlManagerSession::ci_ccmgr_doClose(tSlot *tslot) { struct cc_ctrl_data *data = (struct cc_ctrl_data*)(tslot->private_data); - uint8_t clearData[32]; printf("%s -> %s\n", FILENAME, __FUNCTION__); - printf("close content_control\n"); - for (int i = 0; i < 32; i++) - clearData[i] = 0; - descrambler_set_key((int)data->slot->source, 0, clearData); - descrambler_set_key((int)data->slot->source, 1, clearData); - descrambler_deinit(); element_init(data); @@ -1295,7 +1286,7 @@ int eDVBCIContentControlManagerSession::receivedAPDU(const unsigned char *tag, c switch (tag[2]) { case 0x01: ci_ccmgr_cc_open_cnf(slot); break; case 0x03: ci_ccmgr_cc_data_req(slot, (const uint8_t*)data, len); break; - case 0x05: ci_ccmgr_cc_sync_req(); slot->ccmgr_ready = false; break; + case 0x05: ci_ccmgr_cc_sync_req(); break; case 0x07: ci_ccmgr_cc_sac_data_req(slot, (const uint8_t*)data, len); break; case 0x09: ci_ccmgr_cc_sac_sync_req(slot, (const uint8_t*)data, len); break; default: @@ -1327,7 +1318,7 @@ int eDVBCIContentControlManagerSession::doAction() void eDVBCIContentControlManagerSession::resendKey(tSlot *tslot) { - if (!tslot->SidBlackListed) + if (!tslot->SidBlackListed && (tslot->inUse || tslot->slot == cCA::GetInstance()->GetLiveSlot())) descrambler_set_key((int)tslot->source, tslot->lastParity, tslot->lastKey); }