diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2003-04-21 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2003-04-21 18:00:00 +0200 |
commit | 21a52ccb6d43cce35f7a381f55ea291195416f33 (patch) | |
tree | bc7d86214e695434ca7170bff799bcc4aaca5401 /ci.c | |
parent | 9f919801465f49be6b2118f54bd54df846e2f865 (diff) | |
download | vdr-patch-lnbsharing-21a52ccb6d43cce35f7a381f55ea291195416f33.tar.gz vdr-patch-lnbsharing-21a52ccb6d43cce35f7a381f55ea291195416f33.tar.bz2 |
Version 1.1.28vdr-1.1.28
- Using masks in EIT filtering to reduce the number of filters (thanks to Andreas
Schultz).
- Fixed handling Ca descriptors (thanks to Stefan Huelswitt).
- Now only those Ca descriptors are sent to a CAM that are actually understood
by that CAM.
- Re-enabled CAM communication during replay and on non-Ca channels. This requires
a DVB driver with firmware version 2613 or later.
- It is now possible to do simultaneous recording and replay with a single DVB
card, even with encrypted channels. This requires the use of the Link Layer
firmware, version 2613 or higher; the -icam firmware is still limited to live
encrypted channels only. Finally we have time shift for encrypted channels on
single card systems!
- Enhanced detection of pending user I/O from CAMs to avoid sluggish reaction
to remote control keypresses.
- Implemented "pause live video". You can now press "Menu/Yellow" or "Pause" on
your remote control while watching live video to start an instant recording
of the current programme and immediately start replaying that recording.
Diffstat (limited to 'ci.c')
-rw-r--r-- | ci.c | 61 |
1 files changed, 42 insertions, 19 deletions
@@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 1.9 2003/03/23 15:18:40 kls Exp $ + * $Id: ci.c 1.14 2003/04/20 09:52:45 kls Exp $ */ /* XXX TODO @@ -625,6 +625,7 @@ public: const cCiTransportConnection *Tc(void) { return tc; } int SessionId(void) { return sessionId; } int ResourceId(void) { return resourceId; } + virtual bool HasUserIO(void) { return false; } virtual bool Process(int Length = 0, const uint8_t *Data = NULL); }; @@ -769,7 +770,7 @@ public: cCiApplicationInformation::cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc) :cCiSession(SessionId, RI_APPLICATION_INFORMATION, Tc) { - dbgprotocol("New Aplication Information (session id %d)\n", SessionId); + dbgprotocol("New Application Information (session id %d)\n", SessionId); state = 0; creationTime = time(NULL); menuString = NULL; @@ -827,12 +828,17 @@ bool cCiApplicationInformation::EnterMenu(void) // --- cCiConditionalAccessSupport ------------------------------------------- +#define MAXCASYSTEMIDS 16 + class cCiConditionalAccessSupport : public cCiSession { private: int state; + int numCaSystemIds; + unsigned short caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! public: cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc); virtual bool Process(int Length = 0, const uint8_t *Data = NULL); + const unsigned short *GetCaSystemIds(void) { return caSystemIds; } bool SendPMT(cCiCaPmt &CaPmt); }; @@ -841,6 +847,7 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTrans { dbgprotocol("New Conditional Access Support (session id %d)\n", SessionId); state = 0; + caSystemIds[numCaSystemIds = 0] = 0; } bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data) @@ -853,9 +860,16 @@ bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data) int l = 0; const uint8_t *d = GetData(Data, l); while (l > 1) { - dbgprotocol(" %04X", ((unsigned int)(*d) << 8) | *(d + 1)); + unsigned short id = ((unsigned short)(*d) << 8) | *(d + 1); + dbgprotocol(" %04X", id); d += 2; l -= 2; + if (numCaSystemIds < MAXCASYSTEMIDS) { + caSystemIds[numCaSystemIds++] = id; + caSystemIds[numCaSystemIds] = 0; + } + else + esyslog("ERROR: too many CA system IDs!"); } dbgprotocol("\n"); } @@ -996,6 +1010,7 @@ public: cCiMMI(int SessionId, cCiTransportConnection *Tc); virtual ~cCiMMI(); virtual bool Process(int Length = 0, const uint8_t *Data = NULL); + virtual bool HasUserIO(void) { return menu || enquiry; } cCiMenu *Menu(void); cCiEnquiry *Enquiry(void); bool SendMenuAnswer(uint8_t Selection); @@ -1273,7 +1288,8 @@ void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data) cCiHandler::cCiHandler(int Fd, int NumSlots) { numSlots = NumSlots; - enabled = true; + newCaSupport = false; + hasUserIO = false; for (int i = 0; i < MAX_CI_SESSION; i++) sessions[i] = NULL; tpl = new cCiTransportLayer(Fd, numSlots); @@ -1299,12 +1315,14 @@ cCiHandler *cCiHandler::CreateCiHandler(const char *FileName) if (Caps.slot_type == CA_CI_LINK) return new cCiHandler(fd_ca, NumSlots); else - esyslog("ERROR: CAM doesn't support link layer interface"); + isyslog("CAM doesn't support link layer interface"); } - esyslog("ERROR: no CAM slots found"); + else + esyslog("ERROR: no CAM slots found"); } else LOG_ERROR_STR(FileName); + close(fd_ca); } return NULL; } @@ -1358,7 +1376,8 @@ cCiSession *cCiHandler::CreateSession(int ResourceId) switch (ResourceId) { case RI_RESOURCE_MANAGER: return sessions[i] = new cCiResourceManager(i + 1, tc); case RI_APPLICATION_INFORMATION: return sessions[i] = new cCiApplicationInformation(i + 1, tc); - case RI_CONDITIONAL_ACCESS_SUPPORT: return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc); + case RI_CONDITIONAL_ACCESS_SUPPORT: newCaSupport = true; + return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc); case RI_HOST_CONTROL: break; //XXX case RI_DATE_TIME: return sessions[i] = new cCiDateTime(i + 1, tc); case RI_MMI: return sessions[i] = new cCiMMI(i + 1, tc); @@ -1426,8 +1445,6 @@ int cCiHandler::CloseAllSessions(int Slot) bool cCiHandler::Process(void) { - if (!enabled) - return false; bool result = true; cMutexLock MutexLock(&mutex); for (int Slot = 0; Slot < numSlots; Slot++) { @@ -1466,10 +1483,14 @@ bool cCiHandler::Process(void) tpl->NewConnection(Slot); } } + bool UserIO = false; for (int i = 0; i < MAX_CI_SESSION; i++) { - if (sessions[i]) - sessions[i]->Process(); + if (sessions[i] && sessions[i]->Process()) + UserIO |= sessions[i]->HasUserIO(); } + hasUserIO = UserIO; + if (newCaSupport) + newCaSupport = result = false; // triggers new SetCaPmt at caller! return result; } @@ -1502,16 +1523,18 @@ cCiEnquiry *cCiHandler::GetEnquiry(void) return NULL; } -bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt) +const unsigned short *cCiHandler::GetCaSystemIds(int Slot) { cMutexLock MutexLock(&mutex); - bool result = false; - for (int Slot = 0; Slot < numSlots; Slot++) { - cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot); - if (cas) - result |= cas->SendPMT(CaPmt); - } - return result; + cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot); + return cas ? cas->GetCaSystemIds() : NULL; +} + +bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt, int Slot) +{ + cMutexLock MutexLock(&mutex); + cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot); + return cas && cas->SendPMT(CaPmt); } bool cCiHandler::Reset(int Slot) |