diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 14ddedb3..c7f974c2 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3565,6 +3565,7 @@ Daniel Scheller Onur Sentürk for making the MTD mapper avoid immediately reusing unique PIDs when switching channels + for fixing handling shared CA pids Helmut Binder for improving calculating signal strength and quality diff --git a/HISTORY b/HISTORY index a11eb99e..5ca03181 100644 --- a/HISTORY +++ b/HISTORY @@ -9348,7 +9348,7 @@ Video Disk Recorder Revision History Senzel). - Official release. -2019-03-18: Version 2.4.1 +2019-03-19: Version 2.4.1 - Fixed handling the tfRecording flag in the SVDRP commands MODT and UPDT (reported by Johann Friedrichs). @@ -9389,3 +9389,4 @@ Video Disk Recorder Revision History - Fixed dropping capabilities in case cap_sys_time is not available. - Fixed updating the cursor position when switching channels with the Channel+/- keys while the Channels menu is open. +- Fixed handling shared CA pids (thanks to Onur Sentürk). diff --git a/ci.c b/ci.c index 3edfe12b..a8b065c5 100644 --- a/ci.c +++ b/ci.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 4.22 2018/09/23 10:17:20 kls Exp $ + * $Id: ci.c 4.23 2019/03/19 14:58:06 kls Exp $ */ #include "ci.h" @@ -2505,8 +2505,10 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids) > 0) { if (Active) caPidReceiver->AddPids(CaPids); - else + else { + KeepSharedCaPids(p->programNumber, CaSystemIds, CaPids); caPidReceiver->DelPids(CaPids); + } } } if (RepliesToQuery()) @@ -2522,6 +2524,43 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M } } +void cCamSlot::KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids) +{ + int numPids = 0; + int *pCaPids = CaPids; + while (*pCaPids) { + numPids++; + pCaPids++; + } + if (numPids <= 0) + return; + int CaPids2[MAXRECEIVEPIDS + 1]; + for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) { + if (p->programNumber != ProgramNumber) { + if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids2) > 0) { + int *pCaPids2 = CaPids2; + while (*pCaPids2) { + pCaPids = CaPids; + while (*pCaPids) { + if (*pCaPids == *pCaPids2) { + dsyslog("CAM %d: keeping shared CA pid %d", SlotNumber(), *pCaPids); + // To remove *pCaPids from CaPids we overwrite it with the last valie in the list, and then strip the last value: + *pCaPids = CaPids[numPids - 1]; + numPids--; + CaPids[numPids] = 0; + if (numPids <= 0) + return; + } + else + pCaPids++; + } + pCaPids2++; + } + } + } + } +} + void cCamSlot::SendCaPmts(cCiCaPmtList &CaPmtList) { cMutexLock MutexLock(&mutex); diff --git a/ci.h b/ci.h index 02e59d2e..3db0340a 100644 --- a/ci.h +++ b/ci.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.h 4.12 2018/03/17 12:17:37 kls Exp $ + * $Id: ci.h 4.13 2019/03/19 14:58:00 kls Exp $ */ #ifndef __CI_H @@ -254,6 +254,7 @@ private: cList caProgramList; bool mtdAvailable; cMtdHandler *mtdHandler; + void KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids); void NewConnection(void); void DeleteAllConnections(void); void Process(cTPDU *TPDU = NULL);