12 #include <linux/dvb/ca.h>
14 #include <netinet/in.h>
17 #include <sys/ioctl.h>
30 #define dbgprotocol(a...) do { if (DebugProtocol) fprintf(stderr, a); } while (0)
34 #define SIZE_INDICATOR 0x80
36 static const uint8_t *
GetLength(
const uint8_t *Data,
int &Length)
43 int l = Length & ~SIZE_INDICATOR;
45 for (
int i = 0; i < l; i++)
46 Length = (Length << 8) | *Data++;
51 static uint8_t *
SetLength(uint8_t *Data,
int Length)
59 int n =
sizeof(Length);
60 for (
int i = n - 1; i >= 0; i--) {
61 int b = (Length >> (8 * i)) & 0xFF;
77 while (Length > 0 && (*Data ==
' ' || *Data == 0x05 || *Data == 0x96 || *Data == 0x97)) {
81 char *s =
MALLOC(
char, Length + 1);
82 strncpy(s, (
char *)Data, Length);
89 static char *
GetString(
int &Length,
const uint8_t **Data)
94 if (Length > 0 && Data && *Data) {
98 Length -= d - *Data + l;
107 #define MAX_TPDU_SIZE 2048
108 #define MAX_TPDU_DATA (MAX_TPDU_SIZE - 4)
110 #define DATA_INDICATOR 0x80
114 #define T_CREATE_TC 0x82
115 #define T_CTC_REPLY 0x83
116 #define T_DELETE_TC 0x84
117 #define T_DTC_REPLY 0x85
118 #define T_REQUEST_TC 0x86
119 #define T_NEW_TC 0x87
120 #define T_TC_ERROR 0x88
121 #define T_DATA_LAST 0xA0
122 #define T_DATA_MORE 0xA1
128 const uint8_t *
GetData(
const uint8_t *
Data,
int &Length);
141 void Dump(
int SlotNumber,
bool Outgoing);
144 cTPDU::cTPDU(uint8_t Slot, uint8_t Tcid, uint8_t Tag,
int Length,
const uint8_t *Data)
170 esyslog(
"ERROR: invalid data length for TPDU tag 0x%02X: %d (%d/%d)", Tag, Length, Slot, Tcid);
179 memcpy(p, Data, Length);
183 esyslog(
"ERROR: invalid data length for TPDU tag 0x%02X: %d (%d/%d)", Tag, Length, Slot, Tcid);
186 esyslog(
"ERROR: unknown TPDU tag: 0x%02X (%d/%d)", Tag, Slot, Tcid);
194 fprintf(stderr,
" %d: %s ", SlotNumber, Outgoing ?
"-->" :
"<--");
196 fprintf(stderr,
"%02X ",
buffer[i]);
197 fprintf(stderr,
"%s\n",
size >= MAX_DUMP ?
"..." :
"");
199 fprintf(stderr,
" ");
201 fprintf(stderr,
"%2c ", isprint(
buffer[i]) ?
buffer[i] :
'.');
202 fprintf(stderr,
"%s\n",
size >= MAX_DUMP ?
"..." :
"");
228 #define MAX_SESSIONS_PER_TC 16
242 void SendTPDU(uint8_t Tag,
int Length = 0,
const uint8_t *Data = NULL);
243 void SendTag(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId = 0,
int Status = -1);
260 void SendData(
int Length,
const uint8_t *Data);
269 #define ST_SESSION_NUMBER 0x90
270 #define ST_OPEN_SESSION_REQUEST 0x91
271 #define ST_OPEN_SESSION_RESPONSE 0x92
272 #define ST_CREATE_SESSION 0x93
273 #define ST_CREATE_SESSION_RESPONSE 0x94
274 #define ST_CLOSE_SESSION_REQUEST 0x95
275 #define ST_CLOSE_SESSION_RESPONSE 0x96
280 #define SS_NOT_ALLOCATED 0xF0
284 #define RI_RESOURCE_MANAGER 0x00010041
285 #define RI_APPLICATION_INFORMATION 0x00020041
286 #define RI_CONDITIONAL_ACCESS_SUPPORT 0x00030041
287 #define RI_HOST_CONTROL 0x00200041
288 #define RI_DATE_TIME 0x00240041
289 #define RI_MMI 0x00400041
293 #define AOT_NONE 0x000000
294 #define AOT_PROFILE_ENQ 0x9F8010
295 #define AOT_PROFILE 0x9F8011
296 #define AOT_PROFILE_CHANGE 0x9F8012
297 #define AOT_APPLICATION_INFO_ENQ 0x9F8020
298 #define AOT_APPLICATION_INFO 0x9F8021
299 #define AOT_ENTER_MENU 0x9F8022
300 #define AOT_CA_INFO_ENQ 0x9F8030
301 #define AOT_CA_INFO 0x9F8031
302 #define AOT_CA_PMT 0x9F8032
303 #define AOT_CA_PMT_REPLY 0x9F8033
304 #define AOT_TUNE 0x9F8400
305 #define AOT_REPLACE 0x9F8401
306 #define AOT_CLEAR_REPLACE 0x9F8402
307 #define AOT_ASK_RELEASE 0x9F8403
308 #define AOT_DATE_TIME_ENQ 0x9F8440
309 #define AOT_DATE_TIME 0x9F8441
310 #define AOT_CLOSE_MMI 0x9F8800
311 #define AOT_DISPLAY_CONTROL 0x9F8801
312 #define AOT_DISPLAY_REPLY 0x9F8802
313 #define AOT_TEXT_LAST 0x9F8803
314 #define AOT_TEXT_MORE 0x9F8804
315 #define AOT_KEYPAD_CONTROL 0x9F8805
316 #define AOT_KEYPRESS 0x9F8806
317 #define AOT_ENQ 0x9F8807
318 #define AOT_ANSW 0x9F8808
319 #define AOT_MENU_LAST 0x9F8809
320 #define AOT_MENU_MORE 0x9F880A
321 #define AOT_MENU_ANSW 0x9F880B
322 #define AOT_LIST_LAST 0x9F880C
323 #define AOT_LIST_MORE 0x9F880D
324 #define AOT_SUBTITLE_SEGMENT_LAST 0x9F880E
325 #define AOT_SUBTITLE_SEGMENT_MORE 0x9F880F
326 #define AOT_DISPLAY_MESSAGE 0x9F8810
327 #define AOT_SCENE_END_MARK 0x9F8811
328 #define AOT_SCENE_DONE 0x9F8812
329 #define AOT_SCENE_CONTROL 0x9F8813
330 #define AOT_SUBTITLE_DOWNLOAD_LAST 0x9F8814
331 #define AOT_SUBTITLE_DOWNLOAD_MORE 0x9F8815
332 #define AOT_FLUSH_DOWNLOAD 0x9F8816
333 #define AOT_DOWNLOAD_REPLY 0x9F8817
334 #define AOT_COMMS_CMD 0x9F8C00
335 #define AOT_CONNECTION_DESCRIPTOR 0x9F8C01
336 #define AOT_COMMS_REPLY 0x9F8C02
337 #define AOT_COMMS_SEND_LAST 0x9F8C03
338 #define AOT_COMMS_SEND_MORE 0x9F8C04
339 #define AOT_COMMS_RCV_LAST 0x9F8C05
340 #define AOT_COMMS_RCV_MORE 0x9F8C06
348 int GetTag(
int &Length,
const uint8_t **Data);
349 const uint8_t *
GetData(
const uint8_t *Data,
int &Length);
350 void SendData(
int Tag,
int Length = 0,
const uint8_t *Data = NULL);
358 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
377 if (Length >= 3 && Data && *Data) {
379 for (
int i = 0; i < 3; i++)
380 t = (t << 8) | *(*Data)++;
390 return Length ? Data : NULL;
395 uint8_t buffer[2048];
401 *p++ = (Tag >> 16) & 0xFF;
402 *p++ = (Tag >> 8) & 0xFF;
405 if (p - buffer + Length <
int(
sizeof(buffer))) {
406 memcpy(p, Data, Length);
411 esyslog(
"ERROR: CAM %d: data length (%d) exceeds buffer size",
Tc()->CamSlot()->SlotNumber(), Length);
425 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
438 int Tag =
GetTag(Length, &Data);
457 const uint8_t *d =
GetData(Data, l);
459 esyslog(
"ERROR: CAM %d: resource manager: unexpected data",
Tc()->CamSlot()->SlotNumber());
465 esyslog(
"ERROR: CAM %d: resource manager: unexpected tag %06X in state %d",
Tc()->CamSlot()->SlotNumber(), Tag,
state);
469 default:
esyslog(
"ERROR: CAM %d: resource manager: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
472 else if (
state == 0) {
491 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
512 int Tag =
GetTag(Length, &Data);
517 const uint8_t *d =
GetData(Data, l);
518 if ((l -= 1) < 0)
break;
520 if ((l -= 2) < 0)
break;
523 if ((l -= 2) < 0)
break;
532 default:
esyslog(
"ERROR: CAM %d: application information: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
535 else if (
state == 0) {
554 #define MAXCASYSTEMIDS 64
558 #define CPLM_MORE 0x00
559 #define CPLM_FIRST 0x01
560 #define CPLM_LAST 0x02
561 #define CPLM_ONLY 0x03
562 #define CPLM_ADD 0x04
563 #define CPLM_UPDATE 0x05
567 #define CPCI_OK_DESCRAMBLING 0x01
568 #define CPCI_OK_MMI 0x02
569 #define CPCI_QUERY 0x03
570 #define CPCI_NOT_SELECTED 0x04
585 cCiCaPmt(uint8_t
CmdId,
int Source,
int Transponder,
int ProgramNumber,
const int *CaSystemIds);
589 void AddPid(
int Pid, uint8_t StreamType);
592 cCiCaPmt::cCiCaPmt(uint8_t CmdId,
int Source,
int Transponder,
int ProgramNumber,
const int *CaSystemIds)
600 for (; CaSystemIds[i]; i++)
604 uint8_t caDescriptors[512];
625 uint8_t caDescriptors[512];
648 capmt[esInfoLengthPos + 1] = l & 0xFF;
652 esyslog(
"ERROR: buffer overflow in CA descriptor");
656 esyslog(
"ERROR: adding CA descriptor without Pid!");
663 #define CAEI_POSSIBLE 0x01
664 #define CAEI_POSSIBLE_COND_PURCHASE 0x02
665 #define CAEI_POSSIBLE_COND_TECHNICAL 0x03
666 #define CAEI_NOT_POSSIBLE_ENTITLEMENT 0x71
667 #define CAEI_NOT_POSSIBLE_TECHNICAL 0x73
669 #define CA_ENABLE_FLAG 0x80
671 #define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0)
673 #define QUERY_WAIT_TIME 1000 // ms to wait before sending a query
674 #define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query
685 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
706 int Tag =
GetTag(Length, &Data);
712 const uint8_t *d =
GetData(Data, l);
714 uint16_t
id = ((uint16_t)(*d) << 8) | *(d + 1);
721 esyslog(
"ERROR: CAM %d: too many CA system IDs!",
Tc()->CamSlot()->SlotNumber());
736 dsyslog(
"CAM %d: replies to QUERY - multi channel decryption possible",
Tc()->CamSlot()->SlotNumber());
741 const uint8_t *d =
GetData(Data, l);
743 uint16_t pnr = ((uint16_t)(*d) << 8) | *(d + 1);
752 if (l % 3 == 0 && l > 1) {
758 uint16_t len = ((uint16_t)(*d) << 8) | *(d + 1);
764 unsigned char caepl = *d;
772 uint16_t pid = ((uint16_t)(*d) << 8) | *(d + 1);
773 unsigned char caees = *(d + 2);
788 default:
esyslog(
"ERROR: CAM %d: conditional access support: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
791 else if (
state == 0) {
803 dsyslog(
"CAM %d: doesn't reply to QUERY - only a single channel can be decrypted",
Tc()->CamSlot()->SlotNumber());
810 if (CaPmt &&
state >= 2) {
826 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
839 time_t t = time(NULL);
842 if (gmtime_r(&t, &tm_gmt) && localtime_r(&t, &tm_loc)) {
843 int Y = tm_gmt.tm_year;
844 int M = tm_gmt.tm_mon + 1;
845 int D = tm_gmt.tm_mday;
846 int L = (M == 1 || M == 2) ? 1 : 0;
847 int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
848 #define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10))
849 struct tTime { uint16_t mjd; uint8_t h, m, s;
short offset; };
850 tTime T = { mjd : htons(MJD), h :
DEC2BCD(tm_gmt.tm_hour), m :
DEC2BCD(tm_gmt.tm_min), s :
DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) };
863 int Tag =
GetTag(Length, &Data);
868 const uint8_t *d =
GetData(Data, l);
876 default:
esyslog(
"ERROR: CAM %d: date time: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
889 #define DCC_SET_MMI_MODE 0x01
890 #define DCC_DISPLAY_CHARACTER_TABLE_LIST 0x02
891 #define DCC_INPUT_CHARACTER_TABLE_LIST 0x03
892 #define DCC_OVERLAY_GRAPHICS_CHARACTERISTICS 0x04
893 #define DCC_FULL_SCREEN_GRAPHICS_CHARACTERISTICS 0x05
897 #define MM_HIGH_LEVEL 0x01
898 #define MM_LOW_LEVEL_OVERLAY_GRAPHICS 0x02
899 #define MM_LOW_LEVEL_FULL_SCREEN_GRAPHICS 0x03
903 #define DRI_MMI_MODE_ACK 0x01
904 #define DRI_LIST_DISPLAY_CHARACTER_TABLES 0x02
905 #define DRI_LIST_INPUT_CHARACTER_TABLES 0x03
906 #define DRI_LIST_GRAPHIC_OVERLAY_CHARACTERISTICS 0x04
907 #define DRI_LIST_FULL_SCREEN_GRAPHIC_CHARACTERISTICS 0x05
908 #define DRI_UNKNOWN_DISPLAY_CONTROL_CMD 0xF0
909 #define DRI_UNKNOWN_MMI_MODE 0xF1
910 #define DRI_UNKNOWN_CHARACTER_TABLE 0xF2
914 #define EF_BLIND 0x01
918 #define AI_CANCEL 0x00
919 #define AI_ANSWER 0x01
923 char *
GetText(
int &Length,
const uint8_t **Data);
929 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
965 int Tag =
GetTag(Length, Data);
972 esyslog(
"ERROR: CAM %d: MMI: unexpected text tag: %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
979 int Tag =
GetTag(Length, &Data);
984 const uint8_t *d =
GetData(Data, l);
989 struct tDisplayReply { uint8_t id; uint8_t mode; };
995 default:
esyslog(
"ERROR: CAM %d: MMI: unsupported display control command %02X",
Tc()->CamSlot()->SlotNumber(), *d);
1006 const uint8_t *d =
GetData(Data, l);
1031 const uint8_t *d =
GetData(Data, l);
1033 uint8_t blind = *d++;
1048 const uint8_t *d =
GetData(Data, l);
1054 dbgprotocol(
"Slot %d: <== Close MMI (%d) id = %02X delay = %d\n",
Tc()->CamSlot()->SlotNumber(),
SessionId(),
id, delay);
1057 default:
esyslog(
"ERROR: CAM %d: MMI: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
1093 struct tAnswer { uint8_t id;
char text[256]; };
1097 strncpy(answer.text, Text,
sizeof(answer.text));
1205 #define TC_POLL_TIMEOUT 300 // ms WORKAROUND: TC_POLL_TIMEOUT < 300ms doesn't work with DragonCAM
1206 #define TC_ALIVE_TIMEOUT 2000 // ms after which a transport connection is assumed dead
1231 return cas && cas->
Ready();
1257 uint8_t *p = buffer;
1268 buffer[1] = p - buffer - 2;
1303 if (Length == 6 && *(Data + 1) == 0x04) {
1309 switch (ResourceId) {
1334 if (Session &&
sessions[SessionId] == Session) {
1348 const uint8_t *Data = TPDU->
Data(Length);
1349 if (Data && Length > 1) {
1352 uint16_t SessionId = ntohs(
get_unaligned((uint16_t *)&Data[2]));
1355 Session->
Process(Length - 4, Data + 4);
1407 switch (TPDU->
Tag()) {
1434 esyslog(
"ERROR: unknown TPDU tag: 0x%02X (%s)", TPDU->
Tag(), __FUNCTION__);
1455 esyslog(
"ERROR: unknown state: %d (%s)",
state, __FUNCTION__);
1516 esyslog(
"ERROR: no free CAM slot in CI adapter");
1552 #define MODULE_CHECK_INTERVAL 500 // ms
1553 #define MODULE_RESET_TIMEOUT 2 // s
1574 CamSlots.
Del(
this,
false);
1611 if (d && d->
CamSlot() ==
this)
1643 int n = TPDU->
Tcid();
1682 esyslog(
"ERROR: unknown module status %d (%s)", ms, __FUNCTION__);
1802 if (CaSystemIds && *CaSystemIds) {
1804 for (
int Loop = 1; Loop <= 2; Loop++) {
1807 bool Active =
false;
1811 CaPmt.
AddPid(q->pid, q->streamType);
1815 if ((Loop == 1) != Active) {
1820 p->modified =
false;
1828 cCiCaPmt CaPmt(CmdId, 0, 0, 0, NULL);
1853 for (
const int *ids = cas->
GetCaSystemIds(); ids && *ids; ids++) {
1854 for (
const int *
id = CaSystemIds; *id;
id++) {
1868 if (p->programNumber == ProgramNumber) {
1886 if (q->pid == Pid) {
1887 if (q->active != Active) {
1898 #define STREAM_TYPE_VIDEO 0x02
1899 #define STREAM_TYPE_AUDIO 0x04
1900 #define STREAM_TYPE_PRIVATE 0x06
1911 for (
const int *Apid = Channel->
Apids(); *Apid; Apid++)
1913 for (
const int *Dpid = Channel->
Dpids(); *Dpid; Dpid++)
1915 for (
const int *Spid = Channel->
Spids(); *Spid; Spid++)
1922 #define QUERY_REPLY_WAIT 100 // ms to wait between checks for a reply
1936 for (
const int *Apid = Channel->
Apids(); *Apid; Apid++)
1938 for (
const int *Dpid = Channel->
Dpids(); *Dpid; Dpid++)
1940 for (
const int *Spid = Channel->
Spids(); *Spid; Spid++)
1993 #define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again
2066 #define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL 3600 // seconds between cleanups
2094 if (ccr->ChannelID() == ChannelID)
2113 ccr->ClrChecked(CamSlotNumber);
2114 ccr->ClrDecrypt(CamSlotNumber);
2122 return ccr ? ccr->
CamChecked(CamSlotNumber) :
false;
2129 return ccr ? ccr->
CamDecrypt(CamSlotNumber) :
false;
virtual void Process(int Length=0, const uint8_t *Data=NULL)
uint8_t capmt[2048]
XXX is there a specified maximum?
cCiCaProgramData(int ProgramNumber)
#define AOT_DISPLAY_CONTROL
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices).
virtual void Action(void)
Handles the attached CAM slots in a separate thread.
const int * Dpids(void) const
bool Process(cTPDU *TPDU=NULL)
cCiCaPidData(int Pid, int StreamType)
bool ProvidesCa(const int *CaSystemIds)
Returns true if the CAM in this slot provides one of the given CaSystemIds.
static char * CopyString(int Length, const uint8_t *Data)
virtual ~cCiAdapter()
The derived class must call Cancel(3) in its destructor.
virtual bool HasUserIO(void)
cCiSession(uint16_t SessionId, uint32_t ResourceId, cCiTransportConnection *Tc)
cList< cCiCaPidData > pidList
void AddPid(int ProgramNumber, int Pid, int StreamType)
Adds the given PID information to the list of PIDs.
void Add(cListObject *Object, cListObject *After=NULL)
#define AOT_PROFILE_CHANGE
bool CamChecked(int CamSlotNumber)
int Ca(int Index=0) const
void StartDecrypting(void)
Triggers sending all currently active CA_PMT entries to the CAM, so that it will start decrypting...
int caSystemIds[MAXCASYSTEMIDS+1]
#define MAX_CONNECTIONS_PER_CAM_SLOT
virtual bool Reset(int Slot)=0
Resets the CAM in the given Slot.
static char * GetString(int &Length, const uint8_t **Data)
#define MAX_CAM_SLOTS_PER_ADAPTER
#define AOT_APPLICATION_INFO_ENQ
#define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL
virtual void Process(int Length=0, const uint8_t *Data=NULL)
void SetCamSlot(cCamSlot *CamSlot)
Sets the given CamSlot to be used with this device.
#define dbgprotocol(a...)
#define ST_CLOSE_SESSION_RESPONSE
virtual void Process(int Length=0, const uint8_t *Data=NULL)
virtual eModuleStatus ModuleStatus(int Slot)=0
Returns the status of the CAM in the given Slot.
static bool DumpTPDUDataTransfer
uint8_t ListManagement(void)
int GetTag(int &Length, const uint8_t **Data)
#define CPCI_NOT_SELECTED
virtual void Write(const uint8_t *Buffer, int Length)=0
Writes Length bytes of the given Buffer.
virtual void Process(int Length=0, const uint8_t *Data=NULL)
#define AOT_APPLICATION_INFO
const int * GetCaSystemIds(void)
#define STREAM_TYPE_VIDEO
virtual bool Ready(void)
Returns 'true' if all present CAMs in this adapter are ready.
friend class cCiTransportConnection
cCiSession * GetSessionByResourceId(uint32_t ResourceId)
char * GetText(int &Length, const uint8_t **Data)
int SlotIndex(void)
Returns the index of this CAM slot within its CI adapter.
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
#define ST_SESSION_NUMBER
const uint8_t * GetData(const uint8_t *Data, int &Length)
bool CamDecrypt(int CamSlotNumber)
virtual bool HasUserIO(void)
eModuleStatus ModuleStatus(void)
Returns the status of the CAM in this slot.
void AddPid(int Pid, uint8_t StreamType)
cCiSession * sessions[MAX_SESSIONS_PER_TC+1]
void AddChannel(const cChannel *Channel)
Adds all PIDs if the given Channel to the current list of PIDs.
uint32_t ResourceId(void)
void SetListManagement(uint8_t ListManagement)
#define RI_CONDITIONAL_ACCESS_SUPPORT
void SendCaPmt(uint8_t CmdId)
cCiTransportConnection * tc[MAX_CONNECTIONS_PER_CAM_SLOT+1]
void CreateConnection(void)
void SendTag(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId=0, int Status=-1)
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use...
cDevice * Device(void)
Returns the device this CAM slot is currently assigned to.
#define MODULE_RESET_TIMEOUT
#define ST_CLOSE_SESSION_REQUEST
cCiTransportConnection * tc
T * Next(const T *object) const
cCiSession * GetSessionByResourceId(uint32_t ResourceId)
int caSystemIds[MAXCASYSTEMIDS+1]
cChannelCamRelation(tChannelID ChannelID)
uint32_t ResourceIdToInt(const uint8_t *Data)
void HandleSessions(cTPDU *TPDU)
void Process(cTPDU *TPDU=NULL)
bool HasUserIO(void)
Returns true if there is a pending user interaction, which shall be retrieved via GetMenu() or GetEnq...
void SetDecrypt(tChannelID ChannelID, int CamSlotNumber)
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 cl...
void SendData(int Tag, int Length=0, const uint8_t *Data=NULL)
cListObject * Next(void) const
cCiSession * GetSessionBySessionId(uint16_t SessionId)
cCiMenu * GetMenu(void)
Gets a pending menu, or NULL if there is no menu.
bool SendAnswer(const char *Text)
cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc)
#define ST_OPEN_SESSION_RESPONSE
cList< cCiCaProgramData > caProgramList
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
Gets all CA descriptors for a given channel.
#define STREAM_TYPE_AUDIO
cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds)
#define ST_OPEN_SESSION_REQUEST
virtual ~cCiTransportConnection()
cCiEnquiry * Enquiry(bool Clear=false)
#define AOT_DISPLAY_REPLY
void ClrChecked(int CamSlotNumber)
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
#define MAX_SESSIONS_PER_TC
eModuleStatus lastModuleStatus
#define STREAM_TYPE_PRIVATE
void AddCamSlot(cCamSlot *CamSlot)
Adds the given CamSlot to this CI adapter.
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
cCiTransportConnection * Tc(void)
bool TimedWait(cMutex &Mutex, int TimeoutMs)
void OpenSession(int Length, const uint8_t *Data)
const int * GetCaSystemIds(void)
void SetChecked(int CamSlotNumber)
#define CPCI_OK_DESCRAMBLING
void Dump(int SlotNumber, bool Outgoing)
static uint8_t * SetLength(uint8_t *Data, int Length)
bool Reset(void)
Resets the CAM in this slot.
bool IsDecrypting(void)
Returns true if the CAM in this slot is currently used for decrypting.
bool createConnectionRequested
cCiMMI(uint16_t SessionId, cCiTransportConnection *Tc)
void SendMenuAnswer(uint8_t Selection)
void SendData(int Length, const uint8_t *Data)
int Priority(void) const
Returns the priority of the current receiving session (-MAXPRIORITY..MAXPRIORITY), or IDLEPRIORITY if no receiver is currently active.
const char * GetCamName(void)
void ClrDecrypt(tChannelID ChannelID, int CamSlotNumber)
void SetPid(int Pid, bool Active)
Sets the given Pid (which has previously been added through a call to AddPid()) to Active...
cCamSlot * camSlots[MAX_CAM_SLOTS_PER_ADAPTER]
const int * Apids(void) const
cCiEnquiry * GetEnquiry(void)
Gets a pending enquiry, or NULL if there is no enquiry.
cChannelCamRelation * AddEntry(tChannelID ChannelID)
cCiDateTime(uint16_t SessionId, cCiTransportConnection *Tc)
#define AOT_DATE_TIME_ENQ
#define CAM_CHECKED_TIMEOUT
void Del(cListObject *Object, bool DeleteObject=true)
#define RI_RESOURCE_MANAGER
virtual void Process(int Length=0, const uint8_t *Data=NULL)
void SendPMT(cCiCaPmt *CaPmt)
void Reply(const char *s)
cCiMenu * Menu(bool Clear=false)
bool HasMMI(void)
Returns 'true' if the CAM in this slot has an active MMI.
virtual int Read(uint8_t *Buffer, int MaxLength)=0
Reads one chunk of data into the given Buffer, up to MaxLength bytes.
#define MODULE_CHECK_INTERVAL
tChannelID ChannelID(void)
void SetChecked(tChannelID ChannelID, int CamSlotNumber)
const char * GetCamName(void)
Returns the name of the CAM in this slot, or NULL if there is no ready CAM in this slot...
cCiEnquiry * fetchedEnquiry
void ClrDecrypt(int CamSlotNumber)
cChannelCamRelations ChannelCamRelations
bool Ready(void)
Returns 'true' if the CAM in this slot is ready to decrypt.
void DeleteConnection(void)
int Priority(void)
Returns the priority if the device this slot is currently assigned to, or IDLEPRIORITY if it is not a...
bool CamChecked(tChannelID ChannelID, int CamSlotNumber)
void StopDecrypting(void)
Clears the list of CA_PMT entries and tells the CAM to stop decrypting.
void ClrChecked(tChannelID ChannelID, int CamSlotNumber)
void AddCaDescriptors(int Length, const uint8_t *Data)
const uint8_t * GetData(const uint8_t *Data, int &Length)
void Reset(int CamSlotNumber)
const int * Spids(void) const
cCiTransportConnection(cCamSlot *CamSlot, uint8_t Tcid)
bool EnterMenu(void)
Requests the CAM in this slot to start its menu.
virtual bool Assign(cDevice *Device, bool Query=false)=0
Assigns this adapter to the given Device, if this is possible.
#define ST_CREATE_SESSION_RESPONSE
#define QUERY_REPLY_TIMEOUT
static const uint8_t * GetLength(const uint8_t *Data, int &Length)
bool deleteConnectionRequested
void CloseSession(uint16_t SessionId)
uint8_t buffer[MAX_TPDU_SIZE]
cChannelCamRelation * GetEntry(tChannelID ChannelID)
#define RI_APPLICATION_INFORMATION
bool Assign(cDevice *Device, bool Query=false)
Assigns this CAM slot to the given Device, if this is possible.
void SendTPDU(uint8_t Tag, int Length=0, const uint8_t *Data=NULL)
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
cChannelCamRelations(void)
void DeleteAllConnections(void)
bool RepliesToQuery(void)
const uint8_t * Data(int &Length)
cCamSlot(cCiAdapter *CiAdapter)
Creates a new CAM slot for the given CiAdapter.
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
The cDevice class is the base from which actual devices can be derived.
static bool DebugProtocol
cCiResourceManager(uint16_t SessionId, cCiTransportConnection *Tc)
void SetDecrypt(int CamSlotNumber)