source: trunk/reader-tongfang.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: 5.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 int cw_is_valid(unsigned char *cw) //returns 1 if cw_is_valid, returns 0 if cw is all zeros
6{
7 int i;
8
9 for (i = 0; i < 8; i++)
10 {
11 if (cw[i] != 0) //test if cw = 00
12 {
13 return OK;
14 }
15 }
16 return ERROR;
17}
18
19static int tongfang_read_data(struct s_reader *reader, uchar size, uchar *cta_res, ushort *status)
20{
21 uchar read_data_cmd[]={0x00,0xc0,0x00,0x00,0xff};
22 ushort cta_lr;
23
24 read_data_cmd[4] = size;
25 write_cmd(read_data_cmd, NULL);
26
27 *status = (cta_res[cta_lr - 2] << 8) | cta_res[cta_lr - 1];
28
29 return(cta_lr - 2);
30}
31
32int tongfang_card_init(struct s_reader *reader, ATR newatr)
33{
34 static const uchar begin_cmd[] = {0x00,0xa4,0x04,0x00,0x05,0xf9,0x5a,0x54,0x00,0x06};
35 static const uchar get_serial_cmd[] = {0x80,0x46,0x00,0x00,0x04,0x01,0x00,0x00,0x04};
36 uchar pairing_cmd[] = {0x80,0x4c,0x00,0x00,0x04,0xFF,0xFF,0xFF,0xFF};
37
38 uchar data[257];
39 int data_len = 0;
40 ushort status = 0;
41 uchar boxID[] = {0xFF, 0xFF, 0xFF, 0xFF};
42 int i;
43
44 def_resp;
45 get_hist;
46
47 if ((hist_size < 4) || (memcmp(hist, "NTIC",4))) return ERROR;
48
49 reader->caid[0] = 0x4A02;
50 // For now, only one provider, 0000
51 reader->nprov = 1;
52 memset(reader->prid, 0x00, sizeof(reader->prid));
53
54 cs_ri_log(reader, "[reader-tongfang] Tongfang card detected");
55
56 write_cmd(begin_cmd, begin_cmd + 5);
57 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) return ERROR;
58
59 write_cmd(get_serial_cmd, get_serial_cmd + 5);
60 if((cta_res[cta_lr - 2] & 0xf0) != 0x60) return ERROR;
61 data_len = tongfang_read_data(reader, cta_res[cta_lr - 1], data, &status);
62
63 if(data_len < 0) return ERROR;
64 if(status != 0x9000) return ERROR;
65
66 memset(reader->hexserial, 0, 8);
67 memcpy(reader->hexserial + 2, data, 4); // might be incorrect offset
68
69 if (reader->boxid > 0)
70 {
71 /* the boxid is specified in the config */
72 for (i = 0; i < 4; i++)
73 {
74 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
75 }
76 }
77 memcpy(pairing_cmd + 5, boxID, sizeof(boxID));
78 write_cmd(pairing_cmd, pairing_cmd + 5);
79
80 cs_ri_log(reader, "type: Tongfang, caid: %04X, serial: %llu, hex serial: %02x%02x%02x%02x, BoxID: %02X%02X%02X%02X",
81 reader->caid[0], b2ll(6, reader->hexserial), reader->hexserial[2],
82 reader->hexserial[3], reader->hexserial[4], reader->hexserial[5],
83 boxID[0], boxID[1], boxID[2], boxID[3]);
84
85 return OK;
86}
87
88/*
89Example ecm:
9003 85 80 70 61 8E 2A 16 4F 00 12 0F 21 5A E5 6A
918F 4D C1 57 4E 24 2A 38 3C 26 8A 4C C2 74 A1 23
929F 12 43 80 3A 16 4F 3E 8E 2A C0 40 0F 22 94 E4
936A 89 F1 09 38 8F DF 3D 08 A6 29 1A 61 98 31 82
947F 34 55 74 0E A3 54 38 01 09 00 01 00 01 D9 31
95A5 1B 8B CA A8 95 E0 D1 24 7D 36 8C F6 89 4A F7
96B2 3A 74 3D D1 D4
97*/
98int tongfang_do_ecm(struct s_reader *reader, ECM_REQUEST *er)
99{
100 uchar ecm_cmd[200];
101 int ecm_len;
102 uchar* pbuf = er->ecm;
103 int i = 0;
104 int write_len = 0;
105 def_resp;
106 int read_size = 0;
107 uchar data[100];
108 int data_len = 0;
109 ushort status = 0;
110
111 if((ecm_len = check_sct_len(er->ecm, 3)) < 0) return ERROR;
112
113 cs_debug_mask(D_IFD, "ECM: %s", cs_hexdump(1, er->ecm, ecm_len));
114
115 for(i = 0; i < (ecm_len - 1); i++)
116 {
117 if ((pbuf[0]==0x80)&&(pbuf[1]==0x3a))
118 {
119 break;
120 }
121 pbuf++;
122 }
123 write_len = pbuf[4] + 5;
124
125 memcpy(ecm_cmd, pbuf, write_len);
126
127 write_cmd(ecm_cmd, ecm_cmd + 5);
128
129 if ((cta_lr - 2) >= 2)
130 {
131 read_size = cta_res[1];
132 }
133 else
134 {
135 if((cta_res[cta_lr - 2] & 0xf0) == 0x60)
136 {
137 read_size = cta_res[cta_lr - 1];
138 }
139 else
140 {
141 return ERROR;
142 }
143 }
144
145 data_len = tongfang_read_data(reader, read_size, data, &status);
146
147 if(data_len < 23) return ERROR;
148
149 if(!(er->ecm[0] & 0x01))
150 {
151 memcpy(er->cw, data + 8, 16);
152 }
153 else
154 {
155 memcpy(er->cw, data + 16, 8);
156 memcpy(er->cw + 8, data + 8, 8);
157 }
158
159 // All zeroes is no valid CW, can be a result of wrong boxid
160 if (!cw_is_valid(er->cw) || !cw_is_valid(er->cw + 8)) return ERROR;
161
162 return OK;
163}
164
165int tongfang_get_emm_type(EMM_PACKET *ep, struct s_reader *UNUSED(reader))
166{
167 ep->type = UNKNOWN;
168 return TRUE;
169}
170
171void tongfang_get_emm_filter(struct s_reader *UNUSED(reader), uchar *UNUSED(filter))
172{
173}
174
175int tongfang_do_emm(struct s_reader *reader, EMM_PACKET *ep)
176{
177 uchar emm_cmd[200];
178 def_resp;
179 int write_len;
180
181 if(ep->emm[2] < 5) return ERROR;
182
183 write_len = ep->emm[15] + 5;
184 memcpy(emm_cmd, ep->emm + 11, write_len);
185
186 write_cmd(emm_cmd, emm_cmd + 5);
187
188 return OK;
189}
190
191int tongfang_card_info(struct s_reader * reader)
192{
193 static const uchar get_provider_cmd[] = {0x80,0x44,0x00,0x00,0x08};
194 def_resp;
195 int i;
196
197 write_cmd(get_provider_cmd, NULL);
198 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) return ERROR;
199
200 for(i = 0; i < 4; i++)
201 {
202 cs_ri_log(reader, "[reader-tongfang] Provider:%02x%02x", cta_res[i * 2], cta_res[i * 2 + 1]);
203 }
204 return OK;
205}
206
207void reader_tongfang(struct s_cardsystem *ph)
208{
209 ph->do_emm=tongfang_do_emm;
210 ph->do_ecm=tongfang_do_ecm;
211 ph->card_info=tongfang_card_info;
212 ph->card_init=tongfang_card_init;
213 ph->get_emm_type=tongfang_get_emm_type;
214 ph->caids[0]=0x4B;
215}
Note: See TracBrowser for help on using the repository browser.