summaryrefslogtreecommitdiff
path: root/ci.c
diff options
context:
space:
mode:
Diffstat (limited to 'ci.c')
-rw-r--r--ci.c71
1 files changed, 49 insertions, 22 deletions
diff --git a/ci.c b/ci.c
index 889c853..760052d 100644
--- a/ci.c
+++ b/ci.c
@@ -4,14 +4,11 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ci.c 1.17 2003/10/26 13:04:23 kls Exp $
+ * $Id: ci.c 1.21 2004/01/02 15:07:36 kls Exp $
*/
-/* XXX TODO
-- update CA descriptors in case they change
-XXX*/
-
#include "ci.h"
+#include <asm/unaligned.h>
#include <ctype.h>
#include <linux/dvb/ca.h>
#include <malloc.h>
@@ -21,6 +18,7 @@ XXX*/
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
+#include "pat.h"
#include "tools.h"
/* these might come in handy in case you want to use this code without VDR's other files:
@@ -793,10 +791,10 @@ bool cCiApplicationInformation::Process(int Length, const uint8_t *Data)
if ((l -= 1) < 0) break;
applicationType = *d++;
if ((l -= 2) < 0) break;
- applicationManufacturer = ntohs(*(uint16_t *)d);
+ applicationManufacturer = ntohs(get_unaligned((uint16_t *)d));
d += 2;
if ((l -= 2) < 0) break;
- manufacturerCode = ntohs(*(uint16_t *)d);
+ manufacturerCode = ntohs(get_unaligned((uint16_t *)d));
d += 2;
free(menuString);
menuString = GetString(l, &d);
@@ -1265,8 +1263,9 @@ bool cCiEnquiry::Cancel(void)
#define CPCI_QUERY 0x03
#define CPCI_NOT_SELECTED 0x04
-cCiCaPmt::cCiCaPmt(int ProgramNumber)
+cCiCaPmt::cCiCaPmt(int Source, int Transponder, int ProgramNumber, const unsigned short *CaSystemIds)
{
+ caDescriptorsLength = GetCaDescriptors(Source, Transponder, ProgramNumber, CaSystemIds, sizeof(caDescriptors), caDescriptors, streamFlag);
length = 0;
capmt[length++] = CPLM_ONLY;
capmt[length++] = (ProgramNumber >> 8) & 0xFF;
@@ -1275,20 +1274,31 @@ cCiCaPmt::cCiCaPmt(int ProgramNumber)
esInfoLengthPos = length;
capmt[length++] = 0x00; // program_info_length H (at program level)
capmt[length++] = 0x00; // program_info_length L
+ if (!streamFlag)
+ AddCaDescriptors(caDescriptorsLength, caDescriptors);
}
-void cCiCaPmt::AddPid(int Pid)
+bool cCiCaPmt::Valid(void)
{
- //XXX buffer overflow check???
- capmt[length++] = 0x00; //XXX stream_type (apparently doesn't matter)
- capmt[length++] = (Pid >> 8) & 0xFF;
- capmt[length++] = Pid & 0xFF;
- esInfoLengthPos = length;
- capmt[length++] = 0x00; // ES_info_length H (at ES level)
- capmt[length++] = 0x00; // ES_info_length L
+ return caDescriptorsLength > 0;
+}
+
+void cCiCaPmt::AddPid(int Pid, uint8_t StreamType)
+{
+ if (Pid) {
+ //XXX buffer overflow check???
+ capmt[length++] = StreamType;
+ capmt[length++] = (Pid >> 8) & 0xFF;
+ capmt[length++] = Pid & 0xFF;
+ esInfoLengthPos = length;
+ capmt[length++] = 0x00; // ES_info_length H (at ES level)
+ capmt[length++] = 0x00; // ES_info_length L
+ if (streamFlag)
+ AddCaDescriptors(caDescriptorsLength, caDescriptors);
+ }
}
-void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
+void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data)
{
if (esInfoLengthPos) {
if (length + Length < int(sizeof(capmt))) {
@@ -1355,7 +1365,7 @@ cCiHandler *cCiHandler::CreateCiHandler(const char *FileName)
int cCiHandler::ResourceIdToInt(const uint8_t *Data)
{
- return (ntohl(*(int *)Data));
+ return (ntohl(get_unaligned((int32_t *)Data)));
}
bool cCiHandler::Send(uint8_t Tag, int SessionId, int ResourceId, int Status)
@@ -1367,10 +1377,10 @@ bool cCiHandler::Send(uint8_t Tag, int SessionId, int ResourceId, int Status)
if (Status >= 0)
*p++ = Status;
if (ResourceId) {
- *(int *)p = htonl(ResourceId);
+ put_unaligned(htonl(ResourceId), (int32_t *)p);
p += 4;
}
- *(short *)p = htons(SessionId);
+ put_unaligned(htons(SessionId), (uint16_t *)p);
p += 2;
buffer[1] = p - buffer - 2; // length
return tc && tc->SendData(p - buffer, buffer) == OK;
@@ -1481,7 +1491,7 @@ bool cCiHandler::Process(void)
if (Data && Length > 1) {
switch (*Data) {
case ST_SESSION_NUMBER: if (Length > 4) {
- int SessionId = ntohs(*(short *)&Data[2]);
+ int SessionId = ntohs(get_unaligned((uint16_t *)&Data[2]));
cCiSession *Session = GetSessionBySessionId(SessionId);
if (Session)
Session->Process(Length - 4, Data + 4);
@@ -1492,7 +1502,7 @@ bool cCiHandler::Process(void)
case ST_OPEN_SESSION_REQUEST: OpenSession(Length, Data);
break;
case ST_CLOSE_SESSION_REQUEST: if (Length == 4)
- CloseSession(ntohs(*(short *)&Data[2]));
+ CloseSession(ntohs(get_unaligned((uint16_t *)&Data[2])));
break;
case ST_CREATE_SESSION_RESPONSE: //XXX fall through to default
case ST_CLOSE_SESSION_RESPONSE: //XXX fall through to default
@@ -1556,6 +1566,23 @@ const unsigned short *cCiHandler::GetCaSystemIds(int Slot)
return cas ? cas->GetCaSystemIds() : NULL;
}
+bool cCiHandler::ProvidesCa(const unsigned short *CaSystemIds)
+{
+ cMutexLock MutexLock(&mutex);
+ for (int Slot = 0; Slot < numSlots; Slot++) {
+ cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
+ if (cas) {
+ for (const unsigned short *ids = cas->GetCaSystemIds(); ids && *ids; ids++) {
+ for (const unsigned short *id = CaSystemIds; *id; id++) {
+ if (*id == *ids)
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt, int Slot)
{
cMutexLock MutexLock(&mutex);