SASC-NG
DVBSoftCAM

cSmartCardSeca Class Reference

Inheritance diagram for cSmartCardSeca:

List of all members.

Public Member Functions

 cSmartCardSeca (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)

Detailed Description

Definition at line 142 of file sc-seca.c.


Constructor & Destructor Documentation

cSmartCardSeca::cSmartCardSeca ( void  )

Definition at line 178 of file sc-seca.c.


Member Function Documentation

bool cSmartCardSeca::Decode ( const cEcmInfo *  ecm,
const unsigned char *  data,
unsigned char *  cw 
) [virtual]

Implements cSmartCard.

Definition at line 288 of file sc-seca.c.

References cEcmInfo::Data(), cProviderScSeca::date, cProviders::FindProv(), cProviderScSeca::index, cSmartCard::IsoRead(), cSmartCard::IsoWrite(), cParseSeca::KeyNr(), L_SC_ERROR, L_SC_PROC, cProviderScSeca::name, cParseSeca::Payload(), payload, PRINTF, cParseSeca::ProvId(), cSmartCard::sb, cSmartCard::Status(), and cParseSeca::SysMode().

{
  static unsigned char ins3c[] = { 0xC1,0x3c,0x00,0x00,0x00 }; // coding cw
  static unsigned char ins3a[] = { 0xC1,0x3a,0x00,0x00,0x10 }; // decoding cw    
  static unsigned char ins30[] = { 0xC1,0x30,0x00,0x02,0x09 };
  static unsigned char ins30data[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF }; 

  cProviderScSeca *p=(cProviderScSeca *)FindProv(data);
  if(p && ecm->Data()) {
    PRINTF(L_SC_PROC,"provider 0x%04x index %d '%.16s' (expires %s)",cParseSeca::ProvId(data),p->index,p->name,Date(p->date));
    if(CheckAccess(ecm->Data(),p)) {
      const unsigned char *payload;
      ins3c[2]=p->index | (cParseSeca::SysMode(data) & 0xF0);
      ins3c[3]=cParseSeca::KeyNr(data);
      ins3c[4]=cParseSeca::Payload(data,&payload);
      if(IsoWrite(ins3c,payload)) {
        bool r;
        if(sb[0]==0x90 && sb[1]==0x1A) // need to use token
          r=IsoWrite(ins30,ins30data) && Status() && IsoWrite(ins3c,payload) && Status();
        else
          r=Status();
        if(r && IsoRead(ins3a,cw) && Status())
          return true;
        }
      }
    else PRINTF(L_SC_ERROR,"update your subscription to view this channel");
    }
  return false;
}
bool cSmartCardSeca::Init ( void  ) [virtual]

Implements cSmartCard.

Definition at line 182 of file sc-seca.c.

References cProviders::AddProv(), cSmartCard::atr, cInfoStr::Begin(), Bin2LongLong(), SecaProvInfo::date, cProviderScSeca::date, cInfoStr::Finish(), HexStr(), Atr::hist, Atr::histLen, i, cSmartCard::idStr, cProviderScSeca::index, cSmartCard::infoStr, cSmartCard::IsoRead(), cSmartCard::IsoWrite(), L_SC_ERROR, L_SC_INIT, LOG, MAX_LEN, SecaProvInfo::name, cProviderScSeca::name, SecaProvInfo::pbm, cProviderScSeca::pbm, cLineBuff::Printf(), PRINTF, SecaProvInfo::prov, cProviderSeca::provId, cIdSet::ResetIdSet(), SecaProvInfo::sa, SC_NAME, cIdSet::SetCard(), cSmartCard::Status(), cLineBuff::Strcat(), strn0cpy(), and Atr::T.

Referenced by Update().

{
  static unsigned char ins0e[] = { 0xC1,0x0e,0x00,0x00,0x08 }; // get serial nr. (UA)
  static unsigned char ins16[] = { 0xC1,0x16,0x00,0x00,0x07 }; // get nr. of providers
  static unsigned char ins12[] = { 0xC1,0x12,0x00,0x00,0x19 }; // get provider info
  static unsigned char ins34[] = { 0xC1,0x34,0x00,0x00,0x03 }; // request provider pbm (data=0x00 0x00 0x00)
  static unsigned char ins32[] = { 0xC1,0x32,0x00,0x00,0x0A }; // get the pbm data (p1=provider)

  static const unsigned char atrTester[] = { 0x0E,0x6C,0xB6,0xD6 };
  if(atr->T!=0 || atr->histLen<7 || memcmp(&atr->hist[3],atrTester,4)) {
    PRINTF(L_SC_INIT,"doesn't looks like a Seca card");
    return false;
    }

  infoStr.Begin();
  infoStr.Strcat("Seca smartcard\n");
  const char *type;
  switch(atr->hist[0]*256+atr->hist[1]) {
    case 0x5084: type="Generic"; break;
    case 0x5384: type="Philips"; break;
    case 0x5130:
    case 0x5430:
    case 0x5760: type="Thompson"; break;
    case 0x5284:
    case 0x5842:
    case 0x6060: type="Siemens"; break;
    case 0x7070: type="Canal+ NL"; break;
    default:     type="Unknown"; break;
    }
  snprintf(idStr,sizeof(idStr),"%s (%s %d.%d)",SC_NAME,type,atr->hist[2]&0x0F,atr->hist[2]>>4);
  PRINTF(L_SC_INIT,"cardtype: %s %d.%d",type,atr->hist[2]&0x0F,atr->hist[2]>>4);
  
  ResetIdSet();
  unsigned char buff[MAX_LEN];
  if(!IsoRead(ins0e,buff) || !Status()) {
    PRINTF(L_SC_ERROR,"reading card serial failed");
    return false;
    }
  SetCard(new cCardSeca(&buff[2]));
  PRINTF(L_SC_INIT,"card serial number: %llu",Bin2LongLong(&buff[2],6));
  infoStr.Printf("Type: %s %d.%d  Serial: %llu\n",type,atr->hist[2]&0x0F,atr->hist[2]>>4,Bin2LongLong(&buff[2],6));

  if(!IsoRead(ins16,buff) || !Status()) {
    PRINTF(L_SC_ERROR,"reading provider map failed");
    return false;
    }
  int provMap=buff[2]*256+buff[3];
  if(LOG(L_SC_INIT)) {
    int n=0, i=provMap;
    do { n+=i&1; i>>=1; } while(i);
    PRINTF(L_SC_INIT,"card has %d providers (0x%04x)",n,provMap);
    }

  for(int i=0 ; i<16 ; i++) {
    if(provMap&(1<<i)) {
      PRINTF(L_SC_INIT,"reading info for provider index %d",i);
      ins12[2]=i;
      if(!IsoRead(ins12,buff) || !Status()) {
        PRINTF(L_SC_ERROR,"reading provider info failed");
        return false;
        }
      ins32[2]=i;
      static const unsigned char ins34data[] = { 0x00,0x00,0x00 };
      if(!IsoWrite(ins34,ins34data) || !Status() ||
         !IsoRead(ins32,&buff[ins12[4]]) || !Status())
        memset(&buff[ins12[4]],0xFF,ins32[4]); // fake PBM response if card doesn't support command

      struct SecaProvInfo *spi=(struct SecaProvInfo *)buff;
      cProviderScSeca *p=new cProviderScSeca(spi->prov,spi->sa);
      if(p) {
        AddProv(p);
        p->index=i;
        strn0cpy(p->name,spi->name,sizeof(p->name));
        memcpy(p->date,spi->date,sizeof(p->date));
        memcpy(p->pbm,spi->pbm,sizeof(p->pbm));
        }
      infoStr.Printf("Prov %x (%.16s) until %s\n",p->provId[0]*256+p->provId[1],p->name,Date(p->date));
      char str[20];
      PRINTF(L_SC_INIT,"provider 0x%02x%02x '%.16s' expires %s pbm %s",
             p->provId[0],p->provId[1],p->name,Date(p->date),HexStr(str,p->pbm,sizeof(p->pbm)));
      }
    }

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

Reimplemented from cSmartCard.

Definition at line 318 of file sc-seca.c.

References blocker, cProviders::FindProv(), cProviderScSeca::index, Init(), cSmartCard::IsoWrite(), cParseSeca::KeyNr(), L_SC_PROC, cIdSet::MatchEMM(), cParseSeca::Payload(), payload, PRINTF, cSmartCard::Status(), and cParseSeca::SysMode().

{
  static unsigned char ins40[] = { 0xC1,0x40,0x00,0x00,0x00 }; 

  if(blocker==0 || (data[0]==0x82 && blocker==2) || (data[0]==0x84 && blocker==1)) {
    cProviderScSeca *p=(cProviderScSeca *)FindProv(data);
    if(p && MatchEMM(data)) {
      PRINTF(L_SC_PROC,"got %s update",data[0]==0x82?"UNIQUE":"SHARED");
      const unsigned char *payload;
      ins40[2]=p->index | (cParseSeca::SysMode(data) & 0xF0);
      ins40[3]=cParseSeca::KeyNr(data);
      ins40[4]=cParseSeca::Payload(data,&payload);
      if(IsoWrite(ins40,payload) && Status()) return Init();
      }
    }
  return false;
}

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