adapter: Bypass the target layer
authorSamuel Ortiz <sameo@linux.intel.com>
Thu, 19 Apr 2012 11:06:03 +0000 (13:06 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 19 Apr 2012 11:08:32 +0000 (13:08 +0200)
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
include/tag.h
plugins/mifare.c
plugins/nfctype1.c
plugins/nfctype2.c
plugins/nfctype3.c
plugins/nfctype4.c
src/adapter.c
src/near.h
src/tag.c
test/list-adapters

index b8aae9e..23f458d 100644 (file)
@@ -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.
index 24a9d6d..ba532f1 100644 (file)
@@ -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);
index 9a223bd..a9e5a3e 100644 (file)
@@ -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;
index 7b5c733..3fa1193 100644 (file)
@@ -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;
 
index 71ef4a2..dade247 100644 (file)
@@ -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);
index 75754ee..7929de6 100644 (file)
@@ -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);
 
index 2abdb57..9b9f8b1 100644 (file)
@@ -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;
 
index 638ca56..b5e379e 100644 (file)
@@ -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;
 
index ae497c4..54eada3 100644 (file)
@@ -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 <near/tlv.h>
 
index fad7ef8..8e36364 100644 (file)
--- 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)
index 379aca4..9e86b4d 100755 (executable)
@@ -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])