@@ -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]
@@ -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
};
@@ -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);
@@ -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)
{
@@ -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) },
{ },
};
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> --- doc/tag-api.txt | 8 ++++++++ include/nfc_copy.h | 2 ++ src/near.h | 1 + src/netlink.c | 33 +++++++++++++++++++++++++++++++++ src/tag.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+)