From c78313da991a62eb8e93d7f15e82b92fa6fc4d63 Mon Sep 17 00:00:00 2001 From: Dorota Moskal Date: Mon, 10 Sep 2012 10:06:24 +0200 Subject: [PATCH] mifare: Add mifare_check_presence and check_presence When tag type 2 is Mifare Classic, specific mifare check presence is run. --- plugins/mifare.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++- plugins/nfctype2.c | 48 +++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 14 deletions(-) diff --git a/plugins/mifare.c b/plugins/mifare.c index db71536..400bb00 100644 --- a/plugins/mifare.c +++ b/plugins/mifare.c @@ -44,10 +44,13 @@ * http://www.nxp.com/technical-support-portal/53420/71108/application-notes * */ -/* Prototype */ +/* Prototypes */ int mifare_read(uint32_t adapter_idx, uint32_t target_idx, near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype); +int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx, + near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype); + /* MIFARE command set */ #define MF_CMD_WRITE 0xA2 #define MF_CMD_READ 0x30 @@ -668,3 +671,83 @@ int mifare_read(uint32_t adapter_idx, uint32_t target_idx, return 0; } + +static int check_presence(uint8_t *resp, int length, void *data) +{ + struct mifare_cookie *cookie = data; + int err = 0; + + DBG("%d", length); + + if (length < 0) + err = -EIO; + + if (cookie->cb) + cookie->cb(cookie->adapter_idx, cookie->target_idx, err); + + return err; +} + +int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx, + near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype) +{ + struct mifare_cmd cmd; + struct mifare_cookie *cookie; + uint8_t *key_ref = MAD_public_key; + int err; + + DBG(""); + + /* Check supported and tested Mifare type */ + switch (tgt_subtype) { + case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K: + case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K: + break; + default: + near_error("Mifare tag type %d not supported.", tgt_subtype); + return -1; + } + + /* Alloc global cookie */ + cookie = g_try_malloc0(sizeof(struct mifare_cookie)); + if (cookie == NULL) + return -ENOMEM; + + /* Get the nfcid1 */ + cookie->nfcid1 = near_tag_get_nfcid(adapter_idx, target_idx, + &cookie->nfcid1_len); + cookie->adapter_idx = adapter_idx; + cookie->target_idx = target_idx; + cookie->cb = cb; + + /* + * To check presence of Mifare Classic Tag, + * send authentication command instead of read one + */ + cmd.cmd = MF_CMD_AUTH_KEY_A; + + /* Authenticate the 1st block of the MAD sector */ + cmd.block = MAD1_1ST_BLOCK; + + /* Store the AUTH KEY */ + memcpy(&cmd.key, key_ref, MAD_KEY_LEN); + + /* add the UID */ + memcpy(&cmd.nfcid, cookie->nfcid1, cookie->nfcid1_len); + + err = near_adapter_send(cookie->adapter_idx, + (uint8_t *) &cmd, + sizeof(cmd) - NFC_NFCID1_MAXSIZE + cookie->nfcid1_len, + check_presence, + cookie); + + if (err < 0) + goto out_err; + + return err; + +out_err: + mifare_release(err, cookie); + + return err; +} diff --git a/plugins/nfctype2.c b/plugins/nfctype2.c index dc178ca..a20bf61 100644 --- a/plugins/nfctype2.c +++ b/plugins/nfctype2.c @@ -42,6 +42,9 @@ extern int mifare_read(uint32_t adapter_idx, uint32_t target_idx, near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype); +extern int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx, + near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype); + #define CMD_READ 0x30 #define CMD_READ_SIZE 0x02 @@ -480,27 +483,46 @@ static int nfctype2_check_presence(uint32_t adapter_idx, uint32_t target_idx, { struct type2_cmd cmd; struct t2_cookie *cookie; + enum near_tag_sub_type tgt_subtype; int err; DBG(""); - cmd.cmd = CMD_READ; - cmd.block = META_BLOCK_START; + tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx); - cookie = g_try_malloc0(sizeof(struct t2_cookie)); - if (cookie == NULL) - return -ENOMEM; + switch (tgt_subtype) { + case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT: + cmd.cmd = CMD_READ; + cmd.block = META_BLOCK_START; - cookie->adapter_idx = adapter_idx; - cookie->target_idx = target_idx; - cookie->cb = cb; + cookie = g_try_malloc0(sizeof(struct t2_cookie)); + if (cookie == NULL) + return -ENOMEM; - err = near_adapter_send(adapter_idx, (uint8_t *) &cmd, CMD_READ_SIZE, - check_presence, cookie); - if (err < 0) - goto out; + cookie->adapter_idx = adapter_idx; + cookie->target_idx = target_idx; + cookie->cb = cb; - return 0; + err = near_adapter_send(adapter_idx, (uint8_t *) &cmd, + CMD_READ_SIZE, check_presence, cookie); + if (err < 0) + goto out; + + break; + /* Specific Mifare check presence */ + case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K: + case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K: + err = mifare_check_presence(adapter_idx, target_idx, + cb, tgt_subtype); + break; + + default: + DBG("Unknown TAG Type 2 subtype %d", tgt_subtype); + err = -1; + break; + } + + return err; out: t2_cookie_release(cookie); -- 2.7.4