Skip to content

Commit

Permalink
[core] Don't select NDEF application on Type 4 tags. JB#48413
Browse files Browse the repository at this point in the history
Until NDEF support is actually implemented for Type 4 tags, we better
leave the default application selected.
  • Loading branch information
monich committed Dec 21, 2019
1 parent 80002ca commit 6469fff
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 96 deletions.
71 changes: 12 additions & 59 deletions core/src/nfc_tag_t4.c
Expand Up @@ -45,7 +45,6 @@ typedef struct nfc_isodep_tx {
struct nfc_tag_t4_priv {
guint mtu; /* FSC (Type 4A) or FSD (Type 4B) */
GByteArray* buf;
NfcTargetSequence* init_seq;
guint init_id;
};

Expand Down Expand Up @@ -262,49 +261,6 @@ nfc_isodep_submit(
return 0;
}

static
void
nfc_tag_t4_initialized(
NfcTagType4* self)
{
NfcTagType4Priv* priv = self->priv;
NfcTag* tag = &self->tag;

nfc_target_sequence_unref(priv->init_seq);
priv->init_seq = NULL;
nfc_tag_set_initialized(tag);
}

static
void
nfc_tag_t4_init_select_ndef_app_resp(
NfcTagType4* self,
guint sw,
const void* data,
guint len,
void* user_data)
{
/*
* NFCForum-TS-Type-4-Tag_2.0
* Table 12: NDEF Tag Application Select -
* Detailed R-APDU Field Description
*
* 90h 00h Command completed
* 6Ah 82h NDEF Tag Application not found
*/
if (sw == ISO_SW_OK) {
GDEBUG("NDEF Tag Application selected");
#pragma message("TODO: Read NDEF")
} else if (sw == 0x6a82) {
GDEBUG("NDEF Tag Application not found");
} else if (sw != ISO_SW_IO_ERR) {
GDEBUG("NDEF Tag Application selection error %04X", sw);
} else {
GDEBUG("NDEF Tag Application selection I/O error");
}
nfc_tag_t4_initialized(self);
}

/*==========================================================================*
* Internal interface
*==========================================================================*/
Expand All @@ -315,24 +271,22 @@ nfc_tag_t4_init_base(
NfcTarget* target,
guint mtu)
{
static const guint8 ndef_app_path[] = {
0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
};

NfcTagType4Priv* priv = self->priv;
GUtilData data;

nfc_tag_init_base(&self->tag, target);
priv->mtu = mtu;
priv->init_seq = nfc_target_sequence_new(target);

/* Start init sequence (i.e. read CC file) */
data.bytes = ndef_app_path;
data.size = sizeof(ndef_app_path);
priv->init_id = nfc_isodep_submit(self, ISO_CLA, ISO_INS_SELECT,
ISO_P1_SELECT_DF_BY_NAME, ISO_P2_SELECT_FILE_FIRST,
&data, 0x100, priv->init_seq, nfc_tag_t4_init_select_ndef_app_resp,
NULL, NULL);

/*
* For more information in NDEF application and fetching NDEF
* from a Type 4 tag, see NFCForum-TS-Type-4-Tag_2.0 section
* 5.1 NDEF Management.
*
* Better leave the default application selected and ignore this
* NDEF stuff for now until this feature is requested and even more
* importantly we have a real card to test against.
*/
#pragma message("TODO: Read NDEF")
nfc_tag_set_initialized(&self->tag);
}

/*==========================================================================*
Expand Down Expand Up @@ -382,7 +336,6 @@ nfc_tag_t4_finalize(
NfcTagType4Priv* priv = self->priv;

nfc_target_cancel_transmit(self->tag.target, priv->init_id);
nfc_target_sequence_unref(priv->init_seq);
g_byte_array_free(priv->buf, TRUE);
G_OBJECT_CLASS(nfc_tag_t4_parent_class)->finalize(object);
}
Expand Down
95 changes: 58 additions & 37 deletions unit/core_tag_t4/test_core_tag_t4.c
Expand Up @@ -238,15 +238,6 @@ test_null(
* basic_a
*==========================================================================*/

static
void
test_basic_exit(
NfcTag* tag,
void* user_data)
{
g_main_loop_quit((GMainLoop*)user_data);
}

static
void
test_basic_a(
Expand All @@ -257,18 +248,18 @@ test_basic_a(
NfcParamIsoDepPollA iso_dep_poll_a;
NfcTagType4* t4a;
NfcTag* tag;
gulong id;

memset(&iso_dep_poll_a, 0, sizeof(iso_dep_poll_a));
iso_dep_poll_a.fsc = 256;
t4a = NFC_TAG_T4(nfc_tag_t4a_new(target, NULL, &iso_dep_poll_a));
g_assert(NFC_IS_TAG_T4A(t4a));
tag = &t4a->tag;

/* Just let transmit fail... */
id = nfc_tag_add_initialized_handler(tag, test_basic_exit, loop);
test_run(&test_opt, loop);
nfc_tag_remove_handler(tag, id);
/*
* As of now it gets initialized immediately. If we start supporting
* NDEF application, this process will become asynchronous.
*/
g_assert(tag->flags & NFC_TAG_FLAG_INITIALIZED);

nfc_tag_unref(tag);
nfc_target_unref(target);
Expand All @@ -290,21 +281,18 @@ test_basic_init(
NfcParamPollB poll_b;
NfcTagType4* t4b;
NfcTag* tag;
gulong id;

test_target_add_cmd(TEST_TARGET(target),
TEST_ARRAY_AND_SIZE(test_cmd_select_ndef),
resp, resp_len);

memset(&poll_b, 0, sizeof(poll_b));
poll_b.fsc = 0x0b; /* i.e. 256 */
t4b = NFC_TAG_T4(nfc_tag_t4b_new(target, &poll_b, NULL));
g_assert(NFC_IS_TAG_T4B(t4b));
tag = &t4b->tag;

id = nfc_tag_add_initialized_handler(tag, test_basic_exit, loop);
test_run(&test_opt, loop);
nfc_tag_remove_handler(tag, id);
/*
* As of now it gets initialized immediately. If we start supporting
* NDEF application, this process will become asynchronous.
*/
g_assert(tag->flags & NFC_TAG_FLAG_INITIALIZED);

nfc_tag_unref(tag);
nfc_target_unref(target);
Expand Down Expand Up @@ -386,10 +374,18 @@ typedef struct test_apdu_data {
GUtilData expected;
} TestApduData;

static const guint8 mf_path[] = {
0x3f, 0x00
};

static const guint8 select_mf_expected[] = {
0x00, 0xa4, 0x00, 0x00
};

static const guint8 select_mf_full_expected[] = {
0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00
};

static const guint8 read_256_expected[] = {
0x00, 0xb0, 0x00, 0x00, 0x00
};
Expand All @@ -405,6 +401,9 @@ static const guint8 read_65536_expected[] = {
static const TestApduData apdu_tests[] = {
{ "select_mf", 0x00, 0xa4, 0x00, 0x00, { NULL, 0 }, 0,
{ TEST_ARRAY_AND_SIZE(select_mf_expected) } },
{ "select_mf_full", 0x00, 0xa4, 0x00, 0x00,
{ TEST_ARRAY_AND_SIZE(mf_path) }, 0,
{ TEST_ARRAY_AND_SIZE(select_mf_full_expected) } },
{ "read_256", 0x00, 0xb0, 0x00, 0x00, { NULL, 0 }, 256,
{ TEST_ARRAY_AND_SIZE(read_256_expected) } },
{ "read_257", 0x00, 0xb0, 0x00, 0x00, { NULL, 0 }, 257,
Expand Down Expand Up @@ -473,26 +472,25 @@ test_apdu_ok(
NfcParamPollB poll_b;
NfcTagType4* t4b;
NfcTag* tag;
gulong id;

memset(&test, 0, sizeof(test));
test.data = test_data;
test.loop = g_main_loop_new(NULL, TRUE);

test_target_add_cmd(TEST_TARGET(target),
TEST_ARRAY_AND_SIZE(test_cmd_select_ndef),
TEST_ARRAY_AND_SIZE(test_resp_ok));

memset(&poll_b, 0, sizeof(poll_b));
poll_b.fsc = 0x0b; /* i.e. 256 */
t4b = NFC_TAG_T4(nfc_tag_t4b_new(target, &poll_b, NULL));
g_assert(NFC_IS_TAG_T4B(t4b));
tag = &t4b->tag;

id = nfc_tag_add_initialized_handler(tag, test_apdu_ok_initialized, &test);
/*
* As of now it gets initialized immediately. If we start supporting
* NDEF application, this process will become asynchronous.
*/
g_assert(tag->flags & NFC_TAG_FLAG_INITIALIZED);
test_apdu_ok_initialized(tag, &test);
test_run(&test_opt, test.loop);
g_assert(test.destroyed);
nfc_tag_remove_handler(tag, id);

nfc_tag_unref(tag);
nfc_target_unref(target);
Expand All @@ -503,6 +501,19 @@ test_apdu_ok(
* apdu_fail
*==========================================================================*/

static
void
test_apdu_fail_done(
NfcTagType4* tag,
guint sw, /* 16 bits (SW1 << 8)|SW2 */
const void* data,
guint len,
void* user_data)
{
g_assert(sw == ISO_SW_IO_ERR);
g_main_loop_quit(user_data);
}

static
void
test_apdu_fail(
Expand All @@ -513,21 +524,19 @@ test_apdu_fail(
NfcParamPollB poll_b;
NfcTagType4* t4b;
NfcTag* tag;
gulong id;

test_target_add_cmd(TEST_TARGET(target),
TEST_ARRAY_AND_SIZE(test_cmd_select_ndef),
TEST_ARRAY_AND_SIZE(test_resp_ok));
guint8 zero = 0;

memset(&poll_b, 0, sizeof(poll_b));
poll_b.fsc = 0x0b; /* i.e. 256 */
t4b = NFC_TAG_T4(nfc_tag_t4b_new(target, &poll_b, NULL));
g_assert(NFC_IS_TAG_T4B(t4b));
tag = &t4b->tag;

id = nfc_tag_add_initialized_handler(tag, test_basic_exit, loop);
test_run(&test_opt, loop);
nfc_tag_remove_handler(tag, id);
/*
* As of now it gets initialized immediately. If we start supporting
* NDEF application, this process will become asynchronous.
*/
g_assert(tag->flags & NFC_TAG_FLAG_INITIALIZED);

/* Invalid Le */
g_assert(!nfc_isodep_transmit(t4b, 0x00, 0xb0, 0x00, 0x00, NULL, 0x10001,
Expand All @@ -538,6 +547,18 @@ test_apdu_fail(
g_assert(!nfc_isodep_transmit(t4b, 0x00, 0xb0, 0x00, 0x00, NULL, 0x100,
NULL, NULL, NULL, NULL));

/* Transmission failure */
g_assert(nfc_isodep_transmit(t4b, 0x00, 0xb0, 0x00, 0x00, NULL, 0x100,
NULL, test_apdu_fail_done, NULL, loop));
test_run(&test_opt, loop);

/* Short response */
test_target_add_cmd(TEST_TARGET(tag->target),
TEST_ARRAY_AND_SIZE(select_mf_expected), &zero, 1);
g_assert(nfc_isodep_transmit(t4b, 0x00, 0xa4, 0x00, 0x00, NULL, 0,
NULL, test_apdu_fail_done, NULL, loop));
test_run(&test_opt, loop);

nfc_tag_unref(tag);
nfc_target_unref(target);
g_main_loop_unref(loop);
Expand Down

0 comments on commit 6469fff

Please sign in to comment.