From e718cc7a21a99a99e2c75cd4c89c83f5b576bb17 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 19 Apr 2012 13:06:03 +0200 Subject: [PATCH] adapter: Bypass the target layer Adapters talk to tags or device directly. The target vs initiator idea will be removed from the code base. This commit temporarily breaks p2p. --- doc/adapter-api.txt | 16 +-- include/tag.h | 7 ++ plugins/mifare.c | 12 +- plugins/nfctype1.c | 16 ++- plugins/nfctype2.c | 14 ++- plugins/nfctype3.c | 12 +- plugins/nfctype4.c | 11 +- src/adapter.c | 221 ++++++++++++++++----------------- src/near.h | 16 ++- src/tag.c | 352 ++++++++++++++++++++++++++++++++++++++++++---------- test/list-adapters | 2 +- 11 files changed, 468 insertions(+), 211 deletions(-) diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt index b8aae9e..23f458d 100644 --- a/doc/adapter-api.txt +++ b/doc/adapter-api.txt @@ -27,7 +27,7 @@ Methods: dict GetProperties() this method. It is only valid when the adapter is in initiator mode. - This process will start emitting TargetFound and + This process will start emitting TagFound and PropertyChanged "Polling" signals. Possible errors: org.neard.Error.NotReady @@ -95,18 +95,18 @@ Signals PropertyChanged(string name, variant value) This signal indicates a changed value of the given property. - TargetFound(string address, dict values) + TagFound(string address, dict values) - This signal is sent whenever an NFC target is found, + This signal is sent whenever an NFC tag is found, as a result of a probe response reception. The dictionary contains basically the same values that are returned by the GetProperties method - from the org.neard.Target interface. + from the org.neard.Tag interface. - TargetLost(string address) + TagLost(string address) - This signal is sent whenever the NFC target is no longer + This signal is sent whenever the NFC tag is no longer in sight, or when it's been de-activated. @@ -132,6 +132,6 @@ Properties: string Mode [readwrite] Possible values are "Felica", "MIFARE", "Jewel", "ISO-DEP" and "NFC-DEP". - array{object} Targets [readonly] + array{object} Tags [readonly] - The targets object paths. + The tags object paths. diff --git a/include/tag.h b/include/tag.h index 24a9d6d..ba532f1 100644 --- a/include/tag.h +++ b/include/tag.h @@ -72,9 +72,16 @@ struct near_tag_driver { struct near_tag; +struct near_tag *near_tag_get_tag(uint32_t adapter_idx, uint32_t target_idx); int near_tag_set_uid(struct near_tag *tag, uint8_t *uid, size_t uid_length); int near_tag_set_ro(struct near_tag *tag, near_bool_t readonly); near_bool_t near_tag_get_ro(struct near_tag *tag); +int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx, + uint8_t *data, size_t data_length); +enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx, + uint32_t target_idx); +uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx, + uint8_t *nfcid_len); uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length); uint32_t near_tag_get_adapter_idx(struct near_tag *tag); uint32_t near_tag_get_target_idx(struct near_tag *tag); diff --git a/plugins/mifare.c b/plugins/mifare.c index 9a223bd..a9e5a3e 100644 --- a/plugins/mifare.c +++ b/plugins/mifare.c @@ -448,8 +448,10 @@ static int mifare_process_MADs(void *data) DBG(""); /* Parse MAD entries to get the global size and fill the array */ - if (mf_ck->mad_1 == NULL) + if (mf_ck->mad_1 == NULL) { + err = -EINVAL; goto out_err; + } for (i = 0; i < MAD_V1_AIDS_LEN; i++) { if (mf_ck->mad_1->aids[i] != NFC_AID_TAG) @@ -482,10 +484,14 @@ done_mad: /* n sectors, each sector is 3 blocks, each block is 16 bytes */ DBG("TAG Global size: [%d]", global_tag_size); - mf_ck->tag = near_target_add_tag(mf_ck->adapter_idx, + err = near_tag_add_data(mf_ck->adapter_idx, mf_ck->target_idx, NULL, /* Empty */ global_tag_size); + if (err < 0) + goto out_err; + + mf_ck->tag = near_tag_get_tag(mf_ck->adapter_idx, mf_ck->target_idx); if (mf_ck->tag == NULL) { err = -ENOMEM; goto out_err; @@ -630,7 +636,7 @@ int mifare_read_tag(uint32_t adapter_idx, uint32_t target_idx, cookie = g_try_malloc0(sizeof(struct mifare_cookie)); /* Get the nfcid1 */ - cookie->nfcid1 = near_target_get_nfcid(adapter_idx, target_idx, + cookie->nfcid1 = near_tag_get_nfcid(adapter_idx, target_idx, &cookie->nfcid1_len); cookie->adapter_idx = adapter_idx; cookie->target_idx = target_idx; diff --git a/plugins/nfctype1.c b/plugins/nfctype1.c index 7b5c733..3fa1193 100644 --- a/plugins/nfctype1.c +++ b/plugins/nfctype1.c @@ -237,9 +237,13 @@ static int meta_recv(uint8_t *resp, int length, void *data) goto out_err; } - /* Associate the DATA length to the tag */ - tag = near_target_add_tag(cookie->adapter_idx, cookie->target_idx, + /* Add data to the tag */ + err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx, NULL, TAG_T1_DATA_LENGTH(cc)); + if (err < 0) + goto out_err; + + tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx); if (tag == NULL) { err = -ENOMEM; goto out_err; @@ -251,6 +255,8 @@ static int meta_recv(uint8_t *resp, int length, void *data) goto out_err; } + DBG("2"); + t1_tag->adapter_idx = cookie->adapter_idx; t1_tag->cb = cookie->cb; t1_tag->tag = tag; @@ -288,11 +294,15 @@ static int meta_recv(uint8_t *resp, int length, void *data) } out_err: + DBG("err %d", err); + if (err < 0 && cookie->cb) cookie->cb(cookie->adapter_idx, cookie->target_idx, err); t1_cookie_release(cookie); + + return err; } @@ -467,7 +477,7 @@ static int nfctype1_write_tag(uint32_t adapter_idx, uint32_t target_idx, if (ndef == NULL || cb == NULL) return -EINVAL; - tag = near_target_get_tag(adapter_idx, target_idx); + tag = near_tag_get_tag(adapter_idx, target_idx); if (tag == NULL) return -EINVAL; diff --git a/plugins/nfctype2.c b/plugins/nfctype2.c index 71ef4a2..dade247 100644 --- a/plugins/nfctype2.c +++ b/plugins/nfctype2.c @@ -196,8 +196,12 @@ static int meta_recv(uint8_t *resp, int length, void *data) goto out; } - tag = near_target_add_tag(cookie->adapter_idx, cookie->target_idx, - NULL, TAG_DATA_LENGTH(cc)); + err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx, + NULL, TAG_DATA_LENGTH(cc)); + if (err < 0) + goto out; + + tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx); if (tag == NULL) { err = -ENOMEM; goto out; @@ -266,7 +270,7 @@ static int nfctype2_read_tag(uint32_t adapter_idx, DBG(""); - tgt_subtype = near_target_get_subtype(adapter_idx, target_idx); + tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx); switch (tgt_subtype) { case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT: @@ -395,7 +399,7 @@ static int nfctype2_write_tag(uint32_t adapter_idx, uint32_t target_idx, if (ndef == NULL || cb == NULL) return -EINVAL; - tag = near_target_get_tag(adapter_idx, target_idx); + tag = near_tag_get_tag(adapter_idx, target_idx); if (tag == NULL) return -EINVAL; @@ -404,7 +408,7 @@ static int nfctype2_write_tag(uint32_t adapter_idx, uint32_t target_idx, return -EPERM; } - tgt_subtype = near_target_get_subtype(adapter_idx, target_idx); + tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx); if (tgt_subtype != NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT) { DBG("Unknown Tag Type 2 subtype (%d)", tgt_subtype); diff --git a/plugins/nfctype3.c b/plugins/nfctype3.c index 75754ee..7929de6 100644 --- a/plugins/nfctype3.c +++ b/plugins/nfctype3.c @@ -305,9 +305,13 @@ static int nfctype3_recv_block_0(uint8_t *resp, int length, void *data) ndef_data_length *= 0x100; ndef_data_length += resp[OFS_READ_DATA + 13]; - /* Associate the DATA length to the tag */ - tag = near_target_add_tag(cookie->adapter_idx, cookie->target_idx, + /* Add data to the tag */ + err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx, NULL, ndef_data_length); + if (err < 0) + goto out; + + tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx); if (tag == NULL) { err = -ENOMEM; goto out; @@ -609,7 +613,7 @@ static int nfctype3_write_tag(uint32_t adapter_idx, uint32_t target_idx, if (ndef == NULL || cb == NULL) return -EINVAL; - tag = near_target_get_tag(adapter_idx, target_idx); + tag = near_tag_get_tag(adapter_idx, target_idx); if (tag == NULL) return -EINVAL; @@ -672,6 +676,8 @@ static int nfctype3_check_presence(uint32_t adapter_idx, if (err < 0) goto out; + return 0; + out: t3_cookie_release(cookie); diff --git a/plugins/nfctype4.c b/plugins/nfctype4.c index 2abdb57..9b9f8b1 100644 --- a/plugins/nfctype4.c +++ b/plugins/nfctype4.c @@ -305,11 +305,14 @@ static int t4_readbin_NDEF_ID(uint8_t *resp, int length, void *data) goto out_err; } - tag = near_target_add_tag(cookie->adapter_idx, cookie->target_idx, NULL, - g_ntohs(*((uint16_t *)(resp + NFC_STATUS_BYTE_LEN)))); + /* Add data to the tag */ + err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx, NULL, + g_ntohs(*((uint16_t *)(resp + NFC_STATUS_BYTE_LEN)))); + if (err < 0) + goto out_err; + tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx); if (tag == NULL) { - DBG("near_target_add_tag is null") ; err = -ENOMEM; goto out_err; } @@ -686,7 +689,7 @@ static int nfctype4_write_tag(uint32_t adapter_idx, uint32_t target_idx, if (ndef == NULL || cb == NULL) return -EINVAL; - tag = near_target_get_tag(adapter_idx, target_idx); + tag = near_tag_get_tag(adapter_idx, target_idx); if (tag == NULL) return -EINVAL; diff --git a/src/adapter.c b/src/adapter.c index 638ca56..b5e379e 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -54,9 +54,13 @@ struct near_adapter { near_bool_t constant_poll; near_bool_t dep_up; - GHashTable *targets; - struct near_target *link; - int sock; + GHashTable *tags; + struct near_tag *tag_link; + int tag_sock; + + GHashTable *devices; + struct near_tag *device_link; + int device_sock; GIOChannel *channel; guint watch; @@ -91,11 +95,11 @@ static void free_adapter(gpointer data) g_free(adapter); } -static void free_target(gpointer data) +static void free_tag(gpointer data) { - struct near_target *target = data; + struct near_tag *tag = data; - __near_target_remove(target); + __near_tag_remove(tag); } static void polling_changed(struct near_adapter *adapter) @@ -110,11 +114,11 @@ static int adapter_start_poll(struct near_adapter *adapter) { int err; - if (g_hash_table_size(adapter->targets) > 0) { - DBG("Clearing targets"); + if (g_hash_table_size(adapter->tags) > 0) { + DBG("Clearing tags"); - g_hash_table_remove_all(adapter->targets); - __near_adapter_target_changed(adapter->idx); + g_hash_table_remove_all(adapter->tags); + __near_adapter_tags_changed(adapter->idx); } err = __near_netlink_start_poll(adapter->idx, adapter->protocols); @@ -191,43 +195,45 @@ static void append_protocols(DBusMessageIter *iter, void *user_data) } } -static void append_target_path(gpointer key, gpointer value, gpointer user_data) +static void append_tag_path(gpointer key, gpointer value, gpointer user_data) { - struct near_target *target = value; + struct near_tag *tag = value; DBusMessageIter *iter = user_data; - const char *target_path; + const char *tag_path; - target_path = __near_target_get_path(target); - if (target_path == NULL) + tag_path = __near_tag_get_path(tag); + if (tag_path == NULL) return; - DBG("%s", target_path); + DBG("%s", tag_path); dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, - &target_path); + &tag_path); } -static void append_targets(DBusMessageIter *iter, void *user_data) +static void append_tags(DBusMessageIter *iter, void *user_data) { struct near_adapter *adapter = user_data; DBG(""); - g_hash_table_foreach(adapter->targets, append_target_path, iter); + g_hash_table_foreach(adapter->tags, append_tag_path, iter); } -void __near_adapter_target_changed(uint32_t adapter_idx) +void __near_adapter_tags_changed(uint32_t adapter_idx) { struct near_adapter *adapter; + DBG(""); + adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(adapter_idx)); if (adapter == NULL) return; near_dbus_property_changed_array(adapter->path, - NFC_ADAPTER_INTERFACE, "Targets", - DBUS_TYPE_OBJECT_PATH, append_targets, + NFC_ADAPTER_INTERFACE, "Tags", + DBUS_TYPE_OBJECT_PATH, append_tags, adapter); } static DBusMessage *get_properties(DBusConnection *conn, @@ -256,8 +262,8 @@ static DBusMessage *get_properties(DBusConnection *conn, near_dbus_dict_append_array(&dict, "Protocols", DBUS_TYPE_STRING, append_protocols, adapter); - near_dbus_dict_append_array(&dict, "Targets", - DBUS_TYPE_OBJECT_PATH, append_targets, adapter); + near_dbus_dict_append_array(&dict, "Tags", + DBUS_TYPE_OBJECT_PATH, append_tags, adapter); near_dbus_dict_close(&array, &dict); @@ -417,7 +423,7 @@ static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx, static gboolean check_presence(gpointer user_data) { struct near_adapter *adapter = user_data; - struct near_target *target; + struct near_tag *tag; int err; DBG(""); @@ -425,11 +431,11 @@ static gboolean check_presence(gpointer user_data) if (adapter == NULL) return FALSE; - target = adapter->link; - if (target == NULL) + tag = adapter->tag_link; + if (tag == NULL) return FALSE; - err = __near_tag_check_presence(target, tag_present_cb); + err = __near_tag_check_presence(tag, tag_present_cb); if (err < 0) { DBG("Could not check target presence"); @@ -454,7 +460,7 @@ static void tag_present_cb(uint32_t adapter_idx, uint32_t target_idx, return; if (status < 0) { - DBG("Target is gone"); + DBG("Tag is gone"); near_adapter_disconnect(adapter->idx); if (adapter->constant_poll == TRUE) @@ -676,8 +682,8 @@ static GDBusMethodTable adapter_methods[] = { static GDBusSignalTable adapter_signals[] = { { "PropertyChanged", "sv" }, - { "TargetFound", "o" }, - { "TargetLost", "o" }, + { "TagFound", "o" }, + { "TagLost", "o" }, { } }; @@ -700,9 +706,9 @@ struct near_adapter * __near_adapter_create(uint32_t idx, adapter->powered = powered; adapter->constant_poll = near_setting_get_bool("ConstantPoll"); adapter->dep_up = FALSE; - adapter->targets = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, free_target); - adapter->sock = -1; + adapter->tags = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, free_tag); + adapter->tag_sock = -1; adapter->path = g_strdup_printf("%s/nfc%d", NFC_PATH, idx); @@ -785,6 +791,7 @@ void __near_adapter_remove(struct near_adapter *adapter) g_hash_table_remove(adapter_hash, GINT_TO_POINTER(adapter->idx)); } +#if 0 static int dep_link_up(uint32_t idx, uint32_t target_idx) { return __near_netlink_dep_link_up(idx, target_idx, @@ -795,16 +802,17 @@ static int dep_link_down(uint32_t idx) { return __near_netlink_dep_link_down(idx); } +#endif static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status) { struct near_adapter *adapter; - struct near_target *target; + struct near_tag *tag; struct near_ndef_message *ndef, *ndef_with_header = NULL; uint16_t tag_type; int err; - DBG(""); + DBG("status %d", status); adapter = g_hash_table_lookup(adapter_hash, GINT_TO_POINTER(adapter_idx)); @@ -819,23 +827,23 @@ static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status) return; } - __near_adapter_target_changed(adapter_idx); + __near_adapter_tags_changed(adapter_idx); /* Check if adapter ndef queue has any ndef messages, * then write the ndef data on tag. */ if (g_list_length(adapter->ndef_q) == 0) goto out; - target = g_hash_table_lookup(adapter->targets, + tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx)); - if (target == NULL) + if (tag == NULL) goto out; ndef = __pop_ndef_queue(adapter); if (ndef == NULL) goto out; - tag_type = __near_target_get_tag_type(target); + tag_type = __near_tag_get_type(tag); /* Add NDEF header information depends upon tag type */ switch (tag_type) { @@ -901,7 +909,7 @@ static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status) g_free(ndef->data); g_free(ndef); - err = __near_tag_add_ndef(target, ndef_with_header, __add_ndef_cb); + err = __near_tag_add_ndef(tag, ndef_with_header, __add_ndef_cb); if (err < 0) { g_free(ndef_with_header->data); g_free(ndef_with_header); @@ -922,14 +930,40 @@ out: check_presence, adapter); } +static int adapter_add_tag(struct near_adapter *adapter, uint32_t target_idx, + uint32_t protocols, + uint16_t sens_res, uint8_t sel_res, + uint8_t *nfcid, uint8_t nfcid_len) +{ + struct near_tag *tag; + uint32_t tag_type; + int err; + + tag = __near_tag_add(adapter->idx, target_idx, protocols, + sens_res, sel_res, + nfcid, nfcid_len); + if (tag == NULL) + return -ENODEV; + + g_hash_table_insert(adapter->tags, GINT_TO_POINTER(target_idx), + tag); + + tag_type = __near_tag_get_type(tag); + + err = near_adapter_connect(adapter->idx, target_idx, tag_type); + if (err < 0) { + near_error("Could not connect"); + return err; + } + + return __near_tag_read(tag, tag_read_cb); +} + int __near_adapter_add_target(uint32_t idx, uint32_t target_idx, uint32_t protocols, uint16_t sens_res, uint8_t sel_res, uint8_t *nfcid, uint8_t nfcid_len) { struct near_adapter *adapter; - struct near_target *target; - uint16_t tag_type; - int err; DBG("idx %d", idx); @@ -940,42 +974,18 @@ int __near_adapter_add_target(uint32_t idx, uint32_t target_idx, adapter->polling = FALSE; polling_changed(adapter); - /* TODO target reference */ - target = __near_target_add(idx, target_idx, protocols, + if (protocols & NFC_PROTO_NFC_DEP_MASK) + return -EOPNOTSUPP; + else + return adapter_add_tag(adapter, target_idx, protocols, sens_res, sel_res, nfcid, nfcid_len); - if (target == NULL) - return -ENODEV; - - g_hash_table_insert(adapter->targets, - GINT_TO_POINTER(target_idx), target); - tag_type = __near_target_get_tag_type(target); - - if (tag_type != NFC_PROTO_NFC_DEP) { - err = near_adapter_connect(idx, target_idx, tag_type); - if (err < 0) { - near_error("Could not connect"); - return err; - } - - err = __near_tag_read(target, tag_read_cb); - } else { - /* For p2p, reading is service binding */ - err = __near_tag_read(target, tag_read_cb); - if (err < 0) { - near_error("Could not read tag"); - return err; - } - - err = near_adapter_connect(idx, target_idx, tag_type); - } - - return err; } int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx) { struct near_adapter *adapter; + struct near_tag *tag; DBG("idx %d", idx); @@ -983,11 +993,17 @@ int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx) if (adapter == NULL) return -ENODEV; - g_hash_table_remove(adapter->targets, GINT_TO_POINTER(target_idx)); + tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx)); + if (tag != NULL) { + g_hash_table_remove(adapter->tags, GINT_TO_POINTER(target_idx)); - __near_adapter_target_changed(idx); + __near_adapter_tags_changed(idx); - return 0; + return 0; + } else { + /* TODO search for devices */ + return -ENODEV; + } } static void adapter_flush_rx(struct near_adapter *adapter, int error) @@ -1056,7 +1072,7 @@ static gboolean adapter_recv_event(GIOChannel *channel, GIOCondition condition, int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol) { struct near_adapter *adapter; - struct near_target *target; + struct near_tag *tag; struct sockaddr_nfc addr; int err, sock; @@ -1066,26 +1082,14 @@ int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol) if (adapter == NULL) return -ENODEV; - if (adapter->sock != -1) + if (adapter->tag_sock != -1) return -EALREADY; - target = g_hash_table_lookup(adapter->targets, + tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx)); - if (target == NULL) + if (tag == NULL) return -ENOLINK; - if (protocol == NFC_PROTO_NFC_DEP) { - err = dep_link_up(idx, target_idx); - if (err < 0) - return err; - - adapter->link = target; - - DBG("link %p", adapter->link); - - return 0; - } - sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW); if (sock == -1) return sock; @@ -1101,11 +1105,11 @@ int near_adapter_connect(uint32_t idx, uint32_t target_idx, uint8_t protocol) return err; } - adapter->sock = sock; - adapter->link = target; + adapter->tag_sock = sock; + adapter->tag_link = tag; if (adapter->channel == NULL) - adapter->channel = g_io_channel_unix_new(adapter->sock); + adapter->channel = g_io_channel_unix_new(adapter->tag_sock); g_io_channel_set_flags(adapter->channel, G_IO_FLAG_NONBLOCK, NULL); g_io_channel_set_close_on_unref(adapter->channel, TRUE); @@ -1130,24 +1134,19 @@ int near_adapter_disconnect(uint32_t idx) if (adapter == NULL) return -ENODEV; - DBG("link %p", adapter->link); + DBG("link %p", adapter->tag_link); - if (adapter->link == NULL) + if (adapter->tag_link == NULL) return -ENOLINK; - tag_type = __near_target_get_tag_type(adapter->link); - target_idx = __near_target_get_idx(adapter->link); + tag_type = __near_tag_get_type(adapter->tag_link); + target_idx = __near_tag_get_idx(adapter->tag_link); DBG("tag type %d", tag_type); __near_adapter_remove_target(adapter->idx, target_idx); - if (tag_type == NFC_PROTO_NFC_DEP) { - adapter->link = NULL; - return dep_link_down(idx); - } - - if (adapter->sock == -1) + if (adapter->tag_sock == -1) return -ENOLINK; if (adapter->watch > 0) { @@ -1156,9 +1155,9 @@ int near_adapter_disconnect(uint32_t idx) } adapter->channel = NULL; - close(adapter->sock); - adapter->sock = -1; - adapter->link = NULL; + close(adapter->tag_sock); + adapter->tag_sock = -1; + adapter->tag_link = NULL; return 0; } @@ -1176,7 +1175,7 @@ int near_adapter_send(uint32_t idx, uint8_t *buf, size_t length, if (adapter == NULL) return -ENODEV; - if (adapter->sock == -1 || adapter->link == NULL) + if (adapter->tag_sock == -1 || adapter->tag_link == NULL) return -ENOLINK; if (cb != NULL && adapter->watch != 0) { @@ -1186,7 +1185,7 @@ int near_adapter_send(uint32_t idx, uint8_t *buf, size_t length, DBG("req %p cb %p data %p", req, cb, data); - req->target_idx = __near_target_get_idx(adapter->link); + req->target_idx = __near_tag_get_idx(adapter->tag_link); req->cb = cb; req->data = data; @@ -1194,7 +1193,7 @@ int near_adapter_send(uint32_t idx, uint8_t *buf, size_t length, g_list_append(adapter->ioreq_list, req); } - err = send(adapter->sock, buf, length, 0); + err = send(adapter->tag_sock, buf, length, 0); if (err < 0) goto out_err; diff --git a/src/near.h b/src/near.h index ae497c4..54eada3 100644 --- a/src/near.h +++ b/src/near.h @@ -101,7 +101,7 @@ int __near_adapter_add_target(uint32_t idx, uint32_t target_idx, uint32_t protocols, uint16_t sens_res, uint8_t sel_res, uint8_t *nfcid, uint8_t nfcid_len); int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx); -void __near_adapter_target_changed(uint32_t adapter_idx); +void __near_adapter_tags_changed(uint32_t adapter_idx); void __near_adapter_list(DBusMessageIter *iter, void *user_data); int __near_adapter_init(void); void __near_adapter_cleanup(void); @@ -120,17 +120,25 @@ const char *__near_ndef_get_uri_prefix(uint8_t id); int __near_tag_init(void); void __near_tag_cleanup(void); +struct near_tag *__near_tag_add(uint32_t idx, uint32_t target_idx, + uint32_t protocols, + uint16_t sens_res, uint8_t sel_res, + uint8_t *nfcid, uint8_t nfcid_len); +void __near_tag_remove(struct near_tag *tag); +const char *__near_tag_get_path(struct near_tag *tag); +uint32_t __near_tag_get_idx(struct near_tag *tag); +uint32_t __near_tag_get_type(struct near_tag *tag); void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter); uint32_t __near_tag_n_records(struct near_tag *tag); int __near_tag_add_record(struct near_tag *tag, struct near_ndef_record *record); struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx, uint8_t *data, size_t data_length); void __near_tag_free(struct near_tag *tag); -int __near_tag_read(struct near_target *target, near_tag_io_cb cb); -int __near_tag_add_ndef(struct near_target *target, +int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb); +int __near_tag_add_ndef(struct near_tag *tag, struct near_ndef_message *ndef, near_tag_io_cb cb); -int __near_tag_check_presence(struct near_target *target, near_tag_io_cb cb); +int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb); #include diff --git a/src/tag.c b/src/tag.c index fad7ef8..8e36364 100644 --- a/src/tag.c +++ b/src/tag.c @@ -76,6 +76,23 @@ static GHashTable *tag_hash; static GSList *driver_list = NULL; +struct near_tag *near_tag_get_tag(uint32_t adapter_idx, uint32_t target_idx) +{ + struct near_tag *tag; + char *path; + + path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH, + adapter_idx, target_idx); + if (path == NULL) + return NULL; + + tag = g_hash_table_lookup(tag_hash, path); + g_free(path); + + /* TODO refcount */ + return tag; +} + static void append_records(DBusMessageIter *iter, void *user_data) { struct near_tag *tag = user_data; @@ -235,28 +252,254 @@ void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter) } } -static int tag_initialize(struct near_tag *tag, char *path, +#define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \ + NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK) +#define NFC_TAG_A_TYPE2 0x00 +#define NFC_TAG_A_TYPE4 0x01 +#define NFC_TAG_A_NFC_DEP 0x02 +#define NFC_TAG_A_TYPE4_DEP 0x03 + +#define NFC_TAG_A_SENS_RES_SSD_JEWEL 0x00 +#define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c + +#define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5) +#define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2) +#define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f) +#define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8) + +static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res) +{ + switch(sel_res) { + case 0x00 : + return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT; + case 0x08: + return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K; + case 0x09: + return NEAR_TAG_NFC_T2_MIFARE_MINI; + case 0x18: + return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K; + case 0x20: + return NEAR_TAG_NFC_T2_MIFARE_DESFIRE; + case 0x28 : + return NEAR_TAG_NFC_T2_JCOP30; + case 0x38: + return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL; + case 0x88: + return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON; + case 0x98: + return NEAR_TAG_NFC_T2_MPCOS; + } + + return NEAR_TAG_NFC_SUBTYPE_UNKNOWN; +} + +static void set_tag_type(struct near_tag *tag, + uint16_t sens_res, uint8_t sel_res) +{ + uint8_t platconf, ssd, proto; + + DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol, + sens_res, sel_res); + + switch (tag->protocol) { + case NFC_PROTO_JEWEL_MASK: + platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res); + ssd = NFC_TAG_A_SENS_RES_SSD(sens_res); + + DBG("Jewel"); + + if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) && + (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL)) + tag->type = NFC_PROTO_JEWEL; + break; + + case NFC_PROTO_MIFARE_MASK: + case NFC_PROTO_ISO14443_MASK: + proto = NFC_TAG_A_SEL_PROT(sel_res); + + DBG("proto 0x%x", proto); + + switch(proto) { + case NFC_TAG_A_TYPE2: + tag->type = NFC_PROTO_MIFARE; + tag->sub_type = get_tag_type2_sub_type(sel_res); + break; + case NFC_TAG_A_TYPE4: + tag->type = NFC_PROTO_ISO14443; + break; + case NFC_TAG_A_TYPE4_DEP: + tag->type = NFC_PROTO_NFC_DEP; + break; + } + break; + + case NFC_PROTO_FELICA_MASK: + tag->type = NFC_PROTO_FELICA; + break; + + default: + tag->type = NFC_PROTO_MAX; + break; + } + + DBG("tag type 0x%x", tag->type); +} + +static int tag_initialize(struct near_tag *tag, uint32_t adapter_idx, uint32_t target_idx, - uint8_t * data, size_t data_length) + uint32_t protocols, + uint16_t sens_res, uint8_t sel_res, + uint8_t *nfcid, uint8_t nfcid_len) { - DBG("data length %zu", data_length); + DBG(""); - tag->path = path; + tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH, + adapter_idx, target_idx); + if (tag->path == NULL) + return -ENOMEM; tag->adapter_idx = adapter_idx; tag->target_idx = target_idx; + tag->protocol = protocols; tag->n_records = 0; tag->readonly = 0; - if (data_length > 0) { - tag->data_length = data_length; - tag->data = g_try_malloc0(data_length); - if (tag->data == NULL) - return -ENOMEM; + if (nfcid_len <= NFC_MAX_NFCID1_LEN) { + tag->nfcid_len = nfcid_len; + memcpy(tag->nfcid, nfcid, nfcid_len); + } + + set_tag_type(tag, sens_res, sel_res); + + return 0; +} + +struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx, + uint32_t protocols, + uint16_t sens_res, uint8_t sel_res, + uint8_t *nfcid, uint8_t nfcid_len) +{ + struct near_tag *tag; + char *path; + + tag = near_tag_get_tag(adapter_idx, target_idx); + if (tag != NULL) + return NULL; + + tag = g_try_malloc0(sizeof(struct near_tag)); + if (tag == NULL) + return NULL; + + if (tag_initialize(tag, adapter_idx, target_idx, + protocols, + sens_res, sel_res, + nfcid, nfcid_len) < 0) { + g_free(tag); + return NULL; + } - if (data != NULL) - memcpy(tag->data, data, data_length); + path = g_strdup(tag->path); + if (path == NULL) { + g_free(tag); + return NULL; } + g_hash_table_insert(tag_hash, path, tag); + + DBG("connection %p", connection); + + g_dbus_register_interface(connection, tag->path, + NFC_TAG_INTERFACE, + tag_methods, tag_signals, + NULL, tag, NULL); + + return tag; +} + +void __near_tag_remove(struct near_tag *tag) +{ + char *path = tag->path; + + DBG("path %s", tag->path); + + if (g_hash_table_lookup(tag_hash, tag->path) == NULL) + return; + + g_dbus_unregister_interface(connection, tag->path, + NFC_TAG_INTERFACE); + + g_hash_table_remove(tag_hash, path); +} + +const char *__near_tag_get_path(struct near_tag *tag) +{ + return tag->path; +} + + +uint32_t __near_tag_get_idx(struct near_tag *tag) +{ + return tag->target_idx; +} + +uint32_t __near_tag_get_type(struct near_tag *tag) +{ + return tag->type; +} + +enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx, + uint32_t target_idx) + +{ + struct near_tag *tag; + + tag = near_tag_get_tag(adapter_idx, target_idx); + if (tag == NULL) + return NEAR_TAG_NFC_SUBTYPE_UNKNOWN; + + return tag->sub_type; +} + +uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx, + uint8_t *nfcid_len) +{ + struct near_tag *tag; + uint8_t *nfcid; + + tag = near_tag_get_tag(adapter_idx, target_idx); + if (tag == NULL) + goto fail; + + nfcid = g_try_malloc0(tag->nfcid_len); + if (nfcid == NULL) + goto fail; + + memcpy(nfcid, tag->nfcid, tag->nfcid_len); + *nfcid_len = tag->nfcid_len; + + return nfcid; + +fail: + *nfcid_len = 0; + return NULL; +} + +int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx, + uint8_t *data, size_t data_length) +{ + struct near_tag *tag; + + tag = near_tag_get_tag(adapter_idx, target_idx); + if (tag == NULL) + return -ENODEV; + + tag->data_length = data_length; + tag->data = g_try_malloc0(data_length); + if (tag->data == NULL) + return -ENOMEM; + + if (data != NULL) + memcpy(tag->data, data, data_length); + return 0; } @@ -274,17 +517,12 @@ struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx, if (g_hash_table_lookup(tag_hash, path) != NULL) return NULL; + g_free(path); tag = g_try_malloc0(sizeof(struct near_tag)); if (tag == NULL) return NULL; - if (tag_initialize(tag, path, adapter_idx, target_idx, - data, data_length) < 0) { - g_free(tag); - return NULL; - } - g_hash_table_insert(tag_hash, path, tag); DBG("connection %p", connection); @@ -475,99 +713,61 @@ void near_tag_driver_unregister(struct near_tag_driver *driver) driver_list = g_slist_remove(driver_list, driver); } -int __near_tag_read(struct near_target *target, near_tag_io_cb cb) +int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb) { GSList *list; - uint16_t type; - - DBG(""); - type = __near_target_get_tag_type(target); - if (type == NFC_PROTO_MAX) - return -ENODEV; - - DBG("type 0x%x", type); + DBG("type 0x%x", tag->type); for (list = driver_list; list; list = list->next) { struct near_tag_driver *driver = list->data; DBG("driver type 0x%x", driver->type); - if (driver->type == type) { - uint32_t adapter_idx, target_idx; - - target_idx = __near_target_get_idx(target); - adapter_idx = __near_target_get_adapter_idx(target); - - return driver->read_tag(adapter_idx, target_idx, cb); - } + if (driver->type == tag->type) + return driver->read_tag(tag->adapter_idx, tag->target_idx, cb); } return 0; } -int __near_tag_add_ndef(struct near_target *target, +int __near_tag_add_ndef(struct near_tag *tag, struct near_ndef_message *ndef, near_tag_io_cb cb) { GSList *list; - uint16_t type; - - DBG(""); - - type = __near_target_get_tag_type(target); - if (type == NFC_PROTO_MAX) - return -ENODEV; - DBG("type 0x%x", type); + DBG("type 0x%x", tag->type); for (list = driver_list; list; list = list->next) { struct near_tag_driver *driver = list->data; DBG("driver type 0x%x", driver->type); - if (driver->type == type) { - uint32_t adapter_idx, target_idx; - - target_idx = __near_target_get_idx(target); - adapter_idx = __near_target_get_adapter_idx(target); - - return driver->add_ndef(adapter_idx, target_idx, + if (driver->type == tag->type) + return driver->add_ndef(tag->adapter_idx, tag->target_idx, ndef, cb); - } } return 0; } -int __near_tag_check_presence(struct near_target *target, near_tag_io_cb cb) +int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb) { GSList *list; - uint16_t type; - - DBG(""); - - type = __near_target_get_tag_type(target); - if (type == NFC_PROTO_MAX) - return -ENODEV; - DBG("type 0x%x", type); + DBG("type 0x%x", tag->type); for (list = driver_list; list; list = list->next) { struct near_tag_driver *driver = list->data; DBG("driver type 0x%x", driver->type); - if (driver->type == type) { - uint32_t adapter_idx, target_idx; - - target_idx = __near_target_get_idx(target); - adapter_idx = __near_target_get_adapter_idx(target); - + if (driver->type == tag->type) { if (driver->check_presence == NULL) continue; - return driver->check_presence(adapter_idx, target_idx, cb); + return driver->check_presence(tag->adapter_idx, tag->target_idx, cb); } } @@ -577,10 +777,24 @@ int __near_tag_check_presence(struct near_target *target, near_tag_io_cb cb) static void free_tag(gpointer data) { struct near_tag *tag = data; + GList *list; - DBG(""); + DBG("tag %p", tag); + + for (list = tag->records; list; list = list->next) { + struct near_ndef_record *record = list->data; + + __near_ndef_record_free(record); + } + + DBG("record freed"); + + g_list_free(tag->records); + g_free(tag->path); + g_free(tag->data); + g_free(tag); - __near_tag_free(tag); + DBG("Done"); } int __near_tag_init(void) diff --git a/test/list-adapters b/test/list-adapters index 379aca4..9e86b4d 100755 --- a/test/list-adapters +++ b/test/list-adapters @@ -32,7 +32,7 @@ for path in properties["Adapters"]: val = "true" else: val = "false" - elif key in ["Protocols", "Targets"]: + elif key in ["Protocols", "Tags"]: val = extract_list(properties[key]) else: val = str(properties[key]) -- 2.7.4