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

Detecting whether a particular CAM actually decrypts a given channel is now done separately for each receiver

This commit is contained in:
Klaus Schmidinger 2017-04-02 10:08:49 +02:00
parent f39d31631b
commit 0a5a7893a5
5 changed files with 50 additions and 48 deletions

View File

@ -8938,3 +8938,5 @@ Video Disk Recorder Revision History
The members of cEvent have been slightly rearranged to minimize the memory The members of cEvent have been slightly rearranged to minimize the memory
requirements on both 32 and 64 bit systems. requirements on both 32 and 64 bit systems.
- The file 'cam.data' is no longer written if it is read-only. - The file 'cam.data' is no longer written if it is read-only.
- Detecting whether a particular CAM actually decrypts a given channel is now
done separately for each receiver.

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: device.c 4.11 2017/03/27 14:02:54 kls Exp $ * $Id: device.c 4.12 2017/04/02 10:08:49 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -89,8 +89,6 @@ cDevice::cDevice(void)
nitFilter = NULL; nitFilter = NULL;
camSlot = NULL; camSlot = NULL;
startScrambleDetection = 0;
scramblingTimeout = 0;
occupiedTimeout = 0; occupiedTimeout = 0;
@ -253,7 +251,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (CamSlot->ModuleStatus() == msReady) { if (CamSlot->ModuleStatus() == msReady) {
if (CamSlot->ProvidesCa(Channel->Caids())) { if (CamSlot->ProvidesCa(Channel->Caids())) {
if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->MasterSlotNumber())) { if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->MasterSlotNumber())) {
SlotPriority[CamSlot->Index()] = CamSlot->Priority(); SlotPriority[CamSlot->Index()] = CamSlot->MtdActive() ? IDLEPRIORITY : CamSlot->Priority(); // we don't need to take the priority into account here for MTD CAM slots, because they can be used with several devices in parallel
NumUsableSlots++; NumUsableSlots++;
} }
} }
@ -1652,50 +1650,47 @@ bool cDevice::Receiving(bool Dummy) const
void cDevice::Action(void) void cDevice::Action(void)
{ {
time_t LastScrambledPacket = 0;
if (Running() && OpenDvr()) { if (Running() && OpenDvr()) {
while (Running()) { while (Running()) {
// Read data from the DVR device: // Read data from the DVR device:
uchar *b = NULL; uchar *b = NULL;
if (GetTSPacket(b)) { if (GetTSPacket(b)) {
if (b) { if (b) {
int Pid = TsPid(b);
// Check whether the TS packets are scrambled:
bool DetachReceivers = false;
bool DescramblingOk = false;
int CamSlotNumber = 0;
cCamSlot *cs = NULL;
if (startScrambleDetection) {
cs = CamSlot();
CamSlotNumber = cs ? cs->MasterSlotNumber() : 0;
if (CamSlotNumber) {
if (LastScrambledPacket < startScrambleDetection)
LastScrambledPacket = startScrambleDetection;
time_t Now = time(NULL);
if (TsIsScrambled(b)) {
LastScrambledPacket = Now;
if (Now - startScrambleDetection > scramblingTimeout)
DetachReceivers = true;
}
if (Now - LastScrambledPacket > TS_SCRAMBLING_TIME_OK)
DescramblingOk = true;
}
}
// Distribute the packet to all attached receivers: // Distribute the packet to all attached receivers:
Lock(); Lock();
int Pid = TsPid(b);
bool IsScrambled = TsIsScrambled(b);
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i] && receiver[i]->WantsPid(Pid)) { cReceiver *Receiver = receiver[i];
if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) { if (Receiver && Receiver->WantsPid(Pid)) {
dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *receiver[i]->ChannelID().ToString()); Receiver->Receive(b, TS_SIZE);
ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber); // Check whether the TS packet is scrambled:
Detach(receiver[i]); if (Receiver->startScrambleDetection) {
if (cCamSlot *cs = CamSlot()) {
int CamSlotNumber = cs->MasterSlotNumber();
if (Receiver->lastScrambledPacket < Receiver->startScrambleDetection)
Receiver->lastScrambledPacket = Receiver->startScrambleDetection;
time_t Now = time(NULL);
if (IsScrambled) {
Receiver->lastScrambledPacket = Now;
if (Now - Receiver->startScrambleDetection > Receiver->scramblingTimeout) {
if (!cs->IsActivating() || Receiver->Priority() >= LIVEPRIORITY) {
if (Receiver->ChannelID().Valid()) {
dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *Receiver->ChannelID().ToString());
ChannelCamRelations.SetChecked(Receiver->ChannelID(), CamSlotNumber);
}
Detach(Receiver);
}
}
}
else if (Now - Receiver->lastScrambledPacket > TS_SCRAMBLING_TIME_OK) {
if (Receiver->ChannelID().Valid()) {
dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *Receiver->ChannelID().ToString());
ChannelCamRelations.SetDecrypt(Receiver->ChannelID(), CamSlotNumber);
}
Receiver->startScrambleDetection = 0;
}
} }
else
receiver[i]->Receive(b, TS_SIZE);
if (DescramblingOk && receiver[i]->ChannelID().Valid()) {
dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *receiver[i]->ChannelID().ToString());
ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
startScrambleDetection = 0;
} }
} }
} }
@ -1756,12 +1751,13 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (CamSlots.NumReadyMasterSlots() > 1) { // don't try different CAMs if there is only one if (CamSlots.NumReadyMasterSlots() > 1) { // don't try different CAMs if there is only one
startScrambleDetection = time(NULL); Receiver->startScrambleDetection = time(NULL);
scramblingTimeout = TS_SCRAMBLING_TIMEOUT; Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber()); bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber());
if (KnownToDecrypt) if (KnownToDecrypt)
scramblingTimeout *= 10; // give it time to receive ECM/EMM Receiver->scramblingTimeout *= 10; // give it time to receive ECM/EMM
dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->SlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), scramblingTimeout); if (Receiver->ChannelID().Valid())
dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout);
} }
} }
Start(); Start();

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: device.h 4.4 2017/02/21 13:23:24 kls Exp $ * $Id: device.h 4.5 2017/04/02 10:08:49 kls Exp $
*/ */
#ifndef __DEVICE_H #ifndef __DEVICE_H
@ -426,8 +426,6 @@ public:
// Common Interface facilities: // Common Interface facilities:
private: private:
time_t startScrambleDetection;
int scramblingTimeout;
cCamSlot *camSlot; cCamSlot *camSlot;
public: public:
virtual bool HasCi(void); virtual bool HasCi(void);

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: receiver.c 4.2 2017/02/21 10:59:27 kls Exp $ * $Id: receiver.c 4.3 2017/04/02 10:08:49 kls Exp $
*/ */
#include "receiver.h" #include "receiver.h"
@ -16,6 +16,9 @@ cReceiver::cReceiver(const cChannel *Channel, int Priority)
device = NULL; device = NULL;
SetPriority(Priority); SetPriority(Priority);
numPids = 0; numPids = 0;
lastScrambledPacket = 0;
startScrambleDetection = 0;
scramblingTimeout = 0;
SetPids(Channel); SetPids(Channel);
} }

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: receiver.h 4.1 2015/09/05 11:42:47 kls Exp $ * $Id: receiver.h 4.2 2017/04/02 10:08:49 kls Exp $
*/ */
#ifndef __RECEIVER_H #ifndef __RECEIVER_H
@ -22,6 +22,9 @@ private:
int priority; int priority;
int pids[MAXRECEIVEPIDS]; int pids[MAXRECEIVEPIDS];
int numPids; int numPids;
time_t lastScrambledPacket;
time_t startScrambleDetection;
int scramblingTimeout;
bool WantsPid(int Pid); bool WantsPid(int Pid);
protected: protected:
cDevice *Device(void) { return device; } cDevice *Device(void) { return device; }