Improved CAM handling

This commit is contained in:
Klaus Schmidinger 2003-02-02 15:49:52 +01:00
parent 5693873b9b
commit b7777e230c
5 changed files with 68 additions and 41 deletions

View File

@ -1942,7 +1942,8 @@ Video Disk Recorder Revision History
Kirchgatterer and Robert Schiele). Kirchgatterer and Robert Schiele).
- Fixed skipping unavailable channels in the EPG scanner. - Fixed skipping unavailable channels in the EPG scanner.
2003-01-26: Version 1.1.23 2003-02-02: Version 1.1.23
- Fixed a new/delete malloc/free mismatch in ringbuffer.c (thanks to Stefan - Fixed a new/delete malloc/free mismatch in ringbuffer.c (thanks to Stefan
Huelswitt for reporting this one). Huelswitt for reporting this one).
- Improved CAM handling.

73
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.2 2003/01/11 11:15:19 kls Exp $ * $Id: ci.c 1.3 2003/02/02 15:49:52 kls Exp $
*/ */
/* XXX TODO /* XXX TODO
@ -13,7 +13,6 @@
- update CA descriptors in case they change - update CA descriptors in case they change
- dynamically react on CAM insert/remove - dynamically react on CAM insert/remove
- implement CAM reset (per slot) - implement CAM reset (per slot)
- implement a CA enquiry menu with actual user input
XXX*/ XXX*/
#include "ci.h" #include "ci.h"
@ -45,7 +44,7 @@ static int SysLogLevel = 3;
static bool DumpTPDUDataTransfer = false; static bool DumpTPDUDataTransfer = false;
static bool DebugProtocol = false; static bool DebugProtocol = false;
#define dbgprotocol(a...) if (DebugProtocol) printf(a) #define dbgprotocol(a...) if (DebugProtocol) fprintf(stderr, a)
#define OK 0 #define OK 0
#define TIMEOUT -1 #define TIMEOUT -1
@ -460,19 +459,32 @@ cCiTransportConnection *cCiTransportLayer::NewConnection(void)
return NULL; return NULL;
} }
#define CA_RESET_TIMEOUT 2 // seconds #define CA_RESET_TIMEOUT 3 // seconds
bool cCiTransportLayer::ResetSlot(int Slot) bool cCiTransportLayer::ResetSlot(int Slot)
{ {
dbgprotocol("Resetting slot %d...", Slot);
ca_slot_info_t sinfo; ca_slot_info_t sinfo;
sinfo.num = Slot; sinfo.num = Slot;
ioctl(fd, CA_RESET, Slot); if (ioctl(fd, CA_RESET, 1 << Slot) != -1) {
time_t t0 = time(NULL); time_t t0 = time(NULL);
do { do {
ioctl(fd, CA_GET_SLOT_INFO, &sinfo); if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
if ((sinfo.flags & CA_CI_MODULE_READY) != 0) ioctl(fd, CA_GET_SLOT_INFO, &sinfo);
return true; if ((sinfo.flags & CA_CI_MODULE_READY) != 0) {
} while (time(NULL) - t0 < CA_RESET_TIMEOUT); dbgprotocol("ok.\n");
return true;
}
}
else {
esyslog("ERROR: can't get info on CAM slot %d: %m", Slot);
break;
}
} while (time(NULL) - t0 < CA_RESET_TIMEOUT);
}
else
esyslog("ERROR: can't reset CAM slot %d: %m", Slot);
dbgprotocol("failed!\n");
return false; return false;
} }
@ -818,7 +830,27 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTrans
bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data) bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
{ {
if (state == 0) { if (Data) {
int Tag = GetTag(Length, &Data);
switch (Tag) {
case AOT_CA_INFO: {
dbgprotocol("%d: <== Ca Info", SessionId());
int l = 0;
const uint8_t *d = GetData(Data, l);
while (l > 1) {
dbgprotocol(" %04X", ((unsigned int)(*d) << 8) | *(d + 1));
d += 2;
l -= 2;
}
dbgprotocol("\n");
}
state = 2;
break;
default: esyslog("ERROR: CI conditional access support: unknown tag %06X", Tag);
return false;
}
}
else if (state == 0) {
dbgprotocol("%d: ==> Ca Info Enq\n", SessionId()); dbgprotocol("%d: ==> Ca Info Enq\n", SessionId());
SendData(AOT_CA_INFO_ENQ); SendData(AOT_CA_INFO_ENQ);
state = 1; state = 1;
@ -828,7 +860,7 @@ bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
bool cCiConditionalAccessSupport::SendPMT(cCiCaPmt &CaPmt) bool cCiConditionalAccessSupport::SendPMT(cCiCaPmt &CaPmt)
{ {
if (state == 1) { if (state == 2) {
SendData(AOT_CA_PMT, CaPmt.length, CaPmt.capmt); SendData(AOT_CA_PMT, CaPmt.length, CaPmt.capmt);
return true; return true;
} }
@ -1186,27 +1218,27 @@ cCiCaPmt::cCiCaPmt(int ProgramNumber)
capmt[length++] = (ProgramNumber >> 8) & 0xFF; capmt[length++] = (ProgramNumber >> 8) & 0xFF;
capmt[length++] = ProgramNumber & 0xFF; capmt[length++] = ProgramNumber & 0xFF;
capmt[length++] = 0x00; //XXX version_number, current_next_indicator - apparently may be 0x00 capmt[length++] = 0x00; //XXX version_number, current_next_indicator - apparently may be 0x00
capmt[length++] = 0x00; //XXX program_info_length H (at program level) esInfoLengthPos = length;
capmt[length++] = 0x00; //XXX program_info_length L capmt[length++] = 0x00; // program_info_length H (at program level)
esInfoLengthPos = 0; capmt[length++] = 0x00; // program_info_length L
} }
void cCiCaPmt::AddPid(int Pid) void cCiCaPmt::AddPid(int Pid)
{ {
//XXX buffer overflow check???
capmt[length++] = 0x00; //XXX stream_type (apparently doesn't matter) capmt[length++] = 0x00; //XXX stream_type (apparently doesn't matter)
capmt[length++] = (Pid >> 8) & 0xFF; capmt[length++] = (Pid >> 8) & 0xFF;
capmt[length++] = Pid & 0xFF; capmt[length++] = Pid & 0xFF;
esInfoLengthPos = length; esInfoLengthPos = length;
capmt[length++] = 0x00; // ES_info_length H (at ES level)
capmt[length++] = 0x00; // ES_info_length L
} }
void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data) void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
{ {
if (esInfoLengthPos) { if (esInfoLengthPos) {
if (esInfoLengthPos == length) {
length += 2;
capmt[length++] = CPCI_OK_DESCRAMBLING;
}
if (length + Length < int(sizeof(capmt))) { if (length + Length < int(sizeof(capmt))) {
capmt[length++] = CPCI_OK_DESCRAMBLING;
memcpy(capmt + length, Data, Length); memcpy(capmt + length, Data, Length);
length += Length; length += Length;
int l = length - esInfoLengthPos - 2; int l = length - esInfoLengthPos - 2;
@ -1215,6 +1247,7 @@ void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
} }
else else
esyslog("ERROR: buffer overflow in CA descriptor"); esyslog("ERROR: buffer overflow in CA descriptor");
esInfoLengthPos = 0;
} }
else else
esyslog("ERROR: adding CA descriptor without Pid!"); esyslog("ERROR: adding CA descriptor without Pid!");

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.41 2003/01/06 14:44:27 kls Exp $ * $Id: dvbdevice.c 1.42 2003/02/02 15:31:31 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -263,22 +263,15 @@ void cDvbTuner::Action(void)
int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), sizeof(buffer), buffer); int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), sizeof(buffer), buffer);
if (length > 0) { if (length > 0) {
cCiCaPmt CaPmt(channel.Sid()); cCiCaPmt CaPmt(channel.Sid());
if (channel.Vpid()) { CaPmt.AddCaDescriptor(length, buffer);
if (channel.Vpid())
CaPmt.AddPid(channel.Vpid()); CaPmt.AddPid(channel.Vpid());
CaPmt.AddCaDescriptor(length, buffer); if (channel.Apid1())
}
if (channel.Apid1()) {
CaPmt.AddPid(channel.Apid1()); CaPmt.AddPid(channel.Apid1());
CaPmt.AddCaDescriptor(length, buffer); if (channel.Apid2())
}
if (channel.Apid2()) {
CaPmt.AddPid(channel.Apid2()); CaPmt.AddPid(channel.Apid2());
CaPmt.AddCaDescriptor(length, buffer); if (channel.Dpid1())
}
if (channel.Dpid1()) {
CaPmt.AddPid(channel.Dpid1()); CaPmt.AddPid(channel.Dpid1());
CaPmt.AddCaDescriptor(length, buffer);
}
caSet = ciHandler->SetCaPmt(CaPmt); caSet = ciHandler->SetCaPmt(CaPmt);
} }
} }

6
eit.c
View File

@ -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.64 2003/01/26 12:21:15 kls Exp $ * $Id: eit.c 1.65 2003/02/02 15:41:03 kls Exp $
***************************************************************************/ ***************************************************************************/
#include "eit.h" #include "eit.h"
@ -1349,7 +1349,7 @@ void cSIProcessor::Action()
/** Add a filter with packet identifier pid and /** Add a filter with packet identifier pid and
table identifer tid */ table identifer tid */
bool cSIProcessor::AddFilter(u_char pid, u_char tid) bool cSIProcessor::AddFilter(unsigned short pid, u_char tid)
{ {
dmx_sct_filter_params sctFilterParams; dmx_sct_filter_params sctFilterParams;
memset(&sctFilterParams, 0, sizeof(sctFilterParams)); memset(&sctFilterParams, 0, sizeof(sctFilterParams));
@ -1390,7 +1390,7 @@ bool cSIProcessor::AddFilter(u_char pid, u_char tid)
return false; return false;
} }
bool cSIProcessor::DelFilter(u_char pid, u_char tid) bool cSIProcessor::DelFilter(unsigned short pid, u_char tid)
{ {
for (int a = 0; a < MAX_FILTERS; a++) for (int a = 0; a < MAX_FILTERS; a++)
{ {

8
eit.h
View File

@ -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.23 2003/01/04 10:12:54 kls Exp $ * $Id: eit.h 1.24 2003/02/02 14:07:39 kls Exp $
***************************************************************************/ ***************************************************************************/
#ifndef __EIT_H #ifndef __EIT_H
@ -127,7 +127,7 @@ public:
typedef struct sip_filter { typedef struct sip_filter {
u_char pid; unsigned short pid;
u_char tid; u_char tid;
int handle; int handle;
bool inuse; bool inuse;
@ -155,8 +155,8 @@ private:
char *fileName; char *fileName;
bool active; bool active;
void Action(void); void Action(void);
bool AddFilter(u_char pid, u_char tid); bool AddFilter(unsigned short pid, u_char tid);
bool DelFilter(u_char pid, u_char tid); bool DelFilter(unsigned short pid, u_char tid);
bool ShutDownFilters(void); bool ShutDownFilters(void);
public: public:
cSIProcessor(const char *FileName); cSIProcessor(const char *FileName);