add speed information to data structures
[librfid] / rfid_proto_tcl.c
1 /* ISO 14443-4 (T=CL) implementation, PCD side.
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 <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include <rfid/rfid.h>
29 #include <rfid/rfid_protocol_tcl.h>
30 #include <rfid/rfid_protocol.h>
31 #include <rfid/rfid_layer2.h>
32 #include <rfid/rfid_layer2_iso14443b.h>
33
34 #include <rfid/rfid_asic.h>
35 #include <rfid/rfid_reader.h>
36
37 #include "rfid_iso14443_common.h"
38
39
40 static unsigned int sfgi_to_sfgt(struct rfid_protocol_handle *h, 
41                                  unsigned char sfgi)
42 {
43         /* ISO 14443-4:2000(E) Section 5.2.5. */
44         return (256 * 16 / h->l2h->rh->ah->fc) * (2 ^ sfgi);
45 }
46
47 static unsigned int fwi_to_fwt(struct rfid_protocol_handle *h, 
48                                 unsigned char fwi)
49 {
50         /* ISO 14443-4:2000(E) Section 7.2. */
51         return (256*16 / h->l2h->rh->ah->fc) * (2 ^ fwi);
52 }
53
54 #define activation_fwt(x) (65536 / x->l2h->rh->ah->fc)
55 #define deactivation_fwt(x) activation_fwt(x)
56
57 static int
58 tcl_parse_ats(struct rfid_protocol_handle *h, 
59                 unsigned char *ats, unsigned int size)
60 {
61         unsigned char len = ats[0];
62         unsigned char t0;
63         unsigned char *cur;
64
65         if (len == 0 || size == 0) 
66                 return -1;
67
68         if (size < len)
69                 len = size;
70
71         if (len == 1) {
72                 /* FIXME: assume some default values */
73                 h->priv.tcl.fsc = 32;
74                 h->priv.tcl.ta = 0;
75                 h->priv.tcl.sfgt = sfgi_to_sfgt(h, 0);
76                 if (1 /* FIXME: is_iso14443a */) {
77                         /* Section 7.2: fwi default for type A is 4 */
78                         h->priv.tcl.fwt = fwi_to_fwt(h, 4);
79                 } else {
80                         /* Section 7.2: fwi for type B is always in ATQB */
81                         /* FIXME */
82                 }
83                 return 0;
84         }
85
86         /* guarateed to be at least 2 bytes in size */
87
88         t0 = ats[1];
89         cur = &ats[2];
90
91         iso14443_fsdi_to_fsd(&h->priv.tcl.fsc, t0 & 0x0f);
92
93         if (t0 & (1 << 4)) {
94                 /* TA is transmitted */
95                 h->priv.tcl.ta = *cur++;
96         }
97
98         if (t0 & (1 << 5)) {
99                 /* TB is transmitted */
100                 h->priv.tcl.sfgt = sfgi_to_sfgt(h, *cur & 0x0f);
101                 h->priv.tcl.fwt = fwi_to_fwt(h, (*cur & 0xf0) >> 4);
102                 cur++;
103         }
104
105         if (t0 & (1 << 6)) {
106                 /* TC is transmitted */
107                 if (*cur & 0x01)
108                         h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
109                 if (*cur & 0x02)
110                         h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
111                 cur++;
112         }
113
114         h->priv.tcl.historical_len = (ats+len) - cur;
115         h->priv.tcl.historical_bytes = cur;
116
117         return 0;
118 }
119
120
121 /* request an ATS from the PICC */
122 static int
123 tcl_request_ats(struct rfid_protocol_handle *h)
124 {
125         int ret;
126         unsigned char rats[2];
127         unsigned char fsdi;
128
129         if (h->priv.tcl.state != TCL_STATE_INITIAL)
130                 return -1;
131
132         ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.tcl.fsd);
133         if (ret < 0) {
134                 DEBUGP("unable to encode FSD of %u as FSDI\n", h->priv.tcl.fsd);
135                 return ret;
136         }
137
138         rats[0] = 0xe0;
139         rats[1] = (h->priv.tcl.cid & 0x0f) | ((fsdi << 4) & 0xf0);
140
141         /* transcieve (with CRC) */
142         ret = h->l2h->l2->fn.transcieve(h->l2h, rats, 2, h->priv.tcl.ats,
143                                        &h->priv.tcl.ats_len, activation_fwt(h),
144                                        TCL_TRANSP_F_TX_CRC);
145         if (ret < 0) {
146                 DEBUGP("transcieve of rats failed\n");
147                 h->priv.tcl.state = TCL_STATE_RATS_SENT;
148                 /* FIXME: retransmit */
149                 return ret;
150         }
151         h->priv.tcl.state = TCL_STATE_ATS_RCVD;
152
153         ret = tcl_parse_ats(h, h->priv.tcl.ats, h->priv.tcl.ats_len);
154         if (ret < 0) {
155                 DEBUGP("parsing of ats failed\n");
156                 return ret;
157         }
158
159         return 0;
160 }
161 /* start a PSS run (autimatically configure highest possible speed */
162 static int 
163 tcl_do_pss(struct rfid_protocol_handle *h)
164 {
165         unsigned char ppss[3];
166         unsigned char pps_response[1];
167
168         if (h->priv.tcl.state != TCL_STATE_ATS_RCVD)
169                 return -1;
170
171         /* ISO 14443-4:2000(E) Section 5.3. */
172
173         ppss[0] = 0xd0 & (h->priv.tcl.cid & 0x0f);
174         ppss[1] = 0x11;
175
176         //ppss[2] = 0x00 & foo;
177
178         // FIXME: finish
179         
180         return -1;
181         
182         h->priv.tcl.state = TCL_STATE_ESTABLISHED;
183 }
184
185
186 static int
187 tcl_build_prologue2(struct tcl_handle *th, 
188                     unsigned char *prlg, unsigned int *prlg_len, 
189                     unsigned char pcb)
190 {
191         *prlg_len = 1;
192
193         *prlg = pcb;
194
195         if (th->flags & TCL_HANDLE_F_CID_USED) {
196                 /* ISO 14443-4:2000(E) Section 7.1.1.2 */
197                 *prlg |= TCL_PCB_CID_FOLLOWING;
198                 (*prlg_len)++;
199                 prlg[*prlg_len] = th->cid & 0x0f;
200         }
201
202         /* nad only for I-block (0xc0 == 00) */
203         if ((th->flags & TCL_HANDLE_F_NAD_USED) &&
204             ((pcb & 0xc0) == 0x00)) {
205                 /* ISO 14443-4:2000(E) Section 7.1.1.3 */
206                 /* FIXME: in case of chaining only for first frame */
207                 *prlg |= TCL_PCB_NAD_FOLLOWING;
208                 prlg[*prlg_len] = th->nad;
209                 (*prlg_len)++;
210         }
211
212         return 0;
213 }
214
215 static int
216 tcl_build_prologue_i(struct tcl_handle *th,
217                      unsigned char *prlg, unsigned int *prlg_len)
218 {
219         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
220         return tcl_build_prologue2(th, prlg, prlg_len, 0x02);
221 }
222
223 static int
224 tcl_build_prologue_r(struct tcl_handle *th,
225                      unsigned char *prlg, unsigned int *prlg_len,
226                      unsigned int nak)
227 {
228         unsigned char pcb = 0xa2;
229         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
230
231         if (nak)
232                 pcb |= 0x10;
233
234         return tcl_build_prologue2(th, prlg, prlg_len, pcb);
235 }
236
237 static int
238 tcl_build_prologue_s(struct tcl_handle *th,
239                      unsigned char *prlg, unsigned int *prlg_len)
240 {
241         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
242
243         /* the only S-block from PCD->PICC is DESELECT: */
244         return tcl_build_prologue2(th, prlg, prlg_len, 0xc2);
245 }
246
247 /* FIXME: WTXM implementation */
248
249 static int tcl_prlg_len(struct tcl_handle *th)
250 {
251         int prlg_len = 1;
252
253         if (th->flags & TCL_HANDLE_F_CID_USED)
254                 prlg_len++;
255
256         if (th->flags & TCL_HANDLE_F_NAD_USED)
257                 prlg_len++;
258
259         return prlg_len;
260 }
261
262 #define max_net_tx_framesize(x) (x->fsc - tcl_prlg_len(x))
263
264 static int
265 tcl_connect(struct rfid_protocol_handle *h)
266 {
267         int ret; 
268
269         if (h->priv.tcl.state != TCL_STATE_DESELECTED &&
270             h->priv.tcl.state != TCL_STATE_INITIAL)
271                 return -1;
272
273         switch (h->l2h->l2->id) {
274         case RFID_LAYER2_ISO14443A:
275                 /* Start Type A T=CL Activation Sequence */
276                 ret = tcl_request_ats(h);
277                 if (ret < 0)
278                         return ret;
279
280                 if (0 /* FIXME */) {
281                         ret = tcl_do_pss(h);
282                         if (ret < 0)
283                                 return -1;
284                 }
285                 break;
286         case RFID_LAYER2_ISO14443B:
287                 /* initialized T=CL state from Type B Activation Data */
288                 h->priv.tcl.cid = h->l2h->priv.iso14443b.cid;
289                 h->priv.tcl.fsc = h->l2h->priv.iso14443b.fsc;
290                 h->priv.tcl.fsd = h->l2h->priv.iso14443b.fsd;
291                 h->priv.tcl.fwt = h->l2h->priv.iso14443b.fwt;
292
293                 /* what about ta? sfgt? */
294
295                 if (h->l2h->priv.iso14443b.flags & ISO14443B_CID_SUPPORTED)
296                         h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
297                 if (h->l2h->priv.iso14443b.flags & ISO14443B_NAD_SUPPORTED)
298                         h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
299
300                 switch (h->l2h->priv.iso14443b.state) {
301                         case ISO14443B_STATE_SELECTED:
302                                 h->priv.tcl.state = TCL_STATE_ATS_RCVD;
303                                 break;
304                         case ISO14443B_STATE_ATTRIB_SENT:
305                                 h->priv.tcl.state = TCL_STATE_RATS_SENT;
306                                 break;
307                 }
308
309                 /* PUPI will be presented as ATS/historical bytes */
310                 memcpy(h->priv.tcl.ats, h->l2h->priv.iso14443b.pupi, 4);
311                 h->priv.tcl.ats_len = 4;
312                 h->priv.tcl.historical_bytes = h->priv.tcl.ats;
313
314                 break;
315         default:
316                 DEBUGP("unsupported l2: %u\n", h->l2h->l2->id);
317                 return -1;
318                 break;
319         }
320
321         return 0;
322 }
323
324 static int
325 tcl_deselect(struct rfid_protocol_handle *h)
326 {
327         /* ISO 14443-4:2000(E) Section 8 */
328         int ret;
329         unsigned char frame[3];         /* 3 bytes prologue, no information */
330         unsigned char rx[3];
331         unsigned int rx_len = sizeof(rx);
332         unsigned int prlg_len;
333         struct tcl_handle *th = &h->priv.tcl;
334
335         if (th->state != TCL_STATE_ESTABLISHED) {
336                 /* FIXME: not sure whether deselect is possible here,
337                  * probably better send a HLTA? */
338         }
339
340         /* build DESELECT S-block */
341         ret = tcl_build_prologue_s(th, frame, &prlg_len);
342         if (ret < 0)
343                 return ret;
344
345         ret = h->l2h->l2->fn.transcieve(h->l2h, frame, prlg_len, rx,
346                                      &rx_len, deactivation_fwt(h),
347                                      TCL_TRANSP_F_TX_CRC);
348         if (ret < 0) {
349                 /* FIXME: retransmit, HLT(A|B) */
350                 return ret;
351         }
352
353         th->state = TCL_STATE_DESELECTED;
354
355         return 0;
356 }
357
358 static int
359 tcl_transcieve(struct rfid_protocol_handle *h,
360                 const unsigned char *tx_data, unsigned int tx_len,
361                 unsigned char *rx_data, unsigned int *rx_len,
362                 unsigned int timeout, unsigned int flags)
363 {
364         int ret;
365         unsigned char *tx_buf, *rx_buf;
366         unsigned int prlg_len;
367         struct tcl_handle *th = &h->priv.tcl;
368
369         if (tx_len > max_net_tx_framesize(th)) {
370                 /* slow path: we need to use chaining */
371                 return -1;
372         }
373
374         tx_buf = malloc(tcl_prlg_len(th) + tx_len);
375         if (!tx_buf) {
376                 ret = -ENOMEM;
377                 goto out;
378         }
379         rx_buf = malloc(tcl_prlg_len(th) + *rx_len);
380         if (!rx_buf) {
381                 ret = -ENOMEM;
382                 goto out_txb;
383         }
384
385         if (tcl_build_prologue_i(th, tx_buf, &prlg_len) < 0) {
386                 ret = -1;
387                 goto out_rxb;
388         }
389         memcpy(tx_buf + prlg_len, tx_data, tx_len);
390
391         ret = h->l2h->l2->fn.transcieve(h->l2h, tx_buf, tx_len+prlg_len, 
392                                      rx_buf, rx_len, th->fwt, 0);
393         if (ret < 0)
394                 goto out_rxb;
395
396
397         memcpy(rx_data, rx_buf, *rx_len);
398
399 out_rxb:
400         free(rx_buf);
401 out_txb:
402         free(tx_buf);
403 out:
404         return ret;
405 }
406
407 #if 0
408 int
409 tcl_send(struct tcl_handle *th)
410 {
411         return -1;
412 }
413
414 int
415 tcl_recv()
416 {
417         return -1;
418 }
419 #endif
420
421 static struct rfid_protocol_handle *
422 tcl_init(struct rfid_layer2_handle *l2h)
423 {
424         struct rfid_protocol_handle *th;
425         unsigned int mru = l2h->rh->ah->mru;
426
427         th = malloc(sizeof(struct rfid_protocol_handle) + mru);
428         if (!th)
429                 return NULL;
430
431         /* FIXME: mru should be attribute of layer2 (in case it adds/removes
432          * some overhead */
433         memset(th, 0, sizeof(struct rfid_protocol_handle) + mru);
434
435         /* maximum received ats length equals mru of asic/reader */
436         th->priv.tcl.state = TCL_STATE_INITIAL;
437         th->priv.tcl.ats_len = mru;
438         th->l2h = l2h;
439         th->proto = &rfid_protocol_tcl;
440
441         th->priv.tcl.fsd = iso14443_fsd_approx(mru);
442
443         return th;
444 }
445
446 static int
447 tcl_fini(struct rfid_protocol_handle *ph)
448 {
449         free(ph);
450         return 0;
451 }
452
453 struct rfid_protocol rfid_protocol_tcl = {
454         .id     = RFID_PROTOCOL_TCL,
455         .name   = "ISO 14443-4 / T=CL",
456         .fn     = {
457                 .init = &tcl_init,
458                 .open = &tcl_connect,
459                 .transcieve = &tcl_transcieve,
460                 .close = &tcl_deselect,
461                 .fini = &tcl_fini,
462         },
463 };