2017-06-16 03:57:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 0/4] neard: Add support for deactivating tags

This series adds the ability for client apps to deactivate a currently
active tag. Once deactivated, the client can either poll again to
reactivate the tag or power the adapter off to save power. These
changes will not work until the Linux kernel commits submitted under
the subject, "NFC: Add deactivate target functionality" are committed.
Those commits can be viewed here:

https://lists.01.org/pipermail/linux-nfc/2017-June/004415.html

The commits are based on the commits submitted previously under the
subject, "[PATCH 00/23] neard: Support TI Std & Pro tags, fixups, etc."
which can be viewed here:

https://lists.01.org/pipermail/linux-nfc/2017-June/004392.html

For convenience, these commits are available in the 'submit/deactivate_tag-v1'
branch of this repo on github:

https://github.com/animalcreek/neard.git

Mark Greer (4):
adapter: Make adapter_start_poll() global
adapter: Add call indicating whether constant poll is enabled
tag: Add Tag deactivate support
test: Add option to deactivate tag

doc/tag-api.txt | 8 ++++++++
include/nfc_copy.h | 2 ++
src/adapter.c | 27 ++++++++++++++++-----------
src/near.h | 3 +++
src/netlink.c | 33 +++++++++++++++++++++++++++++++++
src/tag.c | 29 +++++++++++++++++++++++++++++
test/test-tag | 13 +++++++++++++
7 files changed, 104 insertions(+), 11 deletions(-)

--
2.13.0


2017-06-16 03:57:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 4/4] test: Add option to deactivate tag

Add the 'deactivate' option to test-tag which deactivates the
specified tag.

Signed-off-by: Mark Greer <[email protected]>
---
test/test-tag | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/test/test-tag b/test/test-tag
index fd80132..cb2c9e8 100755
--- a/test/test-tag
+++ b/test/test-tag
@@ -11,6 +11,7 @@ def usage():
text = """
list
dump <tag>
+deactivate <tag>
write <tag> <type> <...>

If type is Text, parameters are <encoding> <language> <representation>
@@ -165,5 +166,17 @@ if (sys.argv[1] == "write"):
else:
usage()

+ sys.exit(0)
+
+if (sys.argv[1] == "deactivate"):
+ print sys.argv[2]
+ if (len(sys.argv) != 2):
+ tag = neardutils.find_tag(sys.argv[2])
+ tag.Deactivate()
+ else:
+ usage()
+
+ sys.exit(0)
+
else:
usage()
--
2.13.0

2017-06-16 03:57:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 2/4] adapter: Add call indicating whether constant poll is enabled

Add a routine that returns a boolean indicating whether the adapter
constant poll option is enabled or not.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 5 +++++
src/near.h | 1 +
2 files changed, 6 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index e8c7c61..9c483ca 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -578,6 +578,11 @@ void __near_adapter_destroy(struct near_adapter *adapter)
free_adapter(adapter);
}

+bool __near_adapter_is_constant_poll(struct near_adapter *adapter)
+{
+ return adapter->constant_poll;
+}
+
const char *__near_adapter_get_path(struct near_adapter *adapter)
{
return adapter->path;
diff --git a/src/near.h b/src/near.h
index 7795e61..50a4c8b 100644
--- a/src/near.h
+++ b/src/near.h
@@ -78,6 +78,7 @@ void __near_manager_cleanup(void);
struct near_adapter *__near_adapter_create(uint32_t idx,
const char *name, uint32_t protocols, bool powered);
void __near_adapter_destroy(struct near_adapter *adapter);
+bool __near_adapter_is_constant_poll(struct near_adapter *adapter);
const char *__near_adapter_get_path(struct near_adapter *adapter);
struct near_adapter *__near_adapter_get(uint32_t idx);
int __near_adapter_add(struct near_adapter *adapter);
--
2.13.0

2017-06-16 03:57:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 3/4] 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 <[email protected]>
---
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(+)

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) },
{ },
};

--
2.13.0

2017-06-16 03:57:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 1/4] adapter: Make adapter_start_poll() global

An upcoming commit will need to call adapter_start_poll() from the
tag code so make it global. To be consistent with the names of
other global routines in adapter.c, add the '__near_' prefix.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 22 +++++++++++-----------
src/near.h | 1 +
2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 9e3e75e..e8c7c61 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -152,7 +152,7 @@ static void rf_mode_changed(struct near_adapter *adapter)
NFC_ADAPTER_INTERFACE, "Mode");
}

-static int adapter_start_poll(struct near_adapter *adapter)
+int __near_adapter_start_poll(struct near_adapter *adapter)
{
int err;
uint32_t im_protos, tm_protos;
@@ -375,7 +375,7 @@ static DBusMessage *start_poll_loop(DBusConnection *conn,
else
adapter->poll_mode = NEAR_ADAPTER_MODE_INITIATOR;

- err = adapter_start_poll(adapter);
+ err = __near_adapter_start_poll(adapter);
if (err < 0)
return __near_error_failed(msg, -err);

@@ -433,7 +433,7 @@ static gboolean check_presence(gpointer user_data)
out_err:
near_adapter_disconnect(adapter->idx);
if (adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return FALSE;
}
@@ -447,7 +447,7 @@ static gboolean dep_timer(gpointer user_data)
if (!adapter)
return FALSE;

- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return FALSE;
}
@@ -469,7 +469,7 @@ static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx,

near_adapter_disconnect(adapter->idx);
if (adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return;
}
@@ -606,7 +606,7 @@ int __near_adapter_set_dep_state(uint32_t idx, bool dep)
* that very moment. In this case we need to try polling later
* again, so constant polling will work properly.
*/
- if(adapter_start_poll(adapter) == -EBUSY) {
+ if(__near_adapter_start_poll(adapter) == -EBUSY) {
near_error("Adapter is busy, retry polling later");
g_timeout_add_seconds(1, dep_timer, adapter);
}
@@ -688,7 +688,7 @@ static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
if (status < 0) {
near_adapter_disconnect(adapter->idx);
if (adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return;
}
@@ -717,7 +717,7 @@ static void device_read_cb(uint32_t adapter_idx, uint32_t target_idx,
}

if (adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return;
}
@@ -838,7 +838,7 @@ int __near_adapter_add_target(uint32_t idx, uint32_t target_idx,
iso15693_uid_len, iso15693_uid);

if (ret < 0 && adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return ret;
}
@@ -879,7 +879,7 @@ static gboolean poll_error(gpointer user_data)
__near_netlink_adapter_enable(adapter->idx, true);
}

- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return FALSE;
}
@@ -954,7 +954,7 @@ int __near_adapter_remove_device(uint32_t idx)
adapter->dep_up = false;

if (adapter->constant_poll)
- adapter_start_poll(adapter);
+ __near_adapter_start_poll(adapter);

return 0;
}
diff --git a/src/near.h b/src/near.h
index 1ac6191..7795e61 100644
--- a/src/near.h
+++ b/src/near.h
@@ -94,6 +94,7 @@ int __near_adapter_remove_device(uint32_t idx);
int __near_adapter_set_dep_state(uint32_t idx, bool dep);
bool __near_adapter_get_dep_state(uint32_t idx);
void __near_adapter_listen(struct near_device_driver *driver);
+int __near_adapter_start_poll(struct near_adapter *adapter);
void __near_adapter_start_check_presence(uint32_t adapter_idx, uint32_t target_idx);
void __near_adapter_stop_check_presence(uint32_t adapter_idx, uint32_t target_idx);
int __near_adapter_init(void);
--
2.13.0

2017-11-09 23:38:58

by Samuel Ortiz

[permalink] [raw]
Subject: Re: [PATCH 0/4] neard: Add support for deactivating tags

On Thu, Jun 15, 2017 at 08:57:24PM -0700, Mark Greer wrote:
> This series adds the ability for client apps to deactivate a currently
> active tag. Once deactivated, the client can either poll again to
> reactivate the tag or power the adapter off to save power. These
> changes will not work until the Linux kernel commits submitted under
> the subject, "NFC: Add deactivate target functionality" are committed.
> Those commits can be viewed here:
>
> https://lists.01.org/pipermail/linux-nfc/2017-June/004415.html
>
> The commits are based on the commits submitted previously under the
> subject, "[PATCH 00/23] neard: Support TI Std & Pro tags, fixups, etc."
> which can be viewed here:
>
> https://lists.01.org/pipermail/linux-nfc/2017-June/004392.html
>
> For convenience, these commits are available in the 'submit/deactivate_tag-v1'
> branch of this repo on github:
>
> https://github.com/animalcreek/neard.git
>
> Mark Greer (4):
> adapter: Make adapter_start_poll() global
> adapter: Add call indicating whether constant poll is enabled
> tag: Add Tag deactivate support
> test: Add option to deactivate tag
All 4 patches applied, thanks.

Cheers,
Samuel.