SASC-NG
DVBSoftCAM

cSmartCardConax Class Reference

Inheritance diagram for cSmartCardConax:

List of all members.

Public Member Functions

 cSmartCardConax (void)
virtual bool Init (void)
virtual bool Decode (const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw)
virtual bool Update (int pid, int caid, const unsigned char *data)
virtual bool CanHandle (unsigned short SysId)

Detailed Description

Definition at line 170 of file sc-conax.c.


Constructor & Destructor Documentation

cSmartCardConax::cSmartCardConax ( void  )

Definition at line 200 of file sc-conax.c.

:cSmartCard(&cardCfg,msgs)
{
  sysId=0; cardVer=0; currency=0;
  memset(ua,0,sizeof(ua));
}

Member Function Documentation

bool cSmartCardConax::CanHandle ( unsigned short  SysId) [virtual]

Reimplemented from cSmartCard.

Definition at line 207 of file sc-conax.c.

{
  return (SysId==sysId);
}
bool cSmartCardConax::Decode ( const cEcmInfo *  ecm,
const unsigned char *  data,
unsigned char *  cw 
) [virtual]

Implements cSmartCard.

Definition at line 364 of file sc-conax.c.

References cSmartCard::CheckSctLen(), dtPIN, cSmartCards::FindCardData(), i, cSmartCard::IsoRead(), cSmartCard::IsoWrite(), L_SC_ERROR, MAX_LEN, cSmartCardDataConax::pin, PRINTF, smartcards, and cSmartCard::Status().

{
  static unsigned char insa2[] = { 0xDD,0xA2,0x00,0x00,0x00 };
  static unsigned char insca[] = { 0xDD,0xCA,0x00,0x00,0x00 };
  static unsigned char insc8[] = { 0xDD,0xC8,0x00,0x00,0x07 };
  static unsigned char insc8data[] = { 0x1D,0x05,0x01,0x00,0x00,0x00,0x00 };

  int l;
  if((l=CheckSctLen(data,3))<=0) return false;
  unsigned char buff[MAX_LEN];
  buff[0]=0x14;
  buff[1]=l+1;
  buff[2]=0;
  memcpy(buff+3,data,l);

  insa2[4]=l+3;
  if(!IsoWrite(insa2,buff) || !Status() || (l=GetLen())<=0) return false;
  int gotIdx=0;
  do {
    insca[4]=l;
    if(!IsoRead(insca,buff) || !Status()) return false;
    for(int i=0; i<l; i+=buff[i+1]+2) {
      switch(buff[i]) {
        case 0x25:
          if(buff[i+1]>=13) {
            int idx=buff[i+4];
            if(idx<=1) {
              gotIdx|=(1<<idx);
              memcpy(cw+idx*8,&buff[i+7],8);
              }
            }
          break;
        case 0x31:
          {
          if(buff[i+1]==0x02 && (buff[i+2]==0x00 || buff[i+2]==0x40) && buff[i+3]==0x00)
            break;
          // PIN required
          cSmartCardDataConax cd(dtPIN,ua);
          cSmartCardDataConax *entry=(cSmartCardDataConax *)smartcards.FindCardData(&cd);
          if(entry) {
            memcpy(&insc8data[3],entry->pin,4);
            if(!IsoWrite(insc8,insc8data) || !Status()) {
              PRINTF(L_SC_ERROR,"failed to send PIN");
              return false;
              }
            // resend ECM request
            if(!IsoWrite(insa2,buff) || !Status() || GetLen()<=0) return false;
            gotIdx=0;
            l=0; continue; // abort loop
            }
          else {
            PRINTF(L_SC_ERROR,"no PIN available");
            return false;
            }
          break;
          }
        }
      }
    } while((l=GetLen())>0);
  if(gotIdx!=3) PRINTF(L_SC_ERROR,"strange, only got index %d cw. Failing... (this may be a bug)",gotIdx==1?0:1);
  return gotIdx==3;
}
bool cSmartCardConax::Init ( void  ) [virtual]

Implements cSmartCard.

Definition at line 217 of file sc-conax.c.

References cProviders::AddProv(), ADDR_SIZE, cSmartCard::atr, cInfoStr::Begin(), cSmartCard::CaidsChanged(), CheckNull(), stdent::date, cInfoStr::Finish(), HexStr(), Atr::hist, Atr::histLen, i, stdent::id, cSmartCard::idStr, cSmartCard::infoStr, cSmartCard::IsoRead(), cSmartCard::IsoWrite(), j, L_SC_ERROR, L_SC_INIT, LBEND, LBPUT, LBSTARTF, max(), MAX_LEN, stdent::name, stdent::pbm, cLineBuff::Printf(), PRINTF, cIdSet::ResetIdSet(), SC_NAME, cIdSet::SetCard(), cSmartCard::Status(), STDENTTAG, and cLineBuff::Strcat().

{
  static const unsigned char cnxHist[] = { '0','B','0','0' }; // XXX is this always true ?

  sysId=0; cardVer=0; currency=0;
  memset(ua,0,sizeof(ua));
  ResetIdSet();
  if(atr->histLen<4 || memcmp(atr->hist, cnxHist, atr->histLen)) {
    PRINTF(L_SC_INIT,"doesn't look like a Conax card");
    return false;
    }

  infoStr.Begin();
  infoStr.Strcat("Conax smartcard\n");
  static unsigned char ins26[] = { 0xdd, 0x26, 0x00, 0x00, 0x03 };
  static unsigned char insc6[] = { 0xdd, 0xc6, 0x00, 0x00, 0x03 };
  static unsigned char insca[] = { 0xdd, 0xca, 0x00, 0x00, 0x00 };
  static const unsigned char hostVer[] = { 0x10,0x01,0x01 };  // host version
  unsigned char buff[MAX_LEN];
  int l;
  if(!IsoWrite(ins26,hostVer) || !Status() || (l=GetLen())<=0) {
    PRINTF(L_SC_ERROR,"card caid request failed");
    return false;
    }
  insca[4]=l;
  if(!IsoRead(insca,buff) || !Status()) {
    PRINTF(L_SC_ERROR,"card caid read failed");
    return false;
    }
  for(int i=0; i<l; i+=buff[i+1]+2) {
    switch(buff[i]) {
      case 0x20: cardVer=buff[i+2]; break;
      case 0x28: {
                 int s=(buff[i+2]<<8)+buff[i+3];
                 if(s!=sysId) CaidsChanged();
                 sysId=s;
                 break;
                 }
      case 0x2f: currency=(buff[i+2]<<8)+buff[i+3]; break;
      }
    }
  infoStr.Printf("Card v.%d Caid %04x\n",cardVer,sysId);
  PRINTF(L_SC_INIT,"card v.%d caid %04x",cardVer,sysId);
  snprintf(idStr,sizeof(idStr),"%s (V.%d)",SC_NAME,cardVer);

  static unsigned char ins82[] = { 0xdd,0x82,0x00,0x00,0x11 };
  static const unsigned char ins82Data[] = { 0x11,0x0f,0x01,0xb0,0x0f,0xff,0xff,0xfb,0x00,0x00,0x09,0x04,0x0b,0x00,0xe0,0x30,0x2b };
  if(!IsoWrite(ins82,ins82Data) || !Status() || (l=GetLen())<=0) {
    PRINTF(L_SC_ERROR,"card serial request failed");
    return false;
    }
  insca[4]=l;
  if(!IsoRead(insca,buff) || !Status()) {
    PRINTF(L_SC_ERROR,"card serial read failed");
    return false;
    }
  LBSTARTF(L_SC_INIT);
  LBPUT("card serials");
  for(int i=2; i<l; i+=buff[i+1]+2) {
    if(buff[i]==0x23 && buff[i+1]==ADDR_SIZE) { // Card Address
      if(CheckNull(&buff[i+2],4)) {
        AddProv(new cProviderConax(&buff[i+2]));
        LBPUT(" prov");
        }
      else {
        SetCard(new cCardConax(&buff[i+2]));
        memcpy(ua,&buff[i+2],sizeof(ua));
        LBPUT(" card");
        }
      char str[ADDR_SIZE*2+4];
      LBPUT(" %s",HexStr(str,&buff[i+2],ADDR_SIZE));
      }
    }
  LBEND();

  static const unsigned char stdEntits[] = { 0x1C,0x01,0x00 };
  if(IsoWrite(insc6,stdEntits) && Status() && (l=GetLen())>0) {
    infoStr.Printf("Subscriptions:\n");
    infoStr.Printf("|id  |name        |date             |\n");
    infoStr.Printf("+----+------------+-----------------+\n");

    do {
      insca[4]=l;
      if(!IsoRead(insca,buff) || !Status()) {
        PRINTF(L_SC_ERROR,"failed to read entitlements");
        break;
        }
      for(int i=0; i<l; i+=buff[i+1]+2) {
        if(buff[i]!=STDENTTAG) {
          PRINTF(L_SC_ERROR,"bad entitlement format %02x != %02x",buff[i],STDENTTAG);
          break;
          }

        struct stdent ent;
        memset(&ent,0,sizeof(ent));
        ent.id=(buff[i+2]<<8)|buff[i+3];

        int date=0, pbm=0;
        int max=i+buff[i+1]+2;
        for(int j=i+4; j<max; j+=buff[j+1]+2) {
          switch(buff[j]) {
            case 0x01: // prov. name
              snprintf(ent.name,sizeof(ent.name),"%.12s",&buff[j+2]);
              break;
            case 0x30: // date
              if(date<=3) {
                snprintf(ent.date[date],sizeof(ent.date[0]),"%02d.%02d.%02d",buff[j+2]&0x1F,buff[j+3]&0xF,(1990+((buff[j+3]>>4)+((buff[j+2]>>5)&0x7)*10))%100);
                date++;
                }
              break;
            case 0x20:
              if(pbm<=1) {
                ent.pbm[pbm]=(buff[j+2]<<24)|(buff[j+3]<<16)|(buff[j+4]<<8)|buff[j+5];
                pbm++;
                }
              break;
            }         
          }
        infoStr.Printf("|%04X|%s|%s-%s|\n",ent.id,ent.name,ent.date[0],ent.date[1]);
        infoStr.Printf("|    |            |%s-%s|\n",ent.date[2],ent.date[3]);
        }
      } while((l=GetLen())>0);
    }
  else
    PRINTF(L_SC_ERROR,"requesting entitlements failed");

/*
  static const unsigned char ppvEntits[] = { 0x1C,0x01,0x01 };
  if(IsoWrite(ins26,ppvEntits) && Status()) {
    while((l=GetLen())>0) {
      insca[4]=l;
      if(!IsoRead(insca,buff) || !Status()) {
        PRINTF(L_SC_ERROR,"failed to read PPV entitlements");
        break;
        }


      }
    }
  else
    PRINTF(L_SC_ERROR,"getting PPV entitlements failed");
*/

  infoStr.Finish();
  return true;
}
bool cSmartCardConax::Update ( int  pid,
int  caid,
const unsigned char *  data 
) [virtual]

Reimplemented from cSmartCard.

Definition at line 427 of file sc-conax.c.

References cSmartCard::CheckSctLen(), cSmartCard::IsoWrite(), cIdSet::MatchEMM(), MAX_LEN, and cSmartCard::Status().

{
  static unsigned char ins84[] = { 0xdd,0x84,0x00,0x00,0x00 };
  unsigned char buff[MAX_LEN];

  if(MatchEMM(data)) {
    int l;
    if((l=CheckSctLen(data,2))>0) {
      buff[0]=0x12; buff[1]=l;
      memcpy(&buff[2],data,l);
      ins84[4]=l+2;
      if(IsoWrite(ins84,buff) && !Status()) return true;
      }
    }
  return false;
}

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