From 00e2415b81aa1808ab084874cb2eedccb89ec5ca Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 28 Dec 2013 13:29:54 +0100 Subject: [PATCH] Implemented cCamSlot::Decrypt() --- HISTORY | 8 ++++++++ ci.c | 6 +++++- ci.h | 49 +++++++++++++++++++++++++++++++------------------ device.c | 6 ++++-- device.h | 12 +++++++++--- dvbdevice.c | 7 +++++-- 6 files changed, 62 insertions(+), 26 deletions(-) diff --git a/HISTORY b/HISTORY index 557a6bf3..4620fcd1 100644 --- a/HISTORY +++ b/HISTORY @@ -8089,3 +8089,11 @@ Video Disk Recorder Revision History - Fixed some spellings in positioner.h and Doxyfile (thanks to Ville Skyttä). - Changed '%a' to the POSIX compliant '%m' in all scanf() calls (thanks to Ville Skyttä). +- The new function cCamSlot::Decrypt() can be used by derived classes to implement a + CAM slot that can be freely assigned to any device, without being directly inserted + into the full TS data stream in hardware. +- Many member functions of cCamSlot have been made virtual to allow for easier + implementation of derived classes. +- cTSBuffer now provides the number of available bytes in its Get() function. +- cDvbDevice::GetTSPacket() now calls CamSlot()->Decrypt() in order to allow CAM slots + that can be freely assigned to any device access to the TS data stream. diff --git a/ci.c b/ci.c index 9a4a8295..7fc39595 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 2.12 2013/02/17 13:17:28 kls Exp $ + * $Id: ci.c 3.1 2013/12/28 11:57:51 kls Exp $ */ #include "ci.h" @@ -1983,6 +1983,10 @@ bool cCamSlot::IsDecrypting(void) return false; } +void cCamSlot::Decrypt(uchar *Data, int Count) +{ +} + // --- cChannelCamRelation --------------------------------------------------- #define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again diff --git a/ci.h b/ci.h index 74e02704..f41c0dae 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 2.2 2012/02/29 10:24:27 kls Exp $ + * $Id: ci.h 3.1 2013/12/28 13:20:08 kls Exp $ */ #ifndef __CI_H @@ -169,50 +169,50 @@ public: int SlotNumber(void) { return slotNumber; } ///< Returns the number of this CAM slot within the whole system. ///< The first slot has the number 1. - bool Reset(void); + virtual bool Reset(void); ///< Resets the CAM in this slot. ///< Returns true if the operation was successful. - eModuleStatus ModuleStatus(void); + virtual eModuleStatus ModuleStatus(void); ///< Returns the status of the CAM in this slot. - const char *GetCamName(void); + virtual const char *GetCamName(void); ///< Returns the name of the CAM in this slot, or NULL if there is ///< no ready CAM in this slot. - bool Ready(void); + virtual bool Ready(void); ///< Returns 'true' if the CAM in this slot is ready to decrypt. - bool HasMMI(void); + virtual bool HasMMI(void); ///< Returns 'true' if the CAM in this slot has an active MMI. - bool HasUserIO(void); + virtual bool HasUserIO(void); ///< Returns true if there is a pending user interaction, which shall ///< be retrieved via GetMenu() or GetEnquiry(). - bool EnterMenu(void); + virtual bool EnterMenu(void); ///< Requests the CAM in this slot to start its menu. - cCiMenu *GetMenu(void); + virtual cCiMenu *GetMenu(void); ///< Gets a pending menu, or NULL if there is no menu. - cCiEnquiry *GetEnquiry(void); + virtual cCiEnquiry *GetEnquiry(void); ///< Gets a pending enquiry, or NULL if there is no enquiry. int Priority(void); ///< Returns the priority if the device this slot is currently assigned ///< to, or IDLEPRIORITY if it is not assigned to any device. - bool ProvidesCa(const int *CaSystemIds); + virtual bool ProvidesCa(const int *CaSystemIds); ///< Returns true if the CAM in this slot provides one of the given ///< CaSystemIds. This doesn't necessarily mean that it will be ///< possible to actually decrypt such a programme, since CAMs ///< usually advertise several CA system ids, while the actual ///< decryption is controlled by the smart card inserted into ///< the CAM. - void AddPid(int ProgramNumber, int Pid, int StreamType); + virtual void AddPid(int ProgramNumber, int Pid, int StreamType); ///< Adds the given PID information to the list of PIDs. A later call ///< to SetPid() will (de)activate one of these entries. - void SetPid(int Pid, bool Active); + virtual void SetPid(int Pid, bool Active); ///< Sets the given Pid (which has previously been added through a ///< call to AddPid()) to Active. A later call to StartDecrypting() will ///< send the full list of currently active CA_PMT entries to the CAM. - void AddChannel(const cChannel *Channel); + virtual void AddChannel(const cChannel *Channel); ///< Adds all PIDs if the given Channel to the current list of PIDs. ///< If the source or transponder of the channel are different than ///< what was given in a previous call to AddChannel(), any previously ///< added PIDs will be cleared. - bool CanDecrypt(const cChannel *Channel); + virtual bool CanDecrypt(const cChannel *Channel); ///< Returns true if there is a CAM in this slot that is able to decrypt ///< the given Channel (or at least claims to be able to do so). ///< Since the QUERY/REPLY mechanism for CAMs is pretty unreliable (some @@ -223,13 +223,26 @@ public: ///< to the initial QUERY will perform this check at all. CAMs that never ///< replied to the initial QUERY are assumed not to be able to handle ///< more than one channel at a time. - void StartDecrypting(void); + virtual void StartDecrypting(void); ///< Triggers sending all currently active CA_PMT entries to the CAM, ///< so that it will start decrypting. - void StopDecrypting(void); + virtual void StopDecrypting(void); ///< Clears the list of CA_PMT entries and tells the CAM to stop decrypting. - bool IsDecrypting(void); + virtual bool IsDecrypting(void); ///< Returns true if the CAM in this slot is currently used for decrypting. + virtual void Decrypt(uchar *Data, int Count); + ///< If this is a CAM slot that can be freely assigned to any device, + ///< but will not be directly inserted into the full TS data stream + ///< in hardware, it can implement this function to be given access + ///< to the data in the device's TS buffer. Data points to a buffer + ///< of Count bytes of TS packets. The first byte in Data is guaranteed + ///< to be a TS_SYNC_BYTE. This function may decrypt as many TS packets + ///< in Data as it wants, but it must decrypt at least the very first + ///< TS packet. Only this very first TS packet will be further processed + ///< after the call to this function. The next call will be done with + ///< Data pointing to the TS packet immediately following the previous + ///< one. However, it can not be assumed that a call to Decrypt() with + ///< a Data pointer of P will be followed by a call with P + TS_SIZE. }; class cCamSlots : public cList {}; diff --git a/device.c b/device.c index a028b8a6..c9a70173 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 3.4 2013/12/25 13:20:19 kls Exp $ + * $Id: device.c 3.5 2013/12/28 12:56:24 kls Exp $ */ #include "device.h" @@ -1764,7 +1764,7 @@ void cTSBuffer::Action(void) } } -uchar *cTSBuffer::Get(void) +uchar *cTSBuffer::Get(int *Available) { int Count = 0; if (delivered) { @@ -1785,6 +1785,8 @@ uchar *cTSBuffer::Get(void) return NULL; } delivered = true; + if (Available) + *Available = Count; return p; } return NULL; diff --git a/device.h b/device.h index cf839f68..1cbd6cc9 100644 --- a/device.h +++ b/device.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 3.6 2013/12/25 13:53:35 kls Exp $ + * $Id: device.h 3.7 2013/12/28 12:59:13 kls Exp $ */ #ifndef __DEVICE_H @@ -829,8 +829,14 @@ private: virtual void Action(void); public: cTSBuffer(int File, int Size, int CardIndex); - ~cTSBuffer(); - uchar *Get(void); + virtual ~cTSBuffer(); + uchar *Get(int *Available = NULL); + ///< Returns a pointer to the first TS packet in the buffer. If Available is given, + ///< it will return the total number of consecutive bytes pointed to in the buffer. + ///< It is guaranteed that the returned pointer points to a TS_SYNC_BYTE and that + ///< there are at least TS_SIZE bytes in the buffer. Otherwise NULL will be + ///< returned and the value in Available (if given) is undefined. + ///< Each call to Get() returns a pointer to the next TS packet in the buffer. }; #endif //__DEVICE_H diff --git a/dvbdevice.c b/dvbdevice.c index 84c92654..3f70f20b 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 3.5 2013/10/21 08:59:59 kls Exp $ + * $Id: dvbdevice.c 3.6 2013/12/28 13:21:37 kls Exp $ */ #include "dvbdevice.h" @@ -1668,7 +1668,10 @@ void cDvbDevice::CloseDvr(void) bool cDvbDevice::GetTSPacket(uchar *&Data) { if (tsBuffer) { - Data = tsBuffer->Get(); + int Available; + Data = tsBuffer->Get(&Available); + if (Data && CamSlot()) + CamSlot()->Decrypt(Data, Available); return true; } return false;