- use C99 compiler flags
[librfid] / src / rfid_layer2_iso14443b.c
1 /* ISO 14443-3 B anticollision implementation
2  *
3  * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
4  *
5  */
6
7 /*
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 
10  *  as published by the Free Software Foundation
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include <librfid/rfid.h>
28 #include <librfid/rfid_layer2.h>
29 #include <librfid/rfid_reader.h>
30 #include <librfid/rfid_layer2_iso14443b.h>
31 #include <librfid/rfid_protocol.h>
32
33 #include "rfid_iso14443_common.h"
34
35 #define ATQB_TIMEOUT    ((256*10e6/ISO14443_FREQ_SUBCARRIER)            \
36                          +(200*10e6/ISO14443_FREQ_SUBCARRIER))
37
38 #undef ATQB_TIMEOUT
39 #define ATQB_TIMEOUT    1
40
41 static inline int
42 fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi)
43 {
44         unsigned int multiplier, tmp;
45
46         /* 15 is RFU */
47         if (fwi > 14)
48                 return -1;
49
50         /* According to ISO 14443-3:200(E), Chapter 7.9.4.3, the forumala is
51          * (256 * 16 / fC) * 2^fwi We avoid floating point computations by
52          * shifting everything into the microsecond range.  In integer
53          * calculations 1000000*256*16/13560000 evaluates to 302 (instead of
54          * 302.064897), which provides sufficient precision, IMHO.  The max
55          * result is 302 * 16384 (4947968), which fits well within the 31/32
56          * bit range of an integer */
57
58         multiplier = 1 << fwi;          /* 2 to the power of fwi */
59
60         tmp = (unsigned int) 1000000 * 256 * 16;
61
62         return (tmp / h->rh->ah->asic->fc) * multiplier;
63 }
64
65 static int
66 parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb)
67 {
68         int ret;
69
70         if (atqb->fifty != 0x50)
71                 return -1; 
72
73         if (atqb->protocol_info.fo & 0x01)
74                 h->priv.iso14443b.flags |= ISO14443B_CID_SUPPORTED;
75         if (atqb->protocol_info.fo & 0x02)
76                 h->priv.iso14443b.flags |= ISO14443B_NAD_SUPPORTED;
77
78         ret = fwi_to_fwt(h, &h->priv.iso14443b.fwt, atqb->protocol_info.fwi);
79         if (ret < 0) {
80                 DEBUGP("invalid fwi %u\n", atqb->protocol_info.fwi);
81                 return ret;
82         }
83
84         if (atqb->protocol_info.protocol_type == 0x1) {
85                 DEBUGP("we have a T=CL compliant PICC\n");
86                 h->priv.iso14443b.tcl_capable = 1;
87                 h->proto_supported = (1 << RFID_PROTOCOL_TCL);
88         } else {
89                 DEBUGP("we have a T!=CL PICC\n");
90                 h->priv.iso14443b.tcl_capable = 0;
91                 /* FIXME: what protocols do we support? */
92         }
93
94         iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc, 
95                              atqb->protocol_info.max_frame_size);
96
97         /* FIXME: speed capability */
98
99         memcpy(h->uid, atqb->pupi, sizeof(atqb->pupi));
100         h->uid_len = sizeof(atqb->pupi);
101
102         return 0;
103 }
104
105 static int
106 send_reqb(struct rfid_layer2_handle *h, unsigned char afi,
107           unsigned int is_wup, unsigned int num_initial_slots)
108 {
109         int ret;
110         unsigned char reqb[3];
111         struct iso14443b_atqb atqb;
112         unsigned int atqb_len = sizeof(atqb);
113         unsigned int num_slot_idx = num_initial_slots;
114
115         reqb[0] = 0x05;
116         reqb[1] = afi;
117
118         for (num_slot_idx = num_initial_slots; num_slot_idx <= 4;
119              num_slot_idx++) {
120                 reqb[2] = num_slot_idx & 0x07;
121                 if (is_wup)
122                         reqb[2] |= 0x08;
123
124                 ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
125                                                 reqb, sizeof(reqb),
126                                                  (unsigned char *)&atqb, 
127                                                  &atqb_len, ATQB_TIMEOUT, 0);
128                 h->priv.iso14443b.state = ISO14443B_STATE_REQB_SENT;
129                 if (ret < 0) {
130                         DEBUGP("error during transceive of REQB/WUBP\n");
131                         continue;
132                 }
133
134                 /* FIXME: send N-1 slot marker frames */
135         
136                 if (atqb_len != sizeof(atqb)) {
137                         DEBUGP("error: atqb_len = %u instead of %Zu\n",
138                                 atqb_len, sizeof(atqb));
139                         continue;
140                 }
141
142                 /* FIXME: how to detect a collission at 14443B ?  I guess we
143                  * can only rely on the CRC checking (CRCErr in ErrorFlag
144                  * register?) */
145
146                 if (parse_atqb(h, &atqb) >= 0) {
147                         h->priv.iso14443b.state = ISO14443B_STATE_ATQB_RCVD;
148                         return 0;
149                 }
150         }
151
152         return -1;
153 }
154
155 static inline unsigned int mbli_to_mbl(struct rfid_layer2_handle *h,
156                                         unsigned int mbli)
157 {
158         return (h->priv.iso14443b.fsc * 2 ^ (mbli-1));
159 }
160
161 static int
162 transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
163             unsigned int inf_len, unsigned char *rx_data, unsigned int *rx_len)
164 {
165         struct iso14443b_attrib_hdr *attrib;
166         unsigned int attrib_size = sizeof(*attrib) + inf_len;
167         unsigned char *rx_buf;
168         unsigned char fsdi;
169         int ret = 0;
170         
171         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
172         attrib = malloc(attrib_size);
173         if (!attrib) {
174                 perror("attrib_alloc");
175                 return -1;
176         }
177
178         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
179         rx_buf = malloc(*rx_len+1);
180         if (!rx_buf) {
181                 perror("rx_buf malloc");
182                 ret = -1;
183                 goto out_attrib;
184         }
185
186         /* initialize attrib frame */
187         memset(attrib, 0, attrib_size);
188         if (inf_len)
189                 memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len);
190
191         attrib->one_d = 0x1d;
192         memcpy(attrib->identifier, h->uid, 4);
193
194         /* FIXME: do we want to change TR0/TR1 from its default ? */
195         /* FIXME: do we want to change SOF/EOF from its default ? */
196
197         ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.iso14443b.fsd);
198         if (ret < 0) {
199                 DEBUGP("unable to map FSD(%u) to FSDI\n",
200                         h->priv.iso14443b.fsd);
201                 goto out_rx;
202         }
203         attrib->param2.fsdi = fsdi;
204
205         /* FIXME: spd_in / spd_out */
206         if (h->priv.iso14443b.tcl_capable == 1)
207                 attrib->param3.protocol_type = 0x1;
208
209         attrib->param4.cid = h->priv.iso14443b.cid & 0xf;
210
211         *rx_len = *rx_len + 1;
212         ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
213                                         (unsigned char *) attrib,
214                                         sizeof(*attrib)+inf_len,
215                                         rx_buf, rx_len, h->priv.iso14443b.fwt,
216                                         0);
217         h->priv.iso14443b.state = ISO14443B_STATE_ATTRIB_SENT;
218         if (ret < 0) {
219                 DEBUGP("transceive problem\n");
220                 goto out_rx;
221         }
222
223         if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
224                 DEBUGP("ATTRIB response with invalid CID %u (should be %u)\n",
225                         rx_buf[0] & 0x0f, h->priv.iso14443b.cid);
226                 ret = -1;
227                 goto out_rx;
228         }
229
230         h->priv.iso14443b.state = ISO14443B_STATE_SELECTED;
231         
232         h->priv.iso14443b.mbl = mbli_to_mbl(h, (rx_data[0] & 0xf0) >> 4);
233
234         *rx_len = *rx_len - 1;
235         memcpy(rx_data, rx_buf+1, *rx_len);
236
237 out_rx:
238         free(rx_buf);
239 out_attrib:
240         free(attrib);
241
242         return ret;
243 }
244
245 static int
246 iso14443b_hltb(struct rfid_layer2_handle *h)
247 {
248         int ret;
249         unsigned char hltb[5];
250         unsigned char hltb_resp[1];
251         unsigned int hltb_len = 1;
252
253         hltb[0] = 0x50;
254         memcpy(hltb+1, h->uid, 4);
255
256         ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
257                                         hltb, 5,
258                                         hltb_resp, &hltb_len,
259                                         h->priv.iso14443b.fwt, 0);
260         h->priv.iso14443b.state = ISO14443B_STATE_HLTB_SENT;
261         if (ret < 0) {
262                 DEBUGP("transceive problem\n");
263                 return ret;
264         }
265
266         if (hltb_len != 1 || hltb_resp[0] != 0x00) {
267                 DEBUGP("bad HLTB response\n");
268                 return -1;
269         }
270         h->priv.iso14443b.state = ISO14443B_STATE_HALTED;
271                                                 
272         return 0;
273 }
274
275 static int
276 iso14443b_anticol(struct rfid_layer2_handle *handle)
277 {
278         unsigned char afi = 0; /* FIXME */
279         int ret;
280         unsigned char buf[255];
281         unsigned int buf_len = sizeof(buf);
282
283         ret = send_reqb(handle, afi, 0, 0);
284         if (ret < 0)
285                 return ret;
286
287         ret = transceive_attrib(handle, NULL, 0, buf, &buf_len);
288         if (ret < 0)
289                 return ret;
290
291         return 0;
292 }
293
294 static struct rfid_layer2_handle *
295 iso14443b_init(struct rfid_reader_handle *rh)
296 {
297         int ret;
298         struct rfid_layer2_handle *h = malloc(sizeof(*h));
299         if (!h)
300                 return NULL;
301
302         h->l2 = &rfid_layer2_iso14443b;
303         h->rh = rh;
304         h->priv.iso14443b.state = ISO14443B_STATE_NONE;
305
306         /* FIXME: if we want to support multiple PICC's, we need some
307          * fancy allocation scheme for CID's */
308         h->priv.iso14443b.cid = 0;
309
310         h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru);
311         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
312
313         /* 14443-3 Section 7.1.6 */
314         h->priv.iso14443b.tr0 = (256/ISO14443_FREQ_SUBCARRIER)*10e6;
315         h->priv.iso14443b.tr1 = (200/ISO14443_FREQ_SUBCARRIER)*10e6;
316
317         ret = h->rh->reader->iso14443b.init(h->rh);
318         if (ret < 0) {
319                 DEBUGP("error during reader 14443b init\n");
320                 free(h);
321                 return NULL;
322         }
323
324         return h;
325 }
326
327 static int
328 iso14443b_fini(struct rfid_layer2_handle *handle)
329 {
330         free(handle);
331         return 0;
332 }
333
334 static int
335 iso14443b_transceive(struct rfid_layer2_handle *handle,
336                      enum rfid_frametype frametype,
337                      const unsigned char *tx_buf, unsigned int tx_len,
338                      unsigned char *rx_buf, unsigned int *rx_len,
339                      u_int64_t timeout, unsigned int flags)
340 {
341         DEBUGP("transcieving %u bytes, expecting max %u\n", tx_len, *rx_len);
342         return handle->rh->reader->transceive(handle->rh, frametype,
343                                               tx_buf, tx_len,
344                                               rx_buf, rx_len, timeout, flags);
345 }
346
347 static int
348 iso14443b_getopt(struct rfid_layer2_handle *handle,
349                  int optname, void *optval, unsigned int optlen)
350 {
351         unsigned int *opt_ui = optval;
352
353         switch (optname) {
354         case RFID_OPT_14443B_CID:
355                 *opt_ui = handle->priv.iso14443b.cid;
356                 break;
357         case RFID_OPT_14443B_FSC:
358                 *opt_ui = handle->priv.iso14443b.fsc;
359                 break;
360         case RFID_OPT_14443B_FSD:
361                 *opt_ui = handle->priv.iso14443b.fsd;
362                 break;
363         case RFID_OPT_14443B_FWT:
364                 *opt_ui = handle->priv.iso14443b.fwt;
365                 break;
366         case RFID_OPT_14443B_TR0:
367                 *opt_ui = handle->priv.iso14443b.tr0;
368                 break;
369         case RFID_OPT_14443B_TR1:
370                 *opt_ui = handle->priv.iso14443b.tr1;
371                 break;
372         default:
373                 return -EINVAL;
374                 break;
375         }
376         return 0;
377 }
378
379 static int
380 iso14443b_setopt(struct rfid_layer2_handle *handle,
381                  int optname, const void *optval, unsigned int optlen)
382 {
383         const unsigned int *opt_ui = optval;
384
385         switch (optname) {
386         case RFID_OPT_14443B_CID:
387                 handle->priv.iso14443b.cid = (*opt_ui & 0xf);
388                 break;
389         defaukt:
390                 return -EINVAL;
391                 break;
392         }
393         return 0;
394 }
395
396
397 struct rfid_layer2 rfid_layer2_iso14443b = {
398         .id     = RFID_LAYER2_ISO14443B,
399         .name   = "ISO 14443-3 B",
400         .fn     = {
401                 .init           = &iso14443b_init,
402                 .open           = &iso14443b_anticol,
403                 .transceive     = &iso14443b_transceive,
404                 .close          = &iso14443b_hltb,
405                 .fini           = &iso14443b_fini,
406                 .getopt         = &iso14443b_getopt,
407                 .setopt         = &iso14443b_setopt,
408         },
409 };