12 #include <linux/dvb/ca.h> 14 #include <netinet/in.h> 17 #include <sys/ioctl.h> 34 #define dbgprotocol(a...) do { if (DebugProtocol) fprintf(stderr, a); } while (0) 38 #define SIZE_INDICATOR 0x80 40 static const uint8_t *
GetLength(
const uint8_t *Data,
int &Length)
49 for (
int i = 0; i < l; i++)
50 Length = (Length << 8) | *Data++;
55 static uint8_t *
SetLength(uint8_t *Data,
int Length)
63 int n =
sizeof(Length);
64 for (
int i = n - 1; i >= 0; i--) {
65 int b = (Length >> (8 * i)) & 0xFF;
81 while (Length > 0 && (*Data ==
' ' || *Data == 0x05 || *Data == 0x96 || *Data == 0x97)) {
85 char *s =
MALLOC(
char, Length + 1);
86 strncpy(s, (
char *)Data, Length);
93 static char *
GetString(
int &Length,
const uint8_t **Data)
98 if (Length > 0 && Data && *Data) {
102 Length -= d - *Data + l;
169 length = (int(Data[6] & 0x03) << 8) | Data[7];
171 int v = (Data[10] & 0x3E) >> 1;
173 if (Data[11] == 0 && Data[12] == 0) {
176 memcpy(
buffer, Data + 13, n);
186 dsyslog(
"multi table CAT section - unhandled!");
195 memcpy(
bufp, Data + 4, n);
204 esyslog(
"ERROR: buffer overflow in cCaPidReceiver::Receive()");
213 AttachedDevice->
Detach(
this);
215 for (
int i = 0; i <
length - 4; i++) {
217 int CaId = int(p[i + 2] << 8) | p[i + 3];
218 int EmmPid = int(((p[i + 4] & 0x1F) << 8)) | p[i + 5];
221 case 0x01:
for (
int j = i + 7; j < p[i + 1] + 2; j += 4) {
222 EmmPid = (int(p[j] & 0x0F) << 8) | p[j + 1];
227 i += p[i + 1] + 2 - 1;
245 #define UNSCRAMBLE_TIME 5 // seconds of receiving purely unscrambled data before considering the smart card "activated" 246 #define TS_PACKET_FACTOR 1024 // only process every TS_PACKET_FACTORth packet to keep the load down 276 time_t Now = time(NULL);
289 #define MAX_TPDU_SIZE 2048 290 #define MAX_TPDU_DATA (MAX_TPDU_SIZE - 4) 292 #define DATA_INDICATOR 0x80 296 #define T_CREATE_TC 0x82 297 #define T_CTC_REPLY 0x83 298 #define T_DELETE_TC 0x84 299 #define T_DTC_REPLY 0x85 300 #define T_REQUEST_TC 0x86 301 #define T_NEW_TC 0x87 302 #define T_TC_ERROR 0x88 303 #define T_DATA_LAST 0xA0 304 #define T_DATA_MORE 0xA1 310 const uint8_t *
GetData(
const uint8_t *
Data,
int &Length);
323 void Dump(
int SlotNumber,
bool Outgoing);
326 cTPDU::cTPDU(uint8_t Slot, uint8_t Tcid, uint8_t Tag,
int Length,
const uint8_t *Data)
352 esyslog(
"ERROR: invalid data length for TPDU tag 0x%02X: %d (%d/%d)",
Tag, Length,
Slot,
Tcid);
361 memcpy(p,
Data, Length);
365 esyslog(
"ERROR: invalid data length for TPDU tag 0x%02X: %d (%d/%d)",
Tag, Length,
Slot,
Tcid);
376 fprintf(stderr,
" %d: %s ", SlotNumber, Outgoing ?
"-->" :
"<--");
378 fprintf(stderr,
"%02X ",
buffer[i]);
381 fprintf(stderr,
" ");
383 fprintf(stderr,
"%2c ", isprint(
buffer[i]) ?
buffer[i] :
'.');
410 #define MAX_SESSIONS_PER_TC 16 424 void SendTPDU(uint8_t Tag,
int Length = 0,
const uint8_t *Data = NULL);
425 void SendTag(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId = 0,
int Status = -1);
442 void SendData(
int Length,
const uint8_t *Data);
451 #define ST_SESSION_NUMBER 0x90 452 #define ST_OPEN_SESSION_REQUEST 0x91 453 #define ST_OPEN_SESSION_RESPONSE 0x92 454 #define ST_CREATE_SESSION 0x93 455 #define ST_CREATE_SESSION_RESPONSE 0x94 456 #define ST_CLOSE_SESSION_REQUEST 0x95 457 #define ST_CLOSE_SESSION_RESPONSE 0x96 462 #define SS_NOT_ALLOCATED 0xF0 466 #define RI_RESOURCE_MANAGER 0x00010041 467 #define RI_APPLICATION_INFORMATION 0x00020041 468 #define RI_CONDITIONAL_ACCESS_SUPPORT 0x00030041 469 #define RI_HOST_CONTROL 0x00200041 470 #define RI_DATE_TIME 0x00240041 471 #define RI_MMI 0x00400041 475 #define AOT_NONE 0x000000 476 #define AOT_PROFILE_ENQ 0x9F8010 477 #define AOT_PROFILE 0x9F8011 478 #define AOT_PROFILE_CHANGE 0x9F8012 479 #define AOT_APPLICATION_INFO_ENQ 0x9F8020 480 #define AOT_APPLICATION_INFO 0x9F8021 481 #define AOT_ENTER_MENU 0x9F8022 482 #define AOT_CA_INFO_ENQ 0x9F8030 483 #define AOT_CA_INFO 0x9F8031 484 #define AOT_CA_PMT 0x9F8032 485 #define AOT_CA_PMT_REPLY 0x9F8033 486 #define AOT_TUNE 0x9F8400 487 #define AOT_REPLACE 0x9F8401 488 #define AOT_CLEAR_REPLACE 0x9F8402 489 #define AOT_ASK_RELEASE 0x9F8403 490 #define AOT_DATE_TIME_ENQ 0x9F8440 491 #define AOT_DATE_TIME 0x9F8441 492 #define AOT_CLOSE_MMI 0x9F8800 493 #define AOT_DISPLAY_CONTROL 0x9F8801 494 #define AOT_DISPLAY_REPLY 0x9F8802 495 #define AOT_TEXT_LAST 0x9F8803 496 #define AOT_TEXT_MORE 0x9F8804 497 #define AOT_KEYPAD_CONTROL 0x9F8805 498 #define AOT_KEYPRESS 0x9F8806 499 #define AOT_ENQ 0x9F8807 500 #define AOT_ANSW 0x9F8808 501 #define AOT_MENU_LAST 0x9F8809 502 #define AOT_MENU_MORE 0x9F880A 503 #define AOT_MENU_ANSW 0x9F880B 504 #define AOT_LIST_LAST 0x9F880C 505 #define AOT_LIST_MORE 0x9F880D 506 #define AOT_SUBTITLE_SEGMENT_LAST 0x9F880E 507 #define AOT_SUBTITLE_SEGMENT_MORE 0x9F880F 508 #define AOT_DISPLAY_MESSAGE 0x9F8810 509 #define AOT_SCENE_END_MARK 0x9F8811 510 #define AOT_SCENE_DONE 0x9F8812 511 #define AOT_SCENE_CONTROL 0x9F8813 512 #define AOT_SUBTITLE_DOWNLOAD_LAST 0x9F8814 513 #define AOT_SUBTITLE_DOWNLOAD_MORE 0x9F8815 514 #define AOT_FLUSH_DOWNLOAD 0x9F8816 515 #define AOT_DOWNLOAD_REPLY 0x9F8817 516 #define AOT_COMMS_CMD 0x9F8C00 517 #define AOT_CONNECTION_DESCRIPTOR 0x9F8C01 518 #define AOT_COMMS_REPLY 0x9F8C02 519 #define AOT_COMMS_SEND_LAST 0x9F8C03 520 #define AOT_COMMS_SEND_MORE 0x9F8C04 521 #define AOT_COMMS_RCV_LAST 0x9F8C05 522 #define AOT_COMMS_RCV_MORE 0x9F8C06 530 int GetTag(
int &Length,
const uint8_t **Data);
531 const uint8_t *
GetData(
const uint8_t *Data,
int &Length);
532 void SendData(
int Tag,
int Length = 0,
const uint8_t *Data = NULL);
540 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
559 if (Length >= 3 && Data && *Data) {
561 for (
int i = 0; i < 3; i++)
562 t = (t << 8) | *(*Data)++;
572 return Length ? Data : NULL;
577 uint8_t buffer[2048];
583 *p++ = (Tag >> 16) & 0xFF;
584 *p++ = (Tag >> 8) & 0xFF;
587 if (p - buffer + Length <
int(
sizeof(buffer))) {
589 memcpy(p, Data, Length);
594 esyslog(
"ERROR: CAM %d: data length (%d) exceeds buffer size",
Tc()->CamSlot()->SlotNumber(), Length);
608 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
621 int Tag =
GetTag(Length, &Data);
640 const uint8_t *d =
GetData(Data, l);
642 esyslog(
"ERROR: CAM %d: resource manager: unexpected data",
Tc()->CamSlot()->SlotNumber());
648 esyslog(
"ERROR: CAM %d: resource manager: unexpected tag %06X in state %d",
Tc()->CamSlot()->SlotNumber(), Tag,
state);
652 default:
esyslog(
"ERROR: CAM %d: resource manager: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
655 else if (
state == 0) {
674 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
695 int Tag =
GetTag(Length, &Data);
700 const uint8_t *d =
GetData(Data, l);
701 if ((l -= 1) < 0)
break;
703 if ((l -= 2) < 0)
break;
706 if ((l -= 2) < 0)
break;
715 default:
esyslog(
"ERROR: CAM %d: application information: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
718 else if (
state == 0) {
737 #define MAXCASYSTEMIDS 64 741 #define CPLM_MORE 0x00 742 #define CPLM_FIRST 0x01 743 #define CPLM_LAST 0x02 744 #define CPLM_ONLY 0x03 745 #define CPLM_ADD 0x04 746 #define CPLM_UPDATE 0x05 750 #define CPCI_OK_DESCRAMBLING 0x01 751 #define CPCI_OK_MMI 0x02 752 #define CPCI_QUERY 0x03 753 #define CPCI_NOT_SELECTED 0x04 768 cCiCaPmt(uint8_t
CmdId,
int Source,
int Transponder,
int ProgramNumber,
const int *CaSystemIds);
772 void AddPid(
int Pid, uint8_t StreamType);
775 cCiCaPmt::cCiCaPmt(uint8_t CmdId,
int Source,
int Transponder,
int ProgramNumber,
const int *CaSystemIds)
783 for (; CaSystemIds[i]; i++)
787 uint8_t caDescriptors[512];
808 uint8_t caDescriptors[512];
835 esyslog(
"ERROR: buffer overflow in CA descriptor");
839 esyslog(
"ERROR: adding CA descriptor without Pid!");
846 #define CAEI_POSSIBLE 0x01 847 #define CAEI_POSSIBLE_COND_PURCHASE 0x02 848 #define CAEI_POSSIBLE_COND_TECHNICAL 0x03 849 #define CAEI_NOT_POSSIBLE_ENTITLEMENT 0x71 850 #define CAEI_NOT_POSSIBLE_TECHNICAL 0x73 852 #define CA_ENABLE_FLAG 0x80 854 #define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0) 856 #define QUERY_WAIT_TIME 1000 // ms to wait before sending a query 857 #define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query 868 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
889 int Tag =
GetTag(Length, &Data);
896 const uint8_t *d =
GetData(Data, l);
898 uint16_t
id = ((uint16_t)(*d) << 8) | *(d + 1);
906 esyslog(
"ERROR: CAM %d: too many CA system IDs!",
Tc()->CamSlot()->SlotNumber());
916 dsyslog(
"CAM %d: system ids:%s",
Tc()->CamSlot()->SlotNumber(), *Ids ? *Ids :
" none");
922 dsyslog(
"CAM %d: replies to QUERY - multi channel decryption possible",
Tc()->CamSlot()->SlotNumber());
927 const uint8_t *d =
GetData(Data, l);
929 uint16_t pnr = ((uint16_t)(*d) << 8) | *(d + 1);
938 if (l % 3 == 0 && l > 1) {
944 uint16_t len = ((uint16_t)(*d) << 8) | *(d + 1);
950 unsigned char caepl = *d;
958 uint16_t pid = ((uint16_t)(*d) << 8) | *(d + 1);
959 unsigned char caees = *(d + 2);
974 default:
esyslog(
"ERROR: CAM %d: conditional access support: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
977 else if (
state == 0) {
989 dsyslog(
"CAM %d: doesn't reply to QUERY - only a single channel can be decrypted",
Tc()->CamSlot()->SlotNumber());
996 if (CaPmt &&
state >= 2) {
1012 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
1025 time_t t = time(NULL);
1028 if (gmtime_r(&t, &tm_gmt) && localtime_r(&t, &tm_loc)) {
1029 int Y = tm_gmt.tm_year;
1030 int M = tm_gmt.tm_mon + 1;
1031 int D = tm_gmt.tm_mday;
1032 int L = (M == 1 || M == 2) ? 1 : 0;
1033 int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
1034 #define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10)) 1036 struct tTime { uint16_t mjd; uint8_t h, m, s;
short offset; };
1038 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)) };
1051 int Tag =
GetTag(Length, &Data);
1056 const uint8_t *d =
GetData(Data, l);
1064 default:
esyslog(
"ERROR: CAM %d: date time: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
1077 #define DCC_SET_MMI_MODE 0x01 1078 #define DCC_DISPLAY_CHARACTER_TABLE_LIST 0x02 1079 #define DCC_INPUT_CHARACTER_TABLE_LIST 0x03 1080 #define DCC_OVERLAY_GRAPHICS_CHARACTERISTICS 0x04 1081 #define DCC_FULL_SCREEN_GRAPHICS_CHARACTERISTICS 0x05 1085 #define MM_HIGH_LEVEL 0x01 1086 #define MM_LOW_LEVEL_OVERLAY_GRAPHICS 0x02 1087 #define MM_LOW_LEVEL_FULL_SCREEN_GRAPHICS 0x03 1091 #define DRI_MMI_MODE_ACK 0x01 1092 #define DRI_LIST_DISPLAY_CHARACTER_TABLES 0x02 1093 #define DRI_LIST_INPUT_CHARACTER_TABLES 0x03 1094 #define DRI_LIST_GRAPHIC_OVERLAY_CHARACTERISTICS 0x04 1095 #define DRI_LIST_FULL_SCREEN_GRAPHIC_CHARACTERISTICS 0x05 1096 #define DRI_UNKNOWN_DISPLAY_CONTROL_CMD 0xF0 1097 #define DRI_UNKNOWN_MMI_MODE 0xF1 1098 #define DRI_UNKNOWN_CHARACTER_TABLE 0xF2 1102 #define EF_BLIND 0x01 1106 #define AI_CANCEL 0x00 1107 #define AI_ANSWER 0x01 1111 char *
GetText(
int &Length,
const uint8_t **Data);
1117 virtual void Process(
int Length = 0,
const uint8_t *Data = NULL);
1153 int Tag =
GetTag(Length, Data);
1160 esyslog(
"ERROR: CAM %d: MMI: unexpected text tag: %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
1167 int Tag =
GetTag(Length, &Data);
1172 const uint8_t *d =
GetData(Data, l);
1177 struct tDisplayReply { uint8_t id; uint8_t mode; };
1183 default:
esyslog(
"ERROR: CAM %d: MMI: unsupported display control command %02X",
Tc()->CamSlot()->SlotNumber(), *d);
1194 const uint8_t *d =
GetData(Data, l);
1219 const uint8_t *d =
GetData(Data, l);
1221 uint8_t blind = *d++;
1236 const uint8_t *d =
GetData(Data, l);
1242 dbgprotocol(
"Slot %d: <== Close MMI (%d) id = %02X delay = %d\n",
Tc()->CamSlot()->SlotNumber(),
SessionId(),
id, delay);
1245 default:
esyslog(
"ERROR: CAM %d: MMI: unknown tag %06X",
Tc()->CamSlot()->SlotNumber(), Tag);
1281 struct tAnswer { uint8_t id;
char text[256]; };
1285 strncpy(answer.text, Text,
sizeof(answer.text));
1393 #define TC_POLL_TIMEOUT 300 // ms WORKAROUND: TC_POLL_TIMEOUT < 300ms doesn't work with DragonCAM 1394 #define TC_ALIVE_TIMEOUT 2000 // ms after which a transport connection is assumed dead 1419 return cas && cas->
Ready();
1445 uint8_t *p = buffer;
1456 buffer[1] = p - buffer - 2;
1491 if (Length == 6 && *(Data + 1) == 0x04) {
1497 switch (ResourceId) {
1522 if (Session &&
sessions[SessionId] == Session) {
1536 const uint8_t *Data = TPDU->
Data(Length);
1537 if (Data && Length > 1) {
1540 uint16_t SessionId = ntohs(
get_unaligned((uint16_t *)&Data[2]));
1543 Session->
Process(Length - 4, Data + 4);
1595 switch (TPDU->
Tag()) {
1622 esyslog(
"ERROR: unknown TPDU tag: 0x%02X (%s)", TPDU->
Tag(), __FUNCTION__);
1643 esyslog(
"ERROR: unknown state: %d (%s)",
state, __FUNCTION__);
1703 esyslog(
"ERROR: no free CAM slot in CI adapter");
1739 #define MODULE_CHECK_INTERVAL 500 // ms 1740 #define MODULE_RESET_TIMEOUT 2 // s 1830 int n = TPDU->
Tcid();
1870 esyslog(
"ERROR: unknown module status %d (%s)", ms, __FUNCTION__);
1927 dsyslog(
"CAM %d: activating on device %d with channel %d (%s)",
SlotNumber(), d->DeviceNumber() + 1, Channel->Number(), Channel->Name());
2021 if (CaSystemIds && *CaSystemIds) {
2027 for (
int Loop = 1; Loop <= 2; Loop++) {
2030 bool Active =
false;
2034 CaPmt.
AddPid(q->pid, q->streamType);
2038 if ((Loop == 1) != Active) {
2052 p->modified =
false;
2064 cCiCaPmt CaPmt(CmdId, 0, 0, 0, NULL);
2094 for (
const int *ids = cas->
GetCaSystemIds(); ids && *ids; ids++) {
2095 for (
const int *
id = CaSystemIds; *id;
id++) {
2109 if (p->programNumber == ProgramNumber) {
2127 if (q->pid == Pid) {
2128 if (q->active != Active) {
2139 #define STREAM_TYPE_VIDEO 0x02 2140 #define STREAM_TYPE_AUDIO 0x04 2141 #define STREAM_TYPE_PRIVATE 0x06 2152 for (
const int *Apid = Channel->
Apids(); *Apid; Apid++)
2154 for (
const int *Dpid = Channel->
Dpids(); *Dpid; Dpid++)
2156 for (
const int *Spid = Channel->
Spids(); *Spid; Spid++)
2163 #define QUERY_REPLY_WAIT 100 // ms to wait between checks for a reply 2177 for (
const int *Apid = Channel->
Apids(); *Apid; Apid++)
2179 for (
const int *Dpid = Channel->
Dpids(); *Dpid; Dpid++)
2181 for (
const int *Spid = Channel->
Spids(); *Spid; Spid++)
2244 for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
2247 if (!CamSlot->Ready()) {
2260 #define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again 2333 #define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL 3600 // seconds between cleanups 2361 if (ccr->ChannelID() == ChannelID)
2380 ccr->ClrChecked(CamSlotNumber);
2381 ccr->ClrDecrypt(CamSlotNumber);
2389 return ccr ? ccr->
CamChecked(CamSlotNumber) :
false;
2396 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
virtual void Action(void)
Handles the attached CAM slots in a separate thread.
bool Process(cTPDU *TPDU=NULL)
cCiCaPidData(int Pid, int StreamType)
virtual 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)
virtual void StartActivation(void)
Puts the CAM in this slot into a mode where an inserted smart card can be activated.
cCamSlot * ItCamSlot(int &Iter)
Iterates over all added CAM slots of this adapter.
cCiSession(uint16_t SessionId, uint32_t ResourceId, cCiTransportConnection *Tc)
cList< cCiCaPidData > pidList
virtual void AddPid(int ProgramNumber, int Pid, int StreamType)
Adds the given PID information to the list of PIDs.
virtual void Write(const uint8_t *Buffer, int Length)
Writes Length bytes of the given Buffer.
void Add(cListObject *Object, cListObject *After=NULL)
#define AOT_PROFILE_CHANGE
bool CamChecked(int CamSlotNumber)
virtual void StartDecrypting(void)
Triggers sending all currently active CA_PMT entries to the CAM, so that it will start decrypting...
int caSystemIds[MAXCASYSTEMIDS+1]
bool TsPayloadStart(const uchar *p)
#define MAX_CONNECTIONS_PER_CAM_SLOT
static char * GetString(int &Length, const uint8_t **Data)
#define MAX_CAM_SLOTS_PER_ADAPTER
#define AOT_APPLICATION_INFO_ENQ
static cString sprintf(const char *fmt,...) __attribute__((format(printf
#define CHANNEL_CAM_RELATIONS_CLEANUP_INTERVAL
virtual void Append(T Data)
int QueueMessage(eMessageType Type, const char *s, int Seconds=0, int Timeout=0)
Like Message(), but this function may be called from a background thread.
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...)
virtual void Receive(uchar *Data, int Length)
This function is called from the cDevice we are attached to, and delivers one TS packet from the set ...
#define ST_CLOSE_SESSION_RESPONSE
virtual void Process(int Length=0, const uint8_t *Data=NULL)
void Detach(cFilter *Filter)
Detaches the given filter from this device.
bool AttachReceiver(cReceiver *Receiver)
Attaches the given receiver to this device.
virtual bool CanActivate(void)
Returns true if there is a CAM in this slot that can be put into activation mode. ...
static bool DumpTPDUDataTransfer
bool AddPids(const int *Pids)
Adds the given zero terminated list of Pids to the list of PIDs of this receiver. ...
uint8_t ListManagement(void)
int GetTag(int &Length, const uint8_t **Data)
#define CPCI_NOT_SELECTED
virtual void Process(int Length=0, const uint8_t *Data=NULL)
#define AOT_APPLICATION_INFO
const int * GetCaSystemIds(void)
const int * Spids(void) const
#define STREAM_TYPE_VIDEO
friend class cCiTransportConnection
virtual ~cCaPidReceiver()
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 Ca(int Index=0) const
#define ST_SESSION_NUMBER
const uint8_t * GetData(const uint8_t *Data, int &Length)
bool CamDecrypt(int CamSlotNumber)
virtual bool HasUserIO(void)
virtual 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]
virtual void AddChannel(const cChannel *Channel)
Adds all PIDs if the given Channel to the current list of PIDs.
uint32_t ResourceId(void)
const int * Apids(void) const
void SetListManagement(uint8_t ListManagement)
#define RI_CONDITIONAL_ACCESS_SUPPORT
int TsPid(const uchar *p)
void SendCaPmt(uint8_t CmdId)
virtual bool Reset(int Slot)
Resets the CAM in the given Slot.
cCiTransportConnection * tc[MAX_CONNECTIONS_PER_CAM_SLOT+1]
void CreateConnection(void)
cCaActivationReceiver * caActivationReceiver
void SendTag(uint8_t Tag, uint16_t SessionId, uint32_t ResourceId=0, int Status=-1)
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
#define MODULE_RESET_TIMEOUT
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
void DelPids(const int *Pids)
Deletes the given zero terminated list of Pids from the list of PIDs of this receiver.
#define ST_CLOSE_SESSION_REQUEST
cCiTransportConnection * tc
cCiSession * GetSessionByResourceId(uint32_t ResourceId)
int caSystemIds[MAXCASYSTEMIDS+1]
const int * Dpids(void) const
cChannelCamRelation(tChannelID ChannelID)
uint32_t ResourceIdToInt(const uint8_t *Data)
void HandleSessions(cTPDU *TPDU)
void Process(cTPDU *TPDU=NULL)
virtual 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)
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 cl...
void SendData(int Tag, int Length=0, const uint8_t *Data=NULL)
cCiSession * GetSessionBySessionId(uint16_t SessionId)
virtual 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
T * Next(const T *object) const
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
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)
bool IsAttached(void)
Returns true if this receiver is (still) attached to a device.
#define ST_OPEN_SESSION_REQUEST
virtual ~cCiTransportConnection()
cCiEnquiry * Enquiry(bool Clear=false)
#define AOT_DISPLAY_REPLY
void ClrChecked(int CamSlotNumber)
cCamSlot(cCiAdapter *CiAdapter, bool WantsTsData=false)
Creates a new CAM slot for the given CiAdapter.
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
virtual int Read(uint8_t *Buffer, int MaxLength)
Reads one chunk of data into the given Buffer, up to MaxLength bytes.
#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)
bool AddPid(int Pid)
Adds the given Pid to the list of PIDs of this receiver.
static uint8_t * SetLength(uint8_t *Data, int Length)
virtual bool Reset(void)
Resets the CAM in this slot.
virtual 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)
const char * GetCamName(void)
void DelPid(int Pid)
Deletes the given Pid from the list of PIDs of this receiver.
void ClrDecrypt(tChannelID ChannelID, int CamSlotNumber)
virtual 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]
virtual 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
bool WaitForAllCamSlotsReady(int Timeout=0)
Waits until all CAM slots have become ready, or the given Timeout (seconds) has expired.
#define CAM_CHECKED_TIMEOUT
void Del(cListObject *Object, bool DeleteObject=true)
#define RI_RESOURCE_MANAGER
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
virtual void Process(int Length=0, const uint8_t *Data=NULL)
cChannel * GetByNumber(int Number, int SkipGap=0)
void SendPMT(cCiCaPmt *CaPmt)
void Reply(const char *s)
cCiMenu * Menu(bool Clear=false)
virtual eModuleStatus ModuleStatus(int Slot)
Returns the status of the CAM in the given Slot.
virtual bool HasMMI(void)
Returns 'true' if the CAM in this slot has an active MMI.
virtual ~cCaActivationReceiver()
cCaActivationReceiver(const cChannel *Channel, cCamSlot *CamSlot)
#define MODULE_CHECK_INTERVAL
tChannelID ChannelID(void)
void SetChecked(tChannelID ChannelID, int CamSlotNumber)
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...
cCiEnquiry * fetchedEnquiry
void ClrDecrypt(int CamSlotNumber)
bool TsIsScrambled(const uchar *p)
cChannelCamRelations ChannelCamRelations
cListObject * Next(void) const
virtual bool Ready(void)
Returns 'true' if the CAM in this slot is ready to decrypt.
void DeleteConnection(void)
cCaPidReceiver * caPidReceiver
virtual void CancelActivation(void)
Cancels a previously started activation (if any).
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...
int Priority(void)
Returns the priority of the device this slot is currently assigned to, or IDLEPRIORITY if it is not a...
bool CamChecked(tChannelID ChannelID, int CamSlotNumber)
virtual 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)
cCiTransportConnection(cCamSlot *CamSlot, uint8_t Tcid)
virtual bool EnterMenu(void)
Requests the CAM in this slot to start its menu.
int GetCaPids(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, int *Pids)
Gets all CA pids for a given channel.
#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)
virtual bool Assign(cDevice *Device, bool Query=false)
Assigns this adapter to the given Device, if this is possible.
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.
virtual void Activate(bool On)
This function is called just before the cReceiver gets attached to (On == true) and right after it ge...
virtual bool IsActivating(void)
Returns true if this CAM slot is currently activating a smart card.
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)
int Priority(void) const
Returns the priority of the current receiving session (-MAXPRIORITY..MAXPRIORITY), or IDLEPRIORITY if no receiver is currently active.
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
virtual void Receive(uchar *Data, int Length)
This function is called from the cDevice we are attached to, and delivers one TS packet from the set ...
cCiResourceManager(uint16_t SessionId, cCiTransportConnection *Tc)
cDevice * Device(void)
Returns the device this CAM slot is currently assigned to.
bool TimedOut(void) const
void SetDecrypt(int CamSlotNumber)