- fix for ticker #4787
[oscam.git] / reader-tongfang.c
blob55e20119a7ba4cedb9a6380dc34dc84a5671e1ff
1 #include "globals.h"
2 #ifdef READER_TONGFANG
3 #include "reader-common.h"
5 // returns 1 if cw_is_valid, returns 0 if cw is all zeros
6 static int32_t cw_is_valid(uint8_t *cw)
8 int32_t i;
10 for(i = 0; i < 8; i++)
12 if(cw[i] != 0) // test if cw = 00
14 return OK;
17 return ERROR;
20 static int32_t tongfang_read_data(struct s_reader *reader, uint8_t size, uint8_t *cta_res, uint16_t *status)
22 uint8_t read_data_cmd[] = { 0x00, 0xc0, 0x00, 0x00, 0xff };
23 uint16_t cta_lr;
25 read_data_cmd[4] = size;
26 write_cmd(read_data_cmd, NULL);
28 *status = (cta_res[cta_lr - 2] << 8) | cta_res[cta_lr - 1];
30 return (cta_lr - 2);
33 static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr)
35 static const uint8_t begin_cmd[] = { 0x00, 0xa4, 0x04, 0x00, 0x05, 0xf9, 0x5a, 0x54, 0x00, 0x06 };
36 static const uint8_t get_serial_cmd[] = { 0x80, 0x46, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04 };
37 uint8_t pairing_cmd[] = { 0x80, 0x4c, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0xFF };
39 uint8_t data[257];
40 int32_t data_len = 0;
41 uint16_t status = 0;
42 uint8_t boxID[] = { 0xFF, 0xFF, 0xFF, 0xFF };
43 int32_t i;
45 def_resp;
46 get_hist;
48 if((hist_size < 4) || (memcmp(hist, "NTIC", 4)))
50 return ERROR;
53 reader->caid = 0x4A02;
54 // For now, only one provider, 0000
55 reader->nprov = 1;
56 memset(reader->prid, 0x00, sizeof(reader->prid));
58 rdr_log(reader, "Tongfang card detected");
60 write_cmd(begin_cmd, begin_cmd + 5);
61 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
63 return ERROR;
66 write_cmd(get_serial_cmd, get_serial_cmd + 5);
67 if((cta_res[cta_lr - 2] & 0xf0) != 0x60)
69 return ERROR;
72 data_len = tongfang_read_data(reader, cta_res[cta_lr - 1], data, &status);
73 if(data_len < 0)
75 return ERROR;
78 if(status != 0x9000)
80 return ERROR;
83 memset(reader->hexserial, 0, 8);
84 memcpy(reader->hexserial + 2, data, 4); // might be incorrect offset
86 if(reader->boxid > 0)
88 /* the boxid is specified in the config */
89 for(i = 0; i < 4; i++)
91 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
94 memcpy(pairing_cmd + 5, boxID, sizeof(boxID));
95 write_cmd(pairing_cmd, pairing_cmd + 5);
97 rdr_log_sensitive(reader, "type: Tongfang, caid: %04X, serial: {%llu}, hex serial: {%02x%02x%02x%02x}, BoxID: {%02X%02X%02X%02X}",
98 reader->caid, (unsigned long long) b2ll(6, reader->hexserial), reader->hexserial[2],
99 reader->hexserial[3], reader->hexserial[4], reader->hexserial[5],
100 boxID[0], boxID[1], boxID[2], boxID[3]);
102 return OK;
106 Example ecm:
107 03 85 80 70 61 8E 2A 16 4F 00 12 0F 21 5A E5 6A
108 8F 4D C1 57 4E 24 2A 38 3C 26 8A 4C C2 74 A1 23
109 9F 12 43 80 3A 16 4F 3E 8E 2A C0 40 0F 22 94 E4
110 6A 89 F1 09 38 8F DF 3D 08 A6 29 1A 61 98 31 82
111 7F 34 55 74 0E A3 54 38 01 09 00 01 00 01 D9 31
112 A5 1B 8B CA A8 95 E0 D1 24 7D 36 8C F6 89 4A F7
113 B2 3A 74 3D D1 D4
115 static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
117 uint8_t ecm_cmd[200];
118 int32_t ecm_len;
119 const uint8_t *pbuf = er->ecm;
120 char *tmp;
121 int32_t i = 0;
122 int32_t write_len = 0;
123 def_resp;
124 int32_t read_size = 0;
125 uint8_t data[100];
126 int32_t data_len = 0;
127 uint16_t status = 0;
129 if((ecm_len = check_sct_len(er->ecm, 3)) < 0)
131 return ERROR;
134 if(cs_malloc(&tmp, ecm_len * 3 + 1))
136 rdr_log_dbg(reader, D_IFD, "ECM: %s", cs_hexdump(1, er->ecm, ecm_len, tmp, ecm_len * 3 + 1));
137 NULLFREE(tmp);
140 for(i = 0; i < (ecm_len - 1); i++)
142 if((pbuf[0] == 0x80) && (pbuf[1] == 0x3a))
144 break;
146 pbuf++;
148 write_len = pbuf[4] + 5;
150 memcpy(ecm_cmd, pbuf, write_len);
151 write_cmd(ecm_cmd, ecm_cmd + 5);
153 if((cta_lr - 2) >= 2)
155 read_size = cta_res[1];
157 else
159 if((cta_res[cta_lr - 2] & 0xf0) == 0x60)
161 read_size = cta_res[cta_lr - 1];
163 else
165 return ERROR;
169 data_len = tongfang_read_data(reader, read_size, data, &status);
171 if(data_len < 23)
173 return ERROR;
176 if(!(er->ecm[0] & 0x01))
178 memcpy(ea->cw, data + 8, 16);
180 else
182 memcpy(ea->cw, data + 16, 8);
183 memcpy(ea->cw + 8, data + 8, 8);
186 // All zeroes is no valid CW, can be a result of wrong boxid
187 if(!cw_is_valid(ea->cw) || !cw_is_valid(ea->cw + 8))
189 return ERROR;
192 return OK;
195 static int32_t tongfang_get_emm_type(EMM_PACKET *ep, struct s_reader *UNUSED(reader))
197 ep->type = UNKNOWN;
198 return 1;
201 static int32_t tongfang_do_emm(struct s_reader *reader, EMM_PACKET *ep)
203 uint8_t emm_cmd[200];
204 def_resp;
205 int32_t write_len;
207 if(SCT_LEN(ep->emm) < 8)
209 return ERROR;
212 write_len = ep->emm[15] + 5;
213 memcpy(emm_cmd, ep->emm + 11, write_len);
215 write_cmd(emm_cmd, emm_cmd + 5);
217 return OK;
220 static int32_t tongfang_card_info(struct s_reader *reader)
222 static const uint8_t get_provider_cmd[] = {0x80, 0x44, 0x00, 0x00, 0x08};
223 def_resp;
224 int32_t i;
226 write_cmd(get_provider_cmd, NULL);
227 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
229 return ERROR;
232 for(i = 0; i < 4; i++)
234 rdr_log(reader, "Provider:%02x%02x", cta_res[i * 2], cta_res[i * 2 + 1]);
236 return OK;
239 const struct s_cardsystem reader_tongfang =
241 .desc = "tongfang",
242 .caids = (uint16_t[]){ 0x4B, 0 },
243 .do_emm = tongfang_do_emm,
244 .do_ecm = tongfang_do_ecm,
245 .card_info = tongfang_card_info,
246 .card_init = tongfang_card_init,
247 .get_emm_type = tongfang_get_emm_type,
250 #endif