mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved CAM handling
This commit is contained in:
parent
5693873b9b
commit
b7777e230c
3
HISTORY
3
HISTORY
@ -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
73
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.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!");
|
||||||
|
19
dvbdevice.c
19
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.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
6
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.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
8
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.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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user