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:
parent
f39d31631b
commit
0a5a7893a5
2
HISTORY
2
HISTORY
@ -8938,3 +8938,5 @@ Video Disk Recorder Revision History
|
||||
The members of cEvent have been slightly rearranged to minimize the memory
|
||||
requirements on both 32 and 64 bit systems.
|
||||
- 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.
|
||||
|
82
device.c
82
device.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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"
|
||||
@ -89,8 +89,6 @@ cDevice::cDevice(void)
|
||||
nitFilter = NULL;
|
||||
|
||||
camSlot = NULL;
|
||||
startScrambleDetection = 0;
|
||||
scramblingTimeout = 0;
|
||||
|
||||
occupiedTimeout = 0;
|
||||
|
||||
@ -253,7 +251,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
if (CamSlot->ModuleStatus() == msReady) {
|
||||
if (CamSlot->ProvidesCa(Channel->Caids())) {
|
||||
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++;
|
||||
}
|
||||
}
|
||||
@ -1652,50 +1650,47 @@ bool cDevice::Receiving(bool Dummy) const
|
||||
|
||||
void cDevice::Action(void)
|
||||
{
|
||||
time_t LastScrambledPacket = 0;
|
||||
if (Running() && OpenDvr()) {
|
||||
while (Running()) {
|
||||
// Read data from the DVR device:
|
||||
uchar *b = NULL;
|
||||
if (GetTSPacket(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:
|
||||
Lock();
|
||||
int Pid = TsPid(b);
|
||||
bool IsScrambled = TsIsScrambled(b);
|
||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||
if (receiver[i] && receiver[i]->WantsPid(Pid)) {
|
||||
if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) {
|
||||
dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *receiver[i]->ChannelID().ToString());
|
||||
ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber);
|
||||
Detach(receiver[i]);
|
||||
}
|
||||
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;
|
||||
cReceiver *Receiver = receiver[i];
|
||||
if (Receiver && Receiver->WantsPid(Pid)) {
|
||||
Receiver->Receive(b, TS_SIZE);
|
||||
// Check whether the TS packet is scrambled:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
camSlot->StartDecrypting();
|
||||
if (CamSlots.NumReadyMasterSlots() > 1) { // don't try different CAMs if there is only one
|
||||
startScrambleDetection = time(NULL);
|
||||
scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
|
||||
Receiver->startScrambleDetection = time(NULL);
|
||||
Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
|
||||
bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber());
|
||||
if (KnownToDecrypt)
|
||||
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);
|
||||
Receiver->scramblingTimeout *= 10; // give it time to receive ECM/EMM
|
||||
if (Receiver->ChannelID().Valid())
|
||||
dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout);
|
||||
}
|
||||
}
|
||||
Start();
|
||||
|
4
device.h
4
device.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
@ -426,8 +426,6 @@ public:
|
||||
// Common Interface facilities:
|
||||
|
||||
private:
|
||||
time_t startScrambleDetection;
|
||||
int scramblingTimeout;
|
||||
cCamSlot *camSlot;
|
||||
public:
|
||||
virtual bool HasCi(void);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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"
|
||||
@ -16,6 +16,9 @@ cReceiver::cReceiver(const cChannel *Channel, int Priority)
|
||||
device = NULL;
|
||||
SetPriority(Priority);
|
||||
numPids = 0;
|
||||
lastScrambledPacket = 0;
|
||||
startScrambleDetection = 0;
|
||||
scramblingTimeout = 0;
|
||||
SetPids(Channel);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
@ -22,6 +22,9 @@ private:
|
||||
int priority;
|
||||
int pids[MAXRECEIVEPIDS];
|
||||
int numPids;
|
||||
time_t lastScrambledPacket;
|
||||
time_t startScrambleDetection;
|
||||
int scramblingTimeout;
|
||||
bool WantsPid(int Pid);
|
||||
protected:
|
||||
cDevice *Device(void) { return device; }
|
||||
|
Loading…
Reference in New Issue
Block a user