remove autogenerated file
[librfid] / src / rfid_layer2_iso14443b.c
index 7c92562..df2f95d 100644 (file)
@@ -1,6 +1,6 @@
 /* ISO 14443-3 B anticollision implementation
  *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  *
  */
 
  *
  *  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 <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_protocol.h>
 
 #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)
 {
@@ -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;
+               h->proto_supported = (1 << RFID_PROTOCOL_TCL);
        } 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, 
@@ -114,13 +121,13 @@ send_reqb(struct rfid_layer2_handle *h, unsigned char afi,
                if (is_wup)
                        reqb[2] |= 0x08;
 
-               ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
+               ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
                                                reqb, sizeof(reqb),
                                                 (unsigned char *)&atqb, 
                                                 &atqb_len, ATQB_TIMEOUT, 0);
                h->priv.iso14443b.state = ISO14443B_STATE_REQB_SENT;
                if (ret < 0) {
-                       DEBUGP("error during transcieve of REQB/WUBP\n");
+                       DEBUGP("error during transceive of REQB/WUBP\n");
                        continue;
                }
 
@@ -152,32 +159,25 @@ static inline unsigned int mbli_to_mbl(struct rfid_layer2_handle *h,
 }
 
 static int
-transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
+transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
            unsigned int inf_len, unsigned char *rx_data, unsigned int *rx_len)
 {
-       struct iso14443b_attrib_hdr *attrib;
-       unsigned int attrib_size = sizeof(*attrib) + inf_len;
-       unsigned char *rx_buf;
+       struct {
+               struct iso14443b_attrib_hdr attrib;
+               char buf[256-3];
+       } _attrib_buf;
+
+       struct iso14443b_attrib_hdr *attrib = &_attrib_buf.attrib;
+       unsigned char rx_buf[256];
        unsigned char fsdi;
        int ret = 0;
        
        DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
-       attrib = malloc(attrib_size);
-       if (!attrib) {
-               perror("attrib_alloc");
-               return -1;
-       }
-
-       DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
-       rx_buf = malloc(*rx_len+1);
-       if (!rx_buf) {
-               perror("rx_buf malloc");
-               ret = -1;
-               goto out_attrib;
-       }
+       if (rx_len >= rx_len-1)
+               return -EINVAL;
 
        /* initialize attrib frame */
-       memset(attrib, 0, attrib_size);
+       memset(&_attrib_buf, 0, sizeof(_attrib_buf));
        if (inf_len)
                memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len);
 
@@ -199,21 +199,23 @@ transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
        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->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
+       ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
                                        (unsigned char *) attrib,
                                        sizeof(*attrib)+inf_len,
                                        rx_buf, rx_len, h->priv.iso14443b.fwt,
                                        0);
        h->priv.iso14443b.state = ISO14443B_STATE_ATTRIB_SENT;
        if (ret < 0) {
-               DEBUGP("transcieve problem\n");
+               DEBUGP("transceive problem\n");
                goto out_rx;
        }
 
        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;
        }
@@ -226,9 +228,7 @@ transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
        memcpy(rx_data, rx_buf+1, *rx_len);
 
 out_rx:
-       free(rx_buf);
 out_attrib:
-       free(attrib);
 
        return ret;
 }
@@ -244,13 +244,13 @@ iso14443b_hltb(struct rfid_layer2_handle *h)
        hltb[0] = 0x50;
        memcpy(hltb+1, h->uid, 4);
 
-       ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
+       ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR,
                                        hltb, 5,
                                        hltb_resp, &hltb_len,
                                        h->priv.iso14443b.fwt, 0);
        h->priv.iso14443b.state = ISO14443B_STATE_HLTB_SENT;
        if (ret < 0) {
-               DEBUGP("transcieve problem\n");
+               DEBUGP("transceive problem\n");
                return ret;
        }
 
@@ -275,7 +275,7 @@ iso14443b_anticol(struct rfid_layer2_handle *handle)
        if (ret < 0)
                return ret;
 
-       ret = transcieve_attrib(handle, NULL, 0, buf, &buf_len);
+       ret = transceive_attrib(handle, NULL, 0, buf, &buf_len);
        if (ret < 0)
                return ret;
 
@@ -286,7 +286,7 @@ static struct rfid_layer2_handle *
 iso14443b_init(struct rfid_reader_handle *rh)
 {
        int ret;
-       struct rfid_layer2_handle *h = malloc(sizeof(*h));
+       struct rfid_layer2_handle *h = malloc_layer2_handle(sizeof(*h));
        if (!h)
                return NULL;
 
@@ -294,6 +294,10 @@ iso14443b_init(struct rfid_reader_handle *rh)
        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);
 
@@ -301,10 +305,10 @@ iso14443b_init(struct rfid_reader_handle *rh)
        h->priv.iso14443b.tr0 = (256/ISO14443_FREQ_SUBCARRIER)*10e6;
        h->priv.iso14443b.tr1 = (200/ISO14443_FREQ_SUBCARRIER)*10e6;
 
-       ret = h->rh->reader->iso14443b.init(h->rh);
+       ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO14443B);
        if (ret < 0) {
                DEBUGP("error during reader 14443b init\n");
-               free(h);
+               free_layer2_handle(h);
                return NULL;
        }
 
@@ -314,31 +318,83 @@ iso14443b_init(struct rfid_reader_handle *rh)
 static int
 iso14443b_fini(struct rfid_layer2_handle *handle)
 {
-       free(handle);
+       free_layer2_handle(handle);
        return 0;
 }
 
 static int
-iso14443b_transcieve(struct rfid_layer2_handle *handle,
+iso14443b_transceive(struct rfid_layer2_handle *handle,
                     enum rfid_frametype frametype,
                     const unsigned char *tx_buf, unsigned int tx_len,
                     unsigned char *rx_buf, unsigned int *rx_len,
                     u_int64_t timeout, unsigned int flags)
 {
        DEBUGP("transcieving %u bytes, expecting max %u\n", tx_len, *rx_len);
-       return handle->rh->reader->transcieve(handle->rh, frametype,
+       return handle->rh->reader->transceive(handle->rh, frametype,
                                              tx_buf, tx_len,
                                              rx_buf, rx_len, timeout, flags);
 }
 
-struct rfid_layer2 rfid_layer2_iso14443b = {
+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;
+}
+
+
+const struct rfid_layer2 rfid_layer2_iso14443b = {
        .id     = RFID_LAYER2_ISO14443B,
        .name   = "ISO 14443-3 B",
        .fn     = {
                .init           = &iso14443b_init,
                .open           = &iso14443b_anticol,
-               .transcieve     = &iso14443b_transcieve,
+               .transceive     = &iso14443b_transceive,
                .close          = &iso14443b_hltb,
                .fini           = &iso14443b_fini,
+               .getopt         = &iso14443b_getopt,
+               .setopt         = &iso14443b_setopt,
        },
 };