mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Now handling CAT sections that consist of more than one TS packet
This commit is contained in:
parent
14e37ed124
commit
24b38eb812
1
HISTORY
1
HISTORY
@ -8357,3 +8357,4 @@ Video Disk Recorder Revision History
|
||||
(reported by Dieter Ferdinand).
|
||||
- Changed the German weekday names from "MonDieMitDonFreSamSon" to
|
||||
"Mo.Di.Mi.Do.Fr.Sa.So." (thanks to Stefan Blochberger).
|
||||
- Now handling CAT sections that consist of more than one TS packet.
|
||||
|
108
ci.c
108
ci.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: ci.c 3.15 2015/01/12 10:44:58 kls Exp $
|
||||
* $Id: ci.c 3.16 2015/01/13 14:42:32 kls Exp $
|
||||
*/
|
||||
|
||||
#include "ci.h"
|
||||
@ -114,6 +114,9 @@ class cCaPidReceiver : public cReceiver {
|
||||
private:
|
||||
int catVersion;
|
||||
cVector<int> emmPids;
|
||||
uchar buffer[2048]; // 11 bit length, max. 2048 byte
|
||||
uchar *bufp;
|
||||
int length;
|
||||
void AddEmmPid(int Pid);
|
||||
void DelEmmPids(void);
|
||||
protected:
|
||||
@ -129,6 +132,8 @@ public:
|
||||
cCaPidReceiver::cCaPidReceiver(void)
|
||||
{
|
||||
catVersion = -1;
|
||||
bufp = NULL;
|
||||
length = 0;
|
||||
AddPid(CATPID);
|
||||
}
|
||||
|
||||
@ -156,43 +161,78 @@ void cCaPidReceiver::Activate(bool On)
|
||||
|
||||
void cCaPidReceiver::Receive(uchar *Data, int Length)
|
||||
{
|
||||
if (TsPid(Data) == CATPID && Data[5] == SI::TableIdCAT) {
|
||||
int l = (int(Data[6] & 0x03) << 8) | Data[7]; // section length
|
||||
if (l > 5) {
|
||||
int v = (Data[10] & 0x3E) >> 1; // version number
|
||||
if (v != catVersion) {
|
||||
if (Data[11] == 0 && Data[12] == 0) { // section number, last section number
|
||||
if (l <= TS_SIZE - 8) {
|
||||
cDevice *AttachedDevice = Device();
|
||||
if (AttachedDevice)
|
||||
AttachedDevice->Detach(this);
|
||||
DelEmmPids();
|
||||
for (int i = 13; i < l + 8 - 4; i++) { // +8 = header, -4 = checksum
|
||||
if (Data[i] == 0x09) {
|
||||
int CaId = int(Data[i + 2] << 8) | Data[i + 3];
|
||||
int EmmPid = int(((Data[i + 4] & 0x1F) << 8)) | Data[i + 5];
|
||||
AddEmmPid(EmmPid);
|
||||
switch (CaId >> 8) {
|
||||
case 0x01: for (int j = i + 7; j < Data[i + 1] + 2; j += 4) {
|
||||
EmmPid = (int(Data[j] & 0x0F) << 8) | Data[j + 1];
|
||||
AddEmmPid(EmmPid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i += Data[i + 1] - 1; // -1 to compensate for the loop increment
|
||||
}
|
||||
}
|
||||
if (AttachedDevice)
|
||||
AttachedDevice->AttachReceiver(this);
|
||||
if (TsPid(Data) == CATPID) {
|
||||
uchar *p = NULL;
|
||||
if (TsPayloadStart(Data)) {
|
||||
if (Data[5] == SI::TableIdCAT) {
|
||||
length = (int(Data[6] & 0x03) << 8) | Data[7]; // section length
|
||||
if (length > 5) {
|
||||
int v = (Data[10] & 0x3E) >> 1; // version number
|
||||
if (v != catVersion) {
|
||||
if (Data[11] == 0 && Data[12] == 0) { // section number, last section number
|
||||
if (length > TS_SIZE - 8) {
|
||||
int n = TS_SIZE - 13;
|
||||
memcpy(buffer, Data + 13, n);
|
||||
bufp = buffer + n;
|
||||
length -= n + 5; // 5 = header
|
||||
}
|
||||
else {
|
||||
p = Data + 13; // no need to copy the data
|
||||
length -= 5; // header
|
||||
}
|
||||
}
|
||||
else
|
||||
dsyslog("multi table CAT section - unhandled!");
|
||||
catVersion = v;
|
||||
}
|
||||
else
|
||||
dsyslog("multi packet CAT section - unhandled!");
|
||||
}
|
||||
else
|
||||
dsyslog("multi table CAT section - unhandled!");
|
||||
catVersion = v;
|
||||
}
|
||||
}
|
||||
else if (bufp && length > 0) {
|
||||
int n = min(length, TS_SIZE - 4);
|
||||
if (bufp + n - buffer <= int(sizeof(buffer))) {
|
||||
memcpy(bufp, Data + 4, n);
|
||||
bufp += n;
|
||||
length -= n;
|
||||
if (length <= 0) {
|
||||
p = buffer;
|
||||
length = bufp - buffer;
|
||||
}
|
||||
}
|
||||
else {
|
||||
esyslog("ERROR: buffer overflow in cCaPidReceiver::Receive()");
|
||||
bufp = 0;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
if (p) {
|
||||
int OldCatVersion = catVersion; // must preserve the current version number
|
||||
cDevice *AttachedDevice = Device();
|
||||
if (AttachedDevice)
|
||||
AttachedDevice->Detach(this);
|
||||
DelEmmPids();
|
||||
for (int i = 0; i < length - 4; i++) { // -4 = checksum
|
||||
if (p[i] == 0x09) {
|
||||
int CaId = int(p[i + 2] << 8) | p[i + 3];
|
||||
int EmmPid = int(((p[i + 4] & 0x1F) << 8)) | p[i + 5];
|
||||
AddEmmPid(EmmPid);
|
||||
switch (CaId >> 8) {
|
||||
case 0x01: for (int j = i + 7; j < p[i + 1] + 2; j += 4) {
|
||||
EmmPid = (int(p[j] & 0x0F) << 8) | p[j + 1];
|
||||
AddEmmPid(EmmPid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i += p[i + 1] + 2 - 1; // -1 to compensate for the loop increment
|
||||
}
|
||||
}
|
||||
if (AttachedDevice)
|
||||
AttachedDevice->AttachReceiver(this);
|
||||
catVersion = OldCatVersion;
|
||||
p = NULL;
|
||||
bufp = 0;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user