2017-06-15 18:25:24

by Mark Greer

[permalink] [raw]
Subject: [PATCH 00/23] neard: Support TI Std & Pro tags, fixups, etc.

This is an assortment of commits that make some fixups, do some general
tightening of NDEF data checking, add support for TI Standard and Pro
Type 5 tags, and stop issuing the Read Multiple Blocks command when
formatting a Type 5 tag. The reasoning for each change is in the
individual commit descriptions.

For convenience, a branch with these commits is available in the
submit/updates-v1 branch here:

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

Mark Greer (23):
ndef: Add default language ("en") for Text records
ndef: Fix use of uninitialized variable in property_get_type()
ndef: Unrecognized WKTs should return RECORD_TYPE_UNKNOWN
ndef: Verify RTD record type name encodings
ndef: Discard records containing errors
ndef: Validate text data in WKT Text records
adapter: Return '-errno' when socket() call fails
adapter: Return '-errno' when connect() call fails
adapter: Clear timeout handle when check presence timer stopped
adapter: Clear timer handle when DEP timer stopped
adapter: Do not poll when there is an active tag
nfctype2: Don't read tags with bad magic number
nfctype5: Reduce noise when tag is moved out of range
nfctype5: Add space between 'if' and first '('
nfctype5: Remove superfluous parentheses
nfctype5: Rework code that identifies ST Micro Type 5 tags
nfctype5: Add support for TI Standard and Pro Type 5 tag
nfctype5: Remove useless initialization
nfctype5: Don't issue RMB command when formatting
nfctype5: Discard extra byte in RMB response data
nfctype5: Fix formatting
nfctools: Move nciattach macros & enums to nciattach.c
nfc_copy: Update nfc_copy.h to match Linux kernel's version

include/nfc_copy.h | 63 +++++----
plugins/nfctype2.c | 1 +
plugins/nfctype5.c | 320 ++++++++++++++++++++++++--------------------
src/adapter.c | 15 ++-
src/ndef.c | 43 +++++-
tools/nciattach.c | 12 ++
tools/nfctool/llcp-decode.c | 14 +-
tools/nfctool/snep-decode.c | 12 +-
8 files changed, 290 insertions(+), 190 deletions(-)

--
2.13.0


2017-06-15 18:25:28

by Mark Greer

[permalink] [raw]
Subject: [PATCH 20/23] nfctype5: Discard extra byte in RMB response data

Sometimes there can be an extra byte in the response data for Read
Multiple Blocks (RMB) commands so discard it whenever that happens.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index a91d8f5..d6eec3c 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -654,7 +654,7 @@ static int t5_read_multiple_blocks_resp(uint8_t *resp, int length, void *data)
uint8_t blk_size = near_tag_get_blk_size(tag);
size_t data_length;
GList *records;
- int err;
+ int err, expected_len;

DBG("");

@@ -665,9 +665,16 @@ static int t5_read_multiple_blocks_resp(uint8_t *resp, int length, void *data)
goto out_done;

length -= NFC_HEADER_SIZE;
+ expected_len = sizeof(*t5_resp) +
+ cookie->nb_requested_blocks * blk_size;

- if (length != (int)(sizeof(*t5_resp) +
- (cookie->nb_requested_blocks * blk_size))) {
+ /*
+ * Sometimes an extra byte is returned in RMB response data.
+ * Discard the extra byte whenever that happens.
+ */
+ if (length == (expected_len + 1)) {
+ length--;
+ } else if (length != expected_len) {
err = -EIO;
goto out_done;
}
--
2.13.0

2017-06-15 18:25:24

by Mark Greer

[permalink] [raw]
Subject: [PATCH 02/23] ndef: Fix use of uninitialized variable in property_get_type()

The 'type' variable in property_get_type() is never set when the
record type is invalid. This means that the check for NULL doesn't
work as it should and a bogus string can be appended. Fix this by
adding a default case to the switch statement that checks the record
type ensuring that 'type' is set to NULL when the record type is
invalid.

Signed-off-by: Mark Greer <[email protected]>
---
src/ndef.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/ndef.c b/src/ndef.c
index b90205b..99f3bc3 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -342,6 +342,7 @@ static gboolean property_get_type(const GDBusPropertyTable *property,
case RECORD_TYPE_WKT_ERROR:
case RECORD_TYPE_UNKNOWN:
case RECORD_TYPE_ERROR:
+ default:
type = NULL;
break;

--
2.13.0

2017-06-15 18:25:41

by Mark Greer

[permalink] [raw]
Subject: [PATCH 18/23] nfctype5: Remove useless initialization

There is no point in assigning 'local_data' to 'cookie' when 'cookie'
is going to be reassigned before it is used.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index f26d8fa..873ac79 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -430,7 +430,7 @@ static int t5_read(struct near_tag *tag, uint8_t offset, uint8_t *buf,
size_t len, t5_local_cb local_cb, void *local_data)
{
struct type5_read_single_block_cmd t5_cmd;
- struct t5_cookie *cookie = local_data;
+ struct t5_cookie *cookie;
uint8_t blk_size = near_tag_get_blk_size(tag);
int err;

@@ -529,7 +529,7 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
size_t len, t5_local_cb local_cb, void *local_data)
{
struct type5_write_single_block_cmd *t5_cmd;
- struct t5_cookie *cookie = local_data;
+ struct t5_cookie *cookie;
uint8_t blk_size = near_tag_get_blk_size(tag);
int err;

--
2.13.0

2017-06-15 18:25:30

by Mark Greer

[permalink] [raw]
Subject: [PATCH 10/23] adapter: Clear timer handle when DEP timer stopped

__near_adapter_set_dep_state() stops the neard DEP timer but
doesn't clear the timer handle. This can cause neard to try
to stop the timer when it isn't running. To fix that, clear
the handle so neard doesn't try to stop an already stopped timer.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 7be87e2..eb1a407 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -615,8 +615,10 @@ int __near_adapter_set_dep_state(uint32_t idx, bool dep)
target_idx = __neard_device_get_idx(adapter->device_link);
__near_adapter_remove_target(idx, target_idx);
} else {
- if (adapter->dep_timer > 0)
+ if (adapter->dep_timer > 0) {
g_source_remove(adapter->dep_timer);
+ adapter->dep_timer = 0;
+ }

if (!__near_device_register_interface(adapter->device_link))
return -ENODEV;
--
2.13.0

2017-06-15 18:25:24

by Mark Greer

[permalink] [raw]
Subject: [PATCH 01/23] ndef: Add default language ("en") for Text records

Despite section 3.3 of the NFC Forum RTD-Text 1.0 Technical
Specification stating in part, "The language code MAY NOT be
omitted", some tags have a 0-length language field. A 0-length
language field currently causes neard to exit which isn't ideal
so choose a default language (generic English) which will be
used in these situations.

There is no particular reason to choose English other than it
is the native language of the patch author and it is the
language neard is coded in.

Signed-off-by: Mark Greer <[email protected]>
---
This is identical to an earlier patch submitted to the linux-nfc
mail list in October (link below) so that patch can be discarded.

https://lists.01.org/pipermail/linux-nfc/2016-October/004292.html
---
src/ndef.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/ndef.c b/src/ndef.c
index 5656baf..b90205b 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -409,7 +409,10 @@ static const char *get_text_payload(const GDBusPropertyTable *property,
if (!strcmp(property->name, "Encoding"))
return text->encoding;
else if (!strcmp(property->name, "Language"))
- return text->language_code;
+ if (!text->language_code)
+ return "en";
+ else
+ return text->language_code;
else if (!strcmp(property->name, "Representation"))
return text->data;
else
--
2.13.0

2017-06-15 18:25:24

by Mark Greer

[permalink] [raw]
Subject: [PATCH 03/23] ndef: Unrecognized WKTs should return RECORD_TYPE_UNKNOWN

When get_record_type() doesn't recognize the record type in a record
with a Well Known Type TNF, it falls through to the next case clause
and returns RECORD_TYPE_MIME_TYPE. This is incorrect so add a break
statement to the RECORD_TNF_WELLKNOWN case so that RECORD_TYPE_UNKNOWN
is returned.

Signed-off-by: Mark Greer <[email protected]>
---
src/ndef.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/ndef.c b/src/ndef.c
index 99f3bc3..03d6b13 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -928,6 +928,7 @@ static enum record_type get_record_type(enum record_tnf tnf,
return RECORD_TYPE_UNKNOWN;

}
+ break;

case RECORD_TNF_MIME:
return RECORD_TYPE_MIME_TYPE;
--
2.13.0

2017-06-15 18:25:25

by Mark Greer

[permalink] [raw]
Subject: [PATCH 12/23] nfctype2: Don't read tags with bad magic number

NFC Type 2 tags that have a bad magic number need to be reformatted
so do not try to read them.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype2.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/plugins/nfctype2.c b/plugins/nfctype2.c
index 559ecb0..f0f1158 100644
--- a/plugins/nfctype2.c
+++ b/plugins/nfctype2.c
@@ -275,6 +275,7 @@ static int meta_recv(uint8_t *resp, int length, void *data)
if (TAG_DATA_NFC(cc) != TYPE2_MAGIC) {
DBG("Mark as blank tag");
near_tag_set_blank(tag, TRUE);
+ goto out_tag;
} else {
near_tag_set_blank(tag, FALSE);
}
--
2.13.0

2017-06-15 18:25:25

by Mark Greer

[permalink] [raw]
Subject: [PATCH 08/23] adapter: Return '-errno' when connect() call fails

near_adapter_connect() incorrectly returns '-1' when the connect()
call fails. Instead, it should return '-errno' which is the real
error code.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index bfc64c2..466753b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1054,7 +1054,7 @@ int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol)
err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
if (err) {
close(sock);
- return err;
+ return -errno;
}

adapter->tag_sock = sock;
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 19/23] nfctype5: Don't issue RMB command when formatting

Currently, when neard is formatting a Type 5 tag, it issues the Read
Multiple Blocks (RMB) command to see if the tag supports it. If the
command succeeds, the appropriate bit in the CC is set so the RMB
command can be used in the future. The problem is that when the tag
doesn't support the command, a failure is returned by the kernel causing
the neard adapter code to disconnect from the tag. This effectively
makes the tag unusable by neard.

To avoid this issue, don't bother checking to see if the RMB command
is supported and just assume that it isn't (and therefore, do not set
the MBREAD bit in the CC). This has the benefit of formatting Type 5
tags that don't support RMB at the cost of forcing future readers to
use a series of Read Single Block commands for multi-block reads (i.e.,
slower than a single multi-block read).

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 77 +++++++++++++++++-------------------------------------
1 file changed, 24 insertions(+), 53 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 873ac79..a91d8f5 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -1048,30 +1048,31 @@ static int nfctype5_format_resp(struct near_tag *tag, int err, void *data)
return t5_cookie_release(err, cookie);
}

-static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
- void *data)
+static int nfctype5_format(uint32_t adapter_idx, uint32_t target_idx,
+ near_tag_io_cb cb)
{
- struct type5_read_multiple_blocks_resp *t5_resp =
- (struct type5_read_multiple_blocks_resp *)
- (resp + NFC_HEADER_SIZE);
- struct t5_cookie *cookie = data;
struct type5_cc t5_cc;
- struct near_tag *tag = cookie->tag;
- uint8_t blk_size = near_tag_get_blk_size(tag);
+ struct t5_cookie *cookie;
+ struct near_tag *tag;
size_t mem_size;
- bool read_multiple_supported = false;
int err;

DBG("");

- err = t5_check_resp(resp, length);
- if (!err) {
- length -= NFC_HEADER_SIZE;
+ tag = near_tag_get_tag(adapter_idx, target_idx);
+ if (!tag) {
+ err = -EINVAL;
+ goto out_err;
+ }

- if (length == (int)(sizeof(*t5_resp) + (2 * blk_size)))
- read_multiple_supported = true;
+ cookie = t5_cookie_alloc(tag);
+ if (!cookie) {
+ err = -ENOMEM;
+ goto out_err;
}

+ cookie->cb = cb;
+
t5_cc.cc0 = TYPE5_CC0_NDEF_MAGIC;

t5_cc.cc1 = TYPE5_VERSION_MAJOR << TYPE5_CC1_VER_MAJOR_SHIFT;
@@ -1086,7 +1087,7 @@ static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
*/
t5_cc.cc1 |= TYPE5_CC1_WRITE_ACCESS_ALWAYS;

- mem_size = blk_size * near_tag_get_num_blks(tag);
+ mem_size = near_tag_get_blk_size(tag) * near_tag_get_num_blks(tag);
mem_size = MIN(mem_size, TYPE5_MAX_MEM_SIZE);

t5_cc.cc2 = mem_size / 8;
@@ -1098,53 +1099,23 @@ static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
* just say that its not supported. We also don't know whether
* the tag needs a special frame format so just say "no" for that
* one too. If it does, we probably can't write to the tag anyway.
+ *
+ * In order to know if the tag supports the Read Multiple Blocks
+ * command, we would have to issue that command here to see if it
+ * succeeds. If it does succeed, then TYPE5_CC3_MBREAD_FLAG could
+ * be set; however, if it fails, the adapter code will disconnect
+ * from the tag and the format will fail making the tag unusable.
+ * To avoid that possibility, indicate that Read Multiple Blocks
+ * commands is not supported (i.e., do not set TYPE5_CC3_MBREAD_FLAG).
*/
t5_cc.cc3 = 0;

- /*
- * ST Type5 tags does not support multiblock read for blocks
- * lying in different sectors. So, doing multi block read
- * support setting only for non ST tags.
- */
- if (!t5_manufacturer_is_stmicro(tag)) {
- if (read_multiple_supported)
- t5_cc.cc3 |= TYPE5_CC3_MBREAD_FLAG;
- }
-
err = t5_write(tag, TYPE5_META_START_OFFSET, (uint8_t *)&t5_cc,
sizeof(t5_cc), nfctype5_format_resp, cookie);
if (err < 0)
err = t5_cookie_release(err, cookie);

return err;
-}
-
-static int nfctype5_format(uint32_t adapter_idx, uint32_t target_idx,
- near_tag_io_cb cb)
-{
- struct t5_cookie *cookie;
- struct near_tag *tag;
- int err;
-
- DBG("");
-
- tag = near_tag_get_tag(adapter_idx, target_idx);
- if (!tag) {
- err = -EINVAL;
- goto out_err;
- }
-
- cookie = t5_cookie_alloc(tag);
- if (!cookie) {
- err = -ENOMEM;
- goto out_err;
- }
-
- cookie->cb = cb;
-
- return t5_read_multiple_blocks(tag, 0, 2,
- t5_format_read_multiple_blocks_resp,
- cookie);

out_err:
if (cb)
--
2.13.0

2017-06-15 18:25:19

by Mark Greer

[permalink] [raw]
Subject: [PATCH 04/23] ndef: Verify RTD record type name encodings

The NFC Forum's Record Type Definition (RTD) Technical Specification
version 1.0, section 3.4 (RTD Type Names Requirements) specifies that
RTD type name encodings MUST be done according to the ASCII chart in
Appendix A (Character Set for Record Types). Enforce this by checking
that all of the RTD type name encodings are valid before determining
their type. Conveniently, isprint() does the correct checking.

Signed-off-by: Mark Greer <[email protected]>
---
src/ndef.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/src/ndef.c b/src/ndef.c
index 03d6b13..7a3c76b 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <ctype.h>

#include <glib.h>

@@ -881,6 +882,8 @@ static enum record_type get_external_record_type(uint8_t *type,
static enum record_type get_record_type(enum record_tnf tnf,
uint8_t *type, size_t type_length)
{
+ unsigned int i;
+
DBG("");

switch (tnf) {
@@ -891,6 +894,10 @@ static enum record_type get_record_type(enum record_tnf tnf,
break;

case RECORD_TNF_WELLKNOWN:
+ for (i = 0; i < type_length; i++)
+ if (!isprint(type[i]))
+ return RECORD_TYPE_ERROR;
+
if (type_length == 1) {
if (type[0] == 'T')
return RECORD_TYPE_WKT_TEXT;
--
2.13.0

2017-06-15 18:25:30

by Mark Greer

[permalink] [raw]
Subject: [PATCH 07/23] adapter: Return '-errno' when socket() call fails

near_adapter_connect() incorrectly returns '-1' when the socket()
call fails. Instead, it should return '-errno' which is the real
error code.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index bc29ace..bfc64c2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1044,7 +1044,7 @@ int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol)

sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW);
if (sock == -1)
- return sock;
+ return -errno;

addr.sa_family = AF_NFC;
addr.dev_idx = idx;
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 17/23] nfctype5: Add support for TI Standard and Pro Type 5 tag

Standard and Pro Type 5 tags from Texas Instruments do not support
the Get System Information command which means they cannot be read
with the current neard code. Fortunately, both types of tags have
eight, 4-byte blocks so that information can be filled in instead
of issuing the Get System Information command to get it. With this
change, Standard and Pro tags can now be formatted, read, and written.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 689dec3..f26d8fa 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -117,6 +117,7 @@

#define TYPE5_UID_MANUFAC_IDX 0x06
#define TYPE5_UID_MANUFAC_ID_STMICRO 0x02
+#define TYPE5_UID_MANUFAC_ID_TI 0x07

struct type5_cmd_hdr {
uint8_t flags;
@@ -217,6 +218,49 @@ static bool t5_manufacturer_is_stmicro(struct near_tag *tag)
return t5_manufacturer_is(tag, TYPE5_UID_MANUFAC_ID_STMICRO);
}

+static bool t5_manufacturer_is_ti(struct near_tag *tag)
+{
+ return t5_manufacturer_is(tag, TYPE5_UID_MANUFAC_ID_TI);
+}
+
+static bool t5_tag_is_ti_std(struct near_tag *tag)
+{
+ uint8_t *uid;
+ bool ret = false;
+
+ uid = near_tag_get_iso15693_uid(near_tag_get_adapter_idx(tag),
+ near_tag_get_target_idx(tag));
+ if (!uid) {
+ near_error("No type 5 UID");
+ return false;
+ }
+
+ if ((uid[5] == 0xc0) || (uid[5] == 0xc1))
+ ret = true;
+
+ g_free(uid);
+ return ret;
+}
+
+static bool t5_tag_is_ti_pro(struct near_tag *tag)
+{
+ uint8_t *uid;
+ bool ret;
+
+ uid = near_tag_get_iso15693_uid(near_tag_get_adapter_idx(tag),
+ near_tag_get_target_idx(tag));
+ if (!uid) {
+ near_error("No type 5 UID");
+ return false;
+ }
+
+ if ((uid[5] == 0xc4) || (uid[5] == 0xc5))
+ ret = true;
+
+ g_free(uid);
+ return ret;
+}
+
static int t5_cmd_hdr_init(struct near_tag *tag, struct type5_cmd_hdr *cmd_hdr,
int cmd)
{
@@ -851,10 +895,23 @@ static int nfctype5_read(uint32_t adapter_idx, uint32_t target_idx,
* num_blks once. near_tag_get_blk_size() will return 0 if
* t5_get_sys_info() hasn't been called yet.
*/
- if (near_tag_get_blk_size(tag))
+ if (near_tag_get_blk_size(tag)) {
err = t5_read_meta(tag, cookie);
- else
+ } else if (t5_manufacturer_is_ti(tag) &&
+ (t5_tag_is_ti_std(tag) || t5_tag_is_ti_pro(tag))) {
+ /*
+ * TI Standard and Pro tags do not support the Get System
+ * Information command but are known to have eight, 4-byte
+ * blocks so we can fill that info in and call t5_read_meta()
+ * here.
+ */
+ near_tag_set_blk_size(tag, 4);
+ near_tag_set_num_blks(tag, 8);
+
+ err = t5_read_meta(tag, cookie);
+ } else {
err = t5_get_sys_info(tag, cookie);
+ }

if (err < 0)
err = t5_cookie_release(err, cookie);
--
2.13.0

2017-06-15 18:25:25

by Mark Greer

[permalink] [raw]
Subject: [PATCH 15/23] nfctype5: Remove superfluous parentheses

Remove the superfluous parentheses around calls to
t5_manufacturer_stmicro().

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 29e1d0c..9d09bf8 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -456,7 +456,7 @@ static int t5_write_resp(uint8_t *resp, int length, void *data)
goto out_done;

/* CMD_FLAG_OPTION should be set for non ST tags */
- if (!(t5_manufacturer_stmicro(tag)))
+ if (!t5_manufacturer_stmicro(tag))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = cookie->blk;
@@ -515,7 +515,7 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
* does not work with ST Type5 tags.
* So, implemeting OPTION flag set only for non ST tags.
*/
- if (!(t5_manufacturer_stmicro(tag)))
+ if (!t5_manufacturer_stmicro(tag))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = offset / blk_size;
@@ -1046,7 +1046,7 @@ static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
* lying in different sectors. So, doing multi block read
* support setting only for non ST tags.
*/
- if (!(t5_manufacturer_stmicro(tag))) {
+ if (!t5_manufacturer_stmicro(tag)) {
if (read_multiple_supported)
t5_cc.cc3 |= TYPE5_CC3_MBREAD_FLAG;
}
--
2.13.0

2017-06-15 18:25:32

by Mark Greer

[permalink] [raw]
Subject: [PATCH 16/23] nfctype5: Rework code that identifies ST Micro Type 5 tags

Rework the code that identifies ST Micro Type 5 tags to make it
conform better to established coding style in the file and to
make it easier to add check for tags from other manufacturers.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 51 +++++++++++++++++++++++++++------------------------
1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 9d09bf8..689dec3 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -116,7 +116,7 @@
#define GET_SYS_INFO_FLAG_16B_NB_BLOCK 0x10

#define TYPE5_UID_MANUFAC_IDX 0x06
-#define TYPE5_UID_STMICRO_MANUFAC_ID 0x02
+#define TYPE5_UID_MANUFAC_ID_STMICRO 0x02

struct type5_cmd_hdr {
uint8_t flags;
@@ -194,6 +194,29 @@ struct t5_cookie {
uint8_t nb_requested_blocks;
};

+static bool t5_manufacturer_is(struct near_tag *tag, uint8_t manufacturer_id)
+{
+ uint8_t *uid;
+ bool match;
+
+ uid = near_tag_get_iso15693_uid(near_tag_get_adapter_idx(tag),
+ near_tag_get_target_idx(tag));
+ if (!uid) {
+ near_error("No type 5 UID");
+ return false;
+ }
+
+ match = (uid[TYPE5_UID_MANUFAC_IDX] == manufacturer_id);
+
+ g_free(uid);
+ return match;
+}
+
+static bool t5_manufacturer_is_stmicro(struct near_tag *tag)
+{
+ return t5_manufacturer_is(tag, TYPE5_UID_MANUFAC_ID_STMICRO);
+}
+
static int t5_cmd_hdr_init(struct near_tag *tag, struct type5_cmd_hdr *cmd_hdr,
int cmd)
{
@@ -392,26 +415,6 @@ static int t5_read(struct near_tag *tag, uint8_t offset, uint8_t *buf,
cookie, t5_cookie_release_local);
}

-static bool t5_manufacturer_stmicro(struct near_tag *tag)
-{
- uint8_t *uid;
-
- uid = near_tag_get_iso15693_uid(near_tag_get_adapter_idx(tag),
- near_tag_get_target_idx(tag));
- if (!uid) {
- near_error("No type 5 UID");
- return false;
- }
-
- if (uid[TYPE5_UID_MANUFAC_IDX] != TYPE5_UID_STMICRO_MANUFAC_ID) {
- g_free(uid);
- return false;
- }
-
- g_free(uid);
- return true;
-}
-
static int t5_write_resp(uint8_t *resp, int length, void *data)
{
struct type5_write_single_block_resp *t5_resp =
@@ -456,7 +459,7 @@ static int t5_write_resp(uint8_t *resp, int length, void *data)
goto out_done;

/* CMD_FLAG_OPTION should be set for non ST tags */
- if (!t5_manufacturer_stmicro(tag))
+ if (!t5_manufacturer_is_stmicro(tag))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = cookie->blk;
@@ -515,7 +518,7 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
* does not work with ST Type5 tags.
* So, implemeting OPTION flag set only for non ST tags.
*/
- if (!t5_manufacturer_stmicro(tag))
+ if (!t5_manufacturer_is_stmicro(tag))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = offset / blk_size;
@@ -1046,7 +1049,7 @@ static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
* lying in different sectors. So, doing multi block read
* support setting only for non ST tags.
*/
- if (!t5_manufacturer_stmicro(tag)) {
+ if (!t5_manufacturer_is_stmicro(tag)) {
if (read_multiple_supported)
t5_cc.cc3 |= TYPE5_CC3_MBREAD_FLAG;
}
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 11/23] adapter: Do not poll when there is an active tag

When there is an active tag and a request to start polling is
received by neard, it will discard the currently registered tag
and requests that the kernel start another poll. The kernel receives
this request and returns EBUSY because there is already an active tag.
neard receives this failure and reports it to the poll requestor.
At this point, the tag is active but neard no longer has any knowledge
of it. Fix this by returning EBUSY when there is an active tag and
a new poll request is received.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index eb1a407..9e3e75e 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -358,6 +358,9 @@ static DBusMessage *start_poll_loop(DBusConnection *conn,
return __near_error_failed(msg, ENODEV);
}

+ if (g_hash_table_size(adapter->tags) > 0)
+ return __near_error_failed(msg, EBUSY);
+
dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dbus_mode,
DBUS_TYPE_INVALID);

--
2.13.0

2017-06-15 18:25:30

by Mark Greer

[permalink] [raw]
Subject: [PATCH 06/23] ndef: Validate text data in WKT Text records

Ensure that the text encodings in WKT Text records are valid.

Signed-off-by: Mark Greer <[email protected]>
---
src/ndef.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/ndef.c b/src/ndef.c
index 38dcf72..fb17be9 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -1149,8 +1149,9 @@ static struct near_ndef_text_payload *
parse_text_payload(uint8_t *payload, uint32_t length)
{
struct near_ndef_text_payload *text_payload = NULL;
- uint8_t status, lang_length;
+ uint8_t status, lang_length, len, *txt, *g_str;
uint32_t offset;
+ gboolean valid;

DBG("");

@@ -1185,9 +1186,26 @@ parse_text_payload(uint8_t *payload, uint32_t length)

offset += lang_length;

- if ((length - lang_length - 1) > 0) {
- text_payload->data = g_strndup((char *)(payload + offset),
- length - lang_length - 1);
+ len = length - lang_length - 1;
+
+ if (len > 0) {
+ txt = payload + offset;
+
+ if (status)
+ g_str = g_utf16_to_utf8((gunichar2 *)txt, len, NULL,
+ NULL, NULL);
+ else
+ g_str = txt;
+
+ valid = g_utf8_validate(g_str, len, NULL);
+
+ if (status)
+ g_free(g_str);
+
+ if (!valid)
+ goto fail;
+
+ text_payload->data = g_strndup(txt, len);
} else {
text_payload->data = NULL;
}
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 13/23] nfctype5: Reduce noise when tag is moved out of range

The NFC Type 5 tag code prints a message whenever it receives an
error. This makes it extra noisy compared to the other tag types
whenever a tag is moved out of range. Instead, reduce that noise
by turning the error message into a debug message.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 1beb3a8..2fccec5 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -226,7 +226,7 @@ static int t5_check_resp(uint8_t *resp, int length)
DBG("");

if (length < 0) {
- near_error("Cmd failure: %d", length);
+ DBG("Cmd failure: %d", length);
err = length;
} else if (resp[0]) {
near_error("NFC Failure: 0x%x", resp[0]);
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 14/23] nfctype5: Add space between 'if' and first '('

Add a space between the 'if' and first parenthesis in 'if' statements
as no space is both annoying and contrary to neard coding style.

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index 2fccec5..29e1d0c 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -456,7 +456,7 @@ static int t5_write_resp(uint8_t *resp, int length, void *data)
goto out_done;

/* CMD_FLAG_OPTION should be set for non ST tags */
- if(!(t5_manufacturer_stmicro(tag)))
+ if (!(t5_manufacturer_stmicro(tag)))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = cookie->blk;
@@ -515,7 +515,7 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
* does not work with ST Type5 tags.
* So, implemeting OPTION flag set only for non ST tags.
*/
- if(!(t5_manufacturer_stmicro(tag)))
+ if (!(t5_manufacturer_stmicro(tag)))
t5_cmd->hdr.flags |= CMD_FLAG_OPTION;

t5_cmd->blk_no = offset / blk_size;
@@ -1046,7 +1046,7 @@ static int t5_format_read_multiple_blocks_resp(uint8_t *resp, int length,
* lying in different sectors. So, doing multi block read
* support setting only for non ST tags.
*/
- if(!(t5_manufacturer_stmicro(tag))) {
+ if (!(t5_manufacturer_stmicro(tag))) {
if (read_multiple_supported)
t5_cc.cc3 |= TYPE5_CC3_MBREAD_FLAG;
}
--
2.13.0

2017-06-15 18:25:26

by Mark Greer

[permalink] [raw]
Subject: [PATCH 23/23] nfc_copy: Update nfc_copy.h to match Linux kernel's version

neard's version of Linux's include/uapi/linux/nfc.h file has become
stale so update it to match the most current. The update changes
a few macro names which are used by neard so update those names in
the neard code as well.

Signed-off-by: Mark Greer <[email protected]>
---
include/nfc_copy.h | 51 +++++++++++++++++++++++++++++++++------------
tools/nfctool/llcp-decode.c | 14 ++++++-------
tools/nfctool/snep-decode.c | 12 +++++------
3 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/include/nfc_copy.h b/include/nfc_copy.h
index 0b25f5c..399f39f 100644
--- a/include/nfc_copy.h
+++ b/include/nfc_copy.h
@@ -86,6 +86,9 @@
* for this event is the application ID (AID).
* @NFC_CMD_GET_SE: Dump all discovered secure elements from an NFC controller.
* @NFC_CMD_SE_IO: Send/Receive APDUs to/from the selected secure element.
+ * @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.
*/
enum nfc_commands {
NFC_CMD_UNSPEC,
@@ -117,6 +120,7 @@ enum nfc_commands {
NFC_CMD_GET_SE,
NFC_CMD_SE_IO,
NFC_CMD_ACTIVATE_TARGET,
+ NFC_CMD_VENDOR,
/* private: internal use only */
__NFC_CMD_AFTER_LAST
};
@@ -153,6 +157,11 @@ enum nfc_commands {
* @NFC_ATTR_APDU: Secure element APDU
* @NFC_ATTR_TARGET_ISO15693_DSFID: ISO 15693 Data Storage Format Identifier
* @NFC_ATTR_TARGET_ISO15693_UID: ISO 15693 Unique Identifier
+ * @NFC_ATTR_SE_PARAMS: Parameters data from an evt_transaction
+ * @NFC_ATTR_VENDOR_ID: NFC manufacturer unique ID, typically an OUI
+ * @NFC_ATTR_VENDOR_SUBCMD: Vendor specific sub command
+ * @NFC_ATTR_VENDOR_DATA: Vendor specific data, to be optionally passed
+ * to a vendor specific command implementation
*/
enum nfc_attrs {
NFC_ATTR_UNSPEC,
@@ -183,6 +192,10 @@ enum nfc_attrs {
NFC_ATTR_SE_APDU,
NFC_ATTR_TARGET_ISO15693_DSFID,
NFC_ATTR_TARGET_ISO15693_UID,
+ NFC_ATTR_SE_PARAMS,
+ NFC_ATTR_VENDOR_ID,
+ NFC_ATTR_VENDOR_SUBCMD,
+ NFC_ATTR_VENDOR_DATA,
/* private: internal use only */
__NFC_ATTR_AFTER_LAST
};
@@ -197,15 +210,19 @@ enum nfc_sdp_attr {
};
#define NFC_SDP_ATTR_MAX (__NFC_SDP_ATTR_AFTER_LAST - 1)

-#define NFC_DEVICE_NAME_MAXSIZE 8
-#define NFC_NFCID1_MAXSIZE 10
-#define NFC_NFCID2_MAXSIZE 8
-#define NFC_NFCID3_MAXSIZE 10
-#define NFC_SENSB_RES_MAXSIZE 12
-#define NFC_SENSF_RES_MAXSIZE 18
-#define NFC_GB_MAXSIZE 48
-#define NFC_FIRMWARE_NAME_MAXSIZE 32
-#define NFC_ISO15693_UID_MAXSIZE 8
+#define NFC_DEVICE_NAME_MAXSIZE 8
+#define NFC_NFCID1_MAXSIZE 10
+#define NFC_NFCID2_MAXSIZE 8
+#define NFC_NFCID3_MAXSIZE 10
+#define NFC_SENSB_RES_MAXSIZE 12
+#define NFC_SENSF_RES_MAXSIZE 18
+#define NFC_ATR_REQ_MAXSIZE 64
+#define NFC_ATR_RES_MAXSIZE 64
+#define NFC_ATR_REQ_GB_MAXSIZE 48
+#define NFC_ATR_RES_GB_MAXSIZE 47
+#define NFC_GB_MAXSIZE 48
+#define NFC_FIRMWARE_NAME_MAXSIZE 32
+#define NFC_ISO15693_UID_MAXSIZE 8

/* NFC protocols */
#define NFC_PROTO_JEWEL 1
@@ -274,11 +291,19 @@ struct sockaddr_nfc_llcp {
* First byte is the adapter index
* Second byte contains flags
* - 0x01 - Direction (0=RX, 1=TX)
- * - 0x02-0x80 - Reserved
+ * - 0x02-0x04 - Payload type (000=LLCP, 001=NCI, 010=HCI, 011=Digital,
+ * 100=Proprietary)
+ * - 0x05-0x80 - Reserved
**/
-#define NFC_LLCP_RAW_HEADER_SIZE 2
-#define NFC_LLCP_DIRECTION_RX 0x00
-#define NFC_LLCP_DIRECTION_TX 0x01
+#define NFC_RAW_HEADER_SIZE 2
+#define NFC_DIRECTION_RX 0x00
+#define NFC_DIRECTION_TX 0x01
+
+#define RAW_PAYLOAD_LLCP 0
+#define RAW_PAYLOAD_NCI 1
+#define RAW_PAYLOAD_HCI 2
+#define RAW_PAYLOAD_DIGITAL 3
+#define RAW_PAYLOAD_PROPRIETARY 4

/* socket option names */
#define NFC_LLCP_RW 0
diff --git a/tools/nfctool/llcp-decode.c b/tools/nfctool/llcp-decode.c
index 7f95640..13e7ba7 100644
--- a/tools/nfctool/llcp-decode.c
+++ b/tools/nfctool/llcp-decode.c
@@ -189,7 +189,7 @@ static void llcp_check_cc(struct sniffer_packet *packet)
return;

/* Find the real destination SAP for this CC */
- if (packet->direction == NFC_LLCP_DIRECTION_RX)
+ if (packet->direction == NFC_DIRECTION_RX)
dsap = packet->llcp.local_sap;
else
dsap = packet->llcp.remote_sap;
@@ -308,7 +308,7 @@ static int llcp_decode_packet(guint8 *data, guint32 data_len,
packet->direction = data[1] & 0x01;

/* LLCP header */
- if (packet->direction == NFC_LLCP_DIRECTION_TX) {
+ if (packet->direction == NFC_DIRECTION_TX) {
packet->llcp.remote_sap = (data[2] & 0xFC) >> 2;
packet->llcp.local_sap = data[3] & 0x3F;
} else {
@@ -379,20 +379,20 @@ static int llcp_print_agf(struct sniffer_packet *packet,
goto exit;
}

- if (size + NFC_LLCP_RAW_HEADER_SIZE > pdu_size) {
- pdu_size = size + NFC_LLCP_RAW_HEADER_SIZE;
+ if (size + NFC_RAW_HEADER_SIZE > pdu_size) {
+ pdu_size = size + NFC_RAW_HEADER_SIZE;
pdu = g_realloc(pdu, pdu_size);

pdu[0] = packet->adapter_idx;
pdu[1] = packet->direction;
}

- memcpy(pdu + NFC_LLCP_RAW_HEADER_SIZE,
+ memcpy(pdu + NFC_RAW_HEADER_SIZE,
packet->llcp.data + offset, size);

llcp_printf_msg("-- AGF LLC PDU %02u:", count++);

- llcp_print_pdu(pdu, size + NFC_LLCP_RAW_HEADER_SIZE, timestamp);
+ llcp_print_pdu(pdu, size + NFC_RAW_HEADER_SIZE, timestamp);

offset += size;
}
@@ -530,7 +530,7 @@ int llcp_print_pdu(guint8 *data, guint32 data_len, struct timeval *timestamp)
if (!opts.dump_symm && packet.llcp.ptype == LLCP_PTYPE_SYMM)
return 0;

- if (packet.direction == NFC_LLCP_DIRECTION_RX) {
+ if (packet.direction == NFC_DIRECTION_RX) {
direction_str = ">>";
direction_color = COLOR_RED;
} else {
diff --git a/tools/nfctool/snep-decode.c b/tools/nfctool/snep-decode.c
index bee06e5..6168c15 100644
--- a/tools/nfctool/snep-decode.c
+++ b/tools/nfctool/snep-decode.c
@@ -96,10 +96,10 @@ static void snep_frag_rejected(struct sniffer_packet *packet)
guint8 direction;

/* reverse direction to delete the corresponding fragment */
- if (packet->direction == NFC_LLCP_DIRECTION_RX)
- direction = NFC_LLCP_DIRECTION_TX;
+ if (packet->direction == NFC_DIRECTION_RX)
+ direction = NFC_DIRECTION_TX;
else
- direction = NFC_LLCP_DIRECTION_RX;
+ direction = NFC_DIRECTION_RX;

index = snep_make_frag_index(packet->adapter_idx,
direction,
@@ -129,7 +129,7 @@ static int snep_frag_append(struct snep_frag *frag,
frag->count++;

snep_printf_msg("%s fragment #%hu of %u bytes (total %u/%u)",
- packet->direction == NFC_LLCP_DIRECTION_RX ? "Received" : "Sent",
+ packet->direction == NFC_DIRECTION_RX ? "Received" : "Sent",
frag->count, packet->llcp.data_len,
frag->received, frag->buffer_size);

@@ -177,11 +177,11 @@ static int snep_decode_info(struct sniffer_packet *packet)
frag->index = snep_get_frag_index(packet);

snep_printf_msg("Start %s fragmented message of %u bytes",
- packet->direction == NFC_LLCP_DIRECTION_RX ? "Receiving" : "Sending",
+ packet->direction == NFC_DIRECTION_RX ? "Receiving" : "Sending",
frag->buffer_size);

snep_printf_msg("%s fragment #%hu of %u bytes",
- packet->direction == NFC_LLCP_DIRECTION_RX ? "Received" : "Sent",
+ packet->direction == NFC_DIRECTION_RX ? "Received" : "Sent",
frag->count, frag->received);

DBG("Adding frag with index 0x%x", frag->index);
--
2.13.0

2017-06-15 18:25:28

by Mark Greer

[permalink] [raw]
Subject: [PATCH 22/23] nfctools: Move nciattach macros & enums to nciattach.c

Some header file macros and an enum were copied from Linux and placed
in neard's include/nfc_copy.h file. That isn't the proper place as
nfc_copy.h is supposed to be a pristine copy of the Linux nfc.h file.
Move those header file definitions into tools/nciattach.c since that
is the only file that uses them.

Signed-off-by: Mark Greer <[email protected]>
---
include/nfc_copy.h | 12 ------------
tools/nciattach.c | 12 ++++++++++++
2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/nfc_copy.h b/include/nfc_copy.h
index 9e21738..0b25f5c 100644
--- a/include/nfc_copy.h
+++ b/include/nfc_copy.h
@@ -287,16 +287,4 @@ struct sockaddr_nfc_llcp {
#define NFC_LLCP_REMOTE_LTO 3
#define NFC_LLCP_REMOTE_RW 4

-#ifndef N_NCI
-#define N_NCI 25
-#endif
-
-/* Ioctl */
-#define NCIUARTSETDRIVER _IOW('U', 0, char *)
-
-enum nci_uart_driver {
- NCI_UART_DRIVER_MARVELL = 0,
- NCI_UART_DRIVER_MAX
-};
-
#endif /*__LINUX_NFC_H */
diff --git a/tools/nciattach.c b/tools/nciattach.c
index c71d9c7..370f98b 100644
--- a/tools/nciattach.c
+++ b/tools/nciattach.c
@@ -50,6 +50,18 @@
#define ENABLE_PM 1
#define DISABLE_PM 0

+#ifndef N_NCI
+#define N_NCI 25
+#endif
+
+/* Ioctl */
+#define NCIUARTSETDRIVER _IOW('U', 0, char *)
+
+enum nci_uart_driver {
+ NCI_UART_DRIVER_MARVELL = 0,
+ NCI_UART_DRIVER_MAX
+};
+
struct nci_driver_info {
const char *name;
enum nci_uart_driver driver_id;
--
2.13.0

2017-06-15 18:25:30

by Mark Greer

[permalink] [raw]
Subject: [PATCH 05/23] ndef: Discard records containing errors

Currently, near_ndef_parse_msg() adds records even when they contain
erroneous record types. This can later cause neard to exit when it
tries to signal dbus with incomplete record information. Avoid this
by ignoring records that contain bad record types (and all of the
records that follow in the same NDEF message).

Signed-off-by: Mark Greer <[email protected]>
---
src/ndef.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/ndef.c b/src/ndef.c
index 7a3c76b..38dcf72 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -2845,7 +2845,6 @@ GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length,
case RECORD_TYPE_WKT_COLLISION_RESOLUTION:
case RECORD_TYPE_WKT_ERROR:
case RECORD_TYPE_UNKNOWN:
- case RECORD_TYPE_ERROR:
break;

case RECORD_TYPE_WKT_HANDOVER_REQUEST:
@@ -2927,6 +2926,8 @@ GList *near_ndef_parse_msg(uint8_t *ndef_data, size_t ndef_length,
goto fail;

break;
+ case RECORD_TYPE_ERROR:
+ goto fail;
}

record->data_len = record->header->header_len +
--
2.13.0

2017-06-15 18:25:30

by Mark Greer

[permalink] [raw]
Subject: [PATCH 09/23] adapter: Clear timeout handle when check presence timer stopped

__near_adapter_stop_check_presence() stops the neard check presence
timer but doesn't clear the timer handle. This can cause neard to
try to stop the timer when it isn't running. To fix that, clear the
handle so neard doesn't try to stop an already stopped timer.

Signed-off-by: Mark Greer <[email protected]>
---
src/adapter.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 466753b..7be87e2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -505,8 +505,10 @@ void __near_adapter_stop_check_presence(uint32_t adapter_idx,
if (!adapter)
return;

- if (adapter->presence_timeout > 0)
+ if (adapter->presence_timeout > 0) {
g_source_remove(adapter->presence_timeout);
+ adapter->presence_timeout = 0;
+ }
}

static const GDBusMethodTable adapter_methods[] = {
--
2.13.0

2017-06-15 18:25:31

by Mark Greer

[permalink] [raw]
Subject: [PATCH 21/23] nfctype5: Fix formatting

Use the output of the Linux kernel's 'Lindent' script to format
the code in nfctype5.c. Some of the formatting performed by
Lindent was overridden for various reasons. These include:
- no space between '__attribute__' and '((packed))' to match
other tag files
- struct members names are aligned when defined for readability
- compile-time init of struct members are aligned for readability
- call arguments not lined up when result would cause lines with
more than 80 characters
- no spaces around ampersand when casting address of a variable
- no space between '*' and name in declarations/definitions

Signed-off-by: Mark Greer <[email protected]>
---
plugins/nfctype5.c | 118 ++++++++++++++++++++++++++---------------------------
1 file changed, 58 insertions(+), 60 deletions(-)

diff --git a/plugins/nfctype5.c b/plugins/nfctype5.c
index d6eec3c..3d2cdf0 100644
--- a/plugins/nfctype5.c
+++ b/plugins/nfctype5.c
@@ -262,14 +262,14 @@ static bool t5_tag_is_ti_pro(struct near_tag *tag)
}

static int t5_cmd_hdr_init(struct near_tag *tag, struct type5_cmd_hdr *cmd_hdr,
- int cmd)
+ int cmd)
{
uint8_t *uid;

DBG("");

uid = near_tag_get_iso15693_uid(near_tag_get_adapter_idx(tag),
- near_tag_get_target_idx(tag));
+ near_tag_get_target_idx(tag));
if (!uid) {
near_error("No type 5 UID");
return -EINVAL;
@@ -287,7 +287,7 @@ static int t5_cmd_hdr_init(struct near_tag *tag, struct type5_cmd_hdr *cmd_hdr,
static int t5_check_resp(uint8_t *resp, int length)
{
struct type5_err_resp *t5_err_resp =
- (struct type5_err_resp *)(resp + NFC_HEADER_SIZE);
+ (struct type5_err_resp *)(resp + NFC_HEADER_SIZE);
int err = 0;

DBG("");
@@ -304,7 +304,7 @@ static int t5_check_resp(uint8_t *resp, int length)
if (t5_err_resp->flags & RESP_FLAG_ERR) {
if (length == 2)
near_error("Tag failure: 0x%x",
- t5_err_resp->err_code);
+ t5_err_resp->err_code);
else
near_error("Tag failure: Cause unknown");

@@ -339,7 +339,7 @@ static int t5_cookie_release(int err, void *data)

else if (cookie->cb)
cookie->cb(near_tag_get_adapter_idx(cookie->tag),
- near_tag_get_target_idx(cookie->tag), err);
+ near_tag_get_target_idx(cookie->tag), err);

if (cookie->ndef) {
g_free(cookie->ndef->data);
@@ -375,7 +375,7 @@ static int t5_cookie_release_local(int err, void *data)
static int t5_read_resp(uint8_t *resp, int length, void *data)
{
struct type5_read_single_block_resp *t5_resp =
- (struct type5_read_single_block_resp *)(resp + NFC_HEADER_SIZE);
+ (struct type5_read_single_block_resp *)(resp + NFC_HEADER_SIZE);
struct type5_read_single_block_cmd t5_cmd;
struct t5_cookie *cookie = data;
struct near_tag *tag = cookie->tag;
@@ -400,7 +400,7 @@ static int t5_read_resp(uint8_t *resp, int length, void *data)
length = MIN(length, (int)cookie->bytes_left);

memcpy(&cookie->buf[cookie->dst_offset],
- &t5_resp->data[cookie->src_offset], length);
+ &t5_resp->data[cookie->src_offset], length);

if (cookie->bytes_left <= blk_size)
goto out_done;
@@ -417,8 +417,8 @@ static int t5_read_resp(uint8_t *resp, int length, void *data)
t5_cmd.blk_no = cookie->blk;

return near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)&t5_cmd, sizeof(t5_cmd), t5_read_resp,
- cookie, t5_cookie_release_local);
+ (uint8_t *)&t5_cmd, sizeof(t5_cmd),
+ t5_read_resp, cookie, t5_cookie_release_local);

out_done:
DBG("Done reading: %d", err);
@@ -427,7 +427,7 @@ out_done:
}

static int t5_read(struct near_tag *tag, uint8_t offset, uint8_t *buf,
- size_t len, t5_local_cb local_cb, void *local_data)
+ size_t len, t5_local_cb local_cb, void *local_data)
{
struct type5_read_single_block_cmd t5_cmd;
struct t5_cookie *cookie;
@@ -455,15 +455,15 @@ static int t5_read(struct near_tag *tag, uint8_t offset, uint8_t *buf,
cookie->blk = t5_cmd.blk_no;

return near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)&t5_cmd, sizeof(t5_cmd), t5_read_resp,
- cookie, t5_cookie_release_local);
+ (uint8_t *)&t5_cmd, sizeof(t5_cmd),
+ t5_read_resp, cookie, t5_cookie_release_local);
}

static int t5_write_resp(uint8_t *resp, int length, void *data)
{
struct type5_write_single_block_resp *t5_resp =
- (struct type5_write_single_block_resp *)
- (resp + NFC_HEADER_SIZE);
+ (struct type5_write_single_block_resp *)
+ (resp + NFC_HEADER_SIZE);
struct type5_write_single_block_cmd *t5_cmd = NULL;
struct t5_cookie *cookie = data;
struct near_tag *tag = cookie->tag;
@@ -497,8 +497,7 @@ static int t5_write_resp(uint8_t *resp, int length, void *data)
goto out_done;
}

- err = t5_cmd_hdr_init(tag, &t5_cmd->hdr,
- CMD_WRITE_SINGLE_BLOCK);
+ err = t5_cmd_hdr_init(tag, &t5_cmd->hdr, CMD_WRITE_SINGLE_BLOCK);
if (err)
goto out_done;

@@ -510,8 +509,8 @@ static int t5_write_resp(uint8_t *resp, int length, void *data)
memcpy(t5_cmd->data, &cookie->buf[cookie->src_offset], blk_size);

err = near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)t5_cmd, sizeof(*t5_cmd) + blk_size,
- t5_write_resp, cookie, t5_cookie_release_local);
+ (uint8_t *) t5_cmd, sizeof(*t5_cmd) + blk_size,
+ t5_write_resp, cookie, t5_cookie_release_local);

g_free(t5_cmd);
return err;
@@ -526,7 +525,7 @@ out_done:
}

static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
- size_t len, t5_local_cb local_cb, void *local_data)
+ size_t len, t5_local_cb local_cb, void *local_data)
{
struct type5_write_single_block_cmd *t5_cmd;
struct t5_cookie *cookie;
@@ -537,7 +536,7 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,

if (offset % blk_size) {
near_error("Write - Invalid offset - offset: %d, blk_size: %d",
- offset, blk_size);
+ offset, blk_size);
return -EINVAL;
}

@@ -582,8 +581,8 @@ static int t5_write(struct near_tag *tag, uint8_t offset, uint8_t *buf,
cookie->blk = t5_cmd->blk_no;

err = near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)t5_cmd, sizeof(*t5_cmd) + blk_size,
- t5_write_resp, cookie, t5_cookie_release_local);
+ (uint8_t *) t5_cmd, sizeof(*t5_cmd) + blk_size,
+ t5_write_resp, cookie, t5_cookie_release_local);

out_err:
g_free(t5_cmd);
@@ -624,10 +623,9 @@ static bool t5_cc_is_valid(struct type5_cc *t5_cc)
bool valid = false;

if ((t5_cc->cc0 == TYPE5_CC0_NDEF_MAGIC) &&
- (TYPE5_CC1_VER_GET_MAJOR(t5_cc->cc1) ==
- TYPE5_VERSION_MAJOR) &&
- (TYPE5_CC1_VER_GET_MINOR(t5_cc->cc1) ==
- TYPE5_VERSION_MINOR))
+ (TYPE5_CC1_VER_GET_MAJOR(t5_cc->cc1) ==
+ TYPE5_VERSION_MAJOR) &&
+ (TYPE5_CC1_VER_GET_MINOR(t5_cc->cc1) == TYPE5_VERSION_MINOR))
valid = true;

return valid;
@@ -641,14 +639,14 @@ static size_t t5_cc_get_data_length(struct type5_cc *t5_cc)
static bool t5_cc_is_read_only(struct type5_cc *t5_cc)
{
return (t5_cc->cc1 & TYPE5_CC1_WRITE_ACCESS_MASK) !=
- TYPE5_CC1_WRITE_ACCESS_ALWAYS;
+ TYPE5_CC1_WRITE_ACCESS_ALWAYS;
}

static int t5_read_multiple_blocks_resp(uint8_t *resp, int length, void *data)
{
struct type5_read_multiple_blocks_resp *t5_resp =
- (struct type5_read_multiple_blocks_resp *)
- (resp + NFC_HEADER_SIZE);
+ (struct type5_read_multiple_blocks_resp *)
+ (resp + NFC_HEADER_SIZE);
struct t5_cookie *cookie = data;
struct near_tag *tag = cookie->tag;
uint8_t blk_size = near_tag_get_blk_size(tag);
@@ -666,7 +664,7 @@ static int t5_read_multiple_blocks_resp(uint8_t *resp, int length, void *data)

length -= NFC_HEADER_SIZE;
expected_len = sizeof(*t5_resp) +
- cookie->nb_requested_blocks * blk_size;
+ cookie->nb_requested_blocks * blk_size;

/*
* Sometimes an extra byte is returned in RMB response data.
@@ -692,8 +690,7 @@ out_done:
static int t5_read_multiple_blocks(struct near_tag *tag,
uint8_t starting_block,
uint8_t number_of_blocks,
- near_recv rx_cb,
- struct t5_cookie *cookie)
+ near_recv rx_cb, struct t5_cookie *cookie)
{
struct type5_read_multiple_blocks_cmd t5_cmd;
int err;
@@ -708,8 +705,8 @@ static int t5_read_multiple_blocks(struct near_tag *tag,
t5_cmd.num_blks = number_of_blocks - 1;

return near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)&t5_cmd, sizeof(t5_cmd),
- rx_cb, cookie, t5_cookie_release);
+ (uint8_t *)&t5_cmd, sizeof(t5_cmd),
+ rx_cb, cookie, t5_cookie_release);
}

static int t5_read_meta_resp(struct near_tag *tag, int err, void *data)
@@ -730,11 +727,11 @@ static int t5_read_meta_resp(struct near_tag *tag, int err, void *data)

if (t5_cc_is_valid(t5_cc)) {
data_length = t5_cc_get_data_length(t5_cc) -
- TYPE5_DATA_START_OFFSET(tag);
+ TYPE5_DATA_START_OFFSET(tag);

err = near_tag_add_data(near_tag_get_adapter_idx(tag),
- near_tag_get_target_idx(tag), NULL,
- data_length);
+ near_tag_get_target_idx(tag), NULL,
+ data_length);
if (err)
goto out_err;

@@ -757,13 +754,13 @@ static int t5_read_meta_resp(struct near_tag *tag, int err, void *data)

if (rmb_supported) {
first_block = TYPE5_DATA_START_OFFSET(tag) /
- near_tag_get_blk_size(tag);
+ near_tag_get_blk_size(tag);
cookie->nb_requested_blocks =
- near_tag_get_num_blks(tag) - first_block;
+ near_tag_get_num_blks(tag) - first_block;
err = t5_read_multiple_blocks(tag, first_block,
- cookie->nb_requested_blocks,
- t5_read_multiple_blocks_resp,
- cookie);
+ cookie->nb_requested_blocks,
+ t5_read_multiple_blocks_resp,
+ cookie);
} else {
err = t5_read(tag, TYPE5_DATA_START_OFFSET(tag),
tag_data, data_length, t5_read_data_resp,
@@ -798,7 +795,7 @@ static int t5_read_meta(struct near_tag *tag, struct t5_cookie *cookie)
cookie->buf = buf;

err = t5_read(tag, TYPE5_META_START_OFFSET, buf, TYPE5_LEN_CC_BYTES,
- t5_read_meta_resp, cookie);
+ t5_read_meta_resp, cookie);
if (err < 0)
g_free(buf);

@@ -808,7 +805,7 @@ static int t5_read_meta(struct near_tag *tag, struct t5_cookie *cookie)
static int t5_get_sys_info_resp(uint8_t *resp, int length, void *data)
{
struct type5_get_system_info_resp *t5_resp =
- (struct type5_get_system_info_resp *)(resp + NFC_HEADER_SIZE);
+ (struct type5_get_system_info_resp *)(resp + NFC_HEADER_SIZE);
struct t5_cookie *cookie = data;
struct near_tag *tag = cookie->tag;
uint8_t offset = 0;
@@ -824,7 +821,7 @@ static int t5_get_sys_info_resp(uint8_t *resp, int length, void *data)

if (length < (int)sizeof(*t5_resp)) {
near_error("Get System Info - Invalid response - length: %d",
- length);
+ length);
err = -EIO;
goto out_err;
}
@@ -838,13 +835,14 @@ static int t5_get_sys_info_resp(uint8_t *resp, int length, void *data)
if (t5_resp->info_flags & GET_SYS_INFO_FLAG_MEM_SIZE) {
if (t5_resp->info_flags & GET_SYS_INFO_FLAG_16B_NB_BLOCK) {
near_tag_set_num_blks(tag, (t5_resp->data[offset] |
- (t5_resp->data[offset + 1] << 8)) + 1);
+ (t5_resp->data[offset + 1]
+ << 8)) + 1);
offset += 2;
} else
near_tag_set_num_blks(tag, t5_resp->data[offset++] + 1);
near_tag_set_blk_size(tag,
- (t5_resp->data[offset++] & 0x1f) + 1);
- } else { /* Tag must provide memory size info */
+ (t5_resp->data[offset++] & 0x1f) + 1);
+ } else { /* Tag must provide memory size info */
err = -EIO;
goto out_err;
}
@@ -870,12 +868,12 @@ static int t5_get_sys_info(struct near_tag *tag, struct t5_cookie *cookie)
return err;

return near_adapter_send(near_tag_get_adapter_idx(tag),
- (uint8_t *)&t5_cmd, sizeof(t5_cmd),
- t5_get_sys_info_resp, cookie, NULL);
+ (uint8_t *)&t5_cmd, sizeof(t5_cmd),
+ t5_get_sys_info_resp, cookie, NULL);
}

static int nfctype5_read(uint32_t adapter_idx, uint32_t target_idx,
- near_tag_io_cb cb)
+ near_tag_io_cb cb)
{
struct t5_cookie *cookie;
struct near_tag *tag;
@@ -942,7 +940,7 @@ static int nfctype5_write_resp(struct near_tag *tag, int err, void *data)
}

static int nfctype5_write(uint32_t adapter_idx, uint32_t target_idx,
- struct near_ndef_message *ndef, near_tag_io_cb cb)
+ struct near_ndef_message *ndef, near_tag_io_cb cb)
{
struct t5_cookie *cookie;
struct near_tag *tag;
@@ -966,8 +964,8 @@ static int nfctype5_write(uint32_t adapter_idx, uint32_t target_idx,
cookie->ndef = ndef;

err = t5_write(tag, TYPE5_DATA_START_OFFSET(tag),
- ndef->data + ndef->offset, ndef->length,
- nfctype5_write_resp, cookie);
+ ndef->data + ndef->offset, ndef->length,
+ nfctype5_write_resp, cookie);
if (err < 0)
err = t5_cookie_release(err, cookie);

@@ -981,7 +979,7 @@ out_err:
}

static int nfctype5_check_presence_resp(struct near_tag *tag, int err,
- void *data)
+ void *data)
{
struct t5_cookie *cookie = data;

@@ -993,7 +991,7 @@ static int nfctype5_check_presence_resp(struct near_tag *tag, int err,
}

static int nfctype5_check_presence(uint32_t adapter_idx, uint32_t target_idx,
- near_tag_io_cb cb)
+ near_tag_io_cb cb)
{
struct t5_cookie *cookie;
struct near_tag *tag;
@@ -1056,7 +1054,7 @@ static int nfctype5_format_resp(struct near_tag *tag, int err, void *data)
}

static int nfctype5_format(uint32_t adapter_idx, uint32_t target_idx,
- near_tag_io_cb cb)
+ near_tag_io_cb cb)
{
struct type5_cc t5_cc;
struct t5_cookie *cookie;
@@ -1118,7 +1116,7 @@ static int nfctype5_format(uint32_t adapter_idx, uint32_t target_idx,
t5_cc.cc3 = 0;

err = t5_write(tag, TYPE5_META_START_OFFSET, (uint8_t *)&t5_cc,
- sizeof(t5_cc), nfctype5_format_resp, cookie);
+ sizeof(t5_cc), nfctype5_format_resp, cookie);
if (err < 0)
err = t5_cookie_release(err, cookie);

@@ -1136,7 +1134,7 @@ static struct near_tag_driver type5_driver = {
.priority = NEAR_TAG_PRIORITY_DEFAULT,
.read = nfctype5_read,
.write = nfctype5_write,
- .check_presence = nfctype5_check_presence,
+ .check_presence = nfctype5_check_presence,
.format = nfctype5_format,
};

@@ -1155,4 +1153,4 @@ static void nfctype5_exit(void)
}

NEAR_PLUGIN_DEFINE(nfctype5, "ISO 15693 (NFC Type 5) tags support", VERSION,
- NEAR_PLUGIN_PRIORITY_HIGH, nfctype5_init, nfctype5_exit)
+ NEAR_PLUGIN_PRIORITY_HIGH, nfctype5_init, nfctype5_exit)
--
2.13.0

2017-07-25 18:22:33

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 00/23] neard: Support TI Std & Pro tags, fixups, etc.

On Thu, Jun 15, 2017 at 11:24:53AM -0700, Mark Greer wrote:
> This is an assortment of commits that make some fixups, do some general
> tightening of NDEF data checking, add support for TI Standard and Pro
> Type 5 tags, and stop issuing the Read Multiple Blocks command when
> formatting a Type 5 tag. The reasoning for each change is in the
> individual commit descriptions.
>
> For convenience, a branch with these commits is available in the
> submit/updates-v1 branch here:
>
> https://github.com/animalcreek/neard.git
>
> Mark Greer (23):
> ndef: Add default language ("en") for Text records
> ndef: Fix use of uninitialized variable in property_get_type()
> ndef: Unrecognized WKTs should return RECORD_TYPE_UNKNOWN
> ndef: Verify RTD record type name encodings
> ndef: Discard records containing errors
> ndef: Validate text data in WKT Text records
> adapter: Return '-errno' when socket() call fails
> adapter: Return '-errno' when connect() call fails
> adapter: Clear timeout handle when check presence timer stopped
> adapter: Clear timer handle when DEP timer stopped
> adapter: Do not poll when there is an active tag
> nfctype2: Don't read tags with bad magic number
> nfctype5: Reduce noise when tag is moved out of range
> nfctype5: Add space between 'if' and first '('
> nfctype5: Remove superfluous parentheses
> nfctype5: Rework code that identifies ST Micro Type 5 tags
> nfctype5: Add support for TI Standard and Pro Type 5 tag
> nfctype5: Remove useless initialization
> nfctype5: Don't issue RMB command when formatting
> nfctype5: Discard extra byte in RMB response data
> nfctype5: Fix formatting
> nfctools: Move nciattach macros & enums to nciattach.c
> nfc_copy: Update nfc_copy.h to match Linux kernel's version
>
> include/nfc_copy.h | 63 +++++----
> plugins/nfctype2.c | 1 +
> plugins/nfctype5.c | 320 ++++++++++++++++++++++++--------------------
> src/adapter.c | 15 ++-
> src/ndef.c | 43 +++++-
> tools/nciattach.c | 12 ++
> tools/nfctool/llcp-decode.c | 14 +-
> tools/nfctool/snep-decode.c | 12 +-
> 8 files changed, 290 insertions(+), 190 deletions(-)

Ping?

2017-11-09 23:26:29

by Samuel Ortiz

[permalink] [raw]
Subject: Re: [PATCH 00/23] neard: Support TI Std & Pro tags, fixups, etc.

Hi Mark,

On Thu, Jun 15, 2017 at 11:24:53AM -0700, Mark Greer wrote:
> This is an assortment of commits that make some fixups, do some general
> tightening of NDEF data checking, add support for TI Standard and Pro
> Type 5 tags, and stop issuing the Read Multiple Blocks command when
> formatting a Type 5 tag. The reasoning for each change is in the
> individual commit descriptions.
>
> For convenience, a branch with these commits is available in the
> submit/updates-v1 branch here:
>
> https://github.com/animalcreek/neard.git
Applied, thanks.

Cheers,
Samuel.