|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cSmartCardConax: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) |
Definition at line 170 of file sc-conax.c.
| 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)); }
| 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().