|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cSmartCardSeca: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) |
| cSmartCardSeca::cSmartCardSeca | ( | void | ) |
Definition at line 178 of file sc-seca.c.
:cSmartCard(&cardCfg,msgs) {}
| 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;
}