shuffle structure elements to cope with atr[0]
[librfid] / rfid_layer2_iso14443b.c
1 /* ISO 14443-3 B anticollision implementation
2  *
3  * (C) 2005 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
26 #include <rfid/rfid.h>
27 #include <rfid/rfid_layer2.h>
28 #include <rfid/rfid_reader.h>
29 #include <rfid/rfid_layer2_iso14443b.h>
30
31 #include "rfid_iso14443_common.h"
32
33 #define ATQB_TIMEOUT    ((256*10e6/ISO14443_FREQ_SUBCARRIER)            \
34                          +(200*10e6/ISO14443_FREQ_SUBCARRIER))
35
36 static inline int
37 fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi)
38 {
39         if (fwi > 14)
40                 return -1;
41
42         return (256 * 16 / h->rh->ah->asic->fc) * 2 ^ fwi;
43 }
44
45 static int
46 parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb)
47 {
48         int ret;
49
50         if (atqb->fifty != 0x50)
51                 return -1; 
52
53         if (atqb->protocol_info.fo & 0x01)
54                 h->priv.iso14443b.flags |= ISO14443B_CID_SUPPORTED;
55         if (atqb->protocol_info.fo & 0x02)
56                 h->priv.iso14443b.flags |= ISO14443B_NAD_SUPPORTED;
57
58         ret = fwi_to_fwt(h, &h->priv.iso14443b.fwt, atqb->protocol_info.fwi);
59         if (ret < 0) {
60                 DEBUGP("invalid fwi %u\n", atqb->protocol_info.fwi);
61                 return ret;
62         }
63
64         if (atqb->protocol_info.protocol_type == 0x1) {
65                 DEBUGP("we have a T=CL compliant PICC\n");
66                 h->priv.iso14443b.tcl_capable = 1;
67         } else {
68                 DEBUGP("we have a T!=CL PICC\n");
69                 h->priv.iso14443b.tcl_capable = 0;
70         }
71
72         iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc, 
73                              atqb->protocol_info.max_frame_size);
74
75         /* FIXME: speed capability */
76
77         memcpy(h->priv.iso14443b.pupi, atqb->pupi,
78                 sizeof(h->priv.iso14443b.pupi));
79
80         return 0;
81 }
82
83 static int
84 send_reqb(struct rfid_layer2_handle *h, unsigned char afi,
85           unsigned int is_wup, unsigned int num_initial_slots)
86 {
87         int ret;
88         unsigned char reqb[3];
89         struct iso14443b_atqb atqb;
90         unsigned int atqb_len = sizeof(atqb);
91         unsigned int num_slot_idx = num_initial_slots;
92
93         reqb[0] = 0x05;
94         reqb[1] = afi;
95
96         for (num_slot_idx = num_initial_slots; num_slot_idx <= 4;
97              num_slot_idx++) {
98                 reqb[2] = num_slot_idx & 0x07;
99                 if (is_wup)
100                         reqb[2] |= 0x80;
101
102                 ret = h->rh->reader->transcieve(h->rh, reqb, sizeof(reqb),
103                                                  (unsigned char *)&atqb, 
104                                                  &atqb_len, ATQB_TIMEOUT, 0);
105                 h->priv.iso14443b.state = ISO14443B_STATE_REQB_SENT;
106                 if (ret < 0) {
107                         DEBUGP("error during transcieve of REQB/WUBP\n");
108                         continue;
109                 }
110
111                 /* FIXME: send N-1 slot marker frames */
112         
113                 if (atqb_len != sizeof(atqb)) {
114                         DEBUGP("error: atqb_len = %u instead of %u\n",
115                                 atqb_len, sizeof(atqb));
116                         continue;
117                 }
118
119                 /* FIXME: how to detect a collission at 14443B ?  I guess we
120                  * can only rely on the CRC checking (CRCErr in ErrorFlag
121                  * register?) */
122
123                 if (parse_atqb(h, &atqb) >= 0) {
124                         h->priv.iso14443b.state = ISO14443B_STATE_ATQB_RCVD;
125                         return 0;
126                 }
127         }
128
129         return -1;
130 }
131
132 static inline unsigned int mbli_to_mbl(struct rfid_layer2_handle *h,
133                                         unsigned int mbli)
134 {
135         return (h->priv.iso14443b.fsc * 2 ^ (mbli-1));
136 }
137
138 static int
139 transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
140             unsigned int inf_len, unsigned char *rx_data, unsigned int *rx_len)
141 {
142         struct iso14443b_attrib_hdr *attrib;
143         unsigned int attrib_size = sizeof(*attrib) + inf_len;
144         unsigned char *rx_buf;
145         unsigned char fsdi;
146         int ret = 0;
147         
148         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
149         attrib = malloc(attrib_size);
150         if (!attrib) {
151                 perror("attrib_alloc");
152                 return -1;
153         }
154
155         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
156         rx_buf = malloc(*rx_len+1);
157         if (!rx_buf) {
158                 perror("rx_buf malloc");
159                 ret = -1;
160                 goto out_attrib;
161         }
162
163         /* initialize attrib frame */
164         memset(attrib, 0, attrib_size);
165         if (inf_len)
166                 memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len);
167
168         attrib->one_d = 0x1d;
169         memcpy(attrib->identifier, h->priv.iso14443b.pupi, 4);
170
171         /* FIXME: do we want to change TR0/TR1 from its default ? */
172         /* FIXME: do we want to change SOF/EOF from its default ? */
173
174         ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.iso14443b.fsd);
175         if (ret < 0) {
176                 DEBUGP("unable to map FSD(%u) to FSDI\n",
177                         h->priv.iso14443b.fsd);
178                 goto out_rx;
179         }
180         attrib->param2.fsdi = fsdi;
181
182         /* FIXME: spd_in / spd_out */
183         if (h->priv.iso14443b.tcl_capable == 1)
184                 attrib->param3.protocol_type = 0x1;
185
186         *rx_len = *rx_len + 1;
187         ret = h->rh->reader->transcieve(h->rh, (unsigned char *) attrib,
188                                         sizeof(*attrib)+inf_len,
189                                         rx_buf, rx_len, h->priv.iso14443b.fwt,
190                                         0);
191         h->priv.iso14443b.state = ISO14443B_STATE_ATTRIB_SENT;
192         if (ret < 0) {
193                 DEBUGP("transcieve problem\n");
194                 goto out_rx;
195         }
196
197         if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
198                 DEBUGP("ATTRIB response with invalid CID %u\n",
199                         rx_buf[0] & 0x0f);
200                 ret = -1;
201                 goto out_rx;
202         }
203
204         h->priv.iso14443b.state = ISO14443B_STATE_SELECTED;
205         
206         h->priv.iso14443b.mbl = mbli_to_mbl(h, (rx_data[0] & 0xf0) >> 4);
207
208         *rx_len = *rx_len - 1;
209         memcpy(rx_data, rx_buf+1, *rx_len);
210
211 out_rx:
212         free(rx_buf);
213 out_attrib:
214         free(attrib);
215
216         return ret;
217 }
218
219 static int
220 iso14443b_hltb(struct rfid_layer2_handle *h)
221 {
222         int ret;
223         unsigned char hltb[5];
224         unsigned char hltb_resp[1];
225         unsigned int hltb_len = 1;
226
227         hltb[0] = 0x50;
228         memcpy(hltb+1, h->priv.iso14443b.pupi, 4);
229
230         ret = h->rh->reader->transcieve(h->rh, hltb, 5,
231                                         hltb_resp, &hltb_len,
232                                         h->priv.iso14443b.fwt, 0);
233         h->priv.iso14443b.state = ISO14443B_STATE_HLTB_SENT;
234         if (ret < 0) {
235                 DEBUGP("transcieve problem\n");
236                 return ret;
237         }
238
239         if (hltb_len != 1 || hltb_resp[0] != 0x00) {
240                 DEBUGP("bad HLTB response\n");
241                 return -1;
242         }
243         h->priv.iso14443b.state = ISO14443B_STATE_HALTED;
244                                                 
245         return 0;
246 }
247
248 static int
249 iso14443b_anticol(struct rfid_layer2_handle *handle)
250 {
251         unsigned char afi = 0; /* FIXME */
252         int ret;
253         char buf[255];
254         unsigned int buf_len = sizeof(buf);
255
256         ret = send_reqb(handle, afi, 0, 0);
257         if (ret < 0)
258                 return ret;
259
260         ret = transcieve_attrib(handle, NULL, 0, buf, &buf_len);
261         if (ret < 0)
262                 return ret;
263
264         return 0;
265 }
266
267 static struct rfid_layer2_handle *
268 iso14443b_init(struct rfid_reader_handle *rh)
269 {
270         int ret;
271         struct rfid_layer2_handle *h = malloc(sizeof(*h));
272         if (!h)
273                 return NULL;
274
275         h->l2 = &rfid_layer2_iso14443b;
276         h->rh = rh;
277         h->priv.iso14443b.state = ISO14443B_STATE_NONE;
278
279         h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru);
280         DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
281
282         /* 14443-3 Section 7.1.6 */
283         h->priv.iso14443b.tr0 = (256/ISO14443_FREQ_SUBCARRIER)*10e6;
284         h->priv.iso14443b.tr1 = (200/ISO14443_FREQ_SUBCARRIER)*10e6;
285
286         ret = h->rh->reader->iso14443b.init(h->rh);
287         if (ret < 0) {
288                 DEBUGP("error during reader 14443b init\n");
289                 free(h);
290                 return NULL;
291         }
292
293         return h;
294 }
295
296 static int
297 iso14443b_fini(struct rfid_layer2_handle *handle)
298 {
299         free(handle);
300         return 0;
301 }
302
303 static int
304 iso14443b_transcieve(struct rfid_layer2_handle *handle,
305                      const unsigned char *tx_buf, unsigned int tx_len,
306                      unsigned char *rx_buf, unsigned int *rx_len,
307                      unsigned int timeout, unsigned int flags)
308 {
309         return handle->rh->reader->transcieve(handle->rh, tx_buf, tx_len,
310                                               rx_buf, rx_len, timeout, flags);
311 }
312
313 struct rfid_layer2 rfid_layer2_iso14443b = {
314         .id     = RFID_LAYER2_ISO14443B,
315         .name   = "ISO 14443-3 B",
316         .fn     = {
317                 .init           = &iso14443b_init,
318                 .open           = &iso14443b_anticol,
319                 .transcieve     = &iso14443b_transcieve,
320                 .close          = &iso14443b_hltb,
321                 .fini           = &iso14443b_fini,
322         },
323 };
324