revert breaks some stupid old compilers
[oscam.git] / reader-tongfang.c
blobe4781e4bea8eeacb0abef0e83b5fefa761ed01fd
1 #include "globals.h"
2 #ifdef READER_TONGFANG
3 #include "reader-common.h"
5 static int32_t cw_is_valid(unsigned char *cw) //returns 1 if cw_is_valid, returns 0 if cw is all zeros
7 int32_t i;
9 for(i = 0; i < 8; i++)
11 if(cw[i] != 0) //test if cw = 00
13 return OK;
16 return ERROR;
19 static int32_t tongfang_read_data(struct s_reader *reader, uchar size, uchar *cta_res, uint16_t *status)
21 uchar read_data_cmd[] = {0x00, 0xc0, 0x00, 0x00, 0xff};
22 uint16_t cta_lr;
24 read_data_cmd[4] = size;
25 write_cmd(read_data_cmd, NULL);
27 *status = (cta_res[cta_lr - 2] << 8) | cta_res[cta_lr - 1];
29 return (cta_lr - 2);
32 static int32_t tongfang_card_init(struct s_reader *reader, ATR *newatr)
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};
38 uchar data[257];
39 int32_t data_len = 0;
40 uint16_t status = 0;
41 uchar boxID[] = {0xFF, 0xFF, 0xFF, 0xFF};
42 int32_t i;
44 def_resp;
45 get_hist;
47 if((hist_size < 4) || (memcmp(hist, "NTIC", 4))) { return ERROR; }
49 reader->caid = 0x4A02;
50 // For now, only one provider, 0000
51 reader->nprov = 1;
52 memset(reader->prid, 0x00, sizeof(reader->prid));
54 rdr_log(reader, "Tongfang card detected");
56 write_cmd(begin_cmd, begin_cmd + 5);
57 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }
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);
63 if(data_len < 0) { return ERROR; }
64 if(status != 0x9000) { return ERROR; }
66 memset(reader->hexserial, 0, 8);
67 memcpy(reader->hexserial + 2, data, 4); // might be incorrect offset
69 if(reader->boxid > 0)
71 /* the boxid is specified in the config */
72 for(i = 0; i < 4; i++)
74 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
77 memcpy(pairing_cmd + 5, boxID, sizeof(boxID));
78 write_cmd(pairing_cmd, pairing_cmd + 5);
80 rdr_log_sensitive(reader, "type: Tongfang, caid: %04X, serial: {%llu}, hex serial: {%02x%02x%02x%02x}, BoxID: {%02X%02X%02X%02X}",
81 reader->caid, (unsigned long long) 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]);
85 return OK;
89 Example ecm:
90 03 85 80 70 61 8E 2A 16 4F 00 12 0F 21 5A E5 6A
91 8F 4D C1 57 4E 24 2A 38 3C 26 8A 4C C2 74 A1 23
92 9F 12 43 80 3A 16 4F 3E 8E 2A C0 40 0F 22 94 E4
93 6A 89 F1 09 38 8F DF 3D 08 A6 29 1A 61 98 31 82
94 7F 34 55 74 0E A3 54 38 01 09 00 01 00 01 D9 31
95 A5 1B 8B CA A8 95 E0 D1 24 7D 36 8C F6 89 4A F7
96 B2 3A 74 3D D1 D4
98 static int32_t tongfang_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
100 uchar ecm_cmd[200];
101 int32_t ecm_len;
102 const uchar *pbuf = er->ecm;
103 char *tmp;
104 int32_t i = 0;
105 int32_t write_len = 0;
106 def_resp;
107 int32_t read_size = 0;
108 uchar data[100];
109 int32_t data_len = 0;
110 uint16_t status = 0;
112 if((ecm_len = check_sct_len(er->ecm, 3)) < 0) { return ERROR; }
113 if(cs_malloc(&tmp, ecm_len * 3 + 1))
115 rdr_log_dbg(reader, D_IFD, "ECM: %s", cs_hexdump(1, er->ecm, ecm_len, tmp, ecm_len * 3 + 1));
116 NULLFREE(tmp);
119 for(i = 0; i < (ecm_len - 1); i++)
121 if((pbuf[0] == 0x80) && (pbuf[1] == 0x3a))
123 break;
125 pbuf++;
127 write_len = pbuf[4] + 5;
129 memcpy(ecm_cmd, pbuf, write_len);
131 write_cmd(ecm_cmd, ecm_cmd + 5);
133 if((cta_lr - 2) >= 2)
135 read_size = cta_res[1];
137 else
139 if((cta_res[cta_lr - 2] & 0xf0) == 0x60)
141 read_size = cta_res[cta_lr - 1];
143 else
145 return ERROR;
149 data_len = tongfang_read_data(reader, read_size, data, &status);
151 if(data_len < 23) { return ERROR; }
153 if(!(er->ecm[0] & 0x01))
155 memcpy(ea->cw, data + 8, 16);
157 else
159 memcpy(ea->cw, data + 16, 8);
160 memcpy(ea->cw + 8, data + 8, 8);
163 // All zeroes is no valid CW, can be a result of wrong boxid
164 if(!cw_is_valid(ea->cw) || !cw_is_valid(ea->cw + 8)) { return ERROR; }
166 return OK;
169 static int32_t tongfang_get_emm_type(EMM_PACKET *ep, struct s_reader *UNUSED(reader))
171 ep->type = UNKNOWN;
172 return 1;
175 static int32_t tongfang_do_emm(struct s_reader *reader, EMM_PACKET *ep)
177 uchar emm_cmd[200];
178 def_resp;
179 int32_t write_len;
181 if(SCT_LEN(ep->emm) < 8) { return ERROR; }
183 write_len = ep->emm[15] + 5;
184 memcpy(emm_cmd, ep->emm + 11, write_len);
186 write_cmd(emm_cmd, emm_cmd + 5);
188 return OK;
191 static int32_t tongfang_card_info(struct s_reader *reader)
193 static const uchar get_provider_cmd[] = {0x80, 0x44, 0x00, 0x00, 0x08};
194 def_resp;
195 int32_t i;
197 write_cmd(get_provider_cmd, NULL);
198 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }
200 for(i = 0; i < 4; i++)
202 rdr_log(reader, "Provider:%02x%02x", cta_res[i * 2], cta_res[i * 2 + 1]);
204 return OK;
207 const struct s_cardsystem reader_tongfang =
209 .desc = "tongfang",
210 .caids = (uint16_t[]){ 0x4B, 0 },
211 .do_emm = tongfang_do_emm,
212 .do_ecm = tongfang_do_ecm,
213 .card_info = tongfang_card_info,
214 .card_init = tongfang_card_init,
215 .get_emm_type = tongfang_get_emm_type,
218 #endif