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.