source: branches/merlin/src/reader/common.c@ 485

Last change on this file since 485 was 485, checked in by Merlin, 11 years ago
File size: 5.5 KB
Line 
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
15static 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
35static 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
55static 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
70static 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
92static 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
115int 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
127void 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
147void 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
183int 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
200int 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
213int 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}
Note: See TracBrowser for help on using the repository browser.