summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY2
-rw-r--r--device.c82
-rw-r--r--device.h4
-rw-r--r--receiver.c5
-rw-r--r--receiver.h5
5 files changed, 50 insertions, 48 deletions
diff --git a/HISTORY b/HISTORY
index dd2fd0fc..0350a500 100644
--- a/HISTORY
+++ b/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.
diff --git a/device.c b/device.c
index 247e8c56..1c7f2225 100644
--- a/device.c
+++ b/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();
diff --git a/device.h b/device.h
index 581c187a..7e3592b1 100644
--- a/device.h
+++ b/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);
diff --git a/receiver.c b/receiver.c
index dd61fd65..ef3a5cd1 100644
--- a/receiver.c
+++ b/receiver.c
@@ -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);
}
diff --git a/receiver.h b/receiver.h
index 09da8cda..0ba8cb44 100644
--- a/receiver.h
+++ b/receiver.h
@@ -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; }