else PUSH(atr383,sizeof(atr383))
}
+// -- cSmartCardSlotEmuNagra --------------------------------------------------
+
+class cSmartCardSlotEmuNagra : public cSmartCardSlotEmuGeneric {
+private:
+ int toggle;
+ int dt_count[16];
+protected:
+ virtual void DeviceToggleReset(void);
+ virtual int DeviceWrite(const unsigned char *mem, int len, int delay=0);
+ virtual void EmuPushAtr(void);
+public:
+ cSmartCardSlotEmuNagra(void);
+ };
+
+static cSmartCardSlotLinkReg<cSmartCardSlotEmuNagra> __scs_emunagra("emunagra");
+
+cSmartCardSlotEmuNagra::cSmartCardSlotEmuNagra(void)
+{
+ strcpy(devName,"emunagra");
+ toggle=0;
+ memset(dt_count,0,sizeof(dt_count));
+}
+
+void cSmartCardSlotEmuNagra::DeviceToggleReset(void)
+{
+ toggle=0;
+ memset(dt_count,0,sizeof(dt_count));
+ cSmartCardSlotEmuGeneric::DeviceToggleReset();
+}
+
+int cSmartCardSlotEmuNagra::DeviceWrite(const unsigned char *mem, int len, int delay)
+{
+ PRINTF(L_CORE_SERIAL,"%s: write len=%d delay=%d",devName,len,delay);
+ Flush();
+ cCondWait::SleepMs(100);
+ PUSH(mem,len); // echo back
+
+// for this sample data:
+// BOXKEY: BB99FF99BB997788
+// CARDMOD: 9A2AE686F360A8F63B679E05443FE32969DE606A8521A48003A9C904F53FCE34D6D62B3DA6A9EF090556559068B4B127213A6EC310E629AEA7286D6B46AB6519
+// -> SESSKEY: 9d2cd4cbc4b22bdf65c5c2d8506a2927
+ static const struct Resp {
+ int cmd, cc;
+ unsigned int idata;
+ unsigned char data[MAX_LEN];
+ } resp[] = {
+/* status */ { 0xC0, 0,0x00000000, { 0x08,0xb0,0x04,0x00,0x13,0x00,0x20,0x90,0x00 } },
+/* datetim */ { 0xC8, 0,0x00000000, { 0x08,0xb8,0x04,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* card ID*/ { 0x12, 0,0x00000000, { 0x08,0x92,0x04,0x71,0x2A,0x3B,0x4C,0x90,0x00 } },
+/* IRDINFO */ { 0x22, 0,0x00000000, { 0x3b,0xA2,0x37,0x2A,0xFF,0x90,0x00,0x00,0x00,0x01,0x01,0xE9,0x01,0x01,0x01,0x12,0x3B,0x4F,0x5C,0x00,0x00,0x00,0x01,0x60,0x62,0x18,0x7A,0xA8,0xBE,0x10,0x5C,0x4F,0x3B,0x12,0x31,0x37,0x42,0x42,0x44,0x41,0x4C,0x44,0x50,0x34,0x35,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* */ { 0x22,-1,0x00000080, { 0x3b,0xa2,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT01 */ { 0x22, 0,0x00000001, { 0x10,0xa2,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT04 */ { 0x22, 0,0x00000004, { 0x46,0xa2,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* */ { 0x22,-1,0x00000084, { 0x46,0xa2,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* TIERS */ { 0x22, 0,0x00000005, { 0x59,0xa2,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* */ { 0x22,-1,0x00000085, { 0x59,0xa2,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* DT06 */ { 0x22, 0,0x00000006, { 0x18,0xa2,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* CAMDATA */ { 0x22, 0,0x00000008, { 0x57,0xa2,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* */ { 0x22,-1,0x00000088, { 0x57,0xa2,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00 } },
+/* CMD 26 */ { 0x26, 0,0x123b4f5c, { 0x44,0xa6,0x40,0xa1,0x36,0x96,0xdc,0x3d,0x43,0x98,0xc9,0xd3,0xda,0x73,0xca,0x67,0x37,0x75,0xf0,0x29,0x33,0x6c,0xf9,0x2c,0xb4,0xdd,0x0e,0x18,0xaf,0x9e,0x24,0xb8,0x56,0xa2,0x04,0xd9,0xbf,0x7b,0xf5,0xc2,0x64,0xc4,0x61,0xd0,0xce,0x33,0xa7,0x13,0x56,0x68,0xcd,0xb2,0xa5,0x54,0x04,0xce,0x79,0x72,0x1a,0xde,0x9a,0xc4,0x92,0x2c,0x49,0x4f,0x85,0x90,0x00 } },
+/* CMD 27 */ { 0x27, 0,0xfecd819a, { 0x04,0xa7,0x00,0x90,0x00 } },
+// don't remove this one
+/* END */ { 0xFF, 0,0x00000000, { 0x0 }} };
+
+ unsigned char *rmem=AUTOMEM(len);
+ memcpy(rmem,mem,len);
+ Invert(rmem,len);
+
+ unsigned char buff[MAX_LEN+16];
+ int c=0;
+ if(rmem[0]==0x21 && rmem[1]==0xc1) { // IFS
+ buff[c++]=0x12;
+ buff[c++]=0x00;
+ buff[c++]=0x00;
+ buff[c++]=0x00;
+ }
+ else {
+ int cmd=rmem[8], ilen=rmem[9];
+ unsigned int idata=0;
+ if(ilen>0) {
+ if(ilen>4) ilen=4;
+ for(int i=0; i<ilen; i++) idata=(idata<<8) | rmem[10+i];
+ }
+ bool isdt = (cmd==0x22);
+ for(const struct Resp *r=&resp[0]; 1 ;r++) {
+ if(r->cmd==0xFF) {
+ static const unsigned char fail[] = { 0x12,0x82,0x00,0x90 };
+ c=sizeof(fail);
+ memcpy(buff,fail,c);
+ break;
+ }
+ if(cmd==r->cmd && idata==r->idata && (!isdt || dt_count[idata&0xF]==r->cc || r->cc<0)) {
+ buff[c++]=0x12;
+ buff[c++]=toggle; toggle^=0x40;
+ unsigned int l=r->data[0]+1;
+ memcpy(&buff[c],r->data,l);
+ c+=l;
+ if(isdt) {
+ dt_count[idata&0xF]++;
+ PRINTF(L_CORE_SERIAL,"%s: dt%02x count now %d",devName,idata&0xf,dt_count[idata&0xF]);
+ }
+ break;
+ }
+ }
+ }
+ if(c>0) {
+ buff[c]=XorSum(buff,c); c++;
+ Invert(buff,c);
+ PUSH(buff,c);
+ }
+ return len;
+}
+
+void cSmartCardSlotEmuNagra::EmuPushAtr(void)
+{
+ static const unsigned char atr[] = { 0x03,0x00,0x56,0xff,0x00,0x76,0x7e,0x71,0x80,0x1d,0xff,0xdd,0x8d,0x7d,0x35,0xf5,0xb3,0xd3,0x73,0xfb,0xdd,0x31,0xe9,0xed,0xf3,0x33,0x9f };
+ PUSH(atr,sizeof(atr))
+}
+
#endif // CARD_EMU
// -- cInfoStr -----------------------------------------------------------------