vdr  2.4.1
mtd.h
Go to the documentation of this file.
1 /*
2  * mtd.h: Multi Transponder Decryption
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: mtd.h 1.8.1.1 2019/05/28 15:55:44 kls Exp $
8  */
9 
10 #ifndef __MTD_H
11 #define __MTD_H
12 
13 /*
14 Multiple Transponder Decryption (MTD) is the method of sending TS packets
15 from channels on different transponders to one single CAM for decryption.
16 While decrypting several channels from the same transponder ("Multi Channel
17 Decryption") is straightforward, because the PIDs are unique within one
18 transponder, channels on different transponders might use the same PIDs
19 for different streams.
20 
21 Here's a summary of how MTD is implemented in VDR:
22 
23 Identifying the relevant source code
24 ------------------------------------
25 
26 The actual code that implements the MTD handling is located in the files
27 mtd.h and mtd.c. There are also a few places in ci.[hc], device.c and
28 menu.c where things need to be handled differently for MTD. All functions
29 and variables that have to do with MTD have the three letters "mtd" (upper-
30 and/or lowercase) in their name, so that these code lines can be easily
31 identified if necessary.
32 
33 What a plugin implementing a cCiAdapter/cCamSlot needs to do
34 ------------------------------------------------------------
35 
36 If an implementation of cCiAdapter/cCamSlot supports MTD, it needs to
37 fulfill the following requirements:
38 - The cCiAdapter's Assign() function needs to return true for any given
39  device.
40 - The cCamSlot's constructor needs to call MtdEnable().
41 - The cCamSlot's Decrypt() function shall accept the given TS packet,
42  but shall *not* return a decrypted packet. Decypted packets shall be
43  delivered through a call to MtdPutData(), one at a time.
44 - The cCamSlot's Decrypt() function needs to be thread safe, because
45  it will be called from several cMtdCamSlot objects.
46 
47 Physical vs. virtual CAMs
48 -------------------------
49 
50 MTD is done by having one physical CAM (accessed through a plugin's
51 implementation of cCiAdapter/cCamSlot) and several "virtual" CAMs,
52 implemented through cMtdCamSlot objects ("MTD CAMs"). For each device
53 that requires the physical CAM, one instance of a cMtdCamSlot is created
54 on the fly at runtime, and that MTD CAM is assigned to the device.
55 The MTD CAM takes care of mapping the PIDs, and a cMtdHandler in the
56 physical CAM object distributes the decrypted TS packets to the proper
57 devices.
58 
59 Mapping the PIDs
60 ----------------
61 
62 The main problem with MTD is that the TS packets from different devices
63 (and thus different transponders with possibly overlapping PIDs) need to
64 be combined into one stream, sent to the physical CAM, and finally be sorted
65 apart again and returned to the devices they came from. Both aspects are
66 solved in VDR by mapping the "real" PIDs into "unique" PIDs. Real PIDs
67 are in the range 0x0000-0x1FFF (13 bit). Unique PIDs use the upper 5 bit
68 to indicate the number of the MTD CAM a TS packet came from, and the lower
69 8 bit as individual PID values. Mapping is done with a single array lookup
70 and is thus very fast. The cMtdHandler class takes care of distributing
71 the TS packets to the individual cMtdCamSlot objects, while mapping the
72 PIDs (in both directions) is done by the cMtdMapper class.
73 
74 Mapping the SIDs
75 ----------------
76 
77 Besides the PIDs there are also the "service ids" (SIDs, a.k.a. "programme
78 numbers" or PNRs) that need to be taken care of. SIDs only appear in the
79 CA-PMTs sent to the CAM, so they only need to be mapped from real to unique
80 (not the other way) and since the are only mapped when switching channels,
81 mapping doesn't need to be very fast. Mapping SIDs is also done by the
82 cMtdMapper class.
83 
84 Handling the CAT
85 ----------------
86 
87 Each transponder carries a CAT ("Conditional Access Table") with the fixed PID 1.
88 The CAT contains a list of EMM PIDs, which are necessary to convey entitlement
89 messages to the smart card. Since the CAM only recognizes the CAT if it has
90 its fixed PID of 1, this PID cannot be mapped and has to be sent to the CAM
91 as is. However, the cCaPidReceiver also needs to see the CAM in order to
92 request from the device the TS packets with the EMM PIDs. Since any receivers
93 only get the TS packets after they have been sent through the CAM, we need
94 to send the CAT in both ways, with mapped PID but unmapped EMM PIDs for the
95 cCaPidReceiver, and with unmapped PID but mapped EMM PIDs for the CAM itself.
96 Since the PID 0x0001 can always be distinguished from any mapped PID (which
97 always have a non-zero upper byte), the CAT can be easily channeled in both
98 ways.
99 
100 Handling the CA-PMTs
101 --------------------
102 
103 The CA-PMTs that are sent to the CAM contain both SIDs and PIDs, which are
104 mapped in cCiCaPmt::MtdMapPids().
105 */
106 
107 #include "ci.h"
108 #include "remux.h"
109 #include "ringbuffer.h"
110 
111 class cMtdHandler {
112 private:
114 public:
115  cMtdHandler(void);
120  ~cMtdHandler();
121  cMtdCamSlot *GetMtdCamSlot(cCamSlot *MasterSlot);
124  int Put(const uchar *Data, int Count);
129  int Priority(void);
131  bool IsDecrypting(void);
133  void StartDecrypting(void);
135  void CancelActivation(void);
137  bool IsActivating(void);
139  bool Devices(cVector<int> &DeviceNumbers);
143  void UnAssignAll(void);
145  };
146 
147 #define MTD_DONT_CALL(v) dsyslog("PROGRAMMING ERROR (%s,%d): DON'T CALL %s", __FILE__, __LINE__, __FUNCTION__); return v;
148 
149 class cMtdMapper;
150 
151 void MtdMapSid(uchar *p, cMtdMapper *MtdMapper);
152 void MtdMapPid(uchar *p, cMtdMapper *MtdMapper);
153 
154 class cMtdCamSlot : public cCamSlot {
155 private:
159  bool delivered;
160 protected:
161  virtual const int *GetCaSystemIds(void);
162  virtual void SendCaPmt(uint8_t CmdId);
163 public:
164  cMtdCamSlot(cCamSlot *MasterSlot, int Index);
167  virtual ~cMtdCamSlot();
168  cMtdMapper *MtdMapper(void) { return mtdMapper; }
169  virtual bool RepliesToQuery(void);
170  virtual bool ProvidesCa(const int *CaSystemIds);
171  virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper = NULL);
172  virtual void StartDecrypting(void);
173  virtual void StopDecrypting(void);
174  virtual uchar *Decrypt(uchar *Data, int &Count);
175  virtual void InjectEit(int Sid);
176  int PutData(const uchar *Data, int Count);
177  int PutCat(const uchar *Data, int Count);
178  // The following functions shall not be called for a cMtdCamSlot:
179  virtual cCamSlot *Spawn(void) { MTD_DONT_CALL(NULL); }
180  virtual bool Reset(void) { MTD_DONT_CALL(false); }
182  virtual const char *GetCamName(void) { MTD_DONT_CALL(NULL); }
183  virtual bool Ready(void) { MTD_DONT_CALL(false); }
184  virtual bool HasMMI(void) { MTD_DONT_CALL(false); }
185  virtual bool HasUserIO(void) { MTD_DONT_CALL(false); }
186  virtual bool EnterMenu(void) { MTD_DONT_CALL(false); }
187  virtual cCiMenu *GetMenu(void) { MTD_DONT_CALL(NULL); }
188  virtual cCiEnquiry *GetEnquiry(void) { MTD_DONT_CALL(NULL); }
189  };
190 
191 #endif //__MTD_H
cCamSlot
Definition: ci.h:232
cMtdCamSlot::RepliesToQuery
virtual bool RepliesToQuery(void)
Returns true if the CAM in this slot replies to queries and thus supports MCD ("Multi Channel Decrypt...
Definition: mtd.c:271
ringbuffer.h
cListObject::Index
int Index(void) const
Definition: tools.c:2072
cMtdCamSlot::GetCaSystemIds
virtual const int * GetCaSystemIds(void)
Definition: mtd.c:258
MtdMapPid
void MtdMapPid(uchar *p, cMtdMapper *MtdMapper)
Definition: mtd.c:233
cMtdCamSlot::Ready
virtual bool Ready(void)
Returns 'true' if the CAM in this slot is ready to decrypt.
Definition: mtd.h:183
cMtdHandler::camSlots
cVector< cMtdCamSlot * > camSlots
Definition: mtd.h:113
cMtdCamSlot::mtdMapper
cMtdMapper * mtdMapper
Definition: mtd.h:157
msNone
@ msNone
Definition: ci.h:170
cVector< cMtdCamSlot * >
cMtdHandler::StartDecrypting
void StartDecrypting(void)
Tells all active MTD CAM slots to start decrypting.
Definition: mtd.c:105
cMtdHandler::CancelActivation
void CancelActivation(void)
Tells all active MTD CAM slots to cancel activation.
Definition: mtd.c:115
cMtdCamSlot::ModuleStatus
virtual eModuleStatus ModuleStatus(void)
Returns the status of the CAM in this slot.
Definition: mtd.h:181
cMtdHandler::~cMtdHandler
~cMtdHandler()
Definition: mtd.c:38
cMutex
Definition: thread.h:67
cMtdCamSlot::Spawn
virtual cCamSlot * Spawn(void)
Definition: mtd.h:179
cMtdHandler::cMtdHandler
cMtdHandler(void)
Creates a new MTD handler that distributes TS data received through calls to the Put() function to th...
Definition: mtd.c:34
cMtdCamSlot::mtdBuffer
cRingBufferLinear * mtdBuffer
Definition: mtd.h:158
cMtdCamSlot::~cMtdCamSlot
virtual ~cMtdCamSlot()
Definition: mtd.c:251
uchar
unsigned char uchar
Definition: tools.h:31
cMtdCamSlot::PutCat
int PutCat(const uchar *Data, int Count)
Definition: mtd.c:356
cMtdCamSlot::Decrypt
virtual uchar * 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 in...
Definition: mtd.c:303
cMtdHandler::GetMtdCamSlot
cMtdCamSlot * GetMtdCamSlot(cCamSlot *MasterSlot)
Creates a new MTD CAM slot, or reuses an existing one that is currently unused.
Definition: mtd.c:46
cMtdCamSlot
Definition: mtd.h:154
cMtdCamSlot::Reset
virtual bool Reset(void)
Resets the CAM in this slot.
Definition: mtd.h:180
cMtdCamSlot::StartDecrypting
virtual void StartDecrypting(void)
Sends all CA_PMT entries to the CAM that have been modified since the last call to this function.
Definition: mtd.c:286
cMtdCamSlot::delivered
bool delivered
Definition: mtd.h:159
cMtdHandler::IsDecrypting
bool IsDecrypting(void)
Returns true if any of the active MTD CAM slots is currently decrypting.
Definition: mtd.c:96
cMtdCamSlot::GetCamName
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.
Definition: mtd.h:182
cMtdCamSlot::EnterMenu
virtual bool EnterMenu(void)
Requests the CAM in this slot to start its menu.
Definition: mtd.h:186
cMtdCamSlot::GetEnquiry
virtual cCiEnquiry * GetEnquiry(void)
Gets a pending enquiry, or NULL if there is no enquiry.
Definition: mtd.h:188
cMtdCamSlot::clearMutex
cMutex clearMutex
Definition: mtd.h:156
cChannel
Definition: channels.h:89
cCamSlot::cMtdCamSlot
friend class cMtdCamSlot
Definition: ci.h:236
MTD_DONT_CALL
#define MTD_DONT_CALL(v)
Definition: mtd.h:147
cMtdCamSlot::StopDecrypting
virtual void StopDecrypting(void)
Clears the list of CA_PMT entries and tells the CAM to stop decrypting.
Definition: mtd.c:292
cMtdCamSlot::CanDecrypt
virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper=NULL)
Returns true if there is a CAM in this slot that is able to decrypt the given Channel (or at least cl...
Definition: mtd.c:281
cMtdCamSlot::HasUserIO
virtual bool HasUserIO(void)
Returns true if there is a pending user interaction, which shall be retrieved via GetMenu() or GetEnq...
Definition: mtd.h:185
cMtdCamSlot::HasMMI
virtual bool HasMMI(void)
Returns 'true' if the CAM in this slot has an active MMI.
Definition: mtd.h:184
eModuleStatus
eModuleStatus
Definition: ci.h:170
cMtdCamSlot::ProvidesCa
virtual bool ProvidesCa(const int *CaSystemIds)
Returns true if the CAM in this slot provides one of the given CaSystemIds.
Definition: mtd.c:276
cRingBufferLinear
Definition: ringbuffer.h:48
cMtdCamSlot::MtdMapper
cMtdMapper * MtdMapper(void)
Definition: mtd.h:168
cMtdCamSlot::GetMenu
virtual cCiMenu * GetMenu(void)
Gets a pending menu, or NULL if there is no menu.
Definition: mtd.h:187
ci.h
cMtdHandler
Definition: mtd.h:111
remux.h
cCiMenu
Definition: ci.h:119
cCiEnquiry
Definition: ci.h:148
cMtdHandler::IsActivating
bool IsActivating(void)
Returns true if any of the active MTD CAM slots is currently activating.
Definition: mtd.c:121
cMtdHandler::Put
int Put(const uchar *Data, int Count)
Puts at most Count bytes of Data into the CAM slot which's index is derived from the PID of the TS pa...
Definition: mtd.c:60
cMtdCamSlot::SendCaPmt
virtual void SendCaPmt(uint8_t CmdId)
Definition: mtd.c:263
cMtdMapper
Definition: mtd.c:147
MtdMapSid
void MtdMapSid(uchar *p, cMtdMapper *MtdMapper)
Definition: mtd.c:225
cMtdCamSlot::InjectEit
virtual void InjectEit(int Sid)
Injects a generated EIT with a "present event" for the given Sid into the TS data stream sent to the ...
Definition: mtd.c:340
cMtdHandler::UnAssignAll
void UnAssignAll(void)
Unassigns all MTD CAM slots from their devices.
Definition: mtd.c:137
cMtdHandler::Devices
bool Devices(cVector< int > &DeviceNumbers)
Adds the numbers of the devices of any active MTD CAM slots to the given DeviceNumbers.
Definition: mtd.c:130
cMtdCamSlot::PutData
int PutData(const uchar *Data, int Count)
Definition: mtd.c:345
cMtdHandler::Priority
int Priority(void)
Returns the maximum priority of any of the active MTD CAM slots.
Definition: mtd.c:88