From: Harald Welte Date: Sun, 11 Sep 2005 19:59:05 +0000 (+0000) Subject: As Juergen Heinzl pointed out, much of my original fwi calculations evaluated X-Git-Url: http://git.rot13.org/?p=librfid;a=commitdiff_plain;h=de302387828a8e3de7c7a76681b08824c1c749e6 As Juergen Heinzl pointed out, much of my original fwi calculations evaluated to zero due to the integer range limitations. shifting everything to the microsecond range should solve this problem without introducing ugly floating point arithmetics. git-svn-id: https://svn.gnumonks.org/trunk/librfid@1425 e0336214-984f-0b4b-a45f-81c69e1f0ede --- 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)