aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Greer <mgreer@animalcreek.com>2017-03-08 23:26:15 +0000
committerSamuel Ortiz <sameo@linux.intel.com>2017-11-10 00:43:56 +0100
commitd6044122ebe7a5f92d12b22299cfef9bb3826f2b (patch)
treec7cb7643df432f13722f426cffdc23f912eaf1e9
parent13c6d8470df034d2bc6e2e5d797f7f82f703360f (diff)
downloadneard-d6044122ebe7a5f92d12b22299cfef9bb3826f2b.tar.gz
tag: Add Tag deactivate support
Once a tag has been discovered, it remains active until it is moved out of range, or an error occurs while reading or writing it. While the tag is active, the adapter cannot be powered off. This wastes power when the client application no longer cares whether the tag is in range or not. To address this issue, add the ability for a client application to deactivate an active tag. Once deactivated, the client application can poll the tag again to read it or power off the adapter. The 'NFC_CMD_DEACTIVATE_TARGET' netlink command is added to request that the kernel deactivate the target (tag). Signed-off-by: Mark Greer <mgreer@animalcreek.com>
-rw-r--r--doc/tag-api.txt8
-rw-r--r--include/nfc_copy.h2
-rw-r--r--src/near.h1
-rw-r--r--src/netlink.c33
-rw-r--r--src/tag.c29
5 files changed, 73 insertions, 0 deletions
diff --git a/doc/tag-api.txt b/doc/tag-api.txt
index b388b22..4ed24da 100644
--- a/doc/tag-api.txt
+++ b/doc/tag-api.txt
@@ -25,6 +25,14 @@ Method void Write(dict attributes)
org.neard.Error.InvalidArguments
org.neard.Error.InProgress
+Method void Deactivate()
+
+ Deactivates a tag.
+
+ Possible Errors: org.neard.Error.PermissionDenied
+ org.neard.Error.OutOfMemory
+ org.neard.Error.InvalidArguments
+ org.neard.Error.NotSupported
Properties string Type [readonly]
diff --git a/include/nfc_copy.h b/include/nfc_copy.h
index 399f39f..f6e3c8c 100644
--- a/include/nfc_copy.h
+++ b/include/nfc_copy.h
@@ -89,6 +89,7 @@
* @NFC_CMD_ACTIVATE_TARGET: Request NFC controller to reactivate target.
* @NFC_CMD_VENDOR: Vendor specific command, to be implemented directly
* from the driver in order to support hardware specific operations.
+ * @NFC_CMD_DEACTIVATE_TARGET: Request NFC controller to deactivate target.
*/
enum nfc_commands {
NFC_CMD_UNSPEC,
@@ -121,6 +122,7 @@ enum nfc_commands {
NFC_CMD_SE_IO,
NFC_CMD_ACTIVATE_TARGET,
NFC_CMD_VENDOR,
+ NFC_CMD_DEACTIVATE_TARGET,
/* private: internal use only */
__NFC_CMD_AFTER_LAST
};
diff --git a/src/near.h b/src/near.h
index 50a4c8b..e7f7fa7 100644
--- a/src/near.h
+++ b/src/near.h
@@ -166,6 +166,7 @@ int __near_netlink_start_poll(int idx,
int __near_netlink_stop_poll(int idx);
int __near_netlink_activate_target(uint32_t idx, uint32_t target_idx,
uint32_t protocol);
+int __near_netlink_deactivate_target(uint32_t idx, uint32_t target_idx);
int __near_netlink_dep_link_up(uint32_t idx, uint32_t target_idx,
uint8_t comm_mode, uint8_t rf_mode);
int __near_netlink_dep_link_down(uint32_t idx);
diff --git a/src/netlink.c b/src/netlink.c
index d02d62f..3c77999 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -329,6 +329,39 @@ nla_put_failure:
return err;
}
+int __near_netlink_deactivate_target(uint32_t idx, uint32_t target_idx)
+{
+ struct nl_msg *msg;
+ void *hdr;
+ int err;
+
+ DBG("");
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nfc_state->nfc_id, 0,
+ NLM_F_REQUEST, NFC_CMD_DEACTIVATE_TARGET,
+ NFC_GENL_VERSION);
+ if (!hdr) {
+ err = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ err = -EMSGSIZE;
+
+ NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, idx);
+ NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
+
+ err = nl_send_msg(nfc_state->cmd_sock, msg, NULL, NULL);
+
+nla_put_failure:
+ nlmsg_free(msg);
+
+ return err;
+}
+
int __near_netlink_dep_link_up(uint32_t idx, uint32_t target_idx,
uint8_t comm_mode, uint8_t rf_mode)
{
diff --git a/src/tag.c b/src/tag.c
index 01015a1..9eba4ee 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -486,9 +486,38 @@ fail:
return __near_error_failed(msg, ENOMEM);
}
+static DBusMessage *deactivate_tag(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct near_tag *tag = data;
+ struct near_adapter *adapter;
+ int err;
+
+ DBG("deactivating tag %p", conn);
+
+ adapter = __near_adapter_get(tag->adapter_idx);
+ if (!adapter)
+ return __near_error_failed(msg, EINVAL);
+
+ __near_adapter_stop_check_presence(tag->adapter_idx, tag->target_idx);
+
+ err = __near_netlink_deactivate_target(tag->adapter_idx,
+ tag->target_idx);
+ if (err < 0)
+ return __near_error_failed(msg, -err);
+
+ near_adapter_disconnect(tag->adapter_idx);
+
+ if (__near_adapter_is_constant_poll(adapter))
+ __near_adapter_start_poll(adapter);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
static const GDBusMethodTable tag_methods[] = {
{ GDBUS_ASYNC_METHOD("Write", GDBUS_ARGS({"attributes", "a{sv}"}),
NULL, write_ndef) },
+ { GDBUS_METHOD("Deactivate", NULL, NULL, deactivate_tag) },
{ },
};