SASC
DVBSoftCAM

cSmartCardSlotSerial Class Reference

Inheritance diagram for cSmartCardSlotSerial:

List of all members.

Public Member Functions

 cSmartCardSlotSerial (void)
 cSmartCardSlotSerial (void)

Protected Member Functions

void Flush (void)
void SetDtrRts (void)
virtual bool DeviceOpen (const char *cfg)
virtual void DeviceClose (void)
virtual bool DeviceSetMode (int mode, int baud)
virtual int DeviceRead (unsigned char *mem, int len, int timeout, int initialTimeout=0)
virtual int DeviceWrite (const unsigned char *mem, int len, int delay=0)
virtual void DeviceToggleReset (void)
virtual bool DevicePTS (void)
virtual bool DeviceIsInserted (void)
void Flush (void)
void SetDtrRts (void)
virtual bool DeviceOpen (const char *cfg)
virtual void DeviceClose (void)
virtual bool DeviceSetMode (int mode, int baud)
virtual int DeviceRead (unsigned char *mem, int len, int timeout, int initialTimeout=0)
virtual int DeviceWrite (const unsigned char *mem, int len, int delay=0)
virtual void DeviceToggleReset (void)
virtual bool DevicePTS (void)
virtual bool DeviceIsInserted (void)

Protected Attributes

int fd

Detailed Description

Definition at line 652 of file smartcard.c.


Constructor & Destructor Documentation

cSmartCardSlotSerial::cSmartCardSlotSerial ( void  )

Definition at line 678 of file smartcard.c.

References fd.

{
  fd=-1; statInv=0; invRST=false; custombaud=false;
}
cSmartCardSlotSerial::cSmartCardSlotSerial ( void  )

Member Function Documentation

void cSmartCardSlotSerial::DeviceClose ( void  ) [protected, virtual]

Reimplemented from cSmartCardSlot.

Definition at line 712 of file smartcard.c.

References CHECK, cSmartCardSlot::devName, fd, Flush(), L_CORE_SERIAL, and PRINTF.

{
  if(fd>=0) {
    PRINTF(L_CORE_SERIAL,"%s: shutting down",devName);
    Flush();
    unsigned int modembits=0;
    CHECK(ioctl(fd,TIOCMSET,&modembits));
    close(fd); fd=-1;
    PRINTF(L_CORE_SERIAL,"%s: shutdown done",devName);
    }
}
virtual void cSmartCardSlotSerial::DeviceClose ( void  ) [protected, virtual]

Reimplemented from cSmartCardSlot.

bool cSmartCardSlotSerial::DeviceIsInserted ( void  ) [protected, virtual]

Implements cSmartCardSlot.

Definition at line 946 of file smartcard.c.

References cSmartCardSlot::devName, fd, L_CORE_SERIAL, LOG_ERROR, and PRINTF.

{
  int status=0;
  if(ioctl(fd,TIOCMGET,&status)<0) { LOG_ERROR; return false; }
  PRINTF(L_CORE_SERIAL,"%s: CAR is %sactive (lines:%s%s%s%s%s%s%s%s%s)",
     devName,(status&TIOCM_CAR)?"in":"",
     (status&TIOCM_LE)?" LE":"",  (status&TIOCM_DTR)?" DTR":"",
     (status&TIOCM_RTS)?" RTS":"",(status&TIOCM_ST)?" ST":"",
     (status&TIOCM_SR)?" SR":"",  (status&TIOCM_CTS)?" CTS":"",
     (status&TIOCM_CAR)?" CAR":"",(status&TIOCM_RNG)?" RNG":"",
     (status&TIOCM_DSR)?" DSR":"" );
  status^=statInv; // invert status for broken cardreaders
  return !(status & TIOCM_CAR);
}
virtual bool cSmartCardSlotSerial::DeviceIsInserted ( void  ) [protected, virtual]

Implements cSmartCardSlot.

bool cSmartCardSlotSerial::DeviceOpen ( const char *  cfg) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

Definition at line 683 of file smartcard.c.

References cSmartCardSlot::clock, cSmartCardSlot::devName, fd, ISO_FREQ, L_CORE_LOAD, L_CORE_SERIAL, L_GEN_ERROR, open(), PRINTF, SetDtrRts(), and cSmartCardSlot::slotnum.

{
  int invCD=0;
  if(sscanf(cfg,"%255[^:]:%d:%d:%d",devName,&invCD,&invRST,&clock)>=3) {
    if(clock<=0) clock=ISO_FREQ;
    statInv=invCD ? TIOCM_CAR:0;
    PRINTF(L_CORE_SERIAL,"%s: open serial port",devName);
    fd=open(devName,O_RDWR|O_NONBLOCK|O_NOCTTY);
    if(fd>=0) {
      SetDtrRts();
      PRINTF(L_CORE_SERIAL,"%s: init done",devName);
      PRINTF(L_CORE_LOAD,"cardslot: added serial port %s as port %d (%s CD, %s RESET, CLOCK %d)",
                devName,slotnum,invCD?"inverse":"normal",invRST?"inverse":"normal",clock);
      return true;
      }
    else PRINTF(L_GEN_ERROR,"%s: open failed: %s",devName,strerror(errno));
    }
  else PRINTF(L_GEN_ERROR,"bad parameter for cardslot type 'serial'");
  return false;
}
virtual bool cSmartCardSlotSerial::DeviceOpen ( const char *  cfg) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

bool cSmartCardSlotSerial::DevicePTS ( void  ) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

Definition at line 897 of file smartcard.c.

References cSmartCardSlot::atr, cSmartCardSlot::clock, Atr::D, cSmartCardSlot::DeviceCurrentMode(), DeviceRead(), DeviceSetMode(), DeviceWrite(), Atr::F, L_CORE_SC, LDUMP, Atr::N, PRINTF, cSmartCardSlot::slotnum, SM_1SB, Atr::T, Atr::TA1, Atr::Tspec, and XorSum().

{
  int baud=(int)((float)clock*atr.D/atr.F);
  PRINTF(L_CORE_SC,"%d: PTS cycle: calculated baudrate %d",slotnum,baud);

  if(atr.Tspec<0) {
    PRINTF(L_CORE_SC,"%d: negotiable mode",slotnum);
#ifdef NO_PTS_PROTO
    PRINTF(L_CORE_SC,"%d: PTS disabled at compile time!!!",slotnum);
    return true;
#else
    unsigned char req[4], conf[16];
    req[0]=0xFF;
    req[1]=0x10 | atr.T;
    req[2]=atr.TA1;
    req[3]=XorSum(req,3);
    LDUMP(L_CORE_SC,req,4,"%d: PTS request:",slotnum);
    if(DeviceWrite(req,4)!=4) {
      PRINTF(L_CORE_SC,"%d: PTS request, write failed",slotnum);
      return false;
      }
    if(DeviceRead(conf,4,100,100)!=4) {
      PRINTF(L_CORE_SC,"%d: PTS request, echo readback failed",slotnum);
      return false;
      }
    int n=DeviceRead(conf,-16,200,1000);
    if(n>0) LDUMP(L_CORE_SC,conf,n,"%d: PTS confirm:",slotnum);
    if(n<1 || conf[0]!=0xFF || XorSum(conf,n)!=0) {
      PRINTF(L_CORE_SC,"%d: PTS confirm, bad format",slotnum);
      return false;
      }
    if(n<4 || conf[1]!=req[1] || conf[2]!=req[2]) {
      PRINTF(L_CORE_SC,"%d: PTS not confirmed",slotnum);
      return false;
      }
#endif // NO_PTS_PROTO
    }
  else
    PRINTF(L_CORE_SC,"%d: specific mode Tspec=%d",slotnum,atr.Tspec);

  int mode=DeviceCurrentMode();
  if(atr.N==255) mode|=SM_1SB;
  if(!DeviceSetMode(mode,baud)) {
    PRINTF(L_CORE_SC,"%d: setting baudrate %d failed",slotnum,baud);
    return false;
    }
  return true;
}
virtual bool cSmartCardSlotSerial::DevicePTS ( void  ) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

virtual int cSmartCardSlotSerial::DeviceRead ( unsigned char *  mem,
int  len,
int  timeout,
int  initialTimeout = 0 
) [protected, virtual]

Implements cSmartCardSlot.

int cSmartCardSlotSerial::DeviceRead ( unsigned char *  mem,
int  len,
int  timeout,
int  initialTimeout = 0 
) [protected, virtual]

Implements cSmartCardSlot.

Definition at line 818 of file smartcard.c.

References cSmartCardSlot::devName, fd, HEXDUMP, L_CORE_SERIAL, L_GEN_ERROR, and PRINTF.

Referenced by DevicePTS().

{
  PRINTF(L_CORE_SERIAL,"%s: read len=%d timeout=%d:%d",devName,len,timeout,initialTimeout);
  bool incomplete=false;
  if(len<0) { len=-len; incomplete=true; }
  int to=initialTimeout>0 ? initialTimeout : timeout;
  int n=0;
  while(n<len) {
    int r=read(fd,mem+n,len-n);
    if(r<=0) {
      if(r==0) PRINTF(L_CORE_SERIAL,"%s: read bogus eof",devName);
      if(errno==EAGAIN) {
        struct pollfd u;
        u.fd=fd; u.events=POLLIN;
        r=poll(&u,1,to);
        if(r<0) {
          PRINTF(L_GEN_ERROR,"%s: read poll failed: %s",devName,strerror(errno));
          return -1;
          }
        else if(r==0) { // timeout
          PRINTF(L_CORE_SERIAL,"%s: read timeout (%d ms)",devName,to);
          if(n>0 && incomplete) break; // return bytes read so far
          return -2;
          }
        continue;
        }
      else {
        PRINTF(L_GEN_ERROR,"%s: read failed: %s",devName,strerror(errno));
        return -1;
        }
      }
    n+=r; to=timeout;
    }
  HEXDUMP(L_CORE_SERIAL,mem,n,"%s: read data",devName);
  return n;
}
virtual bool cSmartCardSlotSerial::DeviceSetMode ( int  mode,
int  baud 
) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

bool cSmartCardSlotSerial::DeviceSetMode ( int  mode,
int  baud 
) [protected, virtual]

Implements cSmartCardSlot.

Reimplemented in cSmartCardSlotSRPlus, and cSmartCardSlotSRPlus.

Definition at line 748 of file smartcard.c.

References cSmartCardSlot::currMode, cSmartCardSlot::devName, fd, Flush(), L_CORE_SERIAL, L_GEN_ERROR, LBEND, LBPUT, LBSTARTF, PRINTF, SM_1SB, SM_8E2, SM_8N2, SM_8O2, and SM_MASK.

Referenced by DevicePTS().

{
  if(fd>=0) {
    speed_t bconst=FindBaud(baud);
    bool custom=false;
    if(bconst==B0) { custom=true; bconst=B38400; }

    struct termios tio;
    memset(&tio,0,sizeof(tio));
    LBSTARTF(L_CORE_SERIAL);
    LBPUT("%s: set serial options: %d,",devName,baud);
    tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
    if(!(mode&SM_1SB)) tio.c_cflag |= CSTOPB;
    tio.c_iflag = (INPCK | IGNBRK);
    tio.c_cc[VMIN] = 1;
    cfsetispeed(&tio,bconst);
    cfsetospeed(&tio,bconst);
    switch(mode&SM_MASK) {
      case SM_8E2:
        LBPUT("8e%d",(mode&SM_1SB)?1:2);
        tio.c_cflag |= PARENB; break;
      case SM_8N2:
        LBPUT("8n%d",(mode&SM_1SB)?1:2);
        break;
      case SM_8O2:
        LBPUT("8o%d",(mode&SM_1SB)?1:2);
        tio.c_cflag |= (PARENB | PARODD); break;
      default:
        LBPUT("BAD MODE");
        return false;
      }
    LBEND();

    struct serial_struct s;
    if(ioctl(fd,TIOCGSERIAL,&s)<0) {
      if(custom || custombaud) {
        PRINTF(L_GEN_ERROR,"%s: get serial failed: %s",devName,strerror(errno));
        return false;
        }
      PRINTF(L_CORE_SERIAL,"%s: get serial failed: %s",devName,strerror(errno));
      PRINTF(L_CORE_SERIAL,"%s: custombaud not used, try to continue...",devName);
      }
    else if(!custom && ((s.flags&ASYNC_SPD_MASK)==ASYNC_SPD_CUST || s.custom_divisor!=0)) {
      s.custom_divisor=0;
      s.flags &= ~ASYNC_SPD_MASK;
      if(ioctl(fd,TIOCSSERIAL,&s)<0) {
        PRINTF(L_GEN_ERROR,"%s: set serial failed: %s",devName,strerror(errno));
        return false;
        }
      custombaud=false;
      }
    if(!tcsetattr(fd,TCSANOW,&tio)) {
      if(custom) {
        s.custom_divisor=(s.baud_base+(baud/2))/baud;
        s.flags=(s.flags&~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
        PRINTF(L_CORE_SERIAL,"%s: custom: baud_base=%d baud=%d devisor=%d -> effective baudrate %d (%+.2f%% off)",devName,s.baud_base,baud,s.custom_divisor,s.baud_base/s.custom_divisor,(float)(s.baud_base/s.custom_divisor-baud)/(float)baud);
        if(ioctl(fd,TIOCSSERIAL,&s)<0) {
          PRINTF(L_GEN_ERROR,"%s: set serial failed: %s",devName,strerror(errno));
          return false;
          }
        custombaud=true;
        }
      currMode=mode; Flush();
      return true;
      }
    else PRINTF(L_GEN_ERROR,"%s: tcsetattr failed: %s",devName,strerror(errno));
    }
  return false;
}
virtual void cSmartCardSlotSerial::DeviceToggleReset ( void  ) [protected, virtual]

Implements cSmartCardSlot.

void cSmartCardSlotSerial::DeviceToggleReset ( void  ) [protected, virtual]

Implements cSmartCardSlot.

Definition at line 887 of file smartcard.c.

References CHECK, cSmartCardSlot::devName, fd, Flush(), L_CORE_SERIAL, LOG_ERROR, and PRINTF.

{
  int mask=0;
  if(ioctl(fd,TIOCMGET,&mask)<0) { LOG_ERROR; return; }
  if(mask&TIOCM_RTS) { mask&=~TIOCM_RTS; PRINTF(L_CORE_SERIAL,"%s: toggle RTS, now off",devName); }
  else               { mask|= TIOCM_RTS; PRINTF(L_CORE_SERIAL,"%s: toggle RTS, now on",devName); }
  CHECK(ioctl(fd,TIOCMSET,&mask));
  Flush();
}
int cSmartCardSlotSerial::DeviceWrite ( const unsigned char *  mem,
int  len,
int  delay = 0 
) [protected, virtual]

Implements cSmartCardSlot.

Definition at line 855 of file smartcard.c.

References cSmartCardSlot::devName, fd, Flush(), HEXDUMP, L_CORE_SERIAL, L_GEN_ERROR, PRINTF, and cCondWait::SleepMs().

Referenced by DevicePTS().

{
  PRINTF(L_CORE_SERIAL,"%s: write len=%d delay=%d",devName,len,delay);
  HEXDUMP(L_CORE_SERIAL,mem,len,"%s: write data",devName);
  Flush();
  int n=0;
  while(n<len) {
    struct pollfd u;
    u.fd=fd; u.events=POLLOUT;
    int r;
    do {
      r=poll(&u,1,500);
      if(r<0) {
        PRINTF(L_GEN_ERROR,"%s: write poll failed: %s",devName,strerror(errno));
        return -1;
        }
      else if(r==0) { // timeout
        PRINTF(L_CORE_SERIAL,"%s: write timeout",devName);
        return -2;
        }
      } while(r<1);
    r=write(fd,mem+n,delay>0?1:len-n);
    if(r<0 && errno!=EAGAIN) {
      PRINTF(L_GEN_ERROR,"%s: write failed: %s",devName,strerror(errno));
      return -1;
      }
    if(r>0) n+=r;
    if(delay>0) cCondWait::SleepMs(delay);
    }
  return n;
}
virtual int cSmartCardSlotSerial::DeviceWrite ( const unsigned char *  mem,
int  len,
int  delay = 0 
) [protected, virtual]

Implements cSmartCardSlot.

void cSmartCardSlotSerial::Flush ( void  ) [protected]

Definition at line 724 of file smartcard.c.

References CHECK, and fd.

Referenced by DeviceClose(), DeviceSetMode(), DeviceToggleReset(), and DeviceWrite().

{
  if(fd>=0) CHECK(tcflush(fd,TCIOFLUSH));
}
void cSmartCardSlotSerial::Flush ( void  ) [protected]
void cSmartCardSlotSerial::SetDtrRts ( void  ) [protected]

Definition at line 704 of file smartcard.c.

References CHECK, cSmartCardSlot::devName, fd, L_CORE_SERIAL, and PRINTF.

Referenced by cSmartCardSlotSRPlus::DeviceOpen(), and DeviceOpen().

{
  PRINTF(L_CORE_SERIAL,"%s: set DTR/RTS",devName);
  unsigned int modembits;
  modembits=TIOCM_DTR; CHECK(ioctl(fd, TIOCMBIS, &modembits));
  modembits=TIOCM_RTS; CHECK(ioctl(fd, invRST?TIOCMBIS:TIOCMBIC, &modembits));
}
void cSmartCardSlotSerial::SetDtrRts ( void  ) [protected]

Member Data Documentation


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines