From 011a9849510e0a96ae11dc5452c3b6fd1a5ce0a5 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 6 Apr 2014 10:56:50 +0200 Subject: [PATCH] A cCamSlot that has WantsTsData set to true in its constructor now also gets the CAT and EMM PIDs data --- HISTORY | 4 ++- ci.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- ci.h | 6 ++-- remux.h | 3 +- 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/HISTORY b/HISTORY index f8b2fcb2..2f0ba074 100644 --- a/HISTORY +++ b/HISTORY @@ -8261,10 +8261,12 @@ Video Disk Recorder Revision History - Added support for systemd (thanks to Christopher Reimer). To activate this you need to add "SDNOTIFY=1" to the 'make' call. -2014-03-24: Version 2.1.7 +2014-04-06: Version 2.1.7 - No longer logging an error message in DirSizeMB() if the given directory doesn't exist. This avoids lots of log entries in case several VDRs use the same video directory and one of them has already physically removed a recording directory, while the others still have it in their list of deleted recordings. - Updated the Italian OSD texts (thanks to Diego Pierotto). +- A cCamSlot that has WantsTsData set to true in its constructor now also gets + the CAT and EMM PIDs data. diff --git a/ci.c b/ci.c index 6b0805d7..90777651 100644 --- a/ci.c +++ b/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.12 2014/02/25 09:59:55 kls Exp $ + * $Id: ci.c 3.13 2014/03/26 11:51:09 kls Exp $ */ #include "ci.h" @@ -20,6 +20,8 @@ #include "device.h" #include "pat.h" #include "receiver.h" +#include "remux.h" +#include "libsi/si.h" #include "tools.h" // Set these to 'true' for debug output: @@ -105,14 +107,89 @@ static char *GetString(int &Length, const uint8_t **Data) // --- cCaPidReceiver -------------------------------------------------------- -// A dummy receiver, just used to make the device receive the CA pids. +// A receiver that is used to make the device receive the ECM pids, as well as the +// CAT and the EMM pids. class cCaPidReceiver : public cReceiver { +private: + int catVersion; + cVector emmPids; + void AddEmmPid(int Pid); + void DelEmmPids(void); +protected: + virtual void Activate(bool On); public: + cCaPidReceiver(void); virtual ~cCaPidReceiver() { Detach(); } - virtual void Receive(uchar *Data, int Length) {} + virtual void Receive(uchar *Data, int Length); + bool HasCaPids(void) { return NumPids() - emmPids.Size() - 1 > 0; } }; +cCaPidReceiver::cCaPidReceiver(void) +{ + catVersion = -1; + AddPid(CATPID); +} + +void cCaPidReceiver::AddEmmPid(int Pid) +{ + for (int i = 0; i < emmPids.Size(); i++) { + if (emmPids[i] == Pid) + return; + } + emmPids.Append(Pid); + AddPid(Pid); +} + +void cCaPidReceiver::DelEmmPids(void) +{ + for (int i = 0; i < emmPids.Size(); i++) + DelPid(emmPids[i]); + emmPids.Clear(); +} + +void cCaPidReceiver::Activate(bool On) +{ + catVersion = -1; // can be done independent of '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) { + 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 + } + } + } + else + dsyslog("multi packet CAT section - unhandled!"); + } + else + dsyslog("multi table CAT section - unhandled!"); + catVersion = v; + } + } + } +} + // --- cTPDU ----------------------------------------------------------------- #define MAX_TPDU_SIZE 2048 @@ -1811,7 +1888,7 @@ void cCamSlot::SendCaPmt(uint8_t CmdId) const int *CaSystemIds = cas->GetCaSystemIds(); if (CaSystemIds && *CaSystemIds) { if (caProgramList.Count()) { - if (caPidReceiver && caPidReceiver->NumPids()) { + if (caPidReceiver && caPidReceiver->HasCaPids()) { if (cDevice *d = Device()) d->Detach(caPidReceiver); } @@ -1845,7 +1922,7 @@ void cCamSlot::SendCaPmt(uint8_t CmdId) } } } - if (caPidReceiver && caPidReceiver->NumPids()) { + if (caPidReceiver && caPidReceiver->HasCaPids()) { if (cDevice *d = Device()) d->AttachReceiver(caPidReceiver); } diff --git a/ci.h b/ci.h index ac029c26..4d558537 100644 --- a/ci.h +++ b/ci.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.h 3.7 2014/01/31 09:21:21 kls Exp $ + * $Id: ci.h 3.8 2014/03/26 11:42:17 kls Exp $ */ #ifndef __CI_H @@ -119,7 +119,7 @@ class cTPDU; class cCiTransportConnection; class cCiSession; class cCiCaProgramData; -class cReceiver; +class cCaPidReceiver; class cCamSlot : public cListObject { friend class cCiAdapter; @@ -128,7 +128,7 @@ private: cMutex mutex; cCondVar processed; cCiAdapter *ciAdapter; - cReceiver *caPidReceiver; + cCaPidReceiver *caPidReceiver; int slotIndex; int slotNumber; cCiTransportConnection *tc[MAX_CONNECTIONS_PER_CAM_SLOT + 1]; // connection numbering starts with 1 diff --git a/remux.h b/remux.h index 5574635c..23ce681e 100644 --- a/remux.h +++ b/remux.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 3.3 2014/02/08 12:41:50 kls Exp $ + * $Id: remux.h 3.4 2014/03/26 11:42:17 kls Exp $ */ #ifndef __REMUX_H @@ -50,6 +50,7 @@ public: #define TS_ADAPT_EXTENSION 0x01 #define PATPID 0x0000 // PAT PID (constant 0) +#define CATPID 0x0001 // CAT PID (constant 1) #define MAXPID 0x2000 // for arrays that use a PID as the index #define PTSTICKS 90000 // number of PTS ticks per second