Now the CA descriptors are sent to the CAM in the 'program' or 'ES level' sections

This commit is contained in:
Klaus Schmidinger 2003-12-24 10:30:35 +01:00
parent 1d32f7c059
commit 6c4e6cc666
7 changed files with 67 additions and 43 deletions

View File

@ -83,6 +83,8 @@ Dave Chapman <dave@dchapman.com>
Hans-Peter Raschke <Hans-Peter.Raschke@Wintermann-DatenService.de> Hans-Peter Raschke <Hans-Peter.Raschke@Wintermann-DatenService.de>
for his support in adapting VDR to DVB-C for his support in adapting VDR to DVB-C
for adding the 'statdvb2vdr' tool (see Tools/statdvb2vdr) for adding the 'statdvb2vdr' tool (see Tools/statdvb2vdr)
for reporting that the CA descriptors need to be sent to the CAM in the 'program'
or 'ES level' sections to make SkyCrypt CAMs work
Peter Hofmann <software@pxh.de> Peter Hofmann <software@pxh.de>
for his support in adapting VDR to DVB-C for his support in adapting VDR to DVB-C

View File

@ -2508,3 +2508,6 @@ Video Disk Recorder Revision History
Miguel Sequeira de Justo Teixeira for reporting this one). Miguel Sequeira de Justo Teixeira for reporting this one).
- Added 'StreamType' setting to CAM communication, which is important for - Added 'StreamType' setting to CAM communication, which is important for
Aston/SECA CAMs (thanks to Antonino Sergi). Aston/SECA CAMs (thanks to Antonino Sergi).
- Now the CA descriptors are sent to the CAM in the 'program' or 'ES level'
sections, depending on where they are found in the PMT (thanks to Hans-Peter
Raschke for reporting this one). This should make SkyCrypt CAMs work.

33
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 1.19 2003/12/23 10:19:56 kls Exp $ * $Id: ci.c 1.20 2003/12/24 10:23:24 kls Exp $
*/ */
/* XXX TODO /* XXX TODO
@ -22,6 +22,7 @@ XXX*/
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "pat.h"
#include "tools.h" #include "tools.h"
/* these might come in handy in case you want to use this code without VDR's other files: /* these might come in handy in case you want to use this code without VDR's other files:
@ -1266,8 +1267,9 @@ bool cCiEnquiry::Cancel(void)
#define CPCI_QUERY 0x03 #define CPCI_QUERY 0x03
#define CPCI_NOT_SELECTED 0x04 #define CPCI_NOT_SELECTED 0x04
cCiCaPmt::cCiCaPmt(int ProgramNumber) cCiCaPmt::cCiCaPmt(int Source, int Transponder, int ProgramNumber, const unsigned short *CaSystemIds)
{ {
caDescriptorsLength = GetCaDescriptors(Source, Transponder, ProgramNumber, CaSystemIds, sizeof(caDescriptors), caDescriptors, streamFlag);
length = 0; length = 0;
capmt[length++] = CPLM_ONLY; capmt[length++] = CPLM_ONLY;
capmt[length++] = (ProgramNumber >> 8) & 0xFF; capmt[length++] = (ProgramNumber >> 8) & 0xFF;
@ -1276,20 +1278,31 @@ cCiCaPmt::cCiCaPmt(int ProgramNumber)
esInfoLengthPos = length; esInfoLengthPos = length;
capmt[length++] = 0x00; // program_info_length H (at program level) capmt[length++] = 0x00; // program_info_length H (at program level)
capmt[length++] = 0x00; // program_info_length L capmt[length++] = 0x00; // program_info_length L
if (!streamFlag)
AddCaDescriptors(caDescriptorsLength, caDescriptors);
}
bool cCiCaPmt::Valid(void)
{
return caDescriptorsLength > 0;
} }
void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) void cCiCaPmt::AddPid(int Pid, uint8_t StreamType)
{ {
//XXX buffer overflow check??? if (Pid) {
capmt[length++] = StreamType; //XXX buffer overflow check???
capmt[length++] = (Pid >> 8) & 0xFF; capmt[length++] = StreamType;
capmt[length++] = Pid & 0xFF; capmt[length++] = (Pid >> 8) & 0xFF;
esInfoLengthPos = length; capmt[length++] = Pid & 0xFF;
capmt[length++] = 0x00; // ES_info_length H (at ES level) esInfoLengthPos = length;
capmt[length++] = 0x00; // ES_info_length L capmt[length++] = 0x00; // ES_info_length H (at ES level)
capmt[length++] = 0x00; // ES_info_length L
if (streamFlag)
AddCaDescriptors(caDescriptorsLength, caDescriptors);
}
} }
void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data) void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data)
{ {
if (esInfoLengthPos) { if (esInfoLengthPos) {
if (length + Length < int(sizeof(capmt))) { if (length + Length < int(sizeof(capmt))) {

10
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 1.10 2003/12/23 10:20:59 kls Exp $ * $Id: ci.h 1.11 2003/12/24 10:05:46 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -66,10 +66,14 @@ private:
int length; int length;
int esInfoLengthPos; int esInfoLengthPos;
uint8_t capmt[2048]; ///< XXX is there a specified maximum? uint8_t capmt[2048]; ///< XXX is there a specified maximum?
int caDescriptorsLength;
uint8_t caDescriptors[2048];
bool streamFlag;
void AddCaDescriptors(int Length, const uint8_t *Data);
public: public:
cCiCaPmt(int ProgramNumber); cCiCaPmt(int Source, int Transponder, int ProgramNumber, const unsigned short *CaSystemIds);
bool Valid(void);
void AddPid(int Pid, uint8_t StreamType); void AddPid(int Pid, uint8_t StreamType);
void AddCaDescriptor(int Length, uint8_t *Data);
}; };
#define MAX_CI_SESSION 16 //XXX #define MAX_CI_SESSION 16 //XXX

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: dvbdevice.c 1.74 2003/12/23 10:23:16 kls Exp $ * $Id: dvbdevice.c 1.75 2003/12/24 09:57:29 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -273,19 +273,12 @@ void cDvbTuner::Action(void)
if (ciHandler->Process() && useCa) { if (ciHandler->Process() && useCa) {
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
for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) { for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) {
uchar buffer[2048]; cCiCaPmt CaPmt(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot));
int length = GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot), sizeof(buffer), buffer); if (CaPmt.Valid()) {
if (length > 0) { CaPmt.AddPid(channel.Vpid(), 2);
cCiCaPmt CaPmt(channel.Sid()); CaPmt.AddPid(channel.Apid1(), 4);
CaPmt.AddCaDescriptor(length, buffer); CaPmt.AddPid(channel.Apid2(), 4);
if (channel.Vpid()) CaPmt.AddPid(channel.Dpid1(), 0);
CaPmt.AddPid(channel.Vpid(), 2);
if (channel.Apid1())
CaPmt.AddPid(channel.Apid1(), 4);
if (channel.Apid2())
CaPmt.AddPid(channel.Apid2(), 4);
if (channel.Dpid1())
CaPmt.AddPid(channel.Dpid1(), 0);
if (ciHandler->SetCaPmt(CaPmt, Slot)) { if (ciHandler->SetCaPmt(CaPmt, Slot)) {
tunerStatus = tsCam; tunerStatus = tsCam;
startTime = 0; startTime = 0;

35
pat.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: pat.c 1.1 2003/12/21 15:28:28 kls Exp $ * $Id: pat.c 1.2 2003/12/24 10:23:33 kls Exp $
*/ */
#include "pat.h" #include "pat.h"
@ -25,16 +25,17 @@ private:
int caSystem; int caSystem;
int providerId; int providerId;
int caPid; int caPid;
bool stream;
int length; int length;
uchar *data; uchar *data;
public: public:
cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, int Length, const uchar *Data); cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, bool Stream, int Length, const uchar *Data);
virtual ~cCaDescriptor(); virtual ~cCaDescriptor();
int Length(void) const { return length; } int Length(void) const { return length; }
const uchar *Data(void) const { return data; } const uchar *Data(void) const { return data; }
}; };
cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, int Length, const uchar *Data) cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, bool Stream, int Length, const uchar *Data)
{ {
source = Source; source = Source;
transponder = Transponder; transponder = Transponder;
@ -42,6 +43,7 @@ cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaS
caSystem = CaSystem; caSystem = CaSystem;
providerId = ProviderId; providerId = ProviderId;
caPid = CaPid; caPid = CaPid;
stream = Stream;
length = Length + 6; length = Length + 6;
data = MALLOC(uchar, length); data = MALLOC(uchar, length);
data[0] = SI::CaDescriptorTag; data[0] = SI::CaDescriptorTag;
@ -56,7 +58,7 @@ cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaS
#ifdef DEBUG_CA_DESCRIPTORS #ifdef DEBUG_CA_DESCRIPTORS
char buffer[1024]; char buffer[1024];
char *q = buffer; char *q = buffer;
q += sprintf(q, "CAM: %04X %5d %5d %04X %6X %04X -", source, transponder, serviceId, caSystem, providerId, caPid); q += sprintf(q, "CAM: %04X %5d %5d %04X %6X %04X %d -", source, transponder, serviceId, caSystem, providerId, caPid, stream);
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
q += sprintf(q, " %02X", data[i]); q += sprintf(q, " %02X", data[i]);
dsyslog(buffer); dsyslog(buffer);
@ -74,11 +76,11 @@ class cCaDescriptors : public cList<cCaDescriptor> {
private: private:
cMutex mutex; cMutex mutex;
public: public:
void NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d); void NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d, bool Stream);
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data); int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag);
}; };
void cCaDescriptors::NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d) void cCaDescriptors::NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d, bool Stream)
{ {
// The code for determining the ProviderID was taken from 'libdtv' // The code for determining the ProviderID was taken from 'libdtv'
// written by Rolf Hakenes <hakenes@hippomi.de>. // written by Rolf Hakenes <hakenes@hippomi.de>.
@ -108,23 +110,27 @@ void cCaDescriptors::NewCaDescriptor(int Source, int Transponder, int ServiceId,
if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId && ca->caSystem == d->getCaType() && ca->providerId == ProviderID && ca->caPid == d->getCaPid()) if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId && ca->caSystem == d->getCaType() && ca->providerId == ProviderID && ca->caPid == d->getCaPid())
return; return;
} }
Add(new cCaDescriptor(Source, Transponder, ServiceId, d->getCaType(), ProviderID, d->getCaPid(), Length, Data)); Add(new cCaDescriptor(Source, Transponder, ServiceId, d->getCaType(), ProviderID, d->getCaPid(), Stream, Length, Data));
//XXX update??? //XXX update???
} }
int cCaDescriptors::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data) int cCaDescriptors::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag)
{ {
if (!CaSystemIds || !*CaSystemIds) if (!CaSystemIds || !*CaSystemIds)
return 0; return 0;
if (BufSize > 0 && Data) { if (BufSize > 0 && Data) {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
int length = 0; int length = 0;
int IsStream = -1;
for (cCaDescriptor *d = First(); d; d = Next(d)) { for (cCaDescriptor *d = First(); d; d = Next(d)) {
if (d->source == Source && d->transponder == Transponder && d->serviceId == ServiceId) { if (d->source == Source && d->transponder == Transponder && d->serviceId == ServiceId) {
const unsigned short *caids = CaSystemIds; const unsigned short *caids = CaSystemIds;
do { do {
if (d->caSystem == *caids) { if (d->caSystem == *caids) {
if (length + d->Length() <= BufSize) { if (length + d->Length() <= BufSize) {
if (IsStream >= 0 && IsStream != d->stream)
dsyslog("CAM: different stream flag in CA descriptors");
IsStream = d->stream;
memcpy(Data + length, d->Data(), d->Length()); memcpy(Data + length, d->Data(), d->Length());
length += d->Length(); length += d->Length();
} }
@ -134,6 +140,7 @@ int cCaDescriptors::GetCaDescriptors(int Source, int Transponder, int ServiceId,
} while (*++caids); } while (*++caids);
} }
} }
StreamFlag = IsStream == 1;
return length; return length;
} }
return -1; return -1;
@ -141,9 +148,9 @@ int cCaDescriptors::GetCaDescriptors(int Source, int Transponder, int ServiceId,
cCaDescriptors CaDescriptors; cCaDescriptors CaDescriptors;
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data) int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag)
{ {
return CaDescriptors.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data); return CaDescriptors.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, StreamFlag);
} }
// --- cPatFilter ------------------------------------------------------------ // --- cPatFilter ------------------------------------------------------------
@ -202,7 +209,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
SI::CaDescriptor *d; SI::CaDescriptor *d;
// Scan the common loop: // Scan the common loop:
for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) { for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) {
CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d); CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d, false);
delete d; delete d;
} }
// Scan the stream-specific loop: // Scan the stream-specific loop:
@ -210,9 +217,9 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
for (SI::Loop::Iterator it; pmt.streamLoop.hasNext(it); ) { for (SI::Loop::Iterator it; pmt.streamLoop.hasNext(it); ) {
stream = pmt.streamLoop.getNext(it); stream = pmt.streamLoop.getNext(it);
for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) { for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) {
CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d); CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d, true);
delete d; delete d;
} }
} }
lastPmtScan = 0; // this triggers the next scan lastPmtScan = 0; // this triggers the next scan
} }

6
pat.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: pat.h 1.1 2003/12/21 14:56:03 kls Exp $ * $Id: pat.h 1.2 2003/12/24 10:08:22 kls Exp $
*/ */
#ifndef __PAT_H #ifndef __PAT_H
@ -25,12 +25,14 @@ public:
virtual void SetStatus(bool On); virtual void SetStatus(bool On);
}; };
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data); int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag);
///< 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). Only those CA descriptors ///< 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. ///< 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.
///< The return value in StreamFlag tells whether these CA descriptors are to be used
///< for the individual streams.
#endif //__PAT_H #endif //__PAT_H