From: leslie Date: Fri, 27 Feb 2009 00:01:28 +0000 (+0800) Subject: smartcards: introduce cardslot.conf X-Git-Tag: 0.9.2~60 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=0689ca3467bc5cfc5b50fb70cea7c8d9661ad7f1;p=sasc-ng.git smartcards: introduce cardslot.conf --- diff --git a/Makefile b/Makefile index 05fc2e9..5a410f2 100644 --- a/Makefile +++ b/Makefile @@ -110,14 +110,9 @@ endif # generic stuff # -# smartcard default port +# smartcard default port (dropped) ifdef DEFAULT_PORT - TEST := $(shell echo '$(DEFAULT_PORT)' | sed -ne '/".*",.*,.*,.*/p') - ifneq ($(strip $(TEST)),) - DEFINES += -DDEFAULT_PORT='$(DEFAULT_PORT)' - else - $(error DEFAULT_PORT has bad format) - endif + $(error DEFAULT_PORT support was removed, use cardslot.conf) endif # max number of CAIDs per slot diff --git a/README b/README index 8eba99a..708eac8 100644 --- a/README +++ b/README @@ -243,29 +243,11 @@ Smartcard support ----------------- For most encrpytion systems this plugin supports original subscription -smartcards on a Phoenix/Smartmouse ISO interface connected to a serial port. - -To enable smartcard support you have to copy one or more of the smartcard -systems to the VDR plugin lib directory. To actually activate the smartcard -interface, you should use the commandline option "-s" to specify one or more -serial devices to which the Phoenix interface are connected e.g. use "-s -/dev/ttyS0 -s /dev/ttyS1" to use two intefaces at COM1/COM2. If you want to add -a default smartcard interface at compile time use the make option DEFAULT_PORT, -e.g. DEFAULT_PORT='"/dev/ttyS0",0,0,0'. Note the quotes and double quotes. The -three numeric values are identical to the -I and -R options (set to 1 to enable) -and -C option (set to 0 for default clock) below. - -Appearently there are "broken" card readers which swap the meaning of the CD -line (used for card detection). For these readers use the option "-I". This -enables inverse CD detection for the next interface e.g. "-I -s /dev/ttyS0 -s -/dev/ttyS1" will use inverse CD on COM1 and normal CD on COM2 while "-I -s -/dev/ttyS0 -I -s /dev/ttyS1" will use inverse CD on both. -Some other card readers have a reversed logic with the reset line (card won't -reset with default settings). You can use the option "-R" for these readers. -In some cases it's mandatory to know the exact clock frequency at which your -cardreader runs (e.g. for baudrate calculations). With the option "-C" you can -give a clock frequency (in Hz) which will be used instead of the default -(3571200 Hz) for the next interface e.g. "-C 3579545 -s /dev/ttyS1". +smartcards (e.g. from a Phoenix/Smartmouse ISO interface connected to a serial +port). + +The configuartion of the smartcard slots if done in the "cardslot.conf" file +(see example file for format). Some smartcards need additional information to establish communication with the card (e.g. certificate or box key for camcrypt). These information must be diff --git a/examples/cardslot.conf.example b/examples/cardslot.conf.example new file mode 100644 index 0000000..b5d471b --- /dev/null +++ b/examples/cardslot.conf.example @@ -0,0 +1,13 @@ +; +; Comment lines can start with # or ; +; + +; cardslot with phoenix/smartmouse cardreader on serial port +; +; dev - serial device e.g. /dev/ttyS0 +; CD - card detect 0=normal 1=inverted +; RST - card reset 0=normal 1=inverted +; clock - clock frequency in Hz. If missing or 0, default=3571200 +; +serial:/dev/ttyS0:0:0 +serial:/dev/ttyS1:1:0:3579545 diff --git a/sc.c b/sc.c index 6a7dcdd..c7c92c0 100644 --- a/sc.c +++ b/sc.c @@ -229,9 +229,13 @@ eOSState cMenuEditHexItem::ProcessKey(eKeys Key) class cScInfoItem : public cOsdItem { private: void SetValue(const char *Name, const char *Value); + // + int ident; public: cScInfoItem(const char *Name, int Value, eOSState State=osUnknown); cScInfoItem(const char *Name, const char *Value=0, eOSState State=osUnknown); + void Ident(int id) { ident=id; } + int Ident(void) { return ident; } }; cScInfoItem::cScInfoItem(const char *Name, int Value, eOSState State) @@ -256,6 +260,7 @@ void cScInfoItem::SetValue(const char *Name, const char *Value) asprintf(&buff,Value ? "%s:\t%s":"%s",Name,Value); SetText(buff,false); cStatus::MsgOsdCurrentItem(buff); + ident=-1; } // --- cOpt -------------------------------------------------------------------- @@ -839,11 +844,6 @@ public: virtual eOSState ProcessKey(eKeys Key); }; -static eOSState portStates[] = { osUser1,osUser2,osUser3,osUser4 }; -#if MAX_PORTS!=4 -#error Update portStates[] -#endif - cMenuSetupSc::cMenuSetupSc(const char *CfgDir) { cfgdir=strdup(CfgDir); @@ -860,8 +860,11 @@ cMenuSetupSc::cMenuSetupSc(const char *CfgDir) for(int i=0; smartcards.ListCard(i,id,sizeof(id)); i++) { char buff[32]; snprintf(buff,sizeof(buff),"%s %d",tr("Smartcard interface"),i); - if(id[0]) Add(new cScInfoItem(buff,id,portStates[i])); - else Add(new cScInfoItem(buff,tr("(empty)"))); + cScInfoItem *ii; + if(id[0]) ii=new cScInfoItem(buff,id,osUser4); + else ii=new cScInfoItem(buff,tr("(empty)")); + ii->Ident(i); + Add(ii); } } Add(new cOsdItem(tr("Status information..."),osUser8)); @@ -883,10 +886,10 @@ eOSState cMenuSetupSc::ProcessKey(eKeys Key) { eOSState state = cOsdMenu::ProcessKey(Key); switch(state) { - case osUser1...osUser4: + case osUser4: if(Feature.SmartCard()) { - for(unsigned int i=0; i(Get(Current())); + if(ii) return(AddSubMenu(new cMenuInfoCard(ii->Ident()))); } state=osContinue; break; @@ -1008,12 +1011,17 @@ bool cScSetup::Ignore(unsigned short caid) bool cSoftCAM::Load(const char *cfgdir) { if(!Feature.KeyFile()) keys.Disable(); - if(!Feature.SmartCard()) carddatas.Disable(); + if(!Feature.SmartCard()) { + carddatas.Disable(); + smartcards.Disable(); + } cStructLoaders::Load(false); if(Feature.KeyFile() && keys.Count()<1) PRINTF(L_GEN_ERROR,"no keys loaded for softcam!"); if(!cSystems::Init(cfgdir)) return false; srand(time(0)); + if(Feature.SmartCard()) + smartcards.LaunchWatcher(); return true; } @@ -1307,12 +1315,6 @@ bool cScPlugin::Start(void) cStructLoaders::SetCfgDir(cfgdir); ScSetup.Check(); if(!cSoftCAM::Load(cfgdir)) return false; - if(Feature.SmartCard()) { -#ifdef DEFAULT_PORT - smartcards.AddPort(DEFAULT_PORT); -#endif - smartcards.LaunchWatcher(); - } cScDvbDevice::Startup(); keeper=new cScHousekeeper; return true; @@ -1346,17 +1348,11 @@ const char *cScPlugin::CommandLineHelp(void) free(help_str); // for easier orientation, this is column 80| asprintf(&help_str," -B N --budget=N forces DVB device N to budget mode (using FFdecsa)\n" - " -I --inverse-cd use inverse CD detection for the next serial device\n" - " -R --inverse-rst use inverse RESET for the next serial device\n" - " -C FREQ --clock=FREQ use FREQ as clock for the card reader on the next\n" - " serial device (rather than 3.5712 MHz\n" - " -s DEV --serial=DEV activate Phoenix ISO interface on serial device DEV\n" - " (default: %s)\n" " -d CMD --dialup=CMD call CMD to start/stop dialup-network\n" " (default: %s)\n" " -t SECS --timeout=SECS shutdown timeout for dialup-network\n" " (default: %d secs)\n", - "none","none",netTimeout/1000 + "none",netTimeout/1000 ); return help_str; } @@ -1364,10 +1360,10 @@ const char *cScPlugin::CommandLineHelp(void) bool cScPlugin::ProcessArgs(int argc, char *argv[]) { static struct option long_options[] = { - { "serial", required_argument, NULL, 's' }, + { "serial", optional_argument, NULL, 's' }, { "inverse-cd", no_argument, NULL, 'I' }, { "inverse-rst", no_argument, NULL, 'R' }, - { "clock", required_argument, NULL, 'C' }, + { "clock", optional_argument, NULL, 'C' }, { "dialup", required_argument, NULL, 'd' }, { "external-au", required_argument, NULL, 'E' }, { "budget", required_argument, NULL, 'B' }, @@ -1375,14 +1371,12 @@ bool cScPlugin::ProcessArgs(int argc, char *argv[]) }; int c, option_index=0; - bool invCD=false, invRST=false; - int clock=0; while((c=getopt_long(argc,argv,"d:s:t:B:C:E:IR",long_options,&option_index))!=-1) { switch (c) { - case 'I': invCD=true; break; - case 'R': invRST=true; break; - case 'C': clock=atoi(optarg); break; - case 's': smartcards.AddPort(optarg,invCD,invRST,clock); invCD=false; invRST=false; clock=0; break; + case 'I': + case 'R': + case 'C': + case 's': fprintf(stderr,"smartcard commandline options were removed. use cardslot.conf\n"); return false; case 'd': netscript=optarg; break; case 't': netTimeout=atoi(optarg)*1000; break; case 'E': externalAU=optarg; break; diff --git a/smartcard.c b/smartcard.c index fa7f73d..ef1bc51 100644 --- a/smartcard.c +++ b/smartcard.c @@ -35,7 +35,6 @@ #include "misc.h" #include "log-core.h" -#define DATAFILE "smartcard.conf" #define ISO_FREQ 3571200 // Hz //#define SER_EMU // use serial emulation (select one of the following) @@ -748,6 +747,61 @@ void cInfoStr::Finish() current=Grab(); } +// -- cSmartCardData ----------------------------------------------------------- + +cSmartCardData::cSmartCardData(int Ident) +{ + ident=Ident; +} + +// -- cSmartCardDatas ---------------------------------------------------------- + +cSmartCardDatas carddatas; + +cSmartCardDatas::cSmartCardDatas(void) +:cStructList("smartcard data","smartcard.conf",SL_MISSINGOK|SL_WATCH|SL_VERBOSE) +{} + +cSmartCardData *cSmartCardDatas::Find(cSmartCardData *param) +{ + ListLock(false); + cSmartCardData *cd; + for(cd=First(); cd; cd=Next(cd)) + if(cd->Ident()==param->Ident() && cd->Matches(param)) break; + ListUnlock(); + return cd; +} + +cStructItem *cSmartCardDatas::ParseLine(char *line) +{ + char *r=index(line,':'); + if(r) + for(cSmartCardLink *scl=cSmartCards::first; scl; scl=scl->next) + if(!strncasecmp(scl->name,line,r-line)) { + cSmartCardData *scd=scl->CreateData(); + if(scd && scd->Parse(r+1)) return scd; + delete scd; + break; + } + return 0; +} + +// -- cSmartCardSlot ----------------------------------------------------------- + +cSmartCardSlot::cSmartCardSlot(int num) +{ + Serial=0; Card=0; + CardId=0; UseCount=0; Dead=false; + SlotNum=num; + Clock=ISO_FREQ; +} + +cSmartCardSlot::~cSmartCardSlot() +{ + delete Card; + delete Serial; +} + // -- cSmartCard --------------------------------------------------------------- static const int Ftable[16] = { @@ -1086,45 +1140,6 @@ int cSmartCard::CheckSctLen(const unsigned char *data, int off) return l; } -// -- cSmartCardData ----------------------------------------------------------- - -cSmartCardData::cSmartCardData(int Ident) -{ - ident=Ident; -} - -// -- cSmartCardDatas ---------------------------------------------------------- - -cSmartCardDatas carddatas; - -cSmartCardDatas::cSmartCardDatas(void) -:cStructList("smartcard data",DATAFILE,SL_MISSINGOK|SL_WATCH|SL_VERBOSE) -{} - -cSmartCardData *cSmartCardDatas::Find(cSmartCardData *param) -{ - ListLock(false); - cSmartCardData *cd; - for(cd=First(); cd; cd=Next(cd)) - if(cd->Ident()==param->Ident() && cd->Matches(param)) break; - ListUnlock(); - return cd; -} - -cStructItem *cSmartCardDatas::ParseLine(char *line) -{ - char *r=index(line,':'); - if(r) - for(cSmartCardLink *scl=cSmartCards::first; scl; scl=scl->next) - if(!strncasecmp(scl->name,line,r-line)) { - cSmartCardData *scd=scl->CreateData(); - if(scd && scd->Parse(r+1)) return scd; - delete scd; - break; - } - return 0; -} - // -- cSmartCardLink ----------------------------------------------------------- cSmartCardLink::cSmartCardLink(const char *Name, int Id) @@ -1143,8 +1158,8 @@ static const char *serModes[] = { 0,"8e2","8o2","8n2" }; cSmartCards::cSmartCards(void) :cThread("SmartcardWatcher") +,cStructListPlain("cardslot config","cardslot.conf",SL_MISSINGOK|SL_VERBOSE|SL_NOPURGE) { - for(int i=0 ; i0) Start(); + else { + firstRun=false; + PRINTF(L_GEN_WARN,"no smartcard slot defined!"); + } } void cSmartCards::Shutdown(void) +{ + PreLoad(); +} + +void cSmartCards::PreLoad(void) { Cancel(3); mutex.Lock(); - for(int i=0 ; iOpen()) { - ports[i].Card=0; - ports[i].CardId=0; - ports[i].UseCount=0; - ports[i].Dead=false; - ports[i].PortNum=i; - ports[i].Serial=ser; - ports[i].Clock=clock ? clock : ISO_FREQ; - PRINTF(L_CORE_LOAD,"smartcards: added serial port %s as port %d (%s CD, %s RESET, CLOCK %d)", - devName,i,invCD?"inverse":"normal",invRST?"inverse":"normal",ports[i].Clock); - return true; + char type[32]; + int num; + if(sscanf(line,"%31[^:]:%n",type,&num)==1) { + if(!strcasecmp(type,"serial")) { + int invCD=0, invRST=0, clock=0; + char devName[64]; + if(sscanf(&line[num],"%63[^:]:%d:%d:%d",devName,&invCD,&invRST,&clock)>=3) { + cSmartCardSlot *slot=new cSmartCardSlot(Count()); + if(slot) { + cSerial *ser=new cSerial(devName,invCD,invRST); + if(ser && ser->Open()) { + slot->Serial=ser; + if(clock>0) slot->Clock=clock; + Add(slot); + PRINTF(L_CORE_LOAD,"smartcards: added serial port %s as port %d (%s CD, %s RESET, CLOCK %d)", + devName,slot->SlotNum,invCD?"inverse":"normal",invRST?"inverse":"normal",slot->Clock); + return true; + } + else PRINTF(L_GEN_ERROR,"failed to open serial port %s",devName); + delete ser; + delete slot; + } + else PRINTF(L_GEN_ERROR,"failed to create cardslot"); } - PRINTF(L_GEN_ERROR,"failed to open serial port %s",devName); - delete ser; - return false; - } - else if(!strcmp(ports[i].Serial->DeviceName(),devName)) { - PRINTF(L_GEN_ERROR,"duplicate serial port %s. Check your config!",devName); - return false; + else PRINTF(L_GEN_ERROR,"bad parameter for cardslot type '%s'",type); } + else PRINTF(L_GEN_ERROR,"unknown cardslot type '%s'",type); } - PRINTF(L_GEN_ERROR,"only %d serial ports supported",MAX_PORTS); return false; } + bool cSmartCards::HaveCard(int id) { cMutexLock lock(&mutex); while(Running() && firstRun) cond.Wait(mutex); - for(int i=0 ; iCardId==id) return true; return false; } @@ -1221,18 +1240,18 @@ cSmartCard *cSmartCards::LockCard(int id) { mutex.Lock(); while(Running() && firstRun) cond.Wait(mutex); - for(int i=0 ; iCardId==id) { + slot->UseCount++; mutex.Unlock(); - cSmartCard *sc=ports[i].Card; + cSmartCard *sc=slot->Card; sc->Lock(); - if(CardInserted(ports[i].Serial) && sc->CardUp() && !sc->NeedsReset()) + if(CardInserted(slot->Serial) && sc->CardUp() && !sc->NeedsReset()) return sc; // if failed, unlock the card and decrement UseCount sc->Unlock(); mutex.Lock(); - ports[i].UseCount--; + slot->UseCount--; cond.Broadcast(); break; } @@ -1245,9 +1264,9 @@ void cSmartCards::ReleaseCard(cSmartCard *sc) { sc->Unlock(); mutex.Lock(); - for(int i=0 ; iCard==sc) { + slot->UseCount--; cond.Broadcast(); mutex.Unlock(); return; @@ -1262,37 +1281,37 @@ bool cSmartCards::CardInserted(cSerial *ser) return ser->CheckCAR(); } -bool cSmartCards::CardReset(struct Port *port) +bool cSmartCards::CardReset(cSmartCardSlot *port) { - if(Reset(port)<2 || !cSmartCard::ParseAtr(&port->Atr,port->PortNum,port->Clock)) + if(Reset(port)<2 || !cSmartCard::ParseAtr(&port->Atr,port->SlotNum,port->Clock)) return false; if(!DoPTS(port)) { // reset card again and continue without PTS - if(Reset(port)<2 || !cSmartCard::ParseAtr(&port->Atr,port->PortNum,port->Clock)) + if(Reset(port)<2 || !cSmartCard::ParseAtr(&port->Atr,port->SlotNum,port->Clock)) return false; } return true; } -int cSmartCards::Reset(struct Port *port) +int cSmartCards::Reset(cSmartCardSlot *port) { cSerial *ser=port->Serial; - PRINTF(L_CORE_SC,"%d: reseting card (sermode %s)",port->PortNum,serModes[ser->CurrentMode()]); + PRINTF(L_CORE_SC,"%d: reseting card (sermode %s)",port->SlotNum,serModes[ser->CurrentMode()]); ser->ToggleRTS(); cCondWait::SleepMs(100); ser->ToggleRTS(); int r=ser->Read(port->Atr.atr,-MAX_ATR_LEN,800,2000); port->Atr.atrLen=r; - if(r>0) LDUMP(L_CORE_SC,port->Atr.atr,r,"%d: <- ATR len=%d:",port->PortNum,r); + if(r>0) LDUMP(L_CORE_SC,port->Atr.atr,r,"%d: <- ATR len=%d:",port->SlotNum,r); return r; } -bool cSmartCards::DoPTS(struct Port *port) +bool cSmartCards::DoPTS(cSmartCardSlot *port) { const struct Atr *atr=&port->Atr; if(atr->F!=372 || atr->D!=1.0) { // PTS required cSerial *ser=port->Serial; - const int id=port->PortNum; + const int id=port->SlotNum; int baud=(int)((float)port->Clock*atr->D/atr->F); PRINTF(L_CORE_SC,"%d: PTS cycle: calculated baudrate %d",id,baud); @@ -1341,7 +1360,7 @@ bool cSmartCards::DoPTS(struct Port *port) return true; } -void cSmartCards::SetPort(struct Port *port, cSmartCard *sc, int id, bool dead) +void cSmartCards::SetPort(cSmartCardSlot *port, cSmartCard *sc, int id, bool dead) { mutex.Lock(); while(port->UseCount) cond.Wait(mutex); @@ -1356,63 +1375,62 @@ void cSmartCards::SetPort(struct Port *port, cSmartCard *sc, int id, bool dead) void cSmartCards::Action(void) { while(Running()) { - for(int i=0 ; iSerial; + for(cSmartCardSlot *slot=First(); slot;) { + cSerial *ser=slot->Serial; if(ser) { - if(port->Card) { - cSmartCard *sc=port->Card; + if(slot->Card) { + cSmartCard *sc=slot->Card; sc->Lock(); if(!CardInserted(ser)) { sc->Unlock(); sc=0; - PRINTF(L_CORE_SC,"%d: card removed (UseCount=%d)",port->PortNum,port->UseCount); - SetPort(port,0,0,false); + PRINTF(L_CORE_SC,"%d: card removed (UseCount=%d)",slot->SlotNum,slot->UseCount); + SetPort(slot,0,0,false); } else if(sc->NeedsReset()) { - PRINTF(L_CORE_SC,"%d: card reset requested",port->PortNum); + PRINTF(L_CORE_SC,"%d: card reset requested",slot->SlotNum); if(!ser->SetMode(ser->CurrentMode()&SM_MASK) - || !CardReset(port) - || !sc->Setup(ser,&port->Atr,port->PortNum)) { + || !CardReset(slot) + || !sc->Setup(ser,&slot->Atr,slot->SlotNum)) { sc->Unlock(); sc=0; - PRINTF(L_CORE_SC,"%d: card re-init failed",port->PortNum); - SetPort(port,0,0,true); + PRINTF(L_CORE_SC,"%d: card re-init failed",slot->SlotNum); + SetPort(slot,0,0,true); } } if(sc) sc->Unlock(); } else if(CardInserted(ser)) { - if(!port->Dead) { - PRINTF(L_CORE_SC,"%d: new card inserted",port->PortNum); + if(!slot->Dead) { + PRINTF(L_CORE_SC,"%d: new card inserted",slot->SlotNum); for(int mode=SM_NONE+1 ; modeSetMode(mode)) { - if(CardReset(port)) { + if(CardReset(slot)) { cSmartCardLink *scl=first; while(scl) { - PRINTF(L_CORE_SC,"%d: checking for %s card",port->PortNum,scl->name); + PRINTF(L_CORE_SC,"%d: checking for %s card",slot->SlotNum,scl->name); cSmartCard *sc=scl->Create(); - if(sc && sc->Setup(ser,&port->Atr,port->PortNum)) { - SetPort(port,sc,scl->id,false); + if(sc && sc->Setup(ser,&slot->Atr,slot->SlotNum)) { + SetPort(slot,sc,scl->id,false); goto next; // ugly, any better solution? } delete sc; scl=scl->next; } - PRINTF(L_CORE_SC,"%d: no card handler found",port->PortNum); + PRINTF(L_CORE_SC,"%d: no card handler found",slot->SlotNum); } - else PRINTF(L_CORE_SC,"%d: reset/atr error",port->PortNum); + else PRINTF(L_CORE_SC,"%d: reset/atr error",slot->SlotNum); } - else PRINTF(L_CORE_SC,"%d: failed to set serial mode %s",port->PortNum,serModes[mode]); + else PRINTF(L_CORE_SC,"%d: failed to set serial mode %s",slot->SlotNum,serModes[mode]); } - port->Dead=true; - PRINTF(L_CORE_SC,"%d: can't initialise new card, ignoring port until card reinserted",port->PortNum); + slot->Dead=true; + PRINTF(L_CORE_SC,"%d: can't initialise new card, ignoring port until card reinserted",slot->SlotNum); } } else { - if(port->Dead) PRINTF(L_CORE_SC,"%d: card removed, port reactivated",port->PortNum); - port->Dead=false; + if(slot->Dead) PRINTF(L_CORE_SC,"%d: card removed, port reactivated",slot->SlotNum); + slot->Dead=false; } } -next: i++; +next: slot=Next(slot); } if(firstRun) { mutex.Lock(); @@ -1424,17 +1442,25 @@ next: i++; } } +cSmartCardSlot *cSmartCards::GetSlot(int num) +{ + for(cSmartCardSlot *slot=First(); slot; slot=Next(slot)) + if(slot->SlotNum==num) return slot; + return 0; +} + bool cSmartCards::ListCard(int num, char *str, int len) { - if(num>=MAX_PORTS || !ports[num].Serial) return false; + cSmartCardSlot *slot=GetSlot(num); + if(!slot) return false; str[0]=0; mutex.Lock(); - cSmartCard *sc=ports[num].Card; + cSmartCard *sc=slot->Card; if(sc) { if(!sc->GetCardIdStr(str,len)) { cSmartCardLink *scl=first; while(scl) { - if(scl->id==ports[num].CardId) { + if(scl->id==slot->CardId) { strn0cpy(str,scl->name,len); break; } @@ -1449,10 +1475,11 @@ bool cSmartCards::ListCard(int num, char *str, int len) bool cSmartCards::CardInfo(int num, char *str, int len) { bool res=false; - if(numCard; if(sc) res=sc->GetCardInfoStr(str,len); mutex.Unlock(); } @@ -1461,9 +1488,10 @@ bool cSmartCards::CardInfo(int num, char *str, int len) void cSmartCards::CardReset(int num) { - if(numCard; if(sc) sc->TriggerReset(); mutex.Unlock(); } diff --git a/smartcard.h b/smartcard.h index e7a9ed0..63c1ed9 100644 --- a/smartcard.h +++ b/smartcard.h @@ -61,6 +61,31 @@ public: // ---------------------------------------------------------------- +class cSmartCardData : public cStructItem { +protected: + int ident; +public: + cSmartCardData(int Ident); + virtual ~cSmartCardData() {} + virtual bool Parse(const char *line)=0; + virtual bool Matches(cSmartCardData *cmp)=0; + int Ident(void) const { return ident; } + }; + +// ---------------------------------------------------------------- + +class cSmartCardDatas : public cStructList { +protected: + virtual cStructItem *ParseLine(char *line); +public: + cSmartCardDatas(void); + cSmartCardData *Find(cSmartCardData *param); + }; + +extern cSmartCardDatas carddatas; + +// ---------------------------------------------------------------- + #define SM_NONE 0 #define SM_8E2 1 #define SM_8O2 2 @@ -139,29 +164,18 @@ public: // ---------------------------------------------------------------- -class cSmartCardData : public cStructItem { -protected: - int ident; +class cSmartCardSlot : public cStructItem { public: - cSmartCardData(int Ident); - virtual ~cSmartCardData() {} - virtual bool Parse(const char *line)=0; - virtual bool Matches(cSmartCardData *cmp)=0; - int Ident(void) const { return ident; } - }; - -// ---------------------------------------------------------------- - -class cSmartCardDatas : public cStructList { -protected: - virtual cStructItem *ParseLine(char *line); -public: - cSmartCardDatas(void); - cSmartCardData *Find(cSmartCardData *param); + cSmartCardSlot(int num); + ~cSmartCardSlot(); + // + cSerial *Serial; + bool Dead; + cSmartCard *Card; + int CardId, UseCount, SlotNum, Clock; + struct Atr Atr; }; -extern cSmartCardDatas carddatas; - // ---------------------------------------------------------------- class cSmartCardLink { @@ -178,34 +192,26 @@ public: // ---------------------------------------------------------------- -#define MAX_PORTS 4 - -struct Port { - cSerial *Serial; - bool Dead; - cSmartCard *Card; - int CardId, UseCount, PortNum, Clock; - struct Atr Atr; - }; - -class cSmartCards : private cThread { +class cSmartCards : private cThread, public cStructListPlain { friend class cSmartCardLink; friend class cSmartCardDatas; private: static cSmartCardLink *first; cMutex mutex; cCondVar cond; - struct Port ports[MAX_PORTS]; bool firstRun; // static void Register(cSmartCardLink *scl); bool CardInserted(cSerial *ser); - bool CardReset(struct Port *port); - int Reset(struct Port *port); - bool DoPTS(struct Port *port); - void SetPort(struct Port *port, cSmartCard *sc, int id, bool dead); + bool CardReset(cSmartCardSlot *port); + int Reset(cSmartCardSlot *port); + bool DoPTS(cSmartCardSlot *port); + void SetPort(cSmartCardSlot *port, cSmartCard *sc, int id, bool dead); + cSmartCardSlot *GetSlot(int num); protected: virtual void Action(void); + virtual void PreLoad(void); + virtual bool ParseLinePlain(const char *line); public: cSmartCards(void); void Shutdown(void); @@ -214,7 +220,6 @@ public: cSmartCard *LockCard(int id); void ReleaseCard(cSmartCard *sc); // to be called ONLY from frontend thread! - bool AddPort(const char *devName, bool invCD, bool invRST, int clock); void LaunchWatcher(void); bool ListCard(int num, char *str, int len); bool CardInfo(int num, char *str, int len);