diff options
-rw-r--r-- | include/rfid/rfid_layer2_iso14443b.h | 2 | ||||
-rw-r--r-- | include/rfid/rfid_protocol_tcl.h | 4 | ||||
-rw-r--r-- | rfid_layer2_iso14443b.c | 15 | ||||
-rw-r--r-- | rfid_proto_tcl.c | 26 |
4 files changed, 39 insertions, 8 deletions
diff --git a/include/rfid/rfid_layer2_iso14443b.h b/include/rfid/rfid_layer2_iso14443b.h index 72e6155..b35a118 100644 --- a/include/rfid/rfid_layer2_iso14443b.h +++ b/include/rfid/rfid_layer2_iso14443b.h @@ -49,7 +49,7 @@ struct iso14443b_handle { unsigned int fsc; /* max. frame size card */ unsigned int fsd; /* max. frame size reader */ - unsigned int fwt; /* frame waiting time */ + unsigned int fwt; /* frame waiting time (in usec) */ unsigned int mbl; /* maximum buffer length */ diff --git a/include/rfid/rfid_protocol_tcl.h b/include/rfid/rfid_protocol_tcl.h index c0861cd..f0dbcdc 100644 --- a/include/rfid/rfid_protocol_tcl.h +++ b/include/rfid/rfid_protocol_tcl.h @@ -21,9 +21,9 @@ struct tcl_handle { unsigned int fsc; /* max frame size accepted by card */ unsigned int fsd; /* max frame size accepted by reader */ - unsigned int fwt; /* frame waiting time */ + unsigned int fwt; /* frame waiting time (in usec)*/ unsigned char ta; /* divisor information */ - unsigned char sfgt; /* start-up frame guard time */ + unsigned char sfgt; /* start-up frame guard time (in usec) */ /* otherwise determined */ unsigned int cid; /* Card ID */ diff --git a/rfid_layer2_iso14443b.c b/rfid_layer2_iso14443b.c index 6207827..d36b5da 100644 --- a/rfid_layer2_iso14443b.c +++ b/rfid_layer2_iso14443b.c @@ -36,10 +36,23 @@ static inline int fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi) { + unsigned int multiplier; + + /* 15 is RFU */ if (fwi > 14) return -1; - return (256 * 16 / h->rh->ah->asic->fc) * 2 ^ fwi; + /* According to ISO 14443-3:200(E), Chapter 7.9.4.3, the forumala is + * (256 * 16 / fC) * 2^fwi We avoid floating point computations by + * shifting everything into the microsecond range. In integer + * calculations 1000000*256*16/13560000 evaluates to 302 (instead of + * 302.064897), which provides sufficient precision, IMHO. The max + * result is 302 * 16384 (4947968), which fits well within the 31/32 + * bit range of an integer */ + + multiplier = 1 << fwi; /* 2 to the power of fwi */ + + return (1000000 * 256 * 16 / h->rh->ah->asic->fc) * multiplier } static int diff --git a/rfid_proto_tcl.c b/rfid_proto_tcl.c index a992f70..b8586f5 100644 --- a/rfid_proto_tcl.c +++ b/rfid_proto_tcl.c @@ -40,15 +40,33 @@ static unsigned int sfgi_to_sfgt(struct rfid_protocol_handle *h, unsigned char sfgi) { - /* ISO 14443-4:2000(E) Section 5.2.5. */ - return (256 * 16 / h->l2h->rh->ah->fc) * (2 ^ sfgi); + unsigned int multiplier; + + if (sfgi > 14) + sfgi = 14; + + multiplier = 1 << sfgi; /* 2 to the power of sfgi */ + + /* ISO 14443-4:2000(E) Section 5.2.5: + * (256 * 16 / h->l2h->rh->ah->fc) * (2 ^ sfgi) */ + + return (1000000 * 256*16 / h->l2h->rh->ah->fc) * multiplier; } static unsigned int fwi_to_fwt(struct rfid_protocol_handle *h, unsigned char fwi) { - /* ISO 14443-4:2000(E) Section 7.2. */ - return (256*16 / h->l2h->rh->ah->fc) * (2 ^ fwi); + unsigned int multiplier; + + if (fwi > 14) + fwi = 14; + + multiplier = 1 << fwi; /* 2 to the power of fwi */ + + /* ISO 14443-4:2000(E) Section 7.2.: + * (256*16 / h->l2h->rh->ah->fc) * (2 ^ fwi) */ + + return (1000000 * 256*16 / h->l2h->rh->ah->fc) * multiplier; } #define activation_fwt(x) (65536 / x->l2h->rh->ah->fc) |