1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
/*
* ci.h: Common Interface
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.h 1.20 2005/12/03 11:59:05 kls Exp $
*/
#ifndef __CI_H
#define __CI_H
#include <stdint.h>
#include <stdio.h>
#include "thread.h"
#include "tools.h"
class cCiMMI;
class cCiMenu {
friend class cCiHandler;
friend class cCiMMI;
private:
enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum?
cCiMMI *mmi;
cMutex *mutex;
bool selectable;
char *titleText;
char *subTitleText;
char *bottomText;
char *entries[MAX_CIMENU_ENTRIES];
int numEntries;
bool AddEntry(char *s);
cCiMenu(cCiMMI *MMI, bool Selectable);
public:
~cCiMenu();
const char *TitleText(void) { return titleText; }
const char *SubTitleText(void) { return subTitleText; }
const char *BottomText(void) { return bottomText; }
const char *Entry(int n) { return n < numEntries ? entries[n] : NULL; }
int NumEntries(void) { return numEntries; }
bool Selectable(void) { return selectable; }
bool Select(int Index);
bool Cancel(void);
bool Abort(void);
bool HasUpdate(void);
};
class cCiEnquiry {
friend class cCiHandler;
friend class cCiMMI;
private:
cCiMMI *mmi;
cMutex *mutex;
char *text;
bool blind;
int expectedLength;
cCiEnquiry(cCiMMI *MMI);
public:
~cCiEnquiry();
const char *Text(void) { return text; }
bool Blind(void) { return blind; }
int ExpectedLength(void) { return expectedLength; }
bool Reply(const char *s);
bool Cancel(void);
bool Abort(void);
};
#define MAX_CI_SESSION 16 //XXX
#define MAX_CI_SLOT 16
class cCiCaPidData : public cListObject {
public:
bool active;
int pid;
int streamType;
cCiCaPidData(int Pid, int StreamType)
{
active = false;
pid = Pid;
streamType = StreamType;
}
};
class cCiCaProgramData : public cListObject {
public:
int programNumber;
cList<cCiCaPidData> pidList;
cCiCaProgramData(int ProgramNumber)
{
programNumber = ProgramNumber;
}
};
class cCiSession;
class cCiTransportLayer;
class cCiTransportConnection;
class cCiHandler {
private:
cMutex mutex;
int fd;
int numSlots;
bool newCaSupport;
bool hasUserIO;
bool moduleReady[MAX_CI_SLOT];
cCiSession *sessions[MAX_CI_SESSION];
cCiTransportLayer *tpl;
cCiTransportConnection *tc;
int source;
int transponder;
cList<cCiCaProgramData> caProgramList;
int ResourceIdToInt(const uint8_t *Data);
bool Send(uint8_t Tag, int SessionId, int ResourceId = 0, int Status = -1);
const unsigned short *GetCaSystemIds(int Slot);
cCiSession *GetSessionBySessionId(int SessionId);
cCiSession *GetSessionByResourceId(int ResourceId, int Slot);
cCiSession *CreateSession(int ResourceId);
bool OpenSession(int Length, const uint8_t *Data);
bool CloseSession(int SessionId);
int CloseAllSessions(int Slot);
cCiHandler(int Fd, int NumSlots);
void SendCaPmt(void);
public:
~cCiHandler();
static cCiHandler *CreateCiHandler(const char *FileName);
///< Creates a new cCiHandler for the given CA device.
int NumSlots(void) { return numSlots; }
///< Returns the number of CAM slots provided by this CA device.
bool Ready(void);
///< Returns true if all CAMs in this CA device are ready.
bool Process(int Slot = -1);
///< Processes the given Slot. If Slot is -1, all slots are processed.
///< Returns false in case of an error.
bool HasUserIO(void) { return hasUserIO; }
///< Returns true if there is a pending user interaction, which shall
///< be retrieved via GetMenu() or GetEnquiry().
bool EnterMenu(int Slot);
///< Requests the CAM in the given Slot to start its menu.
cCiMenu *GetMenu(void);
///< Gets a pending menu, or NULL if there is no menu.
cCiEnquiry *GetEnquiry(void);
///< Gets a pending enquiry, or NULL if there is no enquiry.
const char *GetCamName(int Slot);
///< Returns the name of the CAM in the given Slot, or NULL if there
///< is no CAM in that slot.
bool ProvidesCa(const unsigned short *CaSystemIds); //XXX Slot???
///< Returns true if any of the CAMs can provide 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 SetSource(int Source, int Transponder);
///< Sets the Source and Transponder of the device this cCiHandler is
///< currently tuned to. If Source or Transponder are different than
///< what was given in a previous call to SetSource(), any previously
///< added PIDs will be cleared.
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);
///< 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.
bool CanDecrypt(int ProgramNumber);
///< XXX
///< Returns true if there is a CAM in this CA device that is able
///< to decrypt the programme with the given ProgramNumber. The PIDs
///< for this ProgramNumber must have been set through previous calls
///< to SetPid().
void StartDecrypting(void);
///< Triggers sending all currently active CA_PMT entries to the CAM,
///< so that it will start decrypting.
bool Reset(int Slot);
};
#endif //__CI_H
|