add function to set mifare key from internal eeprom
[librfid] / src / rfid_reader_cm5121.c
1 /* Omnikey CardMan 5121 specific RC632 transport layer 
2  *
3  * (C) 2005-2008 by Harald Welte <laforge@gnumonks.org>
4  *
5  * The 5121 is an Atmel AT89C5122 based USB CCID reader (probably the same
6  * design like the 3121).  It's CL RC632 is connected via address/data bus,
7  * not via SPI.
8  *
9  * The vendor-supplied reader firmware provides some undocumented extensions 
10  * to CCID (via PC_to_RDR_Escape) that allow access to registers and FIFO of
11  * the RC632.
12  * 
13  */
14
15 /*
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License version 2 
18  *  as published by the Free Software Foundation
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <errno.h>
33
34 #include <librfid/rfid.h>
35
36 #ifndef LIBRFID_FIRMWARE
37
38
39 #include <librfid/rfid_reader.h>
40 #include <librfid/rfid_asic.h>
41 #include <librfid/rfid_asic_rc632.h>
42 #include <librfid/rfid_reader_cm5121.h>
43 #include <librfid/rfid_layer2.h>
44 #include <librfid/rfid_protocol.h>
45
46 #include "rfid_reader_rc632_common.h"
47
48 #include "cm5121_source.h"
49
50 /* FIXME */
51 #include "rc632.h"
52
53 #define SENDBUF_LEN     256+7+10 /* 256bytes max FSD/FSC, plus 7 bytes header,
54                                     plus 10 bytes reserve */
55 #define RECVBUF_LEN     SENDBUF_LEN
56
57 #ifdef DEBUG_REGISTER
58 #define DEBUGRC DEBUGPC
59 #define DEBUGR DEBUGP
60 #else
61 #define DEBUGRC(x, args ...)    do {} while(0)
62 #define DEBUGR(x, args ...)     do {} while(0)
63 #endif
64
65 static
66 int Write1ByteToReg(struct rfid_asic_transport_handle *rath,
67                     unsigned char reg, unsigned char value)
68 {
69         unsigned char sndbuf[SENDBUF_LEN];
70         unsigned char rcvbuf[RECVBUF_LEN];
71         size_t retlen = RECVBUF_LEN;
72
73         sndbuf[0] = 0x20;
74         sndbuf[1] = 0x00;
75         sndbuf[2] = 0x01;
76         sndbuf[3] = 0x00;
77         sndbuf[4] = 0x00;
78         sndbuf[5] = 0x00;
79         sndbuf[6] = reg;
80         sndbuf[7] = value;
81
82         DEBUGR("reg=0x%02x, val=%02x: ", reg, value);
83
84         if (PC_to_RDR_Escape(rath->data, sndbuf, 8, rcvbuf, 
85                              &retlen) == 0) {
86                 DEBUGRC("OK\n");
87                 return 0;
88         }
89
90         DEBUGRC("ERROR\n");
91         return -1;
92 }
93
94 static int Read1ByteFromReg(struct rfid_asic_transport_handle *rath,
95                             unsigned char reg,
96                             unsigned char *value)
97 {
98         unsigned char sndbuf[SENDBUF_LEN];
99         unsigned char recvbuf[RECVBUF_LEN];
100         size_t retlen = sizeof(recvbuf);
101
102         sndbuf[0] = 0x20;
103         sndbuf[1] = 0x00;
104         sndbuf[2] = 0x00;
105         sndbuf[3] = 0x00;
106         sndbuf[4] = 0x01;
107         sndbuf[5] = 0x00;
108         sndbuf[6] = reg;
109
110         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, 
111                              &retlen) == 0) {
112                 *value = recvbuf[1];
113                 DEBUGR("reg=0x%02x, val=%02x: ", reg, *value);
114                 DEBUGRC("OK\n");
115                 return 0;
116         }
117
118         DEBUGRC("ERROR\n");
119         return -1;
120 }
121
122 static int ReadNBytesFromFIFO(struct rfid_asic_transport_handle *rath,
123                               unsigned char num_bytes,
124                               unsigned char *buf)
125 {
126         unsigned char sndbuf[SENDBUF_LEN];
127         unsigned char recvbuf[0x7f];
128         size_t retlen = sizeof(recvbuf);
129
130         sndbuf[0] = 0x20;
131         sndbuf[1] = 0x00;
132         sndbuf[2] = 0x00;
133         sndbuf[3] = 0x00;
134         sndbuf[4] = num_bytes;
135         sndbuf[5] = 0x00;
136         sndbuf[6] = 0x02;
137
138         DEBUGR("num_bytes=%u: ", num_bytes);
139         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, &retlen) == 0) {
140                 DEBUGRC("%u [%s]\n", retlen,
141                         rfid_hexdump(recvbuf+1, num_bytes));
142                 memcpy(buf, recvbuf+1, num_bytes); // len == 0x7f
143                 return 0;
144         }
145
146         DEBUGRC("ERROR\n");
147         return -1;
148 }
149
150 static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath,
151                              unsigned char len,
152                              const unsigned char *bytes,
153                              unsigned char flags)
154 {
155         unsigned char sndbuf[SENDBUF_LEN];
156         unsigned char recvbuf[0x7f];
157         size_t retlen = sizeof(recvbuf);
158
159         sndbuf[0] = 0x20;
160         sndbuf[1] = 0x00;
161         sndbuf[2] = len;
162         sndbuf[3] = 0x00;
163         sndbuf[4] = 0x00;
164         sndbuf[5] = flags;
165         sndbuf[6] = 0x02;
166
167         DEBUGR("%u [%s]: ", len, rfid_hexdump(bytes, len));
168
169         memcpy(sndbuf+7, bytes, len);
170
171         if (PC_to_RDR_Escape(rath->data, sndbuf, len+7, recvbuf, &retlen) == 0) {
172                 DEBUGRC("OK (%u [%s])\n", retlen, rfid_hexdump(recvbuf, retlen));
173                 return 0;
174         }
175
176         DEBUGRC("ERROR\n");
177         return -1;
178 }
179
180 struct rfid_asic_transport cm5121_ccid = {
181         .name = "CM5121 OpenCT",
182         .priv.rc632 = {
183                 .fn = {
184                         .reg_write      = &Write1ByteToReg,
185                         .reg_read       = &Read1ByteFromReg,
186                         .fifo_write     = &WriteNBytesToFIFO,
187                         .fifo_read      = &ReadNBytesFromFIFO,
188                 },
189         },
190 };
191
192 static int cm5121_enable_rc632(struct rfid_asic_transport_handle *rath)
193 {
194         unsigned char tx_buf[1] = { 0x01 };     
195         unsigned char rx_buf[64];
196         size_t rx_len = sizeof(rx_buf);
197
198         PC_to_RDR_Escape(rath->data, tx_buf, 1, rx_buf, &rx_len);
199
200         return 0;
201 }
202
203 static struct rfid_reader_handle *
204 cm5121_open(void *data)
205 {
206         struct rfid_reader_handle *rh;
207         struct rfid_asic_transport_handle *rath;
208
209         rh = malloc_reader_handle(sizeof(*rh));
210         if (!rh)
211                 return NULL;
212         memset(rh, 0, sizeof(*rh));
213
214         rath = malloc_rat_handle(sizeof(*rath));
215         if (!rath)
216                 goto out_rh;
217         memset(rath, 0, sizeof(*rath));
218
219         rath->rat = &cm5121_ccid;
220         rh->reader = &rfid_reader_cm5121;
221
222         if (cm5121_source_init(rath) < 0)
223                 goto out_rath;
224
225         if (cm5121_enable_rc632(rath) < 0)
226                 goto out_rath;
227
228         rh->ah = rc632_open(rath);
229         if (!rh->ah) 
230                 goto out_rath;
231
232         DEBUGP("returning %p\n", rh);
233         return rh;
234
235 out_rath:
236         free_rat_handle(rath);
237 out_rh:
238         free_reader_handle(rh);
239
240         return NULL;
241 }
242
243 static void
244 cm5121_close(struct rfid_reader_handle *rh)
245 {
246         struct rfid_asic_transport_handle *rath = rh->ah->rath;
247         rc632_close(rh->ah);
248         free_rat_handle(rath);
249         free_reader_handle(rh);
250 }
251
252 const struct rfid_reader rfid_reader_cm5121 = {
253         .name   = "Omnikey CardMan 5121 RFID",
254         .open = &cm5121_open,
255         .close = &cm5121_close,
256         .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
257                         (1 << RFID_LAYER2_ISO14443B) |
258                         (1 << RFID_LAYER2_ISO15693),
259         .proto_supported = (1 << RFID_PROTOCOL_TCL) |
260                         (1 << RFID_PROTOCOL_MIFARE_UL) |
261                         (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
262         .getopt = &_rdr_rc632_getopt,
263         .setopt = &_rdr_rc632_setopt,
264         .transceive = &_rdr_rc632_transceive,
265         .init = &_rdr_rc632_l2_init,
266         .iso14443a = {
267                 .transceive_sf = &_rdr_rc632_transceive_sf,
268                 .transceive_acf = &_rdr_rc632_transceive_acf,
269                 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
270                          RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
271                 .set_speed = &_rdr_rc632_14443a_set_speed,
272         },
273         .iso15693 = {
274                 .transceive_ac = &_rdr_rc632_iso15693_transceive_ac,
275         },
276         .mifare_classic = {
277                 .setkey = &_rdr_rc632_mifare_setkey,
278                 .setkey_ee = &_rdr_rc632_mifare_setkey_ee,
279                 .auth = &_rdr_rc632_mifare_auth,
280         },
281 };
282
283 #endif /* LIBRFID_FIRMWARE */