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

Last change on this file since 485 was 485, checked in by Merlin, 10 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.