1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed detecting whether a CAM replies to queries

This commit is contained in:
Klaus Schmidinger 2017-06-19 12:16:40 +02:00
parent 70f48e6ca3
commit 95947a29d5
3 changed files with 25 additions and 13 deletions

View File

@ -3503,3 +3503,7 @@ Sergey Chernyavskiy <glenvt18@gmail.com>
Frank Richter <kulpstur@t-online.de> Frank Richter <kulpstur@t-online.de>
for adding 'S3W ABS-3A' to sources.conf for adding 'S3W ABS-3A' to sources.conf
Daniel Scheller <d.scheller@gmx.net>
for reporting a problem with detecting whether a CAM replies to queries, which didn't
work on some systems since the implementation of RI_HOST_CONTROL

View File

@ -9130,6 +9130,8 @@ Video Disk Recorder Revision History
before including tools.h in case some plugin needs to use the STL and gets error before including tools.h in case some plugin needs to use the STL and gets error
messages regarding one of the template functions defined in tools.h. messages regarding one of the template functions defined in tools.h.
2017-06-12: Version 2.3.8 2017-06-19: Version 2.3.8
- Updated links in the INSTALL file (thanks to Chris Mayo). - Updated links in the INSTALL file (thanks to Chris Mayo).
- Fixed detecting whether a CAM replies to queries, which didn't work on some systems
since the implementation of RI_HOST_CONTROL (reported by Daniel Scheller).

18
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 4.17 2017/06/10 11:53:39 kls Exp $ * $Id: ci.c 4.18 2017/06/19 12:13:38 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -1041,8 +1041,9 @@ void cCiCaPmt::MtdMapPids(cMtdMapper *MtdMapper)
#define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0) #define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0)
#define QUERY_WAIT_TIME 1000 // ms to wait before sending a query #define QUERY_WAIT_TIME 500 // ms to wait before sending a query
#define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query #define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query
#define QUERY_RETRIES 6 // max. number of retries to check if there is a reply to a query
class cCiConditionalAccessSupport : public cCiSession { class cCiConditionalAccessSupport : public cCiSession {
private: private:
@ -1051,6 +1052,7 @@ private:
int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
bool repliesToQuery; bool repliesToQuery;
cTimeMs timer; cTimeMs timer;
int numRetries;
public: public:
cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc); cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc);
virtual void Process(int Length = 0, const uint8_t *Data = NULL); virtual void Process(int Length = 0, const uint8_t *Data = NULL);
@ -1069,6 +1071,7 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(uint16_t SessionId, cCi
state = 0; // inactive state = 0; // inactive
caSystemIds[numCaSystemIds = 0] = 0; caSystemIds[numCaSystemIds = 0] = 0;
repliesToQuery = false; repliesToQuery = false;
numRetries = 0;
} }
void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data) void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
@ -1098,7 +1101,8 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
caSystemIds[numCaSystemIds] = 0; caSystemIds[numCaSystemIds] = 0;
dbgprotocol("\n"); dbgprotocol("\n");
if (state == 1) { if (state == 1) {
timer.Set(QUERY_WAIT_TIME); // WORKAROUND: Alphacrypt 3.09 doesn't reply to QUERY immediately after reset timer.Set(0);
numRetries = QUERY_RETRIES;
state = 2; // got ca info state = 2; // got ca info
} }
dsyslog("CAM %d: system ids:%s", CamSlot()->SlotNumber(), *Ids ? *Ids : " none"); dsyslog("CAM %d: system ids:%s", CamSlot()->SlotNumber(), *Ids ? *Ids : " none");
@ -1171,17 +1175,19 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
SendData(AOT_CA_INFO_ENQ); SendData(AOT_CA_INFO_ENQ);
state = 1; // enquired ca info state = 1; // enquired ca info
} }
else if (state == 2 && timer.TimedOut()) { else if ((state == 2 || state == 3) && timer.TimedOut()) {
if (numRetries-- > 0) {
cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL); cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL);
SendPMT(&CaPmt); SendPMT(&CaPmt);
timer.Set(QUERY_REPLY_TIMEOUT); timer.Set(QUERY_WAIT_TIME);
state = 3; // waiting for reply state = 3; // waiting for reply
} }
else if (state == 3 && timer.TimedOut()) { else {
dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber()); dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber());
state = 4; // normal operation state = 4; // normal operation
} }
} }
}
void cCiConditionalAccessSupport::SendPMT(cCiCaPmt *CaPmt) void cCiConditionalAccessSupport::SendPMT(cCiCaPmt *CaPmt)
{ {