- use C99 compiler flags
authorHarald Welte <laforge@gnumonks.org>
Sat, 7 Oct 2006 20:55:16 +0000 (20:55 +0000)
committerHarald Welte <laforge@gnumonks.org>
Sat, 7 Oct 2006 20:55:16 +0000 (20:55 +0000)
- implement some getopt/setopt functions for UID and layer2 specific parameters
- basic rfid scanning support
- add commandline arguments for layer2 / scanning to librfid-tool
- try to detect both supported readers automatically in librfid-tool
- add new 'l2_supported' and 'proto_supported members to rfid_reader

git-svn-id: https://svn.gnumonks.org/trunk/librfid@1895 e0336214-984f-0b4b-a45f-81c69e1f0ede

17 files changed:
Makefile.am
include/librfid/Makefile.am
include/librfid/rfid.h
include/librfid/rfid_layer2.h
include/librfid/rfid_layer2_iso14443a.h
include/librfid/rfid_layer2_iso14443b.h
include/librfid/rfid_reader.h
include/librfid/rfid_scan.h [new file with mode: 0644]
src/Makefile.am
src/rfid.c
src/rfid_layer2.c
src/rfid_layer2_iso14443a.c
src/rfid_layer2_iso14443b.c
src/rfid_reader_cm5121.c
src/rfid_reader_openpcd.c
src/rfid_scan.c [new file with mode: 0644]
utils/librfid-tool.c

index 69140e2..3a8a1ca 100644 (file)
@@ -3,6 +3,8 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
 SUBDIRS = include src utils
 LINKOPTS = -lusb
 
 SUBDIRS = include src utils
 LINKOPTS = -lusb
 
+AM_CFLAGS = -std=gnu99
+
 $(OBJECTS): libtool
 libtool: $(LIBTOOL_DEPS)
        $(SHELL) ./config.status --recheck
 $(OBJECTS): libtool
 libtool: $(LIBTOOL_DEPS)
        $(SHELL) ./config.status --recheck
index 59ce8cb..4b1337d 100644 (file)
@@ -1,10 +1,11 @@
 
 
-pkginclude_HEADERS = rfid.h rfid_asic.h rfid_asic_rc632.h \
+pkginclude_HEADERS = rfid.h rfid_scan.h rfid_asic.h rfid_asic_rc632.h \
                        rfid_layer2.h rfid_layer2_iso14443a.h \
                        rfid_layer2_iso14443b.h rfid_layer2_iso15693.h \
                        rfid_protocol.h rfid_protocol_tcl.h \
                        rfid_protocol_mifare_ul.h \
                        rfid_protocol_mifare_classic.h \
                        rfid_reader.h \
                        rfid_layer2.h rfid_layer2_iso14443a.h \
                        rfid_layer2_iso14443b.h rfid_layer2_iso15693.h \
                        rfid_protocol.h rfid_protocol_tcl.h \
                        rfid_protocol_mifare_ul.h \
                        rfid_protocol_mifare_classic.h \
                        rfid_reader.h \
-                       rfid_reader_cm5121.h
+                       rfid_reader_cm5121.h \
+                       rfid_reader_openpcd.h
 
 
index b1943d7..c3f8fc1 100644 (file)
@@ -11,7 +11,9 @@ enum rfid_frametype {
        RFID_MIFARE_FRAME,
 };
 
        RFID_MIFARE_FRAME,
 };
 
-#if 1
+//#define DEBUG
+
+#ifdef DEBUG
 #define DEBUGP(x, args ...) fprintf(stderr, "%s(%d):%s: " x, __FILE__, __LINE__, __FUNCTION__, ## args)
 #define DEBUGPC(x, args ...) fprintf(stderr, x, ## args)
 #else
 #define DEBUGP(x, args ...) fprintf(stderr, "%s(%d):%s: " x, __FILE__, __LINE__, __FUNCTION__, ## args)
 #define DEBUGPC(x, args ...) fprintf(stderr, x, ## args)
 #else
@@ -29,4 +31,11 @@ extern const char *rfid_hexdump(const void *data, unsigned int len);
 
 int rfid_init();
 
 
 int rfid_init();
 
+enum rfid_opt_level {
+       RFID_LEVEL_ASIC,
+       RFID_LEVEL_READER,
+       RFID_LEVEL_LAYER2,
+       RFID_LEVEL_LAYER3,
+};
+
 #endif /* _RFID_H */
 #endif /* _RFID_H */
index 3dd54a2..514a735 100644 (file)
@@ -14,6 +14,12 @@ enum rfid_layer2_id {
        RFID_LAYER2_ISO15693,
 };
 
        RFID_LAYER2_ISO15693,
 };
 
+/* 0...0xffff = global options, 0x10000...0x1ffff = private options */
+#define RFID_OPT_L2_PRIV               0x00010000
+enum rfid_layer2_opt {
+       RFID_OPT_LAYER2_UID             = 0x0001,
+};
+
 struct rfid_layer2_handle *rfid_layer2_init(struct rfid_reader_handle *rh,
                                            unsigned int id);
 int rfid_layer2_open(struct rfid_layer2_handle *l2h);
 struct rfid_layer2_handle *rfid_layer2_init(struct rfid_reader_handle *rh,
                                            unsigned int id);
 int rfid_layer2_open(struct rfid_layer2_handle *l2h);
@@ -63,6 +69,7 @@ struct rfid_layer2_handle {
        struct rfid_reader_handle *rh;
        unsigned char uid[10];  /* triple size 14443a id is 10 bytes */
        unsigned int uid_len;
        struct rfid_reader_handle *rh;
        unsigned char uid[10];  /* triple size 14443a id is 10 bytes */
        unsigned int uid_len;
+       unsigned int proto_supported;
        union {
                struct iso14443a_handle iso14443a;
                struct iso14443b_handle iso14443b;
        union {
                struct iso14443a_handle iso14443a;
                struct iso14443b_handle iso14443b;
index 81f1680..87b6be0 100644 (file)
@@ -2,8 +2,8 @@
 #define _RFID_ISO14443A_H
 
 enum rfid_14443a_opt {
 #define _RFID_ISO14443A_H
 
 enum rfid_14443a_opt {
-       RFID_OPT_14443A_SPEED_RX        = 0x00000001,
-       RFID_OPT_14443A_SPEED_TX        = 0x00000002,
+       RFID_OPT_14443A_SPEED_RX        = 0x00010001,
+       RFID_OPT_14443A_SPEED_TX        = 0x00010002,
 };
 
 enum rfid_14443_opt_speed {
 };
 
 enum rfid_14443_opt_speed {
index 5d6d979..07c185f 100644 (file)
@@ -1,6 +1,17 @@
 #ifndef _RFID_LAYER2_ISO14443B_H
 #define _RFID_LAYER2_ISO14443B_H
 
 #ifndef _RFID_LAYER2_ISO14443B_H
 #define _RFID_LAYER2_ISO14443B_H
 
+#include <librfid/rfid_layer2.h>
+
+enum rfid_iso14443_opt {
+       RFID_OPT_14443B_CID             = 0x00010001,
+       RFID_OPT_14443B_FSC             = 0x00010002,
+       RFID_OPT_14443B_FSD             = 0x00010003,
+       RFID_OPT_14443B_FWT             = 0x00010004,
+       RFID_OPT_14443B_TR0             = 0x00010005,
+       RFID_OPT_14443B_TR1             = 0x00010006,
+};
+
 #ifdef __LIBRFID__
 
 struct iso14443b_atqb {
 #ifdef __LIBRFID__
 
 struct iso14443b_atqb {
index ce29981..2221abd 100644 (file)
@@ -9,6 +9,9 @@ struct rfid_reader_handle;
 struct rfid_reader {
        char *name;
        unsigned int id;
 struct rfid_reader {
        char *name;
        unsigned int id;
+       unsigned int l2_supported;
+       unsigned int proto_supported;
+
        int (*transceive)(struct rfid_reader_handle *h,
                          enum rfid_frametype frametype,
                          const unsigned char *tx_buf, unsigned int tx_len,
        int (*transceive)(struct rfid_reader_handle *h,
                          enum rfid_frametype frametype,
                          const unsigned char *tx_buf, unsigned int tx_len,
diff --git a/include/librfid/rfid_scan.h b/include/librfid/rfid_scan.h
new file mode 100644 (file)
index 0000000..dcfd7bf
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _RFID_SCAN_H
+#define _RFID_SCAN_H
+
+#include <librfid/rfid_reader.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
+
+int rfid_scan(struct rfid_reader_handle *rh,
+             struct rfid_layer2_handle **l2h,
+             struct rfid_protocol_handle **ph);
+
+#endif /* _RFID_SCAN_H */
index 04d17d4..c0cbfbe 100644 (file)
@@ -5,7 +5,7 @@ AM_CFLAGS = -std=gnu99
 
 lib_LTLIBRARIES = librfid.la
 
 
 lib_LTLIBRARIES = librfid.la
 
-CORE=rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c
+CORE=rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c rfid_scan.c
 L2=rfid_layer2_iso14443a.c rfid_layer2_iso14443b.c rfid_layer2_iso15693.c rfid_iso14443_common.c
 PROTO=rfid_proto_tcl.c rfid_proto_mifare_ul.c rfid_proto_mifare_classic.c
 READER=rfid_reader_cm5121.c rfid_asic_rc632.c rfid_reader_openpcd.c
 L2=rfid_layer2_iso14443a.c rfid_layer2_iso14443b.c rfid_layer2_iso15693.c rfid_iso14443_common.c
 PROTO=rfid_proto_tcl.c rfid_proto_mifare_ul.c rfid_proto_mifare_classic.c
 READER=rfid_reader_cm5121.c rfid_asic_rc632.c rfid_reader_openpcd.c
index b90043f..ba166a2 100644 (file)
@@ -1,4 +1,6 @@
-/*
+/* librfid core 
+ *  (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
  *  as published by the Free Software Foundation
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
  *  as published by the Free Software Foundation
@@ -40,6 +42,54 @@ rfid_hexdump(const void *data, unsigned int len)
        return string;
 }
 
        return string;
 }
 
+#if 0
+int rfid_setopt(struct rfid_handle *rh, unsigned int level,
+               unsigned int optname,
+               const void *opt, unsigned int *optlen)
+{
+       switch (level) {
+       case RFID_LEVEL_ASIC:
+       case RFID_LEVEL_READER:
+               return -EINVAL;
+               break;
+       case RFID_LEVEL_LAYER2:
+               return rfid_layer2_setopt(optname, opt, optlen);
+               break;
+       case RFID_LEVEL_LAYER3:
+               return rfid_layer3_setopt(optname, opt, optlen);
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+
+       return 0;
+}
+
+int rfid_getopt(struct rfid_handle *rh, unsigned int level,
+               unsigned int optname,
+               void *opt, unsigned int *optlen)
+{
+       switch (level) {
+       case RFID_LEVEL_ASIC:
+       case RFID_LEVEL_READER:
+               return -EINVAL;
+               break;
+       case RFID_LEVEL_LAYER2:
+               return rfid_layer2_getopt(optname, opt, optlen);
+               break;
+       case RFID_LEVEL_LAYER3:
+               return rfid_layer3_getopt(optname, opt, optlen);
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+
+       return 0;
+}
+#endif
+
 int rfid_init()
 {
        rfid_reader_register(&rfid_reader_cm5121);
 int rfid_init()
 {
        rfid_reader_register(&rfid_reader_cm5121);
index eef0560..7461d87 100644 (file)
@@ -1,5 +1,5 @@
 /* librfid - layer 2 protocol handler 
 /* librfid - layer 2 protocol handler 
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  */
 
 /*
  */
 
 /*
@@ -92,18 +92,43 @@ int
 rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname,
                   void *optval, unsigned int *optlen)
 {
 rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname,
                   void *optval, unsigned int *optlen)
 {
-       if (!ph->l2->fn.getopt)
-               return -EINVAL;
-
-       return ph->l2->fn.getopt(ph, optname, optval, optlen);
+       if (optname >> 16 == 0) {
+               unsigned char *optchar = optval;
+
+               switch (optname) {
+               case RFID_OPT_LAYER2_UID:
+                       if (ph->uid_len < *optlen)
+                               *optlen = ph->uid_len;
+                       memcpy(optchar, ph->uid, *optlen);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }
+       } else {
+               if (!ph->l2->fn.getopt)
+                       return -EINVAL;
+
+               return ph->l2->fn.getopt(ph, optname, optval, optlen);
+       }
+       return 0;
 }
 
 int
 rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname,
                   const void *optval, unsigned int optlen)
 {
 }
 
 int
 rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname,
                   const void *optval, unsigned int optlen)
 {
-       if (!ph->l2->fn.setopt)
-               return -EINVAL;
-
-       return ph->l2->fn.setopt(ph, optname, optval, optlen);
+       if (optname >> 16 == 0) {
+               switch (optname) {
+               default:
+                       return -EINVAL;
+                       break;
+               }
+       } else {
+               if (!ph->l2->fn.setopt)
+                       return -EINVAL;
+
+               return ph->l2->fn.setopt(ph, optname, optval, optlen);
+       }
+       return 0;
 }
 }
index a83c71a..7ebc240 100644 (file)
@@ -1,6 +1,6 @@
 /* ISO 14443-3 A anticollision implementation
  *
 /* ISO 14443-3 A anticollision implementation
  *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  *
  */
 
  *
  */
 
@@ -28,6 +28,7 @@
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2_iso14443a.h>
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_protocol.h>
 
 #define TIMEOUT 1236
 
 
 #define TIMEOUT 1236
 
@@ -225,9 +226,12 @@ cascade:
 
        if (sak[0] & 0x20) {
                DEBUGP("we have a T=CL compliant PICC\n");
 
        if (sak[0] & 0x20) {
                DEBUGP("we have a T=CL compliant PICC\n");
+               handle->proto_supported = 1 << RFID_PROTOCOL_TCL;
                h->tcl_capable = 1;
        } else {
                DEBUGP("we have a T!=CL PICC\n");
                h->tcl_capable = 1;
        } else {
                DEBUGP("we have a T!=CL PICC\n");
+               handle->proto_supported = (1 << RFID_PROTOCOL_MIFARE_UL)|
+                                         (1 << RFID_PROTOCOL_MIFARE_CLASSIC);
                h->tcl_capable = 0;
        }
 
                h->tcl_capable = 0;
        }
 
index 454df0a..8227a32 100644 (file)
@@ -1,6 +1,6 @@
 /* ISO 14443-3 B anticollision implementation
  *
 /* ISO 14443-3 B anticollision implementation
  *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  *
  */
 
  *
  */
 
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <errno.h>
 
 #include <librfid/rfid.h>
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2_iso14443b.h>
 
 #include <librfid/rfid.h>
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2_iso14443b.h>
+#include <librfid/rfid_protocol.h>
 
 #include "rfid_iso14443_common.h"
 
 #define ATQB_TIMEOUT   ((256*10e6/ISO14443_FREQ_SUBCARRIER)            \
                         +(200*10e6/ISO14443_FREQ_SUBCARRIER))
 
 
 #include "rfid_iso14443_common.h"
 
 #define ATQB_TIMEOUT   ((256*10e6/ISO14443_FREQ_SUBCARRIER)            \
                         +(200*10e6/ISO14443_FREQ_SUBCARRIER))
 
+#undef ATQB_TIMEOUT
+#define ATQB_TIMEOUT   1
+
 static inline int
 fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi)
 {
 static inline int
 fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi)
 {
@@ -79,9 +84,11 @@ parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb)
        if (atqb->protocol_info.protocol_type == 0x1) {
                DEBUGP("we have a T=CL compliant PICC\n");
                h->priv.iso14443b.tcl_capable = 1;
        if (atqb->protocol_info.protocol_type == 0x1) {
                DEBUGP("we have a T=CL compliant PICC\n");
                h->priv.iso14443b.tcl_capable = 1;
+               h->proto_supported = (1 << RFID_PROTOCOL_TCL);
        } else {
                DEBUGP("we have a T!=CL PICC\n");
                h->priv.iso14443b.tcl_capable = 0;
        } else {
                DEBUGP("we have a T!=CL PICC\n");
                h->priv.iso14443b.tcl_capable = 0;
+               /* FIXME: what protocols do we support? */
        }
 
        iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc, 
        }
 
        iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc, 
@@ -199,6 +206,8 @@ transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
        if (h->priv.iso14443b.tcl_capable == 1)
                attrib->param3.protocol_type = 0x1;
 
        if (h->priv.iso14443b.tcl_capable == 1)
                attrib->param3.protocol_type = 0x1;
 
+       attrib->param4.cid = h->priv.iso14443b.cid & 0xf;
+
        *rx_len = *rx_len + 1;
        ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
                                        (unsigned char *) attrib,
        *rx_len = *rx_len + 1;
        ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
                                        (unsigned char *) attrib,
@@ -212,8 +221,8 @@ transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
        }
 
        if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
        }
 
        if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
-               DEBUGP("ATTRIB response with invalid CID %u\n",
-                       rx_buf[0] & 0x0f);
+               DEBUGP("ATTRIB response with invalid CID %u (should be %u)\n",
+                       rx_buf[0] & 0x0f, h->priv.iso14443b.cid);
                ret = -1;
                goto out_rx;
        }
                ret = -1;
                goto out_rx;
        }
@@ -294,6 +303,10 @@ iso14443b_init(struct rfid_reader_handle *rh)
        h->rh = rh;
        h->priv.iso14443b.state = ISO14443B_STATE_NONE;
 
        h->rh = rh;
        h->priv.iso14443b.state = ISO14443B_STATE_NONE;
 
+       /* FIXME: if we want to support multiple PICC's, we need some
+        * fancy allocation scheme for CID's */
+       h->priv.iso14443b.cid = 0;
+
        h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru);
        DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
 
        h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru);
        DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
 
@@ -331,6 +344,56 @@ iso14443b_transceive(struct rfid_layer2_handle *handle,
                                              rx_buf, rx_len, timeout, flags);
 }
 
                                              rx_buf, rx_len, timeout, flags);
 }
 
+static int
+iso14443b_getopt(struct rfid_layer2_handle *handle,
+                int optname, void *optval, unsigned int optlen)
+{
+       unsigned int *opt_ui = optval;
+
+       switch (optname) {
+       case RFID_OPT_14443B_CID:
+               *opt_ui = handle->priv.iso14443b.cid;
+               break;
+       case RFID_OPT_14443B_FSC:
+               *opt_ui = handle->priv.iso14443b.fsc;
+               break;
+       case RFID_OPT_14443B_FSD:
+               *opt_ui = handle->priv.iso14443b.fsd;
+               break;
+       case RFID_OPT_14443B_FWT:
+               *opt_ui = handle->priv.iso14443b.fwt;
+               break;
+       case RFID_OPT_14443B_TR0:
+               *opt_ui = handle->priv.iso14443b.tr0;
+               break;
+       case RFID_OPT_14443B_TR1:
+               *opt_ui = handle->priv.iso14443b.tr1;
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+       return 0;
+}
+
+static int
+iso14443b_setopt(struct rfid_layer2_handle *handle,
+                int optname, const void *optval, unsigned int optlen)
+{
+       const unsigned int *opt_ui = optval;
+
+       switch (optname) {
+       case RFID_OPT_14443B_CID:
+               handle->priv.iso14443b.cid = (*opt_ui & 0xf);
+               break;
+       defaukt:
+               return -EINVAL;
+               break;
+       }
+       return 0;
+}
+
+
 struct rfid_layer2 rfid_layer2_iso14443b = {
        .id     = RFID_LAYER2_ISO14443B,
        .name   = "ISO 14443-3 B",
 struct rfid_layer2 rfid_layer2_iso14443b = {
        .id     = RFID_LAYER2_ISO14443B,
        .name   = "ISO 14443-3 B",
@@ -340,5 +403,7 @@ struct rfid_layer2 rfid_layer2_iso14443b = {
                .transceive     = &iso14443b_transceive,
                .close          = &iso14443b_hltb,
                .fini           = &iso14443b_fini,
                .transceive     = &iso14443b_transceive,
                .close          = &iso14443b_hltb,
                .fini           = &iso14443b_fini,
+               .getopt         = &iso14443b_getopt,
+               .setopt         = &iso14443b_setopt,
        },
 };
        },
 };
index ab1e701..a9907ad 100644 (file)
@@ -1,6 +1,6 @@
 /* Omnikey CardMan 5121 specific RC632 transport layer 
  *
 /* Omnikey CardMan 5121 specific RC632 transport layer 
  *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  *
  * The 5121 is an Atmel AT89C5122 based USB CCID reader (probably the same
  * design like the 3121).  It's CL RC632 is connected via address/data bus,
  *
  * The 5121 is an Atmel AT89C5122 based USB CCID reader (probably the same
  * design like the 3121).  It's CL RC632 is connected via address/data bus,
@@ -37,6 +37,8 @@
 #include <librfid/rfid_asic.h>
 #include <librfid/rfid_asic_rc632.h>
 #include <librfid/rfid_reader_cm5121.h>
 #include <librfid/rfid_asic.h>
 #include <librfid/rfid_asic_rc632.h>
 #include <librfid/rfid_reader_cm5121.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
 
 #include "cm5121_source.h"
 
 
 #include "cm5121_source.h"
 
@@ -360,6 +362,12 @@ struct rfid_reader rfid_reader_cm5121 = {
        .open = &cm5121_open,
        .close = &cm5121_close,
        .transceive = &cm5121_transceive,
        .open = &cm5121_open,
        .close = &cm5121_close,
        .transceive = &cm5121_transceive,
+       .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
+                       (1 << RFID_LAYER2_ISO14443B) |
+                       (1 << RFID_LAYER2_ISO15693),
+       .proto_supported = (1 << RFID_PROTOCOL_TCL) |
+                       (1 << RFID_PROTOCOL_MIFARE_UL) |
+                       (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
        .iso14443a = {
                .init = &cm5121_14443a_init,
                .transceive_sf = &cm5121_transceive_sf,
        .iso14443a = {
                .init = &cm5121_14443a_init,
                .transceive_sf = &cm5121_transceive_sf,
index 51852f0..053a711 100644 (file)
@@ -39,6 +39,8 @@
 #include <librfid/rfid_asic.h>
 #include <librfid/rfid_asic_rc632.h>
 #include <librfid/rfid_reader_openpcd.h>
 #include <librfid/rfid_asic.h>
 #include <librfid/rfid_asic_rc632.h>
 #include <librfid/rfid_reader_openpcd.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
 
 /* FIXME */
 #include "rc632.h"
 
 /* FIXME */
 #include "rc632.h"
@@ -391,6 +393,12 @@ struct rfid_reader rfid_reader_openpcd = {
        .open = &openpcd_open,
        .close = &openpcd_close,
        .transceive = &openpcd_transceive,
        .open = &openpcd_open,
        .close = &openpcd_close,
        .transceive = &openpcd_transceive,
+       .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
+                       (1 << RFID_LAYER2_ISO14443B) |
+                       (1 << RFID_LAYER2_ISO15693),
+       .proto_supported = (1 << RFID_PROTOCOL_TCL) |
+                       (1 << RFID_PROTOCOL_MIFARE_UL) |
+                       (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
        .iso14443a = {
                .init = &openpcd_14443a_init,
                .transceive_sf = &openpcd_transceive_sf,
        .iso14443a = {
                .init = &openpcd_14443a_init,
                .transceive_sf = &openpcd_transceive_sf,
diff --git a/src/rfid_scan.c b/src/rfid_scan.c
new file mode 100644 (file)
index 0000000..1abb4df
--- /dev/null
@@ -0,0 +1,113 @@
+/* RFID scanning implementation
+ *
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ */
+
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 
+ *  as published by the Free Software Foundation
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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
+ */
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_reader.h>
+#include <librfid/rfid_protocol.h>
+
+static struct rfid_layer2_handle *
+rfid_layer2_scan1(struct rfid_reader_handle *rh, int l2)
+{
+       struct rfid_layer2_handle *l2h;
+
+       if (rh->reader->l2_supported & (1 << l2)) {
+               l2h = rfid_layer2_init(rh, l2);
+               if (!l2h)
+                       return NULL;
+               if (rfid_layer2_open(l2h) < 0) {
+                       rfid_layer2_fini(l2h);
+                       return NULL;
+               } else 
+                       return l2h;
+       }
+
+       return NULL;
+}
+
+static struct rfid_layer2_handle *
+rfid_layer2_scan(struct rfid_reader_handle *rh)
+{
+       struct rfid_layer2_handle *l2h;
+       int i;
+
+#define RFID_LAYER2_MAX 16
+       for (i = 0; i < RFID_LAYER2_MAX; i++) {
+               l2h = rfid_layer2_scan1(rh, i);
+               if (l2h)
+                       return l2h;
+       }
+
+       return NULL;
+}
+
+static struct rfid_protocol_handle *
+rfid_protocol_scan1(struct rfid_layer2_handle *l2h, int proto)
+{
+       struct rfid_protocol_handle *ph;
+
+       if (l2h->rh->reader->proto_supported & (1 << proto) &&
+           l2h->proto_supported & (1 << proto)) {
+               ph = rfid_protocol_init(l2h, proto);
+               if (!ph)
+                       return NULL;
+               if (rfid_protocol_open(ph) < 0) {
+                       rfid_protocol_fini(ph);
+                       return NULL;
+               } else
+                       return ph;
+       }
+
+       return NULL;
+}
+
+static struct rfid_protocol_handle *
+rfid_protocol_scan(struct rfid_layer2_handle *l2h)
+{
+       struct rfid_protocol_handle *ph;
+       int i;
+
+#define RFID_PROTOCOL_MAX 16
+       for (i = 0; i < RFID_PROTOCOL_MAX; i++) {
+               ph = rfid_protocol_scan1(l2h, i);
+               if (ph)
+                       return ph;
+       }
+
+       return NULL;
+}
+
+/* Scan for any RFID transponder within range of the given reader.
+ * Abort after the first successfully found transponder. */
+int rfid_scan(struct rfid_reader_handle *rh,
+             struct rfid_layer2_handle **l2h,
+             struct rfid_protocol_handle **ph)
+{
+       *l2h = rfid_layer2_scan(rh);
+       if (!*l2h)
+               return 0;
+       
+       *ph = rfid_protocol_scan(l2h);
+       if (!*ph)
+               return 2;
+       
+       return 3;
+}
index 0c21a4d..c96f948 100644 (file)
@@ -1,4 +1,7 @@
-/*
+/* librfid-tool - a small command-line tool for librfid testing
+ *
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
  *  as published by the Free Software Foundation
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
  *  as published by the Free Software Foundation
@@ -23,6 +26,7 @@
 #include <getopt.h>
 
 #include <librfid/rfid.h>
 #include <getopt.h>
 
 #include <librfid/rfid.h>
+#include <librfid/rfid_scan.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_protocol.h>
 #include <librfid/rfid_reader.h>
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_protocol.h>
@@ -53,14 +57,7 @@ static struct rfid_reader_handle *rh;
 static struct rfid_layer2_handle *l2h;
 static struct rfid_protocol_handle *ph;
 
 static struct rfid_layer2_handle *l2h;
 static struct rfid_protocol_handle *ph;
 
-static int init()
-{
-       unsigned char buf[0x3f];
-       int rc;
-
-       printf("initializing librfid\n");
-       rfid_init();
-
+static int reader() {
        printf("opening reader handle\n");
        rh = rfid_reader_open(NULL, RFID_READER_CM5121);
        if (!rh) {
        printf("opening reader handle\n");
        rh = rfid_reader_open(NULL, RFID_READER_CM5121);
        if (!rh) {
@@ -71,10 +68,16 @@ static int init()
                        return -1;
                }
        }
                        return -1;
                }
        }
+       return 0;
+}
+static int init(int layer2)
+{
+       unsigned char buf[0x3f];
+       int rc;
+
 
        printf("opening layer2 handle\n");
 
        printf("opening layer2 handle\n");
-       l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A);
-       //l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B);
+       l2h = rfid_layer2_init(rh, layer2);
        if (!l2h) {
                fprintf(stderr, "error during iso14443a_init\n");
                return -1;
        if (!l2h) {
                fprintf(stderr, "error during iso14443a_init\n");
                return -1;
@@ -308,13 +311,36 @@ static int proto_by_name(const char *name)
        return -1;
 }
 
        return -1;
 }
 
+static char *l2_names[] = {
+       [RFID_LAYER2_ISO14443A] = "iso14443a",
+       [RFID_LAYER2_ISO14443B] = "iso14443b",
+       [RFID_LAYER2_ISO15693] = "iso15693",
+};
+
+static int l2_by_name(const char *name)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(l2_names); i++) {
+               if (l2_names[i] == NULL)
+                       continue;
+               if (!strcasecmp(name, l2_names[i]))
+                       return i;
+       }
+       return -1;
+}
+
 static void help(void)
 {
 static void help(void)
 {
-       printf(" -p     --protocol {tcl,mifare-ultralight,mifare-classic}\n");
+       printf( " -s    --scan\n"
+               " -p    --protocol {tcl,mifare-ultralight,mifare-classic}\n"
+               " -l    --layer2   {iso14443a,iso14443b,iso15693}\n"
+               " -h    --help\n");
 }
 
 static struct option opts[] = {
        { "help", 0, 0, 'h' },
 }
 
 static struct option opts[] = {
        { "help", 0, 0, 'h' },
+       { "layer2", 1, 0, 'l' },
        { "protocol", 1, 0, 'p' },
        {0, 0, 0, 0}
 };
        { "protocol", 1, 0, 'p' },
        {0, 0, 0, 0}
 };
@@ -323,22 +349,42 @@ int main(int argc, char **argv)
 {
        int rc;
        char buf[0x40];
 {
        int rc;
        char buf[0x40];
-       int i, protocol = -1;
+       int i, protocol = -1, layer2 = -1;
        
        printf("librfid_tool - (C) 2006 by Harald Welte\n"
        
        printf("librfid_tool - (C) 2006 by Harald Welte\n"
-              "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
+              "This program is Free Software and has "
+              "ABSOLUTELY NO WARRANTY\n\n");
+
+       printf("initializing librfid\n");
+       rfid_init();
 
        while (1) {
                int c, option_index = 0;
 
        while (1) {
                int c, option_index = 0;
-               c = getopt_long(argc, argv, "hp:", opts, &option_index);
+               c = getopt_long(argc, argv, "hp:l:s", opts, &option_index);
                if (c == -1)
                        break;
 
                switch (c) {
                if (c == -1)
                        break;
 
                switch (c) {
+               case 's':
+                       if (reader() < 0)
+                               exit(1);
+                       printf("scanning for RFID token...\n");
+                       i = rfid_scan(rh, &l2h, &ph);
+                       exit(0);
+                       break;
                case 'p':
                        protocol = proto_by_name(optarg);
                        if (protocol < 0) {
                case 'p':
                        protocol = proto_by_name(optarg);
                        if (protocol < 0) {
-                               fprintf(stderr, "unknown protocol `%s'\n", optarg);
+                               fprintf(stderr, "unknown protocol `%s'\n", 
+                                       optarg);
+                               exit(2);
+                       }
+                       break;
+               case 'l':
+                       layer2 = l2_by_name(optarg);
+                       if (layer2 < 0) {
+                               fprintf(stderr, "unknown layer2 `%s'\n",
+                                       optarg);
                                exit(2);
                        }
                        break;
                                exit(2);
                        }
                        break;
@@ -349,12 +395,25 @@ int main(int argc, char **argv)
                }
        }
 
                }
        }
 
-       if (protocol < 0) {
+       switch (protocol) {
+       case RFID_PROTOCOL_MIFARE_UL:
+       case RFID_PROTOCOL_MIFARE_CLASSIC:
+               layer2 = RFID_LAYER2_ISO14443A;
+               break;
+       case -1:
                fprintf(stderr, "you have to specify --protocol\n");
                exit(2);
        }
 
                fprintf(stderr, "you have to specify --protocol\n");
                exit(2);
        }
 
-       if (init() < 0)
+       if (layer2 < 0) {
+               fprintf(stderr, "you have to specify --layer2\n");
+               exit(2);
+       }
+       
+       if (reader() < 0)
+               exit(1);
+
+       if (init(layer2) < 0)
                exit(1);
 
        if (l3(protocol) < 0)
                exit(1);
 
        if (l3(protocol) < 0)