mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Now only those Ca descriptors are sent to a CAM that are actually understood by that CAM
This commit is contained in:
parent
b57eae00d3
commit
78d85cee06
2
HISTORY
2
HISTORY
@ -2039,3 +2039,5 @@ Video Disk Recorder Revision History
|
|||||||
- Using masks in EIT filtering to reduce the number of filters (thanks to Andreas
|
- Using masks in EIT filtering to reduce the number of filters (thanks to Andreas
|
||||||
Schultz).
|
Schultz).
|
||||||
- Fixed handling Ca descriptors (thanks to Stefan Huelswitt).
|
- Fixed handling Ca descriptors (thanks to Stefan Huelswitt).
|
||||||
|
- Now only those Ca descriptors are sent to a CAM that are actually understood
|
||||||
|
by that CAM.
|
||||||
|
43
ci.c
43
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 1.9 2003/03/23 15:18:40 kls Exp $
|
* $Id: ci.c 1.10 2003/04/18 12:48:49 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* XXX TODO
|
/* XXX TODO
|
||||||
@ -769,7 +769,7 @@ public:
|
|||||||
cCiApplicationInformation::cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc)
|
cCiApplicationInformation::cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc)
|
||||||
:cCiSession(SessionId, RI_APPLICATION_INFORMATION, Tc)
|
:cCiSession(SessionId, RI_APPLICATION_INFORMATION, Tc)
|
||||||
{
|
{
|
||||||
dbgprotocol("New Aplication Information (session id %d)\n", SessionId);
|
dbgprotocol("New Application Information (session id %d)\n", SessionId);
|
||||||
state = 0;
|
state = 0;
|
||||||
creationTime = time(NULL);
|
creationTime = time(NULL);
|
||||||
menuString = NULL;
|
menuString = NULL;
|
||||||
@ -827,12 +827,17 @@ bool cCiApplicationInformation::EnterMenu(void)
|
|||||||
|
|
||||||
// --- cCiConditionalAccessSupport -------------------------------------------
|
// --- cCiConditionalAccessSupport -------------------------------------------
|
||||||
|
|
||||||
|
#define MAXCASYSTEMIDS 16
|
||||||
|
|
||||||
class cCiConditionalAccessSupport : public cCiSession {
|
class cCiConditionalAccessSupport : public cCiSession {
|
||||||
private:
|
private:
|
||||||
int state;
|
int state;
|
||||||
|
int numCaSystemIds;
|
||||||
|
unsigned short caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
|
||||||
public:
|
public:
|
||||||
cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc);
|
cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc);
|
||||||
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
|
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
|
||||||
|
const unsigned short *GetCaSystemIds(void) { return caSystemIds; }
|
||||||
bool SendPMT(cCiCaPmt &CaPmt);
|
bool SendPMT(cCiCaPmt &CaPmt);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -841,6 +846,7 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTrans
|
|||||||
{
|
{
|
||||||
dbgprotocol("New Conditional Access Support (session id %d)\n", SessionId);
|
dbgprotocol("New Conditional Access Support (session id %d)\n", SessionId);
|
||||||
state = 0;
|
state = 0;
|
||||||
|
caSystemIds[numCaSystemIds = 0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
|
bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
|
||||||
@ -853,9 +859,16 @@ bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
|
|||||||
int l = 0;
|
int l = 0;
|
||||||
const uint8_t *d = GetData(Data, l);
|
const uint8_t *d = GetData(Data, l);
|
||||||
while (l > 1) {
|
while (l > 1) {
|
||||||
dbgprotocol(" %04X", ((unsigned int)(*d) << 8) | *(d + 1));
|
unsigned short id = ((unsigned short)(*d) << 8) | *(d + 1);
|
||||||
|
dbgprotocol(" %04X", id);
|
||||||
d += 2;
|
d += 2;
|
||||||
l -= 2;
|
l -= 2;
|
||||||
|
if (numCaSystemIds < MAXCASYSTEMIDS) {
|
||||||
|
caSystemIds[numCaSystemIds++] = id;
|
||||||
|
caSystemIds[numCaSystemIds] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog("ERROR: too many CA system IDs!");
|
||||||
}
|
}
|
||||||
dbgprotocol("\n");
|
dbgprotocol("\n");
|
||||||
}
|
}
|
||||||
@ -1274,6 +1287,7 @@ cCiHandler::cCiHandler(int Fd, int NumSlots)
|
|||||||
{
|
{
|
||||||
numSlots = NumSlots;
|
numSlots = NumSlots;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
newCaSupport = false;
|
||||||
for (int i = 0; i < MAX_CI_SESSION; i++)
|
for (int i = 0; i < MAX_CI_SESSION; i++)
|
||||||
sessions[i] = NULL;
|
sessions[i] = NULL;
|
||||||
tpl = new cCiTransportLayer(Fd, numSlots);
|
tpl = new cCiTransportLayer(Fd, numSlots);
|
||||||
@ -1358,7 +1372,8 @@ cCiSession *cCiHandler::CreateSession(int ResourceId)
|
|||||||
switch (ResourceId) {
|
switch (ResourceId) {
|
||||||
case RI_RESOURCE_MANAGER: return sessions[i] = new cCiResourceManager(i + 1, tc);
|
case RI_RESOURCE_MANAGER: return sessions[i] = new cCiResourceManager(i + 1, tc);
|
||||||
case RI_APPLICATION_INFORMATION: return sessions[i] = new cCiApplicationInformation(i + 1, tc);
|
case RI_APPLICATION_INFORMATION: return sessions[i] = new cCiApplicationInformation(i + 1, tc);
|
||||||
case RI_CONDITIONAL_ACCESS_SUPPORT: return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc);
|
case RI_CONDITIONAL_ACCESS_SUPPORT: newCaSupport = true;
|
||||||
|
return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc);
|
||||||
case RI_HOST_CONTROL: break; //XXX
|
case RI_HOST_CONTROL: break; //XXX
|
||||||
case RI_DATE_TIME: return sessions[i] = new cCiDateTime(i + 1, tc);
|
case RI_DATE_TIME: return sessions[i] = new cCiDateTime(i + 1, tc);
|
||||||
case RI_MMI: return sessions[i] = new cCiMMI(i + 1, tc);
|
case RI_MMI: return sessions[i] = new cCiMMI(i + 1, tc);
|
||||||
@ -1470,6 +1485,8 @@ bool cCiHandler::Process(void)
|
|||||||
if (sessions[i])
|
if (sessions[i])
|
||||||
sessions[i]->Process();
|
sessions[i]->Process();
|
||||||
}
|
}
|
||||||
|
if (newCaSupport)
|
||||||
|
newCaSupport = result = false; // triggers new SetCaPmt at caller!
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1502,16 +1519,18 @@ cCiEnquiry *cCiHandler::GetEnquiry(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt)
|
const unsigned short *cCiHandler::GetCaSystemIds(int Slot)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
cMutexLock MutexLock(&mutex);
|
||||||
bool result = false;
|
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
||||||
for (int Slot = 0; Slot < numSlots; Slot++) {
|
return cas ? cas->GetCaSystemIds() : NULL;
|
||||||
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
}
|
||||||
if (cas)
|
|
||||||
result |= cas->SendPMT(CaPmt);
|
bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt, int Slot)
|
||||||
}
|
{
|
||||||
return result;
|
cMutexLock MutexLock(&mutex);
|
||||||
|
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
||||||
|
return cas && cas->SendPMT(CaPmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cCiHandler::Reset(int Slot)
|
bool cCiHandler::Reset(int Slot)
|
||||||
|
7
ci.h
7
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 1.4 2003/03/23 15:18:40 kls Exp $
|
* $Id: ci.h 1.5 2003/04/18 12:41:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CI_H
|
#ifndef __CI_H
|
||||||
@ -81,6 +81,7 @@ private:
|
|||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
int numSlots;
|
int numSlots;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
bool newCaSupport;
|
||||||
cCiSession *sessions[MAX_CI_SESSION];
|
cCiSession *sessions[MAX_CI_SESSION];
|
||||||
cCiTransportLayer *tpl;
|
cCiTransportLayer *tpl;
|
||||||
cCiTransportConnection *tc;
|
cCiTransportConnection *tc;
|
||||||
@ -96,12 +97,14 @@ private:
|
|||||||
public:
|
public:
|
||||||
~cCiHandler();
|
~cCiHandler();
|
||||||
static cCiHandler *CreateCiHandler(const char *FileName);
|
static cCiHandler *CreateCiHandler(const char *FileName);
|
||||||
|
int NumSlots(void) { return numSlots; }
|
||||||
void SetEnabled(bool Enabled) { enabled = Enabled; }
|
void SetEnabled(bool Enabled) { enabled = Enabled; }
|
||||||
bool Process(void);
|
bool Process(void);
|
||||||
bool EnterMenu(int Slot);
|
bool EnterMenu(int Slot);
|
||||||
cCiMenu *GetMenu(void);
|
cCiMenu *GetMenu(void);
|
||||||
cCiEnquiry *GetEnquiry(void);
|
cCiEnquiry *GetEnquiry(void);
|
||||||
bool SetCaPmt(cCiCaPmt &CaPmt);
|
const unsigned short *GetCaSystemIds(int Slot);
|
||||||
|
bool SetCaPmt(cCiCaPmt &CaPmt, int Slot);
|
||||||
bool Reset(int Slot);
|
bool Reset(int Slot);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
42
dvbdevice.c
42
dvbdevice.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: dvbdevice.c 1.51 2003/04/12 15:06:11 kls Exp $
|
* $Id: dvbdevice.c 1.52 2003/04/18 11:35:08 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -264,27 +264,29 @@ void cDvbTuner::Action(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tunerStatus >= tsLocked) {
|
if (tunerStatus >= tsLocked) {
|
||||||
if (ciHandler && channel.Ca()) {
|
if (ciHandler && channel.Ca() > CACONFBASE) {
|
||||||
if (ciHandler->Process()) {
|
if (ciHandler->Process()) {
|
||||||
if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed
|
if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed
|
||||||
uchar buffer[2048];
|
for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) {
|
||||||
int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), sizeof(buffer), buffer);
|
uchar buffer[2048];
|
||||||
if (length > 0) {
|
int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot), sizeof(buffer), buffer);
|
||||||
cCiCaPmt CaPmt(channel.Sid());
|
if (length > 0) {
|
||||||
CaPmt.AddCaDescriptor(length, buffer);
|
cCiCaPmt CaPmt(channel.Sid());
|
||||||
if (channel.Vpid())
|
CaPmt.AddCaDescriptor(length, buffer);
|
||||||
CaPmt.AddPid(channel.Vpid());
|
if (channel.Vpid())
|
||||||
if (channel.Apid1())
|
CaPmt.AddPid(channel.Vpid());
|
||||||
CaPmt.AddPid(channel.Apid1());
|
if (channel.Apid1())
|
||||||
if (channel.Apid2())
|
CaPmt.AddPid(channel.Apid1());
|
||||||
CaPmt.AddPid(channel.Apid2());
|
if (channel.Apid2())
|
||||||
if (channel.Dpid1())
|
CaPmt.AddPid(channel.Apid2());
|
||||||
CaPmt.AddPid(channel.Dpid1());
|
if (channel.Dpid1())
|
||||||
if (ciHandler->SetCaPmt(CaPmt)) {
|
CaPmt.AddPid(channel.Dpid1());
|
||||||
tunerStatus = tsCam;
|
if (ciHandler->SetCaPmt(CaPmt, Slot)) {
|
||||||
startTime = 0;
|
tunerStatus = tsCam;
|
||||||
}
|
startTime = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
38
eit.c
38
eit.c
@ -16,7 +16,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.c 1.70 2003/04/18 11:29:11 kls Exp $
|
* $Id: eit.c 1.71 2003/04/18 11:30:42 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -1059,12 +1059,8 @@ public:
|
|||||||
const cCaDescriptor *cCaDescriptors::Get(int Source, int Transponder, int ServiceId, int CaSystem)
|
const cCaDescriptor *cCaDescriptors::Get(int Source, int Transponder, int ServiceId, int CaSystem)
|
||||||
{
|
{
|
||||||
for (cCaDescriptor *ca = First(); ca; ca = Next(ca)) {
|
for (cCaDescriptor *ca = First(); ca; ca = Next(ca)) {
|
||||||
if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId) {
|
if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId && ca->caSystem == CaSystem)
|
||||||
if (CaSystem == -1 || ca->caSystem == CaSystem)
|
return ca;
|
||||||
return ca;
|
|
||||||
if (CaSystem < 0)
|
|
||||||
CaSystem++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1452,24 +1448,24 @@ void cSIProcessor::NewCaDescriptor(struct Descriptor *d, int ProgramID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data)
|
int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data)
|
||||||
{
|
{
|
||||||
|
if (!CaSystemIds || !*CaSystemIds)
|
||||||
|
return 0;
|
||||||
if (BufSize > 0 && Data) {
|
if (BufSize > 0 && Data) {
|
||||||
cMutexLock MutexLock(&caDescriptorsMutex);
|
cMutexLock MutexLock(&caDescriptorsMutex);
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int i = -1; ; i--) {
|
do {
|
||||||
const cCaDescriptor *d = caDescriptors->Get(Source, Transponder, ServiceId, i);
|
const cCaDescriptor *d = caDescriptors->Get(Source, Transponder, ServiceId, *CaSystemIds);
|
||||||
if (d) {
|
if (d) {
|
||||||
if (length + d->Length() <= BufSize) {
|
if (length + d->Length() <= BufSize) {
|
||||||
memcpy(Data + length, d->Data(), d->Length());
|
memcpy(Data + length, d->Data(), d->Length());
|
||||||
length += d->Length();
|
length += d->Length();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
} while (*++CaSystemIds);
|
||||||
break;
|
|
||||||
}
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
7
eit.h
7
eit.h
@ -16,7 +16,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.h 1.26 2003/04/13 14:01:24 kls Exp $
|
* $Id: eit.h 1.27 2003/04/18 11:30:42 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef __EIT_H
|
#ifndef __EIT_H
|
||||||
@ -168,10 +168,11 @@ public:
|
|||||||
// Caller must provide a cMutexLock which has to survive the entire
|
// Caller must provide a cMutexLock which has to survive the entire
|
||||||
// time the returned cSchedules is accessed. Once the cSchedules is no
|
// time the returned cSchedules is accessed. Once the cSchedules is no
|
||||||
// longer used, the cMutexLock must be destroyed.
|
// longer used, the cMutexLock must be destroyed.
|
||||||
static int GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data);
|
static int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data);
|
||||||
///< Gets all CA descriptors for a given channel.
|
///< Gets all CA descriptors for a given channel.
|
||||||
///< Copies all available CA descriptors for the given Source, Transponder and ServiceId
|
///< Copies all available CA descriptors for the given Source, Transponder and ServiceId
|
||||||
///< into the provided buffer at Data (at most BufSize bytes).
|
///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors
|
||||||
|
///< are copied that match one of the given CA system IDs.
|
||||||
///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are
|
///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are
|
||||||
///< available), or -1 if BufSize was too small to hold all CA descriptors.
|
///< available), or -1 if BufSize was too small to hold all CA descriptors.
|
||||||
static bool Read(FILE *f = NULL);
|
static bool Read(FILE *f = NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user