Timeout patch
[oscam.git] / reader-conax.c
blob0926c9df9cebfe3a89c2d886fdf25d1d45208898
1 #include "globals.h"
2 #include "reader-common.h"
4 extern uchar cta_cmd[], cta_res[];
5 extern ushort cta_lr;
7 #define CMD_LEN 5
9 static unsigned int Conax_ToDate(char data0, char data1)
10 { /* decimal: yyyymmdd */
11 int y,m,d;
12 unsigned int l;
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;
21 static char *chid_date(uchar *ptr, char *buf, int l)
23 if (buf)
25 snprintf(buf, l, "%04d/%02d/%02d",
26 1990+(ptr[1]>>4)+(((ptr[0]>>5)&7)*10), ptr[1]&0xf, ptr[0]&0x1f);
28 return(buf);
32 static int card_write(uchar *cmd, uchar *data, int wflag)
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);
43 #define write_cmd(cmd, data) \
44 { \
45 if (card_write(cmd, data, 1)) return(0); \
48 #define read_cmd(cmd, data) \
49 { \
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
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);
67 int conax_card_init(uchar *atr, int atrsize)
69 int i, j, n;
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};
74 uchar cardver=0;
76 if ((memcmp(atr+3, atr_0b00, sizeof(atr_0b00))) &&
77 (memcmp(atr+4, atr_0b00, sizeof(atr_0b00))))
78 return(0);
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)
84 switch(cta_res[i])
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)
92 switch(cta_res[i])
94 case 0x23: if (!j) memcpy(reader[ridx].hexserial, &cta_res[i+3], 6);
95 j++;
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");
101 return(1);
104 int conax_do_ecm(ECM_REQUEST *er)
106 int i, n, rc=0;
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)
112 return(0);
113 buf[0]=0x14;
114 buf[1]=n+1;
115 buf[2]=0;
116 memcpy(buf+3, er->ecm, n);
117 insA2[4]=n+3;
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
131 rc|=(1<<n);
132 memcpy(er->cw+(n<<3), cta_res+i+7, 8);
136 return(rc==3);
139 int conax_do_emm(EMM_PACKET *ep)
141 int rc=0;
142 return(rc);
145 int conax_card_info(void)
147 int type, i, j, k, n=0;
148 ushort provid;
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++)
158 n=0;
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)
171 int l;
172 switch(cta_res[i])
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);
177 provname[l]='\0';
178 break;
179 case 0x30: chid_date(cta_res+i+2, pdate+(k++<<4), 15);
180 break;
183 cs_ri_log("%s: %d, id: %04X, date: %s - %s, name: %s",
184 txt[type], ++n, provid, pdate, pdate+16, trim(provname));
189 return(1);