1 /* Gemini 2000 x501 specific RC632 transport layer
3 * (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
5 * Are there extensions allowing to access registers and FIFO of the rc632?
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
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.
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
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>
37 #define SENDBUF_LEN 100
38 #define RECVBUF_LEN 40
41 int Write1ByteToReg(struct rfid_asic_transport_handle *rath,
42 unsigned char reg, unsigned char value)
44 unsigned char sndbuf[SENDBUF_LEN];
45 unsigned char rcvbuf[RECVBUF_LEN];
46 unsigned int retlen = RECVBUF_LEN;
57 DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
59 if (PC_to_RDR_Escape(rath->data, sndbuf, 8, rcvbuf,
69 static int Read1ByteFromReg(struct rfid_asic_transport_handle *rath,
73 unsigned char sndbuf[SENDBUF_LEN];
74 unsigned char recvbuf[RECVBUF_LEN];
75 unsigned int retlen = sizeof(recvbuf);
85 if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf,
88 DEBUGP("reg=0x%02x, val=%02x: ", reg, *value);
97 static int ReadNBytesFromFIFO(struct rfid_asic_transport_handle *rath,
98 unsigned char num_bytes,
101 unsigned char sndbuf[SENDBUF_LEN];
102 unsigned char recvbuf[0x7f];
103 unsigned int retlen = sizeof(recvbuf);
109 sndbuf[4] = num_bytes;
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
125 static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath,
127 const unsigned char *bytes,
130 unsigned char sndbuf[SENDBUF_LEN];
131 unsigned char recvbuf[0x7f];
132 unsigned int retlen = sizeof(recvbuf);
142 DEBUGP("%u [%s]: ", len, rfid_hexdump(bytes, len));
144 memcpy(sndbuf+7, bytes, len);
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));
156 static int TestFIFO(struct rc632_handle *handle)
158 unsigned char sndbuf[60]; // 0x3c
160 // FIXME: repne stosd, call
162 memset(sndbuf, 0, sizeof(sndbuf));
164 if (WriteNBytesToFIFO(handle, sizeof(sndbuf), sndbuf, 0) < 0)
167 return ReadNBytesFromFIFO(handle, sizeof(sndbuf), sndbuf);
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)
177 return rh->ah->asic->priv.rc632.fn.transcieve(rh->ah, frametype,
178 tx_data, tx_len, rx_data,
179 rx_len, timeout, flags);
182 static int x501_transcieve_sf(struct rfid_reader_handle *rh,
183 unsigned char cmd, struct iso14443a_atqa *atqa)
185 return rh->ah->asic->priv.rc632.fn.iso14443a.transcieve_sf(rh->ah,
191 x501_transcieve_acf(struct rfid_reader_handle *rh,
192 struct iso14443a_anticol_cmd *cmd,
193 unsigned int *bit_of_col)
195 return rh->ah->asic->priv.rc632.fn.iso14443a.transcieve_acf(rh->ah,
200 x501_14443a_init(struct rfid_reader_handle *rh)
202 return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
206 x501_14443a_set_speed(struct rfid_reader_handle *rh,
212 DEBUGP("setting rate: ");
214 case RFID_14443A_SPEED_106K:
218 case RFID_14443A_SPEED_212K:
222 case RFID_14443A_SPEED_424K:
226 case RFID_14443A_SPEED_848K:
234 return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
239 x501_14443b_init(struct rfid_reader_handle *rh)
241 return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
245 x501_15693_init(struct rfid_reader_handle *rh)
247 return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
251 x501_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
253 return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
257 x501_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
258 u_int32_t serno, u_int8_t block)
260 return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
264 struct rfid_asic_transport x501_ccid = {
265 .name = "X501 OpenCT",
268 .reg_write = &Write1ByteToReg,
269 .reg_read = &Read1ByteFromReg,
270 .fifo_write = &WriteNBytesToFIFO,
271 .fifo_read = &ReadNBytesFromFIFO,
276 static int x501_enable_rc632(struct rfid_asic_transport_handle *rath)
278 unsigned char tx_buf[1] = { 0x01 };
279 unsigned char rx_buf[64];
280 unsigned int rx_len = sizeof(rx_buf);
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);
288 static struct rfid_reader_handle *
289 x501_open(void *data)
291 struct rfid_reader_handle *rh;
292 struct rfid_asic_transport_handle *rath;
294 rh = malloc(sizeof(*rh));
297 memset(rh, 0, sizeof(*rh));
299 rath = malloc(sizeof(*rath));
302 memset(rath, 0, sizeof(*rath));
304 rath->rat = &x501_ccid;
305 rh->reader = &rfid_reader_x501;
307 if (x501_source_init(rath) < 0)
310 if (x501_enable_rc632(rath) < 0)
313 rh->ah = rc632_open(rath);
317 DEBUGP("returning %p\n", rh);
329 x501_close(struct rfid_reader_handle *rh)
331 struct rfid_asic_transport_handle *rath = rh->ah->rath;
337 struct rfid_reader rfid_reader_x501 = {
338 .name = "Omnikey CardMan 5121 RFID",
340 .close = &x501_close,
341 .transcieve = &x501_transcieve,
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,
351 .init = &x501_14443b_init,
354 .setkey = &x501_mifare_setkey,
355 .auth = &x501_mifare_auth,