source: trunk/reader-conax.c@ 431

Last change on this file since 431 was 96, checked in by polo, 11 years ago

Add card info logging when log file reach MaxLogSize

File size: 7.6 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3
4extern uchar cta_cmd[], cta_res[];
5extern ushort cta_lr;
6
7#define CMD_LEN 5
8
9static unsigned int Conax_ToDate(char data0, char data1)
10{ /* decimal: yyyymmdd */
11 int y,m,d;
12 unsigned int l;
13
14 y= 1990+ ((data1>>4) + ((data0>>5)&0x7)*10);
15 m= data1&0xf;
16 d= data0&0x1f;
17 l= (y*100+m)*100+d;
18 return l;
19}
20
21static char *chid_date(uchar *ptr, char *buf, int l)
22{
23 if (buf)
24 {
25 snprintf(buf, l, "%04d/%02d/%02d",
26 1990+(ptr[1]>>4)+(((ptr[0]>>5)&7)*10), ptr[1]&0xf, ptr[0]&0x1f);
27 }
28 return(buf);
29}
30
31
32static int card_write(uchar *cmd, uchar *data, int wflag)
33{
34 int l;
35 uchar buf[MAX_LEN];
36 memcpy(buf, cmd, CMD_LEN);
37 l=wflag ? cmd[4] : 0;
38 if (l && data) memcpy(buf+CMD_LEN, data, l);
39 l=reader_cmd2icc(buf, CMD_LEN+l);
40 return(l);
41}
42
43#define write_cmd(cmd, data) \
44{ \
45 if (card_write(cmd, data, 1)) return(0); \
46}
47
48#define read_cmd(cmd, data) \
49{ \
50 if (card_write(cmd, data, 0)) return(0); \
51}
52
53static int read_record(uchar *cmd, uchar *data)
54{
55 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
56
57 write_cmd(cmd, data); // select record
58 if (cta_res[0]!=0x98)
59 return(-1);
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]))
63 return(-1);
64 return(cta_lr-2);
65}
66
67int conax_card_init(uchar *atr, int atrsize)
68{
69 int i, j, n;
70 uchar atr_0b00[] = { '0', 'B', '0', '0' };
71 uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x40};
72 uchar ins82[] = {0xDD, 0x82, 0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0xb0, 0x0f, 0xff, \
73 0xff, 0xfb, 0x00, 0x00, 0x09, 0x04, 0x0b, 0x00, 0xe0, 0x30, 0x2b };
74
75 uchar cardver=0;
76
77 if ((memcmp(atr+3, atr_0b00, sizeof(atr_0b00))) &&
78 (memcmp(atr+4, atr_0b00, sizeof(atr_0b00))))
79 return(0);
80
81 reader[ridx].caid[0]=0xB00;
82
83 if ((n=read_record(ins26, ins26+5))<0) return(0); // read caid, card-version
84 for (i=0; i<n; i+=cta_res[i+1]+2)
85 switch(cta_res[i])
86 {
87 case 0x20: cardver=cta_res[i+2]; break;
88 case 0x28: reader[ridx].caid[0]=(cta_res[i+2]<<8)|cta_res[i+3];
89 }
90
91 if ((n=read_record(ins82, ins82+5))<0) return(0); // read serial
92
93 for (j=0, i=2; i<n; i+=cta_res[i+1]+2)
94 switch(cta_res[i])
95 {
96
97 case 0x09:
98 reader[ridx].prid[j][0]=0x00;
99 reader[ridx].prid[j][1]=0x00;
100 reader[ridx].prid[j][2]=cta_res[i+4];
101 reader[ridx].prid[j][3]=cta_res[i+5];
102
103 break;
104 case 0x23:
105 if ( cta_res[i+5] != 0x00)
106 {
107 memcpy(reader[ridx].hexserial, &cta_res[i+3], 6);
108 }else{
109
110 memcpy(reader[ridx].sa[j], &cta_res[i+5], 4);
111 j++;
112 }
113 break;
114 }
115
116
117
118 reader[ridx].nprov = j;
119
120
121
122 cs_ri_log("type: conax, caid: %04X, serial: %llu, card: v%d",
123 reader[ridx].caid[0], b2ll(6, reader[ridx].hexserial), cardver);
124 cs_ri_log("Conax-Provider:%d", reader[ridx].nprov);
125
126 for (j=0; j<reader[ridx].nprov; j++)
127 {
128 cs_ri_log("Provider:%d Provider-Id:%06X", j+1, b2ll(4, reader[ridx].prid[j]));
129 cs_ri_log("Provider:%d SharedAddress:%08X", j+1, b2ll(4, reader[ridx].sa[j]));
130 }
131
132 cs_log("ready for requests");
133 return(1);
134}
135
136int conax_send_pin(void)
137{
138 unsigned char insPIN[] = { 0xDD,0xC8,0x00,0x00,0x07,0x1D,0x05,0x01,0x00,0x00,0x00,0x00 }; //letzte vier ist der Pin-Code
139 memcpy(insPIN+8,reader[ridx].pincode,4);
140
141 write_cmd(insPIN, insPIN+5);
142 cs_ri_log("[conax]-sending pincode to card");
143
144 return(1);
145}
146
147
148int conax_do_ecm(ECM_REQUEST *er)
149{
150 int i,j,n, rc=0;
151 unsigned char insA2[] = { 0xDD,0xA2,0x00,0x00,0x00 };
152 unsigned char insCA[] = { 0xDD,0xCA,0x00,0x00,0x00 };
153
154 unsigned char buf[256];
155
156 if ((n=CheckSctLen(er->ecm, 3))<0)
157 return(0);
158
159 buf[0]=0x14;
160 buf[1]=n+1;
161 buf[2]=0;
162
163 memcpy(buf+3, er->ecm, n);
164 insA2[4]=n+3;
165
166 write_cmd(insA2, buf); // write Header + ECM
167
168 while ((cta_res[cta_lr-2]==0x98) && // Antwort
169 ((insCA[4]=cta_res[cta_lr-1])>0) && (insCA[4]!=0xFF))
170 {
171 read_cmd(insCA, NULL); //Codeword auslesen
172
173 if ((cta_res[cta_lr-2]==0x98) ||
174 ((cta_res[cta_lr-2]==0x90) ))
175 {
176 for(i=0; i<cta_lr-2; i+=cta_res[i+1]+2)
177
178 switch (cta_res[i])
179 {
180 case 0x25:
181 if ( (cta_res[i+1]>=0xD) && !((n=cta_res[i+4])&0xFE) )
182 {
183 rc|=(1<<n);
184 memcpy(er->cw+(n<<3), cta_res+i+7, 8);
185 }
186 break;
187 case 0x31:
188 if ( (cta_res[i+1]==0x02 && cta_res[i+2]==0x00 && cta_res[i+3]==0x00) || \
189 (cta_res[i+1]==0x02 && cta_res[i+2]==0x40 && cta_res[i+3]==0x00) )
190 break;
191 else if (strcmp(reader[ridx].pincode, "none"))
192 {
193 conax_send_pin();
194 write_cmd(insA2, buf); // write Header + ECM
195 while ((cta_res[cta_lr-2]==0x98) && // Antwort
196 ((insCA[4]=cta_res[cta_lr-1])>0) && (insCA[4]!=0xFF))
197 {
198 read_cmd(insCA, NULL); //Codeword auslesen
199 if ((cta_res[cta_lr-2]==0x98) ||
200 ((cta_res[cta_lr-2]==0x90) && (!cta_res[cta_lr-1])))
201 {
202
203 for(j=0;j<cta_lr-2; j+=cta_res[j+1]+2)
204 if ((cta_res[j]==0x25) && // access: is cw
205 (cta_res[j+1]>=0xD) && // 0xD: 5 header + 8 cw
206 !((n=cta_res[j+4])&0xFE)) // cw idx must be 0 or 1
207 {
208 rc|=(1<<n);
209 memcpy(er->cw+(n<<3), cta_res+j+7, 8);
210 }
211 }
212 }
213
214 }
215 break;
216
217 }
218
219
220
221 }
222 }
223 return(rc==3);
224}
225
226int conax_do_emm(EMM_PACKET *ep)
227{
228 /* by KrazyIvan
229 * EMM with lenght 83 and 85, is the same as ECM and PPV.
230 * EMM with lenght AA and A8 (keyupdate).
231 * 82 70 82 00 00 00 00 2c 86 52 70 79 64 10 16 bc
232 * */
233
234
235 unsigned char insEMM[] = { 0xDD,0x84,0x00,0x00,0x00 };
236 unsigned char buf[255];
237 int rc=0;
238
239 int l=ep->emm[2];
240 ep->type=l+3;
241
242 insEMM[4]=l+5;
243 buf[0]=0x12;
244 buf[1]=l+3;
245 memcpy(buf+2, ep->emm, buf[1]);
246 write_cmd(insEMM, buf);
247
248 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
249
250 return(rc);
251
252}
253
254int conax_card_info(void)
255{
256 int type, i, j, k, n=0;
257 ushort provid;
258 char provname[32], pdate[32];
259 uchar insC6[] = {0xDD, 0xC6, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x00};
260 uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x01};
261 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
262 char *txt[] = { "Package", "PPV-Event" };
263 uchar *cmd[] = { insC6, ins26 };
264
265 cs_log("card detected");
266 cs_log("type: conax");
267
268 for (type=0; type<2; type++)
269 {
270 n=0;
271 write_cmd(cmd[type], cmd[type]+5);
272 while (cta_res[cta_lr-2]==0x98)
273 {
274 insCA[4]=cta_res[1]; // get len
275 read_cmd(insCA, NULL); // read
276 if ((cta_res[cta_lr-2]==0x90) || (cta_res[cta_lr-2]==0x98))
277 {
278 for (j=0; j<cta_lr-2; j+=cta_res[j+1]+2)
279 {
280 provid=(cta_res[j+2+type]<<8) | cta_res[j+3+type];
281 for (k=0, i=j+4+type; (i<j+cta_res[j+1]) && (k<2); i+=cta_res[i+1]+2)
282 {
283 int l;
284 switch(cta_res[i])
285 {
286 case 0x01: l=(cta_res[i+1]<(sizeof(provname)-1)) ?
287 cta_res[i+1] : sizeof(provname)-1;
288 memcpy(provname, cta_res+i+2, l);
289 provname[l]='\0';
290 break;
291 case 0x30: chid_date(cta_res+i+2, pdate+(k++<<4), 15);
292 break;
293 }
294 }
295 cs_ri_log("%s: %d, id: %04X, date: %s - %s, name: %s",
296 txt[type], ++n, provid, pdate, pdate+16, trim(provname));
297 }
298 }
299 }
300 }
301
302 reader[ridx].online = 1;
303
304 return(1);
305}
Note: See TracBrowser for help on using the repository browser.