2 #include "reader-common.h"
4 extern uchar cta_cmd
[], cta_res
[];
9 static unsigned int Conax_ToDate(char data0
, char data1
)
10 { /* decimal: yyyymmdd */
14 y
= 1990+ ((data1
>>4) + ((data0
>>5)&0x7)*10);
21 static char *chid_date(uchar
*ptr
, char *buf
, int l
)
25 snprintf(buf
, l
, "%04d/%02d/%02d",
26 1990+(ptr
[1]>>4)+(((ptr
[0]>>5)&7)*10), ptr
[1]&0xf, ptr
[0]&0x1f);
32 static int card_write(uchar
*cmd
, uchar
*data
, int wflag
)
36 memcpy(buf
, cmd
, CMD_LEN
);
38 if (l
&& data
) memcpy(buf
+CMD_LEN
, data
, l
);
39 l
=reader_cmd2icc(buf
, CMD_LEN
+l
);
43 #define write_cmd(cmd, data) \
45 if (card_write(cmd, data, 1)) return(0); \
48 #define read_cmd(cmd, data) \
50 if (card_write(cmd, data, 0)) return(0); \
53 static int read_record(uchar
*cmd
, uchar
*data
)
55 uchar insCA
[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
57 write_cmd(cmd
, data
); // select record
60 insCA
[4]=cta_res
[1]; // get len
61 read_cmd(insCA
, NULL
); // read record
62 if ((cta_res
[cta_lr
-2]!=0x90) || (cta_res
[cta_lr
-1]))
67 int conax_card_init(uchar
*atr
, int atrsize
)
70 uchar atr_0b00
[] = { '0', 'B', '0', '0' };
71 uchar ins26
[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x01};
72 // uchar ins82[] = {0xDD, 0x82, 0x00, 0x00, 0x14, 0x11, 0x12, 0x01, 0xB0, 0x0F, 0xFF, 0xFF, 0xDD, 0x00, 0x00, 0x09, 0x04, 0x0B, 0x00, 0xE0, 0x30, 0x1B, 0x64, 0x3D, 0xFE};
73 uchar ins82
[]= {0xDD, 0x82, 0x00, 0x00, 0x10, 0x11, 0x0e, 0x01, 0xb0, 0x0f, 0xff, 0xff, 0xc5, 0x00, 0x00, 0x09, 0x04, 0x0b, 0x00, 0xe0, 0x30};
76 if ((memcmp(atr
+3, atr_0b00
, sizeof(atr_0b00
))) &&
77 (memcmp(atr
+4, atr_0b00
, sizeof(atr_0b00
))))
80 reader
[ridx
].caid
[0]=0xB00;
82 if ((n
=read_record(ins26
, ins26
+5))<0) return(0); // read caid, card-version
83 for (i
=0; i
<n
; i
+=cta_res
[i
+1]+2)
86 case 0x20: cardver
=cta_res
[i
+2]; break;
87 case 0x28: reader
[ridx
].caid
[0]=(cta_res
[i
+2]<<8)|cta_res
[i
+3];
90 if ((n
=read_record(ins82
, ins82
+5))<0) return(0); // read serial
91 for (j
=0, i
=2; i
<n
; i
+=cta_res
[i
+1]+2)
94 case 0x23: if (!j
) memcpy(reader
[ridx
].hexserial
, &cta_res
[i
+3], 6);
98 cs_ri_log("type: conax, caid: %04X, serial: %llu, card: v%d",
99 reader
[ridx
].caid
[0], b2ll(6, reader
[ridx
].hexserial
), cardver
);
100 cs_log("ready for requests");
104 int conax_do_ecm(ECM_REQUEST
*er
)
107 unsigned char insA2
[] = { 0xDD,0xA2,0x00,0x00,0x00 };
108 unsigned char insCA
[] = { 0xDD,0xCA,0x00,0x00,0x00 };
109 unsigned char buf
[256];
111 if ((n
=CheckSctLen(er
->ecm
, 3))<0)
116 memcpy(buf
+3, er
->ecm
, n
);
118 write_cmd(insA2
, buf
);
119 while ((cta_res
[cta_lr
-2]==0x98) &&
120 ((insCA
[4]=cta_res
[cta_lr
-1])>0) && (insCA
[4]!=0xFF))
122 read_cmd(insCA
, NULL
);
123 if ((cta_res
[cta_lr
-2]==0x98) ||
124 ((cta_res
[cta_lr
-2]==0x90) && (!cta_res
[cta_lr
-1])))
126 for(i
=0; i
<cta_lr
-2; i
+=cta_res
[i
+1]+2)
127 if ((cta_res
[i
]==0x25) && // access: is cw
128 (cta_res
[i
+1]>=0xD) && // 0xD: 5 header + 8 cw
129 !((n
=cta_res
[i
+4])&0xFE)) // cw idx must be 0 or 1
132 memcpy(er
->cw
+(n
<<3), cta_res
+i
+7, 8);
139 int conax_do_emm(EMM_PACKET
*ep
)
145 int conax_card_info(void)
147 int type
, i
, j
, k
, n
=0;
149 char provname
[32], pdate
[32];
150 uchar insC6
[] = {0xDD, 0xC6, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x00};
151 uchar ins26
[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x01};
152 uchar insCA
[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
153 char *txt
[] = { "provider", "ppvevent" };
154 uchar
*cmd
[] = { insC6
, ins26
};
156 for (type
=0; type
<2; type
++)
159 write_cmd(cmd
[type
], cmd
[type
]+5);
160 while (cta_res
[cta_lr
-2]==0x98)
162 insCA
[4]=cta_res
[1]; // get len
163 read_cmd(insCA
, NULL
); // read
164 if ((cta_res
[cta_lr
-2]==0x90) || (cta_res
[cta_lr
-2]==0x98))
166 for (j
=0; j
<cta_lr
-2; j
+=cta_res
[j
+1]+2)
168 provid
=(cta_res
[j
+2+type
]<<8) | cta_res
[j
+3+type
];
169 for (k
=0, i
=j
+4+type
; (i
<j
+cta_res
[j
+1]) && (k
<2); i
+=cta_res
[i
+1]+2)
174 case 0x01: l
=(cta_res
[i
+1]<(sizeof(provname
)-1)) ?
175 cta_res
[i
+1] : sizeof(provname
)-1;
176 memcpy(provname
, cta_res
+i
+2, l
);
179 case 0x30: chid_date(cta_res
+i
+2, pdate
+(k
++<<4), 15);
183 cs_ri_log("%s: %d, id: %04X, date: %s - %s, name: %s",
184 txt
[type
], ++n
, provid
, pdate
, pdate
+16, trim(provname
));