1 | #include "globals.h" |
---|
2 | #include "reader/common.h" |
---|
3 | |
---|
4 | #include "reader/serial.h" |
---|
5 | |
---|
6 | #include "CAM/common.h" |
---|
7 | |
---|
8 | #include "simples.h" |
---|
9 | #include "log.h" |
---|
10 | |
---|
11 | #include <signal.h> |
---|
12 | #include <stdio.h> |
---|
13 | #include <time.h> |
---|
14 | |
---|
15 | static void reader_common_clear_memory(struct s_reader *reader) |
---|
16 | { |
---|
17 | reader->online = 0; |
---|
18 | reader->card_status = 0; |
---|
19 | reader->card_system = 0; |
---|
20 | memset(reader->card_atr, 0, sizeof (reader->card_atr)); |
---|
21 | reader->card_atr_size = 0; |
---|
22 | |
---|
23 | memset(reader->hexserial, 0, sizeof (reader->hexserial)); |
---|
24 | memset(reader->prid, 0xFF, sizeof (reader->prid)); |
---|
25 | memset(reader->caid, 0, sizeof (reader->caid)); |
---|
26 | memset(reader->availkeys, 0, sizeof (reader->availkeys)); |
---|
27 | reader->acs = 0; |
---|
28 | reader->nprov = 0; |
---|
29 | |
---|
30 | client[cs_idx].lastemm = 0; |
---|
31 | client[cs_idx].lastecm = 0; |
---|
32 | client[cs_idx].au = -1; |
---|
33 | } |
---|
34 | |
---|
35 | static int reader_common_card_is_inserted(struct s_reader *reader) |
---|
36 | { |
---|
37 | int rc = 0; |
---|
38 | |
---|
39 | /* Check that we don't have "disabled" this reader */ |
---|
40 | char filename[255]; |
---|
41 | if (strrchr (reader->device, '/')) { |
---|
42 | snprintf(filename, sizeof(filename), "%sdisable-%s", cs_confdir, strrchr(reader->device, '/')+1); |
---|
43 | if (file_exists(filename)) return 0; |
---|
44 | } |
---|
45 | snprintf(filename, sizeof(filename), "%sdisable-%s", cs_confdir, reader->label); |
---|
46 | if (file_exists(filename)) return 0; |
---|
47 | |
---|
48 | if ((reader->type & R_IS_SERIAL) != 0) { |
---|
49 | rc = reader_serial_card_is_inserted(); |
---|
50 | } |
---|
51 | |
---|
52 | return rc; |
---|
53 | } |
---|
54 | |
---|
55 | static int reader_common_get_atr(struct s_reader *reader) |
---|
56 | { |
---|
57 | int rc = 0; |
---|
58 | |
---|
59 | if ((reader->type & R_IS_SERIAL) != 0) { |
---|
60 | rc = reader_serial_get_atr(reader->card_atr, &reader->card_atr_size); |
---|
61 | } |
---|
62 | |
---|
63 | if (rc) { |
---|
64 | log_normal("Reader: ATR = %s", cs_hexdump(1, reader->card_atr, reader->card_atr_size)); |
---|
65 | } |
---|
66 | |
---|
67 | return rc; |
---|
68 | } |
---|
69 | |
---|
70 | static int reader_common_get_bitrates(struct s_reader *reader) |
---|
71 | { |
---|
72 | int rc = 0; |
---|
73 | unsigned long reader_bitrate_optimal; |
---|
74 | unsigned long reader_bitrate_effective; |
---|
75 | |
---|
76 | if ((reader->type & R_IS_SERIAL) != 0) { |
---|
77 | rc = reader_serial_get_bitrates(&reader_bitrate_optimal, &reader_bitrate_effective); |
---|
78 | } |
---|
79 | |
---|
80 | if (rc) { |
---|
81 | if (reader_bitrate_effective == reader_bitrate_optimal) { |
---|
82 | log_normal("Reader: Using optimal bitrate of %lu bit/s", reader_bitrate_optimal); |
---|
83 | } else { |
---|
84 | log_normal("Reader: Using approximate bitrate of %lu bit/s", reader_bitrate_effective); |
---|
85 | log_normal("Reader: Optimal bitrate is %lu bit/s (%+.2f%% off)", reader_bitrate_optimal, (((double) reader_bitrate_effective) - reader_bitrate_optimal) / reader_bitrate_optimal * 100); |
---|
86 | } |
---|
87 | } |
---|
88 | |
---|
89 | return rc; |
---|
90 | } |
---|
91 | |
---|
92 | static int reader_common_init_card(struct s_reader *reader) |
---|
93 | { |
---|
94 | /* Get Answer to Reset from card */ |
---|
95 | if (!reader_common_get_atr(reader)) { |
---|
96 | return 0; |
---|
97 | } |
---|
98 | |
---|
99 | /* Show some information about bitrate */ |
---|
100 | if (!reader_common_get_bitrates(reader)) { |
---|
101 | return 0; |
---|
102 | } |
---|
103 | |
---|
104 | /* Detect the card system */ |
---|
105 | if (!cam_common_detect(reader->card_atr, reader->card_atr_size)) { |
---|
106 | return 0; |
---|
107 | } |
---|
108 | |
---|
109 | /* Load information from card */ |
---|
110 | reader_common_load_card(reader); |
---|
111 | |
---|
112 | return 1; |
---|
113 | } |
---|
114 | |
---|
115 | int reader_common_init(struct s_reader *reader) |
---|
116 | { |
---|
117 | int rc = 0; |
---|
118 | |
---|
119 | if ((reader->type & R_IS_SERIAL) != 0) { |
---|
120 | rc = reader_serial_init(reader); |
---|
121 | log_normal("Reader: Initialized serial reader %s (%s @ %2.2f Mhz %s%s)", reader->label, reader->device, (float) reader->frequency / 1000000, reader->detect & 0x80 ? "!" : "", RDR_CD_TXT[reader->detect & 0x7f]); |
---|
122 | } |
---|
123 | |
---|
124 | return rc; |
---|
125 | } |
---|
126 | |
---|
127 | void reader_common_load_card(struct s_reader *reader) |
---|
128 | { |
---|
129 | reader_common_check_health(reader); |
---|
130 | |
---|
131 | if (reader->card_status == CARD_INSERTED) { |
---|
132 | /* Disable the reader if it was already online */ |
---|
133 | reader->online = 0; |
---|
134 | |
---|
135 | client[cs_idx].last = time((time_t) 0); |
---|
136 | |
---|
137 | /* Ask the CAM to load the card information */ |
---|
138 | if (cam_common_load_card()) { |
---|
139 | /* Mark the reader as online */ |
---|
140 | reader->online = 1; |
---|
141 | |
---|
142 | log_normal("Reader: Ready for requests (%s)", reader->label); |
---|
143 | } |
---|
144 | } |
---|
145 | } |
---|
146 | |
---|
147 | void reader_common_check_health(struct s_reader *reader) |
---|
148 | { |
---|
149 | /* Check if there is a card inserted in the reader */ |
---|
150 | if (reader_common_card_is_inserted(reader)) { |
---|
151 | /* Check if card was just inserted */ |
---|
152 | if ((reader->card_status & CARD_INSERTED) == 0) { |
---|
153 | reader->card_status = CARD_INSERTED; |
---|
154 | log_normal("Reader: Card detected in %s", reader->label); |
---|
155 | |
---|
156 | /* Try to initialize the card */ |
---|
157 | if (!reader_common_init_card(reader)) { |
---|
158 | reader->card_status |= CARD_FAILURE; |
---|
159 | log_normal("Reader: Cannot initialize card in %s !", reader->label); |
---|
160 | } else { |
---|
161 | client[cs_idx].au = ridx; |
---|
162 | } |
---|
163 | |
---|
164 | /* ? */ |
---|
165 | int i; |
---|
166 | for (i = 1; i < CS_MAXPID; i++) { |
---|
167 | if (client[i].pid && client[i].typ == 'c' && client[i].usr[0]) { |
---|
168 | kill(client[i].pid, SIGQUIT); |
---|
169 | } |
---|
170 | } |
---|
171 | } |
---|
172 | } else { |
---|
173 | /* Check if card was just ejected */ |
---|
174 | if ((reader->card_status & CARD_INSERTED) != 0) { |
---|
175 | log_normal("Reader: Card ejected from %s", reader->label); |
---|
176 | |
---|
177 | /* Clear all infos from card */ |
---|
178 | reader_common_clear_memory(reader); |
---|
179 | } |
---|
180 | } |
---|
181 | } |
---|
182 | |
---|
183 | int reader_common_process_ecm(struct s_reader *reader, ECM_REQUEST *er) |
---|
184 | { |
---|
185 | int rc = 0; |
---|
186 | |
---|
187 | if (reader->online) { |
---|
188 | if ((reader->caid[0] >> 8) == ((er->caid >> 8) & 0xFF)) { // TODO: move this somewhere else |
---|
189 | client[cs_idx].last_srvid = er->srvid; |
---|
190 | client[cs_idx].last_caid = er->caid; |
---|
191 | client[cs_idx].last = time((time_t) 0); |
---|
192 | |
---|
193 | rc = cam_common_process_ecm(er); |
---|
194 | } |
---|
195 | } |
---|
196 | |
---|
197 | return rc; |
---|
198 | } |
---|
199 | |
---|
200 | int reader_common_process_emm(struct s_reader *reader, EMM_PACKET *ep) |
---|
201 | { |
---|
202 | int rc = 0; |
---|
203 | |
---|
204 | if (reader->online) { |
---|
205 | client[cs_idx].last = time((time_t) 0); |
---|
206 | |
---|
207 | rc = cam_common_process_emm(ep); |
---|
208 | } |
---|
209 | |
---|
210 | return rc; |
---|
211 | } |
---|
212 | |
---|
213 | int reader_common_cmd2card(struct s_reader *reader, uchar *cmd, ushort cmd_size, uchar *result, ushort result_max_size, ushort *result_size) |
---|
214 | { |
---|
215 | int rc = 0; |
---|
216 | |
---|
217 | if ((reader->type & R_IS_SERIAL) != 0) { |
---|
218 | rc = (reader_serial_cmd2card(cmd, cmd_size, result, result_max_size, result_size) == 0); |
---|
219 | } |
---|
220 | |
---|
221 | return rc; |
---|
222 | } |
---|