mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
The channel/CAM relations are now stored in the file 'cam.data'; fixed a flaw in handling timeouts for encrypted channels
This commit is contained in:
parent
882273d508
commit
d1ddb39781
@ -3383,6 +3383,7 @@ Dietmar Spingler <d_spingler@gmx.de>
|
|||||||
for suggesting to provide a way of using no DVB devices at all
|
for suggesting to provide a way of using no DVB devices at all
|
||||||
for suggesting that the -V and -h options should list the plugins in alphabetical order
|
for suggesting that the -V and -h options should list the plugins in alphabetical order
|
||||||
for suggesting to implement the setup option "Recording/Record key handling"
|
for suggesting to implement the setup option "Recording/Record key handling"
|
||||||
|
for suggesting to cache the channel/CAM relations in the file 'cam.data'
|
||||||
|
|
||||||
Stefan Schallenberg <infos@nafets.de>
|
Stefan Schallenberg <infos@nafets.de>
|
||||||
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
|
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
|
||||||
|
8
HISTORY
8
HISTORY
@ -8882,10 +8882,16 @@ Video Disk Recorder Revision History
|
|||||||
- Added a short sleep to cTSBuffer::Action() to avoid high CPU usage (thanks to
|
- Added a short sleep to cTSBuffer::Action() to avoid high CPU usage (thanks to
|
||||||
Sergey Chernyavskiy).
|
Sergey Chernyavskiy).
|
||||||
|
|
||||||
2017-01-08: Version 2.3.3
|
2017-01-09: Version 2.3.3
|
||||||
|
|
||||||
- Added 'S3W ABS-3A' to sources.conf (thanks to Frank Richter).
|
- Added 'S3W ABS-3A' to sources.conf (thanks to Frank Richter).
|
||||||
- Fixed a possible deadlock in the recordings handler thread.
|
- Fixed a possible deadlock in the recordings handler thread.
|
||||||
- Updated the Russian OSD texts (thanks to Andrey Pridvorov).
|
- Updated the Russian OSD texts (thanks to Andrey Pridvorov).
|
||||||
- Added a missing dependency to the Makefile to avoid error messages in the
|
- Added a missing dependency to the Makefile to avoid error messages in the
|
||||||
clean-plugins target (thanks to Tobias Grimm).
|
clean-plugins target (thanks to Tobias Grimm).
|
||||||
|
- The channel/CAM relations (i.e. the information which CAM can decrypt a given
|
||||||
|
channel) are now stored in the file 'cam.data' in the cache directory (suggested
|
||||||
|
by Dietmar Spingler). This speeds up switching to encrypted channels after
|
||||||
|
newly starting VDR, in case there is more than one CAM in the system.
|
||||||
|
- Fixed a flaw in handling timeouts for encrypted channels.
|
||||||
|
|
||||||
|
61
ci.c
61
ci.c
@ -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.3 2016/12/23 14:00:45 kls Exp $
|
* $Id: ci.c 4.4 2017/01/09 12:51:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ci.h"
|
#include "ci.h"
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -2317,6 +2318,7 @@ void cChannelCamRelation::ClrDecrypt(int CamSlotNumber)
|
|||||||
|
|
||||||
// --- cChannelCamRelations --------------------------------------------------
|
// --- cChannelCamRelations --------------------------------------------------
|
||||||
|
|
||||||
|
#define MAX_CAM_NUMBER 32
|
||||||
#define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL 3600 // seconds between cleanups
|
#define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL 3600 // seconds between cleanups
|
||||||
|
|
||||||
cChannelCamRelations ChannelCamRelations;
|
cChannelCamRelations ChannelCamRelations;
|
||||||
@ -2414,3 +2416,60 @@ void cChannelCamRelations::ClrDecrypt(tChannelID ChannelID, int CamSlotNumber)
|
|||||||
if (ccr)
|
if (ccr)
|
||||||
ccr->ClrDecrypt(CamSlotNumber);
|
ccr->ClrDecrypt(CamSlotNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cChannelCamRelations::Load(const char *FileName)
|
||||||
|
{
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
|
fileName = FileName;
|
||||||
|
if (access(fileName, R_OK) == 0) {
|
||||||
|
dsyslog("loading %s", *fileName);
|
||||||
|
if (FILE *f = fopen(fileName, "r")) {
|
||||||
|
cReadLine ReadLine;
|
||||||
|
char *s;
|
||||||
|
while ((s = ReadLine.Read(f)) != NULL) {
|
||||||
|
if (char *p = strchr(s, ' ')) {
|
||||||
|
*p = 0;
|
||||||
|
if (*++p) {
|
||||||
|
tChannelID ChannelID = tChannelID::FromString(s);
|
||||||
|
if (ChannelID.Valid()) {
|
||||||
|
char *q;
|
||||||
|
char *strtok_next;
|
||||||
|
while ((q = strtok_r(p, " ", &strtok_next)) != NULL) {
|
||||||
|
int CamSlotNumber = atoi(q);
|
||||||
|
if (CamSlotNumber >= 1 && CamSlotNumber <= MAX_CAM_NUMBER)
|
||||||
|
SetDecrypt(ChannelID, CamSlotNumber);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_ERROR_STR(*fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cChannelCamRelations::Save(void)
|
||||||
|
{
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
|
dsyslog("saving %s", *fileName);
|
||||||
|
cSafeFile f(fileName);
|
||||||
|
if (f.Open()) {
|
||||||
|
for (cChannelCamRelation *ccr = First(); ccr; ccr = Next(ccr)) {
|
||||||
|
if (ccr->ChannelID().Valid()) {
|
||||||
|
cString s;
|
||||||
|
for (int i = 1; i <= MAX_CAM_NUMBER; i++) {
|
||||||
|
if (ccr->CamDecrypt(i))
|
||||||
|
s = cString::sprintf("%s%s%d", *s ? *s : "", *s ? " " : "", i);
|
||||||
|
}
|
||||||
|
if (*s)
|
||||||
|
fprintf(f, "%s %s\n", *ccr->ChannelID().ToString(), *s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_ERROR_STR(*fileName);
|
||||||
|
}
|
||||||
|
5
ci.h
5
ci.h
@ -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.h 3.11 2015/01/31 14:36:41 kls Exp $
|
* $Id: ci.h 4.1 2017/01/09 12:51:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CI_H
|
#ifndef __CI_H
|
||||||
@ -310,6 +310,7 @@ class cChannelCamRelation;
|
|||||||
class cChannelCamRelations : public cList<cChannelCamRelation> {
|
class cChannelCamRelations : public cList<cChannelCamRelation> {
|
||||||
private:
|
private:
|
||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
|
cString fileName;
|
||||||
cChannelCamRelation *GetEntry(tChannelID ChannelID);
|
cChannelCamRelation *GetEntry(tChannelID ChannelID);
|
||||||
cChannelCamRelation *AddEntry(tChannelID ChannelID);
|
cChannelCamRelation *AddEntry(tChannelID ChannelID);
|
||||||
time_t lastCleanup;
|
time_t lastCleanup;
|
||||||
@ -323,6 +324,8 @@ public:
|
|||||||
void SetDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
void SetDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
||||||
void ClrChecked(tChannelID ChannelID, int CamSlotNumber);
|
void ClrChecked(tChannelID ChannelID, int CamSlotNumber);
|
||||||
void ClrDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
void ClrDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
||||||
|
void Load(const char *FileName);
|
||||||
|
void Save(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern cChannelCamRelations ChannelCamRelations;
|
extern cChannelCamRelations ChannelCamRelations;
|
||||||
|
27
device.c
27
device.c
@ -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.3 2016/12/23 14:43:44 kls Exp $
|
* $Id: device.c 4.4 2017/01/09 12:51:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -90,6 +90,7 @@ cDevice::cDevice(void)
|
|||||||
|
|
||||||
camSlot = NULL;
|
camSlot = NULL;
|
||||||
startScrambleDetection = 0;
|
startScrambleDetection = 0;
|
||||||
|
scramblingTimeout = 0;
|
||||||
|
|
||||||
occupiedTimeout = 0;
|
occupiedTimeout = 0;
|
||||||
|
|
||||||
@ -1574,6 +1575,7 @@ 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:
|
||||||
@ -1590,15 +1592,16 @@ void cDevice::Action(void)
|
|||||||
cs = CamSlot();
|
cs = CamSlot();
|
||||||
CamSlotNumber = cs ? cs->SlotNumber() : 0;
|
CamSlotNumber = cs ? cs->SlotNumber() : 0;
|
||||||
if (CamSlotNumber) {
|
if (CamSlotNumber) {
|
||||||
int t = time(NULL) - startScrambleDetection;
|
if (LastScrambledPacket < startScrambleDetection)
|
||||||
|
LastScrambledPacket = startScrambleDetection;
|
||||||
|
time_t Now = time(NULL);
|
||||||
if (TsIsScrambled(b)) {
|
if (TsIsScrambled(b)) {
|
||||||
if (t > TS_SCRAMBLING_TIMEOUT)
|
LastScrambledPacket = Now;
|
||||||
|
if (Now - startScrambleDetection > scramblingTimeout)
|
||||||
DetachReceivers = true;
|
DetachReceivers = true;
|
||||||
}
|
}
|
||||||
else if (t > TS_SCRAMBLING_TIME_OK) {
|
if (Now - LastScrambledPacket > TS_SCRAMBLING_TIME_OK)
|
||||||
DescramblingOk = true;
|
DescramblingOk = true;
|
||||||
startScrambleDetection = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Distribute the packet to all attached receivers:
|
// Distribute the packet to all attached receivers:
|
||||||
@ -1606,14 +1609,17 @@ void cDevice::Action(void)
|
|||||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||||
if (receiver[i] && receiver[i]->WantsPid(Pid)) {
|
if (receiver[i] && receiver[i]->WantsPid(Pid)) {
|
||||||
if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) {
|
if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) {
|
||||||
dsyslog("detaching receiver - won't decrypt channel %s with CAM %d", *receiver[i]->ChannelID().ToString(), CamSlotNumber);
|
dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *receiver[i]->ChannelID().ToString());
|
||||||
ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber);
|
ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber);
|
||||||
Detach(receiver[i]);
|
Detach(receiver[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
receiver[i]->Receive(b, TS_SIZE);
|
receiver[i]->Receive(b, TS_SIZE);
|
||||||
if (DescramblingOk)
|
if (DescramblingOk) {
|
||||||
|
dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *receiver[i]->ChannelID().ToString());
|
||||||
ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
|
ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
|
||||||
|
startScrambleDetection = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Unlock();
|
Unlock();
|
||||||
@ -1673,6 +1679,11 @@ 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();
|
||||||
startScrambleDetection = time(NULL);
|
startScrambleDetection = time(NULL);
|
||||||
|
scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
|
||||||
|
bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->SlotNumber());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
Start();
|
Start();
|
||||||
return true;
|
return true;
|
||||||
|
3
device.h
3
device.h
@ -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.2 2016/12/06 14:12:39 kls Exp $
|
* $Id: device.h 4.3 2017/01/09 12:51:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DEVICE_H
|
#ifndef __DEVICE_H
|
||||||
@ -425,6 +425,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
time_t startScrambleDetection;
|
time_t startScrambleDetection;
|
||||||
|
int scramblingTimeout;
|
||||||
cCamSlot *camSlot;
|
cCamSlot *camSlot;
|
||||||
public:
|
public:
|
||||||
virtual bool HasCi(void);
|
virtual bool HasCi(void);
|
||||||
|
16
vdr.5
16
vdr.5
@ -8,7 +8,7 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.5 3.4 2015/02/17 13:43:53 kls Exp $
|
.\" $Id: vdr.5 4.1 2017/01/09 13:35:08 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 5 "19 Feb 2015" "2.2" "Video Disk Recorder Files"
|
.TH vdr 5 "19 Feb 2015" "2.2" "Video Disk Recorder Files"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -899,6 +899,20 @@ Note that the \fBevent id\fR that comes from the DVB data stream is actually
|
|||||||
just 16 bit wide. The internal representation in VDR allows for 32 bit to
|
just 16 bit wide. The internal representation in VDR allows for 32 bit to
|
||||||
be used, so that external tools can generate EPG data that is guaranteed
|
be used, so that external tools can generate EPG data that is guaranteed
|
||||||
not to collide with the ids of existing data.
|
not to collide with the ids of existing data.
|
||||||
|
.SS CAM DATA
|
||||||
|
The file \fIcam.data\fR contains information about which CAM in the system can
|
||||||
|
decrypt a particular channel.
|
||||||
|
Each line in this file contains a channel id, followed by one or more (blank
|
||||||
|
separated) numbers, indicating the CAMs that have successfully decrypted this
|
||||||
|
channel earlier.
|
||||||
|
|
||||||
|
When tuning to an encrypted channel, this information is used to select the
|
||||||
|
proper CAM for decrypting this channel. This channel/CAM relationship is not
|
||||||
|
hardcoded, though. If a given channel can't be decrypted with a CAM listed
|
||||||
|
in this file, other CAMs will be tried just as well. The main purpose of this
|
||||||
|
file is to speed up channel switching in systems with more than one CAM.
|
||||||
|
|
||||||
|
This file will be read at program startup and saved when the program ends.
|
||||||
.SS COMMANDLINE OPTIONS
|
.SS COMMANDLINE OPTIONS
|
||||||
If started without any options, vdr tries to read any files in the directory
|
If started without any options, vdr tries to read any files in the directory
|
||||||
/etc/vdr/conf.d with names that do not begin with a '.' and that end with '.conf'.
|
/etc/vdr/conf.d with names that do not begin with a '.' and that end with '.conf'.
|
||||||
|
7
vdr.c
7
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.tvdr.de
|
* The project's page is at http://www.tvdr.de
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 4.9 2016/12/23 14:34:37 kls Exp $
|
* $Id: vdr.c 4.10 2017/01/09 13:22:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -878,6 +878,10 @@ int main(int argc, char *argv[])
|
|||||||
if (!cPositioner::GetPositioner()) // no plugin has created a positioner
|
if (!cPositioner::GetPositioner()) // no plugin has created a positioner
|
||||||
new cDiseqcPositioner;
|
new cDiseqcPositioner;
|
||||||
|
|
||||||
|
// CAM data:
|
||||||
|
|
||||||
|
ChannelCamRelations.Load(AddDirectory(CacheDirectory, "cam.data"));
|
||||||
|
|
||||||
// Channel:
|
// Channel:
|
||||||
|
|
||||||
if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
|
if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
|
||||||
@ -1555,6 +1559,7 @@ Exit:
|
|||||||
|
|
||||||
StopSVDRPClientHandler();
|
StopSVDRPClientHandler();
|
||||||
StopSVDRPServerHandler();
|
StopSVDRPServerHandler();
|
||||||
|
ChannelCamRelations.Save();
|
||||||
PluginManager.StopPlugins();
|
PluginManager.StopPlugins();
|
||||||
cRecordControls::Shutdown();
|
cRecordControls::Shutdown();
|
||||||
RecordingsHandler.DelAll();
|
RecordingsHandler.DelAll();
|
||||||
|
Loading…
Reference in New Issue
Block a user