sed s/cm5121/x501/ - need to be hacked now (hopefully there is a way to access regist...
[rfid/librfid.git] / src / rfid_reader_x501.c
1 /* Gemini 2000 x501 specific RC632 transport layer 
2  *
3  * (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
4  *
5  * Are there extensions allowing to access registers and FIFO of the rc632?
6  * 
7  */
8
9 /*
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License version 2 
12  *  as published by the Free Software Foundation
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #include <librfid/rfid.h>
30 #include <librfid/rfid_reader.h>
31 #include <librfid/rfid_asic.h>
32 #include <librfid/rfid_asic_rc632.h>
33 #include <librfid/rfid_reader_x501.h>
34
35 #include "rc632.h"
36
37 #define SENDBUF_LEN     100
38 #define RECVBUF_LEN     40
39
40 static
41 int Write1ByteToReg(struct rfid_asic_transport_handle *rath,
42                     unsigned char reg, unsigned char value)
43 {
44         unsigned char sndbuf[SENDBUF_LEN];
45         unsigned char rcvbuf[RECVBUF_LEN];
46         unsigned int retlen = RECVBUF_LEN;
47
48         sndbuf[0] = 0x20;
49         sndbuf[1] = 0x00;
50         sndbuf[2] = 0x01;
51         sndbuf[3] = 0x00;
52         sndbuf[4] = 0x00;
53         sndbuf[5] = 0x00;
54         sndbuf[6] = reg;
55         sndbuf[7] = value;
56
57         DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
58
59         if (PC_to_RDR_Escape(rath->data, sndbuf, 8, rcvbuf, 
60                              &retlen) == 0) {
61                 DEBUGPC("OK\n");
62                 return 0;
63         }
64
65         DEBUGPC("ERROR\n");
66         return -1;
67 }
68
69 static int Read1ByteFromReg(struct rfid_asic_transport_handle *rath,
70                             unsigned char reg,
71                             unsigned char *value)
72 {
73         unsigned char sndbuf[SENDBUF_LEN];
74         unsigned char recvbuf[RECVBUF_LEN];
75         unsigned int retlen = sizeof(recvbuf);
76
77         sndbuf[0] = 0x20;
78         sndbuf[1] = 0x00;
79         sndbuf[2] = 0x00;
80         sndbuf[3] = 0x00;
81         sndbuf[4] = 0x01;
82         sndbuf[5] = 0x00;
83         sndbuf[6] = reg;
84
85         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, 
86                              &retlen) == 0) {
87                 *value = recvbuf[1];
88                 DEBUGP("reg=0x%02x, val=%02x: ", reg, *value);
89                 DEBUGPC("OK\n");
90                 return 0;
91         }
92
93         DEBUGPC("ERROR\n");
94         return -1;
95 }
96
97 static int ReadNBytesFromFIFO(struct rfid_asic_transport_handle *rath,
98                               unsigned char num_bytes,
99                               unsigned char *buf)
100 {
101         unsigned char sndbuf[SENDBUF_LEN];
102         unsigned char recvbuf[0x7f];
103         unsigned int retlen = sizeof(recvbuf);
104
105         sndbuf[0] = 0x20;
106         sndbuf[1] = 0x00;
107         sndbuf[2] = 0x00;
108         sndbuf[3] = 0x00;
109         sndbuf[4] = num_bytes;
110         sndbuf[5] = 0x00;
111         sndbuf[6] = 0x02;
112
113         DEBUGP("num_bytes=%u: ", num_bytes);
114         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, &retlen) == 0) {
115                 DEBUGPC("%u [%s]\n", retlen,
116                         rfid_hexdump(recvbuf+1, num_bytes));
117                 memcpy(buf, recvbuf+1, num_bytes); // len == 0x7f
118                 return 0;
119         }
120
121         DEBUGPC("ERROR\n");
122         return -1;
123 }
124
125 static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath,
126                              unsigned char len,
127                              const unsigned char *bytes,
128                              unsigned char flags)
129 {
130         unsigned char sndbuf[SENDBUF_LEN];
131         unsigned char recvbuf[0x7f];
132         unsigned int retlen = sizeof(recvbuf);
133
134         sndbuf[0] = 0x20;
135         sndbuf[1] = 0x00;
136         sndbuf[2] = len;
137         sndbuf[3] = 0x00;
138         sndbuf[4] = 0x00;
139         sndbuf[5] = flags;
140         sndbuf[6] = 0x02;
141
142         DEBUGP("%u [%s]: ", len, rfid_hexdump(bytes, len));
143
144         memcpy(sndbuf+7, bytes, len);
145
146         if (PC_to_RDR_Escape(rath->data, sndbuf, len+7, recvbuf, &retlen) == 0) {
147                 DEBUGPC("OK (%u [%s])\n", retlen, rfid_hexdump(recvbuf, retlen));
148                 return 0;
149         }
150
151         DEBUGPC("ERROR\n");
152         return -1;
153 }
154
155 #if 0
156 static int TestFIFO(struct rc632_handle *handle)
157 {
158         unsigned char sndbuf[60]; // 0x3c
159
160         // FIXME: repne stosd, call
161
162         memset(sndbuf, 0, sizeof(sndbuf));
163
164         if (WriteNBytesToFIFO(handle, sizeof(sndbuf), sndbuf, 0) < 0)
165                 return -1;
166
167         return ReadNBytesFromFIFO(handle, sizeof(sndbuf), sndbuf);
168 }
169 #endif
170
171 static int x501_transcieve(struct rfid_reader_handle *rh,
172                              enum rfid_frametype frametype,
173                              const unsigned char *tx_data, unsigned int tx_len,
174                              unsigned char *rx_data, unsigned int *rx_len,
175                              u_int64_t timeout, unsigned int flags)
176 {
177         return rh->ah->asic->priv.rc632.fn.transcieve(rh->ah, frametype,
178                                                 tx_data, tx_len, rx_data,
179                                                 rx_len, timeout, flags);
180 }
181
182 static int x501_transcieve_sf(struct rfid_reader_handle *rh,
183                                unsigned char cmd, struct iso14443a_atqa *atqa)
184 {
185         return rh->ah->asic->priv.rc632.fn.iso14443a.transcieve_sf(rh->ah,
186                                                                    cmd,
187                                                                    atqa);
188 }
189
190 static int
191 x501_transcieve_acf(struct rfid_reader_handle *rh,
192                       struct iso14443a_anticol_cmd *cmd,
193                       unsigned int *bit_of_col)
194 {
195         return rh->ah->asic->priv.rc632.fn.iso14443a.transcieve_acf(rh->ah,
196                                                          cmd, bit_of_col);
197 }
198
199 static int
200 x501_14443a_init(struct rfid_reader_handle *rh)
201 {
202         return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
203 }
204
205 static int
206 x501_14443a_set_speed(struct rfid_reader_handle *rh, 
207                         unsigned int tx,
208                         unsigned int speed)
209 {
210         u_int8_t rate;
211         
212         DEBUGP("setting rate: ");
213         switch (speed) {
214         case RFID_14443A_SPEED_106K:
215                 rate = 0x00;
216                 DEBUGPC("106K\n");
217                 break;
218         case RFID_14443A_SPEED_212K:
219                 rate = 0x01;
220                 DEBUGPC("212K\n");
221                 break;
222         case RFID_14443A_SPEED_424K:
223                 rate = 0x02;
224                 DEBUGPC("424K\n");
225                 break;
226         case RFID_14443A_SPEED_848K:
227                 rate = 0x03;
228                 DEBUGPC("848K\n");
229                 break;
230         default:
231                 return -EINVAL;
232                 break;
233         }
234         return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
235                                                                 tx, rate);
236 }
237
238 static int
239 x501_14443b_init(struct rfid_reader_handle *rh)
240 {
241         return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
242 }
243
244 static int
245 x501_15693_init(struct rfid_reader_handle *rh)
246 {
247         return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
248 }
249
250 static int
251 x501_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
252 {
253         return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
254 }
255
256 static int
257 x501_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, 
258                    u_int32_t serno, u_int8_t block)
259 {
260         return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, 
261                                                         cmd, serno, block);
262 }
263
264 struct rfid_asic_transport x501_ccid = {
265         .name = "X501 OpenCT",
266         .priv.rc632 = {
267                 .fn = {
268                         .reg_write      = &Write1ByteToReg,
269                         .reg_read       = &Read1ByteFromReg,
270                         .fifo_write     = &WriteNBytesToFIFO,
271                         .fifo_read      = &ReadNBytesFromFIFO,
272                 },
273         },
274 };
275
276 static int x501_enable_rc632(struct rfid_asic_transport_handle *rath)
277 {
278         unsigned char tx_buf[1] = { 0x01 };     
279         unsigned char rx_buf[64];
280         unsigned int rx_len = sizeof(rx_buf);
281
282         PC_to_RDR_Escape(rath->data, tx_buf, 1, rx_buf, &rx_len);
283         printf("received %u bytes from 01 command\n", rx_len);
284
285         return 0;
286 }
287
288 static struct rfid_reader_handle *
289 x501_open(void *data)
290 {
291         struct rfid_reader_handle *rh;
292         struct rfid_asic_transport_handle *rath;
293
294         rh = malloc(sizeof(*rh));
295         if (!rh)
296                 return NULL;
297         memset(rh, 0, sizeof(*rh));
298
299         rath = malloc(sizeof(*rath));
300         if (!rath)
301                 goto out_rh;
302         memset(rath, 0, sizeof(*rath));
303
304         rath->rat = &x501_ccid;
305         rh->reader = &rfid_reader_x501;
306
307         if (x501_source_init(rath) < 0)
308                 goto out_rath;
309
310         if (x501_enable_rc632(rath) < 0)
311                 goto out_rath;
312
313         rh->ah = rc632_open(rath);
314         if (!rh->ah) 
315                 goto out_rath;
316
317         DEBUGP("returning %p\n", rh);
318         return rh;
319
320 out_rath:
321         free(rath);
322 out_rh:
323         free(rh);
324
325         return NULL;
326 }
327
328 static void
329 x501_close(struct rfid_reader_handle *rh)
330 {
331         struct rfid_asic_transport_handle *rath = rh->ah->rath;
332         rc632_close(rh->ah);
333         free(rath);
334         free(rh);
335 }
336
337 struct rfid_reader rfid_reader_x501 = {
338         .name   = "Omnikey CardMan 5121 RFID",
339         .open = &x501_open,
340         .close = &x501_close,
341         .transcieve = &x501_transcieve,
342         .iso14443a = {
343                 .init = &x501_14443a_init,
344                 .transcieve_sf = &x501_transcieve_sf,
345                 .transcieve_acf = &x501_transcieve_acf,
346                 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
347                          RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
348                 .set_speed = &x501_14443a_set_speed,
349         },
350         .iso14443b = {
351                 .init = &x501_14443b_init,
352         },
353         .mifare_classic = {
354                 .setkey = &x501_mifare_setkey,
355                 .auth = &x501_mifare_auth,
356         },
357 };
358
359