NFC: netlink: Add new netlink command NFC_CMD_ACTIVATE_TARGET
authorChristophe Ricard <christophe.ricard@gmail.com>
Tue, 2 Dec 2014 20:27:50 +0000 (21:27 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 2 Dec 2014 21:47:37 +0000 (22:47 +0100)
Some tag might get deactivated after some read or write tentative.
This may happen for example with Mifare Ultralight C tag when trying
to read the last 4 blocks (starting block 0x2c) configured as write
only.
NFC_CMD_ACTIVATE_TARGET will try to reselect the tag in order to
detect if it got remove from the field or if it is still present.

Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
include/uapi/linux/nfc.h
net/nfc/netlink.c

index 19a75da..3c5efb1 100644 (file)
@@ -116,6 +116,7 @@ enum nfc_commands {
        NFC_EVENT_SE_TRANSACTION,
        NFC_CMD_GET_SE,
        NFC_CMD_SE_IO,
+       NFC_CMD_ACTIVATE_TARGET,
 /* private: internal use only */
        __NFC_CMD_AFTER_LAST
 };
index 43cb1c1..9581831 100644 (file)
@@ -810,6 +810,31 @@ out:
        return rc;
 }
 
+static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info)
+{
+       struct nfc_dev *dev;
+       u32 device_idx, target_idx, protocol;
+       int rc;
+
+       if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
+               return -EINVAL;
+
+       device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
+
+       dev = nfc_get_device(device_idx);
+       if (!dev)
+               return -ENODEV;
+
+       target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
+       protocol = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
+
+       nfc_deactivate_target(dev, target_idx);
+       rc = nfc_activate_target(dev, target_idx, protocol);
+
+       nfc_put_device(dev);
+       return 0;
+}
+
 static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
 {
        struct nfc_dev *dev;
@@ -1455,6 +1480,11 @@ static const struct genl_ops nfc_genl_ops[] = {
                .doit = nfc_genl_se_io,
                .policy = nfc_genl_policy,
        },
+       {
+               .cmd = NFC_CMD_ACTIVATE_TARGET,
+               .doit = nfc_genl_activate_target,
+               .policy = nfc_genl_policy,
+       },
 };