diff options
Diffstat (limited to 'ci.c')
-rw-r--r-- | ci.c | 71 |
1 files changed, 49 insertions, 22 deletions
@@ -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); |