vdr  2.7.6
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 5.1 2025/03/02 11:03:35 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 StopDecrypting(void);
137  void CancelActivation(void);
139  bool IsActivating(void);
141  bool Devices(cVector<int> &DeviceNumbers);
145  void UnAssignAll(void);
147  };
148 
149 #define MTD_DONT_CALL(v) dsyslog("PROGRAMMING ERROR (%s,%d): DON'T CALL %s", __FILE__, __LINE__, __FUNCTION__); return v;
150 
151 class cMtdMapper;
152 
153 void MtdMapSid(uchar *p, cMtdMapper *MtdMapper);
154 void MtdMapPid(uchar *p, cMtdMapper *MtdMapper);
155 
156 class cMtdCamSlot : public cCamSlot {
157 private:
161  bool delivered;
162 protected:
163  virtual const int *GetCaSystemIds(void) override;
164  virtual void SendCaPmt(uint8_t CmdId) override;
165 public:
169  virtual ~cMtdCamSlot() override;
170  cMtdMapper *MtdMapper(void) { return mtdMapper; }
171  virtual bool RepliesToQuery(void) override;
172  virtual bool ProvidesCa(const int *CaSystemIds) override;
173  virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper = NULL) override;
174  virtual void StartDecrypting(void) override;
175  virtual void StopDecrypting(void) override;
176  virtual uchar *Decrypt(uchar *Data, int &Count) override;
177  virtual bool TsPostProcess(uchar *Data) override;
178  virtual void InjectEit(int Sid) override;
179  int PutData(const uchar *Data, int Count);
180  int PutCat(const uchar *Data, int Count);
181  // The following functions shall not be called for a cMtdCamSlot:
182  virtual cCamSlot *Spawn(void) { MTD_DONT_CALL(NULL); }
183  virtual bool Reset(void) override { MTD_DONT_CALL(false); }
184  virtual eModuleStatus ModuleStatus(void) override { MTD_DONT_CALL(msNone); }
185  virtual const char *GetCamName(void) override { MTD_DONT_CALL(NULL); }
186  virtual bool Ready(void) override { MTD_DONT_CALL(false); }
187  virtual bool HasMMI(void) override { MTD_DONT_CALL(false); }
188  virtual bool HasUserIO(void) override { MTD_DONT_CALL(false); }
189  virtual bool EnterMenu(void) override { MTD_DONT_CALL(false); }
190  virtual cCiMenu *GetMenu(void) override { MTD_DONT_CALL(NULL); }
191  virtual cCiEnquiry *GetEnquiry(void) override { MTD_DONT_CALL(NULL); }
192  };
193 
194 #endif //__MTD_H
eModuleStatus
Definition: ci.h:170
@ msNone
Definition: ci.h:170
Definition: ci.h:232
friend class cMtdCamSlot
Definition: ci.h:236
cCamSlot * MasterSlot(void)
Returns this CAM slot's master slot, or a pointer to itself if it is a master slot.
Definition: ci.h:309
Definition: ci.h:148
Definition: ci.h:119
int Index(void) const
Definition: tools.c:2097
virtual void StopDecrypting(void) override
Clears the list of CA_PMT entries and tells the CAM to stop decrypting.
Definition: mtd.c:300
virtual const char * GetCamName(void) override
Returns the name of the CAM in this slot, or NULL if there is no ready CAM in this slot.
Definition: mtd.h:185
cMutex clearMutex
Definition: mtd.h:158
virtual void InjectEit(int Sid) override
Injects a generated EIT with a "present event" for the given Sid into the TS data stream sent to the ...
Definition: mtd.c:351
virtual bool EnterMenu(void) override
Requests the CAM in this slot to start its menu.
Definition: mtd.h:189
virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper=NULL) override
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:289
virtual eModuleStatus ModuleStatus(void) override
Returns the status of the CAM in this slot.
Definition: mtd.h:184
virtual bool ProvidesCa(const int *CaSystemIds) override
Returns true if the CAM in this slot provides one of the given CaSystemIds.
Definition: mtd.c:284
cRingBufferLinear * mtdBuffer
Definition: mtd.h:160
virtual void StartDecrypting(void) override
Sends all CA_PMT entries to the CAM that have been modified since the last call to this function.
Definition: mtd.c:294
virtual bool HasUserIO(void) override
Returns true if there is a pending user interaction, which shall be retrieved via GetMenu() or GetEnq...
Definition: mtd.h:188
virtual bool HasMMI(void) override
Returns 'true' if the CAM in this slot has an active MMI.
Definition: mtd.h:187
virtual cCiEnquiry * GetEnquiry(void) override
Gets a pending enquiry, or NULL if there is no enquiry.
Definition: mtd.h:191
bool delivered
Definition: mtd.h:161
virtual ~cMtdCamSlot() override
Definition: mtd.c:259
int PutCat(const uchar *Data, int Count)
Definition: mtd.c:367
virtual uchar * Decrypt(uchar *Data, int &Count) override
If this is a CAM slot that can be freely assigned to any device, but will not be directly inserted in...
Definition: mtd.c:309
cMtdMapper * mtdMapper
Definition: mtd.h:159
virtual bool Reset(void) override
Resets the CAM in this slot.
Definition: mtd.h:183
virtual cCamSlot * Spawn(void)
Definition: mtd.h:182
virtual bool RepliesToQuery(void) override
Returns true if the CAM in this slot replies to queries and thus supports MCD ("Multi Channel Decrypt...
Definition: mtd.c:279
virtual bool Ready(void) override
Returns 'true' if the CAM in this slot is ready to decrypt.
Definition: mtd.h:186
virtual bool TsPostProcess(uchar *Data) override
If there is a cCiSession that needs to do additional processing on TS packets (after the CAM has done...
Definition: mtd.c:346
virtual const int * GetCaSystemIds(void) override
Definition: mtd.c:266
cMtdMapper * MtdMapper(void)
Definition: mtd.h:170
virtual void SendCaPmt(uint8_t CmdId) override
Definition: mtd.c:271
int PutData(const uchar *Data, int Count)
Definition: mtd.c:356
virtual cCiMenu * GetMenu(void) override
Gets a pending menu, or NULL if there is no menu.
Definition: mtd.h:190
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
~cMtdHandler()
Definition: mtd.c:38
bool IsActivating(void)
Returns true if any of the active MTD CAM slots is currently activating.
Definition: mtd.c:129
cVector< cMtdCamSlot * > camSlots
Definition: mtd.h:113
void StartDecrypting(void)
Tells all active MTD CAM slots to start decrypting.
Definition: mtd.c:105
cMtdHandler(void)
Creates a new MTD handler that distributes TS data received through calls to the Put() function to th...
Definition: mtd.c:34
bool IsDecrypting(void)
Returns true if any of the active MTD CAM slots is currently decrypting.
Definition: mtd.c:96
void CancelActivation(void)
Tells all active MTD CAM slots to cancel activation.
Definition: mtd.c:123
cMtdCamSlot * GetMtdCamSlot(cCamSlot *MasterSlot)
Creates a new MTD CAM slot, or reuses an existing one that is currently unused.
Definition: mtd.c:46
void StopDecrypting(void)
Tells all active MTD CAM slots to stop decrypting.
Definition: mtd.c:115
int Priority(void)
Returns the maximum priority of any of the active MTD CAM slots.
Definition: mtd.c:88
void UnAssignAll(void)
Unassigns all MTD CAM slots from their devices.
Definition: mtd.c:145
bool Devices(cVector< int > &DeviceNumbers)
Adds the numbers of the devices of any active MTD CAM slots to the given DeviceNumbers.
Definition: mtd.c:138
Definition: thread.h:67
void MtdMapPid(uchar *p, cMtdMapper *MtdMapper)
Definition: mtd.c:241
#define MTD_DONT_CALL(v)
Definition: mtd.h:149
void MtdMapSid(uchar *p, cMtdMapper *MtdMapper)
Definition: mtd.c:233
unsigned char uchar
Definition: tools.h:31