1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed lock handling in CAM communication to avoid problems with multiple CAMs per device or CAMs with more than one smart card

This commit is contained in:
Klaus Schmidinger 2005-10-30 13:21:23 +01:00
parent 3c59953017
commit 6e982f765e
3 changed files with 36 additions and 23 deletions

View File

@ -3905,3 +3905,5 @@ Video Disk Recorder Revision History
- Updated the Estonian OSD texts (thanks to Arthur Konovalov). - Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Added missing mutex locks to cCiMenu::Abort() and cCiEnquiry::Abort() (reported - Added missing mutex locks to cCiMenu::Abort() and cCiEnquiry::Abort() (reported
by Marco Schlüßler). by Marco Schlüßler).
- Fixed lock handling in CAM communication to avoid problems with multiple CAMs
per device or CAMs with more than one smart card.

49
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 1.37 2005/10/30 10:24:38 kls Exp $ * $Id: ci.c 1.38 2005/10/30 13:04:10 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -156,7 +156,7 @@ public:
uint8_t Status(void); uint8_t Status(void);
int Write(int fd); int Write(int fd);
int Read(int fd); int Read(int fd);
void Dump(bool Outgoing); void Dump(int fd, bool Outgoing);
}; };
cTPDU::cTPDU(uint8_t Slot, uint8_t Tcid, uint8_t Tag, int Length, const uint8_t *Data) cTPDU::cTPDU(uint8_t Slot, uint8_t Tcid, uint8_t Tag, int Length, const uint8_t *Data)
@ -207,9 +207,9 @@ cTPDU::cTPDU(uint8_t Slot, uint8_t Tcid, uint8_t Tag, int Length, const uint8_t
int cTPDU::Write(int fd) int cTPDU::Write(int fd)
{ {
Dump(true); Dump(fd, true);
if (size) if (size)
return write(fd, data, size) == size ? OK : ERROR; return safe_write(fd, data, size) == size ? OK : ERROR;
esyslog("ERROR: attemp to write TPDU with zero size"); esyslog("ERROR: attemp to write TPDU with zero size");
return ERROR; return ERROR;
} }
@ -222,20 +222,20 @@ int cTPDU::Read(int fd)
size = 0; size = 0;
return ERROR; return ERROR;
} }
Dump(false); Dump(fd, false);
return OK; return OK;
} }
void cTPDU::Dump(bool Outgoing) void cTPDU::Dump(int fd, bool Outgoing)
{ {
if (DumpTPDUDataTransfer) { if (DumpTPDUDataTransfer) {
#define MAX_DUMP 256 #define MAX_DUMP 256
fprintf(stderr, "%s ", Outgoing ? "-->" : "<--"); fprintf(stderr, "%2d %s ", fd, Outgoing ? "-->" : "<--");
for (int i = 0; i < size && i < MAX_DUMP; i++) for (int i = 0; i < size && i < MAX_DUMP; i++)
fprintf(stderr, "%02X ", data[i]); fprintf(stderr, "%02X ", data[i]);
fprintf(stderr, "%s\n", size >= MAX_DUMP ? "..." : ""); fprintf(stderr, "%s\n", size >= MAX_DUMP ? "..." : "");
if (!Outgoing) { if (!Outgoing) {
fprintf(stderr, " "); fprintf(stderr, " ");
for (int i = 0; i < size && i < MAX_DUMP; i++) for (int i = 0; i < size && i < MAX_DUMP; i++)
fprintf(stderr, "%2c ", isprint(data[i]) ? data[i] : '.'); fprintf(stderr, "%2c ", isprint(data[i]) ? data[i] : '.');
fprintf(stderr, "%s\n", size >= MAX_DUMP ? "..." : ""); fprintf(stderr, "%s\n", size >= MAX_DUMP ? "..." : "");
@ -1048,12 +1048,12 @@ cCiMMI::cCiMMI(int SessionId, cCiTransportConnection *Tc)
cCiMMI::~cCiMMI() cCiMMI::~cCiMMI()
{ {
if (fetchedMenu) { if (fetchedMenu) {
cMutexLock MutexLock(&fetchedMenu->mutex); cMutexLock MutexLock(fetchedMenu->mutex);
fetchedMenu->mmi = NULL; fetchedMenu->mmi = NULL;
} }
delete menu; delete menu;
if (fetchedEnquiry) { if (fetchedEnquiry) {
cMutexLock MutexLock(&fetchedEnquiry->mutex); cMutexLock MutexLock(fetchedEnquiry->mutex);
fetchedEnquiry->mmi = NULL; fetchedEnquiry->mmi = NULL;
} }
delete enquiry; delete enquiry;
@ -1227,7 +1227,7 @@ cCiMenu::cCiMenu(cCiMMI *MMI, bool Selectable)
cCiMenu::~cCiMenu() cCiMenu::~cCiMenu()
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
if (mmi) if (mmi)
mmi->Menu(true); mmi->Menu(true);
free(titleText); free(titleText);
@ -1254,7 +1254,8 @@ bool cCiMenu::HasUpdate(void)
bool cCiMenu::Select(int Index) bool cCiMenu::Select(int Index)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
dbgprotocol("%d: ==> Select %d\n", mmi ? mmi->SessionId() : -1, Index);
if (mmi && -1 <= Index && Index < numEntries) if (mmi && -1 <= Index && Index < numEntries)
return mmi->SendMenuAnswer(Index + 1); return mmi->SendMenuAnswer(Index + 1);
return false; return false;
@ -1267,7 +1268,7 @@ bool cCiMenu::Cancel(void)
bool cCiMenu::Abort(void) bool cCiMenu::Abort(void)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
return mmi && mmi->SendCloseMMI(); return mmi && mmi->SendCloseMMI();
} }
@ -1283,7 +1284,7 @@ cCiEnquiry::cCiEnquiry(cCiMMI *MMI)
cCiEnquiry::~cCiEnquiry() cCiEnquiry::~cCiEnquiry()
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
if (mmi) if (mmi)
mmi->Enquiry(true); mmi->Enquiry(true);
free(text); free(text);
@ -1291,7 +1292,7 @@ cCiEnquiry::~cCiEnquiry()
bool cCiEnquiry::Reply(const char *s) bool cCiEnquiry::Reply(const char *s)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
return mmi ? mmi->SendAnswer(s) : false; return mmi ? mmi->SendAnswer(s) : false;
} }
@ -1302,7 +1303,7 @@ bool cCiEnquiry::Cancel(void)
bool cCiEnquiry::Abort(void) bool cCiEnquiry::Abort(void)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(mutex);
return mmi && mmi->SendCloseMMI(); return mmi && mmi->SendCloseMMI();
} }
@ -1619,8 +1620,12 @@ cCiMenu *cCiHandler::GetMenu(void)
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
for (int Slot = 0; Slot < numSlots; Slot++) { for (int Slot = 0; Slot < numSlots; Slot++) {
cCiMMI *mmi = (cCiMMI *)GetSessionByResourceId(RI_MMI, Slot); cCiMMI *mmi = (cCiMMI *)GetSessionByResourceId(RI_MMI, Slot);
if (mmi) if (mmi) {
return mmi->Menu(); cCiMenu *Menu = mmi->Menu();
if (Menu)
Menu->mutex = &mutex;
return Menu;
}
} }
return NULL; return NULL;
} }
@ -1630,8 +1635,12 @@ cCiEnquiry *cCiHandler::GetEnquiry(void)
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
for (int Slot = 0; Slot < numSlots; Slot++) { for (int Slot = 0; Slot < numSlots; Slot++) {
cCiMMI *mmi = (cCiMMI *)GetSessionByResourceId(RI_MMI, Slot); cCiMMI *mmi = (cCiMMI *)GetSessionByResourceId(RI_MMI, Slot);
if (mmi) if (mmi) {
return mmi->Enquiry(); cCiEnquiry *Enquiry = mmi->Enquiry();
if (Enquiry)
Enquiry->mutex = &mutex;
return Enquiry;
}
} }
return NULL; return NULL;
} }

8
ci.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.h 1.17 2005/10/03 12:49:52 kls Exp $ * $Id: ci.h 1.18 2005/10/30 12:31:14 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -17,11 +17,12 @@
class cCiMMI; class cCiMMI;
class cCiMenu { class cCiMenu {
friend class cCiHandler;
friend class cCiMMI; friend class cCiMMI;
private: private:
enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum? enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum?
cCiMMI *mmi; cCiMMI *mmi;
cMutex mutex; cMutex *mutex;
bool selectable; bool selectable;
char *titleText; char *titleText;
char *subTitleText; char *subTitleText;
@ -45,10 +46,11 @@ public:
}; };
class cCiEnquiry { class cCiEnquiry {
friend class cCiHandler;
friend class cCiMMI; friend class cCiMMI;
private: private:
cCiMMI *mmi; cCiMMI *mmi;
cMutex mutex; cMutex *mutex;
char *text; char *text;
bool blind; bool blind;
int expectedLength; int expectedLength;