X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_layer2_iso14443a.c;h=9bdd25a1a35ba33ec02cea2024bfceaeee862d75;hb=6b2db45060b26cc4e42ca6130f236596f9a02c82;hp=429577cf6d7fd5440b12628782bedfd187c557d0;hpb=f0a3a3f8c4f39dfacf2d370bd23b27cd5b3358bf;p=librfid diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c index 429577c..9bdd25a 100644 --- a/src/rfid_layer2_iso14443a.c +++ b/src/rfid_layer2_iso14443a.c @@ -16,13 +16,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include +#ifdef __MINGW32__ +#include +#endif/*__MINGW32__*/ #include #include @@ -32,13 +35,15 @@ #define TIMEOUT 1236 +unsigned long randctx[4]={0x22d4a017,0x773a1f44,0xc39e1460,0x9cde8801}; + /* Transceive a 7-bit short frame */ int iso14443a_transceive_sf(struct rfid_layer2_handle *handle, unsigned char cmd, struct iso14443a_atqa *atqa) { - struct rfid_reader *rdr = handle->rh->reader; + const struct rfid_reader *rdr = handle->rh->reader; return rdr->iso14443a.transceive_sf(handle->rh, cmd, atqa); } @@ -49,7 +54,7 @@ iso14443a_transceive_acf(struct rfid_layer2_handle *handle, struct iso14443a_anticol_cmd *acf, unsigned int *bit_of_col) { - struct rfid_reader *rdr = handle->rh->reader; + const struct rfid_reader *rdr = handle->rh->reader; return rdr->iso14443a.transceive_acf(handle->rh, acf, bit_of_col); } @@ -80,20 +85,37 @@ iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits) return 0; } +static int random_bit(void) +{ + unsigned long e; + + e = randctx[0]; + randctx[0] = randctx[1]; + randctx[1] = (randctx[2]<<19) + (randctx[2]>>13) + randctx[3]; + randctx[2] = randctx[3] ^ randctx[0]; + randctx[3] = e+randctx[1]; + + return randctx[1]&1; +} + /* first bit is '1', second bit '2' */ static void -set_bit_in_field(unsigned char *bitfield, unsigned int bit) +rnd_toggle_bit_in_field(unsigned char *bitfield, unsigned int size, unsigned int bit) { - unsigned int byte_count = bit / 8; - unsigned int bit_count = bit % 8; - - DEBUGP("bitfield=%p, byte_count=%u, bit_count=%u\n", - bitfield, byte_count, bit_count); - DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count)); - *(bitfield+byte_count) |= 1 << (bit_count-1); - DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count)); + unsigned int byte,rnd; + + if (bit && (bit <= (size*8))) { + rnd = random_bit(); + + DEBUGP("xor'ing bit %u with %u\n",bit,rnd); + bit--; + byte = bit/8; + bit = rnd << (bit % 8); + bitfield[byte] ^= bit; + } } + static int iso14443a_anticol(struct rfid_layer2_handle *handle) { @@ -122,7 +144,7 @@ iso14443a_anticol(struct rfid_layer2_handle *handle) return ret; } h->state = ISO14443A_STATE_ATQA_RCVD; - + DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1)); if (!atqa->bf_anticol) { @@ -150,18 +172,20 @@ cascade: ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col); if (ret < 0) return ret; - DEBUGP("bit_of_col = %u\n", bit_of_col); while (bit_of_col != ISO14443A_BITOFCOL_NONE) { - set_bit_in_field(&acf.uid_bits[0], bit_of_col-16); + DEBUGP("collision at pos %u\n", bit_of_col); + iso14443a_code_nvb_bits(&acf.nvb, bit_of_col); + rnd_toggle_bit_in_field(acf.uid_bits, sizeof(acf.uid_bits), bit_of_col); + DEBUGP("acf: nvb=0x%02X uid_bits=%s\n",acf.nvb,rfid_hexdump(acf.uid_bits,sizeof(acf.uid_bits))); ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col); - DEBUGP("bit_of_col = %u\n", bit_of_col); if (ret < 0) return ret; } iso14443a_code_nvb_bits(&acf.nvb, 7*8); + ret = iso14443a_transceive(handle, RFID_14443A_FRAME_REGULAR, (unsigned char *)&acf, 7, (unsigned char *) &sak, &rx_len, @@ -264,7 +288,7 @@ iso14443a_setopt(struct rfid_layer2_handle *handle, int optname, const void *optval, unsigned int optlen) { int ret = -EINVAL; - struct rfid_reader *rdr = handle->rh->reader; + const struct rfid_reader *rdr = handle->rh->reader; unsigned int speed; switch (optname) { @@ -280,6 +304,13 @@ iso14443a_setopt(struct rfid_layer2_handle *handle, int optname, speed = *(unsigned int *)optval; ret = rdr->iso14443a.set_speed(handle->rh, 1, speed); break; + case RFID_OPT_14443A_WUPA: + if((unsigned int*)optval) + handle->flags |= RFID_OPT_LAYER2_WUP; + else + handle->flags &= ~RFID_OPT_LAYER2_WUP; + ret = 0; + break; }; return ret; @@ -287,17 +318,22 @@ iso14443a_setopt(struct rfid_layer2_handle *handle, int optname, static int iso14443a_getopt(struct rfid_layer2_handle *handle, int optname, - void *optval, unsigned int optlen) + void *optval, unsigned int *optlen) { int ret = -EINVAL; struct iso14443a_handle *h = &handle->priv.iso14443a; struct iso14443a_atqa *atqa = optval; + int *wupa = optval; switch (optname) { case RFID_OPT_14443A_ATQA: *atqa = h->atqa; ret = 0; break; + case RFID_OPT_14443A_WUPA: + *wupa = ((handle->flags & RFID_OPT_LAYER2_WUP) != 0); + ret = 0; + break; }; return ret; @@ -313,7 +349,13 @@ iso14443a_init(struct rfid_reader_handle *rh) return NULL; memset(h, 0, sizeof(*h)); - + +#ifdef __MINGW32__ + randctx[0] ^= GetTickCount(); +#endif/*__MINGW32__*/ + for(ret=0;ret<23;ret++) + random_bit(); + h->l2 = &rfid_layer2_iso14443a; h->rh = rh; h->priv.iso14443a.state = ISO14443A_STATE_NONE;