source: trunk/reader-conax.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

File size: 9.1 KB
Line 
1//FIXME Not checked on threadsafety yet; after checking please remove this line
2#include "globals.h"
3#include "reader-common.h"
4
5static char *chid_date(const uchar *ptr, char *buf, int l)
6{
7 if (buf)
8 {
9 snprintf(buf, l, "%04d/%02d/%02d",
10 1990+(ptr[1]>>4)+(((ptr[0]>>5)&7)*10), ptr[1]&0xf, ptr[0]&0x1f);
11 }
12 return(buf);
13}
14
15static int read_record(struct s_reader * reader, const uchar *cmd, const uchar *data, uchar * cta_res)
16{
17 ushort cta_lr;
18 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
19
20 write_cmd(cmd, data); // select record
21 if (cta_res[0]!=0x98)
22 return(-1);
23
24 insCA[4]=cta_res[1]; // get len
25 write_cmd(insCA, NULL); // read record
26 if ((cta_res[cta_lr-2]!=0x90) || (cta_res[cta_lr-1]))
27 return(-1);
28 return(cta_lr-2);
29}
30
31int conax_card_init(struct s_reader * reader, ATR newatr)
32{
33 unsigned char cta_res[CTA_RES_LEN];
34 int i, j, n;
35 static const uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x40};
36 uchar ins82[] = {0xDD, 0x82, 0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0xb0, 0x0f, 0xff, \
37 0xff, 0xfb, 0x00, 0x00, 0x09, 0x04, 0x0b, 0x00, 0xe0, 0x30, 0x2b };
38
39 uchar cardver=0;
40
41 get_hist;
42 if ((hist_size < 4) || (memcmp(hist,"0B00",4)))
43 return ERROR;
44
45 reader->caid[0]=0xB00;
46
47 if ((n=read_record(reader, ins26, ins26+5, cta_res))<=0) return ERROR; // read caid, card-version
48
49 for (i=0; i<n; i+=cta_res[i+1]+2)
50 switch(cta_res[i])
51 {
52 case 0x20: cardver=cta_res[i+2]; break;
53 case 0x28: reader->caid[0]=(cta_res[i+2]<<8)|cta_res[i+3];
54 }
55
56 // Ins82 command needs to use the correct CAID reported in nano 0x28
57 ins82[17]=(reader->caid[0]>>8)&0xFF;
58 ins82[18]=(reader->caid[0])&0xFF;
59
60 if ((n=read_record(reader, ins82, ins82+5, cta_res))<=0) return ERROR; // read serial
61
62 for (j=0, i=2; i<n; i+=cta_res[i+1]+2)
63 switch(cta_res[i])
64 {
65 case 0x23:
66 if (cta_res[i+5] != 0x00) {
67 memcpy(reader->hexserial, &cta_res[i+3], 6);
68 }
69 else {
70 memcpy(reader->sa[j], &cta_res[i+5], 4);
71 j++;
72 }
73 break;
74 }
75
76 // we have one provider, 0x0000
77 reader->nprov = 1;
78 memset(reader->prid, 0x00, sizeof(reader->prid));
79
80 cs_ri_log(reader, "type: Conax, caid: %04X, serial: %llu, hex serial: %02x%02x%02x%02x, card: v%d",
81 reader->caid[0], b2ll(6, reader->hexserial), reader->hexserial[2],
82 reader->hexserial[3], reader->hexserial[4], reader->hexserial[5], cardver);
83
84 cs_ri_log(reader, "Providers: %d", reader->nprov);
85
86 for (j=0; j<reader->nprov; j++)
87 {
88 cs_ri_log(reader, "Provider: %d Provider-Id: %06X", j+1, b2ll(4, reader->prid[j]));
89 cs_ri_log(reader, "Provider: %d SharedAddress: %08X", j+1, b2ll(4, reader->sa[j]));
90 }
91
92 return OK;
93}
94
95static int conax_send_pin(struct s_reader * reader)
96{
97 def_resp;
98 unsigned char insPIN[] = { 0xDD,0xC8,0x00,0x00,0x07,0x1D,0x05,0x01,0x00,0x00,0x00,0x00 }; //Last four are the Pin-Code
99 memcpy(insPIN+8,reader->pincode,4);
100
101 write_cmd(insPIN, insPIN+5);
102 cs_ri_log(reader, "sending pincode to card");
103
104 return OK;
105}
106
107
108int conax_do_ecm(struct s_reader * reader, ECM_REQUEST *er)
109{
110 def_resp;
111 int i,j,n, rc=0;
112 unsigned char insA2[] = { 0xDD,0xA2,0x00,0x00,0x00 };
113 unsigned char insCA[] = { 0xDD,0xCA,0x00,0x00,0x00 };
114
115 unsigned char buf[256];
116
117 if ((n=check_sct_len(er->ecm, 3))<0)
118 return ERROR;
119
120 buf[0]=0x14;
121 buf[1]=n+1;
122 buf[2]=0;
123
124 memcpy(buf+3, er->ecm, n);
125 insA2[4]=n+3;
126
127 write_cmd(insA2, buf); // write Header + ECM
128
129 while ((cta_res[cta_lr-2]==0x98) && // Antwort
130 ((insCA[4]=cta_res[cta_lr-1])>0) && (insCA[4]!=0xFF))
131 {
132 write_cmd(insCA, NULL); //Codeword auslesen
133
134 if ((cta_res[cta_lr-2]==0x98) ||
135 ((cta_res[cta_lr-2]==0x90) ))
136 {
137 for(i=0; i<cta_lr-2; i+=cta_res[i+1]+2)
138 {
139 switch (cta_res[i])
140 {
141 case 0x25:
142 if ( (cta_res[i+1]>=0xD) && !((n=cta_res[i+4])&0xFE) )
143 {
144 rc|=(1<<n);
145 memcpy(er->cw+(n<<3), cta_res+i+7, 8);
146 }
147 break;
148 case 0x31:
149 if ( (cta_res[i+1]==0x02 && cta_res[i+2]==0x00 && cta_res[i+3]==0x00) || \
150 (cta_res[i+1]==0x02 && cta_res[i+2]==0x40 && cta_res[i+3]==0x00) )
151 break;
152 else if (strcmp(reader->pincode, "none"))
153 {
154 conax_send_pin(reader);
155 write_cmd(insA2, buf); // write Header + ECM
156
157 while ((cta_res[cta_lr-2]==0x98) && // Antwort
158 ((insCA[4]=cta_res[cta_lr-1])>0) && (insCA[4]!=0xFF))
159 {
160 write_cmd(insCA, NULL); //Codeword auslesen
161
162 if ((cta_res[cta_lr-2]==0x98) ||
163 ((cta_res[cta_lr-2]==0x90) && (!cta_res[cta_lr-1])))
164 {
165 for(j=0;j<cta_lr-2; j+=cta_res[j+1]+2)
166 if ((cta_res[j]==0x25) && // access: is cw
167 (cta_res[j+1]>=0xD) && // 0xD: 5 header + 8 cw
168 !((n=cta_res[j+4])&0xFE)) // cw idx must be 0 or 1
169 {
170 rc|=(1<<n);
171 memcpy(er->cw+(n<<3), cta_res+j+7, 8);
172 }
173 }
174 }
175 }
176 break;
177 }
178 }
179 }
180 }
181 if (rc==3)
182 return OK;
183 else
184 return ERROR;
185}
186
187int conax_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr)
188{
189 int i, ok = 0;
190
191 cs_debug_mask(D_EMM, "Entered conax_get_emm_type ep->emm[2]=%02x", ep->emm[2]);
192
193 for (i = 0; i < rdr->nprov; i++) {
194 ok = (!memcmp(&ep->emm[6], rdr->sa[i], 4));
195 if (ok) break;
196 }
197
198 if (ok) {
199 ep->type = SHARED;
200 memset(ep->hexserial, 0, 8);
201 memcpy(ep->hexserial, &ep->emm[6], 4);
202 cs_debug_mask(D_EMM, "CONAX EMM: SHARED, ep->hexserial = %s", cs_hexdump(1, ep->hexserial, 8));
203 return TRUE;
204 }
205 else {
206 if (!memcmp(&ep->emm[6], rdr->hexserial+2, 4)) {
207 ep->type = UNIQUE;
208 memset(ep->hexserial, 0, 8);
209 memcpy(ep->hexserial+2, &ep->emm[6], 4);
210 cs_debug_mask(D_EMM, "CONAX EMM: UNIQUE, ep->hexserial = %s", cs_hexdump(1, ep->hexserial, 8));
211 return TRUE;
212 }
213 else {
214 ep->type = GLOBAL;
215 cs_debug_mask(D_EMM, "CONAX EMM: GLOBAL");
216 memset(ep->hexserial, 0, 8);
217 return TRUE;
218 }
219 }
220}
221
222void conax_get_emm_filter(struct s_reader * rdr, uchar *filter)
223{
224 filter[0]=0xFF; //header
225 filter[1]=3; //filter count
226
227 filter[2]=GLOBAL;
228 filter[3]=1; // FIXME: dont see any conax global EMM yet
229
230 filter[4+0] = 0x82;
231 filter[4+0+16] = 0xFF;
232 filter[4+8] = 0x70;
233 filter[4+8+16] = 0xFF;
234
235 filter[36]=SHARED;
236 filter[37]=0;
237
238 filter[38+0] = 0x82;
239 filter[38+0+16] = 0xFF;
240 filter[38+8] = 0x70;
241 filter[38+8+16] = 0xFF;
242 memcpy(filter+38+4, rdr->sa[0], 4);
243 memset(filter+38+4+16, 0xFF, 4);
244
245 filter[70]=UNIQUE;
246 filter[71]=0;
247 filter[72+0] = 0x82;
248 filter[72+0+16] = 0xFF;
249 filter[72+8] = 0x70;
250 filter[72+8+16] = 0xFF;
251 memcpy(filter+72+4, rdr->hexserial + 2, 4);
252 memset(filter+72+4+16, 0xFF, 4);
253
254 return;
255}
256
257int conax_do_emm(struct s_reader * reader, EMM_PACKET *ep)
258{
259 def_resp;
260 unsigned char insEMM[] = { 0xDD,0x84,0x00,0x00,0x00 };
261 unsigned char buf[255];
262 int rc=0;
263
264 const int l = ep->emm[2];
265
266 insEMM[4]=l+5;
267 buf[0]=0x12;
268 buf[1]=l+3;
269 memcpy(buf+2, ep->emm, buf[1]);
270 write_cmd(insEMM, buf);
271
272 rc=((cta_res[0]==0x90)&&(cta_res[1]==0x00));
273
274 if (rc)
275 return OK;
276 else
277 return ERROR;
278}
279
280int conax_card_info(struct s_reader * reader)
281{
282 def_resp;
283 int type, i, j, k, n=0;
284 ushort provid;
285 char provname[32], pdate[32];
286 static const uchar insC6[] = {0xDD, 0xC6, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x00};
287 static const uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x01};
288 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
289 char *txt[] = { "Package", "PPV-Event" };
290 static const uchar *cmd[] = { insC6, ins26 };
291
292 for (type=0; type<2; type++)
293 {
294 n=0;
295 write_cmd(cmd[type], cmd[type]+5);
296 while (cta_res[cta_lr-2]==0x98)
297 {
298 insCA[4]=cta_res[cta_lr-1]; // get len
299 write_cmd(insCA, NULL); // read
300 if ((cta_res[cta_lr-2]==0x90) || (cta_res[cta_lr-2]==0x98))
301 {
302 for (j=0; j<cta_lr-2; j+=cta_res[j+1]+2)
303 {
304 provid=(cta_res[j+2+type]<<8) | cta_res[j+3+type];
305 for (k=0, i=j+4+type; (i<j+cta_res[j+1]) && (k<2); i+=cta_res[i+1]+2)
306 {
307 int l;
308 switch(cta_res[i])
309 {
310 case 0x01: l=(cta_res[i+1]<(sizeof(provname)-1)) ?
311 cta_res[i+1] : sizeof(provname)-1;
312 memcpy(provname, cta_res+i+2, l);
313 provname[l]='\0';
314 break;
315 case 0x30: chid_date(cta_res+i+2, pdate+(k++<<4), 15);
316 break;
317 }
318 }
319 cs_ri_log(reader, "%s: %d, id: %04X, date: %s - %s, name: %s",
320 txt[type], ++n, provid, pdate, pdate+16, trim(provname));
321 }
322 }
323 }
324 }
325 cs_log("[conax-reader] ready for requests");
326 return OK;
327}
328
329void reader_conax(struct s_cardsystem *ph)
330{
331 ph->do_emm=conax_do_emm;
332 ph->do_ecm=conax_do_ecm;
333 ph->card_info=conax_card_info;
334 ph->card_init=conax_card_init;
335 ph->get_emm_type=conax_get_emm_type;
336 ph->get_emm_filter=conax_get_emm_filter;
337 ph->caids[0]=0x0B;
338}
Note: See TracBrowser for help on using the repository browser.