Skip to content

Commit

Permalink
[core] Generic access to ISO-DEP activation parameters. JB#50041
Browse files Browse the repository at this point in the history
Type 4 tags have ISO-DEP interface specific parameters which are passed
to NFC chip during tag activation process. This patch adds API to access
such parameters.
  • Loading branch information
LuxInTenebr1s authored and monich committed Aug 21, 2020
1 parent 275edcd commit af2b326
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 14 deletions.
44 changes: 39 additions & 5 deletions core/include/nfc_tag_t4.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019 Jolla Ltd.
* Copyright (C) 2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -42,15 +43,13 @@
G_BEGIN_DECLS

typedef struct nfc_tag_t4_priv NfcTagType4Priv;
typedef union nfc_param_iso_dep NfcParamIsoDep;

struct nfc_tag_t4 {
NfcTag tag;
NfcTagType4Priv* priv;
};

struct nfc_param_iso_dep_poll_a {
guint fsc; /* FSC (FSDI converted to bytes) */
GUtilData t1; /* T1 to Tk (aka historical bytes) */
/* Since 1.0.39 */
const NfcParamIsoDep* iso_dep;
};

GType nfc_tag_t4_get_type();
Expand Down Expand Up @@ -83,6 +82,41 @@ GType nfc_tag_t4b_get_type();
*/
#define ISO_SW_IO_ERR (0)

/* ISO-DEP activation parameter */

typedef struct nfc_param_iso_dep_poll_a {
guint fsc; /* FSC (FSDI converted to bytes) */
GUtilData t1; /* T1 to Tk (aka historical bytes) */
/* Since 1.0.39 */
guint8 t0; /* Format byte T0 */

/*
* NFC-Forum-TS-DigitalProtocol 1.0
* Table 65: Coding of Format Byte T0
*
* Presence of interface bytes within NFC-A/ISO-DEP Poll activation
* parameter is determined with bits of Format Byte set to '1'
*/
#define NFC_PARAM_ISODEP_T0_A (0x10) /* TA is transmitted */
#define NFC_PARAM_ISODEP_T0_B (0x20) /* TB is transmitted */
#define NFC_PARAM_ISODEP_T0_C (0x40) /* TC is transmitted */

guint8 ta; /* Interface byte TA (optional) */
guint8 tb; /* Interface byte TB (optional) */
guint8 tc; /* Interface byte TC (optional) */
} NfcParamIsoDepPollA; /* Since 1.0.20 */

typedef struct nfc_param_iso_dep_poll_b {
guint mbli; /* Maximum buffer length index */
guint did; /* Device ID */
GUtilData hlr; /* Higher Layer Response */
} NfcParamIsoDepPollB; /* Since 1.0.39 */

union nfc_param_iso_dep {
NfcParamIsoDepPollA a;
NfcParamIsoDepPollB b;
}; /* Since 1.0.39 */

typedef
void
(*NfcTagType4ResponseFunc)(
Expand Down
48 changes: 47 additions & 1 deletion core/src/nfc_tag_t4.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -39,6 +40,8 @@
#include "nfc_util.h"
#include "nfc_log.h"

#include <gutil_macros.h>

typedef struct nfc_isodep_tx {
NfcTagType4* t4;
NfcTagType4ResponseFunc resp;
Expand All @@ -60,6 +63,7 @@ struct nfc_tag_t4_priv {
NfcTargetSequence* init_seq;
NfcIsoDepNdefRead* init_read;
guint init_id;
NfcParamIsoDep* iso_dep; /* Since 1.0.39 */
};

G_DEFINE_ABSTRACT_TYPE(NfcTagType4, nfc_tag_t4, NFC_TYPE_TAG)
Expand Down Expand Up @@ -672,14 +676,55 @@ nfc_tag_t4_init_base(
NfcTagType4* self,
NfcTarget* target,
guint mtu,
const NfcParamPoll* poll)
const NfcParamPoll* poll,
const NfcParamIsoDep* iso_dep)
{
NfcTag* tag = &self->tag;
NfcTagType4Priv* priv = self->priv;

nfc_tag_init_base(tag, target, poll);
priv->mtu = mtu;

if (iso_dep) {
const gsize aligned_size = G_ALIGN8(sizeof(*iso_dep));
const GUtilData* src;
gsize size;

/*
* Allocate the whole thing (including additional data) from a
* single memory block and adjust the pointers.
*/
switch (target->technology) {
case NFC_TECHNOLOGY_A:
src = &iso_dep->a.t1;
size = src->size ? (aligned_size + src->size) : sizeof(*iso_dep);
*(priv->iso_dep = g_malloc0(size)) = *iso_dep;
if (src->bytes) {
guint8* dest = (guint8*)priv->iso_dep + aligned_size;

memcpy(dest, src->bytes, src->size);
priv->iso_dep->a.t1.bytes = dest;
}
self->iso_dep = priv->iso_dep;
break;
case NFC_TECHNOLOGY_B:
src = &iso_dep->b.hlr;
size = src->size ? (aligned_size + src->size) : sizeof(*iso_dep);
*(priv->iso_dep = g_malloc0(size)) = *iso_dep;
if (src->bytes) {
guint8* dest = (guint8*)priv->iso_dep + aligned_size;

memcpy(dest, src->bytes, src->size);
priv->iso_dep->b.hlr.bytes = dest;
}
self->iso_dep = priv->iso_dep;
break;
case NFC_TECHNOLOGY_F:
case NFC_TECHNOLOGY_UNKNOWN:
break;
}
}

/*
* We only try to read NDEF Tag file if the target can be reactivated.
* Reactivation is supported by most commonly used NCI-based adapter
Expand Down Expand Up @@ -763,6 +808,7 @@ nfc_tag_t4_finalize(
nfc_target_sequence_unref(priv->init_seq);
nfc_iso_dep_ndef_read_free(priv->init_read);
g_byte_array_free(priv->buf, TRUE);
g_free(priv->iso_dep);
G_OBJECT_CLASS(nfc_tag_t4_parent_class)->finalize(object);
}

Expand Down
4 changes: 3 additions & 1 deletion core/src/nfc_tag_t4_p.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -59,7 +60,8 @@ nfc_tag_t4_init_base(
NfcTagType4* tag,
NfcTarget* target,
guint mtu,
const NfcParamPoll* poll)
const NfcParamPoll* poll,
const NfcParamIsoDep* iso_dep)
NFCD_INTERNAL;

#endif /* NFC_TAG_T4_PRIVATE_H */
Expand Down
16 changes: 11 additions & 5 deletions core/src/nfc_tag_t4a.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -52,27 +53,32 @@ NfcTagType4a*
nfc_tag_t4a_new(
NfcTarget* target,
const NfcParamPollA* poll_a,
const NfcParamIsoDepPollA* iso_dep_param)
const NfcParamIsoDepPollA* iso_dep_a)
{
if (G_LIKELY(iso_dep_param)) {
if (G_LIKELY(iso_dep_a)) {
NfcTagType4a* self = g_object_new(NFC_TYPE_TAG_T4A, NULL);
NfcTagType4* t4 = &self->t4;
NfcParamIsoDep iso_dep;

GDEBUG("Type 4A tag");
GASSERT(target->technology == NFC_TECHNOLOGY_A);
memset(&iso_dep, 0, sizeof(iso_dep));
iso_dep.a = *iso_dep_a;
if (poll_a) {
NfcParamPoll poll;

GASSERT(target->technology == NFC_TECHNOLOGY_A);
memset(&poll, 0, sizeof(poll));
poll.a = *poll_a;
nfc_tag_t4_init_base(&self->t4, target, iso_dep_param->fsc, &poll);
nfc_tag_t4_init_base(t4, target, iso_dep_a->fsc, &poll, &iso_dep);
} else {
nfc_tag_t4_init_base(&self->t4, target, iso_dep_param->fsc, NULL);
nfc_tag_t4_init_base(t4, target, iso_dep_a->fsc, NULL, &iso_dep);
}
return self;
}
return NULL;
}


/*==========================================================================*
* Internals
*==========================================================================*/
Expand Down
14 changes: 12 additions & 2 deletions core/src/nfc_tag_t4b.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2019-2020 Jolla Ltd.
* Copyright (C) 2019-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -52,17 +53,26 @@ NfcTagType4b*
nfc_tag_t4b_new(
NfcTarget* target,
const NfcParamPollB* poll_b,
const NfcParamIsoDepPollB* iso_dep_param)
const NfcParamIsoDepPollB* iso_dep_b)
{
if (G_LIKELY(poll_b)) {
NfcTagType4b* self = g_object_new(NFC_TYPE_TAG_T4B, NULL);
NfcTagType4* t4 = &self->t4;
NfcParamPoll poll;

GDEBUG("Type 4B tag");
GASSERT(target->technology == NFC_TECHNOLOGY_B);
memset(&poll, 0, sizeof(poll));
poll.b = *poll_b;
nfc_tag_t4_init_base(&self->t4, target, poll_b->fsc, &poll);
if (iso_dep_b) {
NfcParamIsoDep iso_dep;

memset(&iso_dep, 0, sizeof(iso_dep));
iso_dep.b = *iso_dep_b;
nfc_tag_t4_init_base(t4, target, poll_b->fsc, &poll, &iso_dep);
} else {
nfc_tag_t4_init_base(t4, target, poll_b->fsc, &poll, NULL);
}
return self;
}
return NULL;
Expand Down

0 comments on commit af2b326

Please sign in to comment.