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
11 if(cw
[i
] != 0) //test if cw = 00
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};
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];
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};
41 uchar boxID
[] = {0xFF, 0xFF, 0xFF, 0xFF};
47 if((hist_size
< 4) || (memcmp(hist
, "NTIC", 4))) { return ERROR
; }
49 reader
->caid
= 0x4A02;
50 // For now, only one provider, 0000
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
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]);
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
98 static int32_t tongfang_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
102 const uchar
*pbuf
= er
->ecm
;
105 int32_t write_len
= 0;
107 int32_t read_size
= 0;
109 int32_t data_len
= 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));
119 for(i
= 0; i
< (ecm_len
- 1); i
++)
121 if((pbuf
[0] == 0x80) && (pbuf
[1] == 0x3a))
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];
139 if((cta_res
[cta_lr
- 2] & 0xf0) == 0x60)
141 read_size
= cta_res
[cta_lr
- 1];
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);
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
; }
169 static int32_t tongfang_get_emm_type(EMM_PACKET
*ep
, struct s_reader
*UNUSED(reader
))
175 static int32_t tongfang_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
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);
191 static int32_t tongfang_card_info(struct s_reader
*reader
)
193 static const uchar get_provider_cmd
[] = {0x80, 0x44, 0x00, 0x00, 0x08};
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]);
207 const struct s_cardsystem reader_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
,