mifare: Add mifare_check_presence and check_presence
authorDorota Moskal <dorota.moskal@tieto.com>
Mon, 10 Sep 2012 08:06:24 +0000 (10:06 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 13 Sep 2012 17:30:21 +0000 (19:30 +0200)
When tag type 2 is Mifare Classic, specific mifare check presence is run.

plugins/mifare.c
plugins/nfctype2.c

index db71536..400bb00 100644 (file)
  * 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;
+}
index dc178ca..a20bf61 100644 (file)
@@ -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);