Mapping PIDs in CanDecrypt(); improved description of Start-/StopDecrypting(); removed obsolete cMtdCamSlot::IsDecrypting(); fixed getting device fpr channel up/down

This commit is contained in:
Klaus Schmidinger 2017-03-23 14:34:53 +01:00
parent b7be7c900a
commit 2d9eb7e25d
5 changed files with 55 additions and 35 deletions

14
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.7 2017/03/18 15:20:27 kls Exp $ * $Id: ci.c 4.8 2017/03/23 14:30:56 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -2205,6 +2205,8 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M
} }
} }
} }
else if (CmdId == CPCI_NOT_SELECTED)
CaPmtList.Add(CmdId, 0, 0, 0, NULL);
} }
} }
@ -2343,7 +2345,7 @@ void cCamSlot::AddChannel(const cChannel *Channel)
#define QUERY_REPLY_WAIT 100 // ms to wait between checks for a reply #define QUERY_REPLY_WAIT 100 // ms to wait between checks for a reply
bool cCamSlot::CanDecrypt(const cChannel *Channel) bool cCamSlot::CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper)
{ {
if (Channel->Ca() < CA_ENCRYPTED_MIN) if (Channel->Ca() < CA_ENCRYPTED_MIN)
return true; // channel not encrypted return true; // channel not encrypted
@ -2361,6 +2363,8 @@ bool cCamSlot::CanDecrypt(const cChannel *Channel)
CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE);
for (const int *Spid = Channel->Spids(); *Spid; Spid++) for (const int *Spid = Channel->Spids(); *Spid; Spid++)
CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE);
if (MtdMapper)
CaPmt.MtdMapPids(MtdMapper);
cas->SendPMT(&CaPmt); cas->SendPMT(&CaPmt);
cTimeMs Timeout(QUERY_REPLY_TIMEOUT); cTimeMs Timeout(QUERY_REPLY_TIMEOUT);
do { do {
@ -2385,7 +2389,11 @@ void cCamSlot::StartDecrypting(void)
void cCamSlot::StopDecrypting(void) void cCamSlot::StopDecrypting(void)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
caProgramList.Clear(); if (caProgramList.Count()) {
caProgramList.Clear();
if (!dynamic_cast<cMtdCamSlot *>(this))
SendCaPmt(CPCI_NOT_SELECTED);
}
} }
bool cCamSlot::IsDecrypting(void) bool cCamSlot::IsDecrypting(void)

15
ci.h
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.h 4.4 2017/03/19 10:48:14 kls Exp $ * $Id: ci.h 4.5 2017/03/23 14:23:33 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -314,7 +314,7 @@ public:
///< If the source or transponder of the channel are different than ///< If the source or transponder of the channel are different than
///< what was given in a previous call to AddChannel(), any previously ///< what was given in a previous call to AddChannel(), any previously
///< added PIDs will be cleared. ///< added PIDs will be cleared.
virtual bool CanDecrypt(const cChannel *Channel); virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper = NULL);
///< Returns true if there is a CAM in this slot that is able to decrypt ///< Returns true if there is a CAM in this slot that is able to decrypt
///< the given Channel (or at least claims to be able to do so). ///< the given Channel (or at least claims to be able to do so).
///< Since the QUERY/REPLY mechanism for CAMs is pretty unreliable (some ///< Since the QUERY/REPLY mechanism for CAMs is pretty unreliable (some
@ -325,11 +325,18 @@ public:
///< to the initial QUERY will perform this check at all. CAMs that never ///< to the initial QUERY will perform this check at all. CAMs that never
///< replied to the initial QUERY are assumed not to be able to handle ///< replied to the initial QUERY are assumed not to be able to handle
///< more than one channel at a time. ///< more than one channel at a time.
///< If MtdMapper is given, all SIDs and PIDs will be mapped accordingly.
virtual void StartDecrypting(void); virtual void StartDecrypting(void);
///< Triggers sending all currently active CA_PMT entries to the CAM, ///< Sends all CA_PMT entries to the CAM that have been modified since the
///< so that it will start decrypting. ///< last call to this function. This includes CA_PMTs that have been
///< added or activated, as well as ones that have been deactivated.
///< StartDecrypting() will be called whenever a PID is activated or
///< deactivated.
virtual void StopDecrypting(void); virtual void StopDecrypting(void);
///< Clears the list of CA_PMT entries and tells the CAM to stop decrypting. ///< Clears the list of CA_PMT entries and tells the CAM to stop decrypting.
///< Note that this function is only called when there are no more PIDs for
///< the CAM to decrypt. There is no symmetry between StartDecrypting() and
///< StopDecrypting().
virtual bool IsDecrypting(void); virtual bool IsDecrypting(void);
///< Returns true if the CAM in this slot is currently used for decrypting. ///< Returns true if the CAM in this slot is currently used for decrypting.
virtual uchar *Decrypt(uchar *Data, int &Count); virtual uchar *Decrypt(uchar *Data, int &Count);

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.8 2017/03/18 15:45:53 kls Exp $ * $Id: device.c 4.9 2017/03/23 14:19:59 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -320,8 +320,8 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (!NumUsableSlots) if (!NumUsableSlots)
break; // no CAM necessary, so just one loop over the devices break; // no CAM necessary, so just one loop over the devices
} }
if (d && !Query) { if (d) {
if (NeedsDetachReceivers) if (!Query && NeedsDetachReceivers)
d->DetachAllReceivers(); d->DetachAllReceivers();
if (s) { if (s) {
// Some of the following statements could probably be combined, but let's keep them // Some of the following statements could probably be combined, but let's keep them
@ -333,9 +333,11 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
} }
else { else {
// device d has a CAM slot, but it's not the right one // device d has a CAM slot, but it's not the right one
d->CamSlot()->Assign(NULL); if (!Query) {
s = s->MtdSpawn(); d->CamSlot()->Assign(NULL);
s->Assign(d); s = s->MtdSpawn();
s->Assign(d);
}
} }
} }
else { else {
@ -343,9 +345,10 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (s->Device() != d) { if (s->Device() != d) {
// CAM slot s is currently assigned to a different device than d // CAM slot s is currently assigned to a different device than d
if (Priority > s->Priority()) { if (Priority > s->Priority()) {
s->Device()->DetachAllReceivers(); if (!Query) {
d->CamSlot()->Assign(NULL); d->CamSlot()->Assign(NULL);
s->Assign(d); s->Assign(d);
}
} }
else { else {
d = NULL; d = NULL;
@ -359,8 +362,10 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
else { else {
if (s != d->CamSlot()) { if (s != d->CamSlot()) {
// device d has a CAM slot, but it's not the right one // device d has a CAM slot, but it's not the right one
d->CamSlot()->Assign(NULL); if (!Query) {
s->Assign(d); d->CamSlot()->Assign(NULL);
s->Assign(d);
}
} }
else { else {
// device d already has a proper CAM slot, so nothing to do here // device d already has a proper CAM slot, so nothing to do here
@ -372,16 +377,20 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
// device d has no CAM slot, ... // device d has no CAM slot, ...
if (s->MtdActive()) { if (s->MtdActive()) {
// ... so we assign s with MTD support // ... so we assign s with MTD support
s = s->MtdSpawn(); if (!Query) {
s->Assign(d); s = s->MtdSpawn();
s->Assign(d);
}
} }
else { else {
// CAM slot s has no MTD support ... // CAM slot s has no MTD support ...
if (s->Device()) { if (s->Device()) {
// ... but it is assigned to a different device, so we reassign it to d // ... but it is assigned to a different device, so we reassign it to d
if (Priority > s->Priority()) { if (Priority > s->Priority()) {
s->Device()->DetachAllReceivers(); if (!Query) {
s->Assign(d); s->Device()->DetachAllReceivers();
s->Assign(d);
}
} }
else { else {
d = NULL; d = NULL;
@ -390,7 +399,8 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
} }
else { else {
// ... and is not assigned to any device, so we just assign it to d // ... and is not assigned to any device, so we just assign it to d
s->Assign(d); if (!Query)
s->Assign(d);
} }
} }
} }

14
mtd.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: mtd.c 1.3 2017/03/19 14:20:22 kls Exp $ * $Id: mtd.c 1.4 2017/03/23 14:34:53 kls Exp $
*/ */
#include "mtd.h" #include "mtd.h"
@ -262,10 +262,9 @@ bool cMtdCamSlot::ProvidesCa(const int *CaSystemIds)
return MasterSlot()->ProvidesCa(CaSystemIds); return MasterSlot()->ProvidesCa(CaSystemIds);
} }
bool cMtdCamSlot::CanDecrypt(const cChannel *Channel) bool cMtdCamSlot::CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper)
{ {
//TODO PID mapping? return MasterSlot()->CanDecrypt(Channel, mtdMapper);
return MasterSlot()->CanDecrypt(Channel);
} }
void cMtdCamSlot::StartDecrypting(void) void cMtdCamSlot::StartDecrypting(void)
@ -277,15 +276,12 @@ void cMtdCamSlot::StartDecrypting(void)
void cMtdCamSlot::StopDecrypting(void) void cMtdCamSlot::StopDecrypting(void)
{ {
cCamSlot::StopDecrypting(); cCamSlot::StopDecrypting();
if (!MasterSlot()->IsDecrypting())
MasterSlot()->StopDecrypting();
mtdMapper->Clear(); mtdMapper->Clear();
clearBuffer = true; clearBuffer = true;
} }
bool cMtdCamSlot::IsDecrypting(void)
{
return cCamSlot::IsDecrypting();
}
uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count) uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count)
{ {
// Send data to CAM: // Send data to CAM:

5
mtd.h
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: mtd.h 1.3 2017/03/19 13:32:48 kls Exp $ * $Id: mtd.h 1.4 2017/03/23 12:48:22 kls Exp $
*/ */
#ifndef __MTD_H #ifndef __MTD_H
@ -166,10 +166,9 @@ public:
cMtdMapper *MtdMapper(void) { return mtdMapper; } cMtdMapper *MtdMapper(void) { return mtdMapper; }
virtual bool RepliesToQuery(void); virtual bool RepliesToQuery(void);
virtual bool ProvidesCa(const int *CaSystemIds); virtual bool ProvidesCa(const int *CaSystemIds);
virtual bool CanDecrypt(const cChannel *Channel); virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper = NULL);
virtual void StartDecrypting(void); virtual void StartDecrypting(void);
virtual void StopDecrypting(void); virtual void StopDecrypting(void);
virtual bool IsDecrypting(void);
virtual uchar *Decrypt(uchar *Data, int &Count); virtual uchar *Decrypt(uchar *Data, int &Count);
int PutData(const uchar *Data, int Count); int PutData(const uchar *Data, int Count);
int PutCat(const uchar *Data, int Count); int PutCat(const uchar *Data, int Count);