Add set of tags functions - bugfix: double free
[profile/ivi/neard.git] / src / tag.c
index b4aff76..2a46837 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -230,6 +230,18 @@ static DBusMessage *set_property(DBusConnection *conn,
 
 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
 {
+       struct near_tag *tag;
+
+       tag = near_tag_get_tag(adapter_idx, target_idx);
+
+       if (tag == NULL)
+               return;
+
+       dbus_message_unref(tag->write_msg);
+       tag->write_msg = NULL;
+
+       __near_adapter_start_check_presence(adapter_idx, target_idx);
+
        __near_adapter_tags_changed(adapter_idx);
 }
 
@@ -241,12 +253,14 @@ static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
 
        DBG("Write status %d", status);
 
-       conn = near_dbus_get_connection();
        tag = near_tag_get_tag(adapter_idx, target_idx);
-
-       if (conn == NULL || tag == NULL)
+       if (tag == NULL)
                return;
 
+       conn = near_dbus_get_connection();
+       if (conn == NULL)
+               goto out;
+
        if (status != 0) {
                reply = __near_error_failed(tag->write_msg, EINVAL);
                if (reply != NULL)
@@ -255,16 +269,26 @@ static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
                g_dbus_send_reply(conn, tag->write_msg, DBUS_TYPE_INVALID);
        }
 
-       dbus_message_unref(tag->write_msg);
-       tag->write_msg = NULL;
-
        near_ndef_records_free(tag->records);
        tag->n_records = 0;
        tag->records = NULL;
        g_free(tag->data);
+       tag->data = NULL;
 
-       if (status == 0)
+       if (status == 0) {
+               /*
+                * If writing succeeded,
+                * check presence will be restored after reading
+                */
                __near_tag_read(tag, tag_read_cb);
+               return;
+       }
+
+out:
+       dbus_message_unref(tag->write_msg);
+       tag->write_msg = NULL;
+
+       __near_adapter_start_check_presence(tag->adapter_idx, tag->target_idx);
 }
 
 static void format_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
@@ -754,6 +778,11 @@ void near_tag_set_blank(struct near_tag *tag, near_bool_t blank)
        tag->blank = blank;
 }
 
+near_bool_t near_tag_get_blank(struct near_tag *tag)
+{
+       return tag->blank;
+}
+
 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
 {
        if (data_length == NULL)
@@ -908,6 +937,9 @@ int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
 
        DBG("type 0x%x", tag->type);
 
+       /* Stop check presence while reading */
+       __near_adapter_stop_check_presence(tag->adapter_idx, tag->target_idx);
+
        for (list = driver_list; list; list = list->next) {
                struct near_tag_driver *driver = list->data;
 
@@ -936,21 +968,32 @@ int __near_tag_write(struct near_tag *tag,
                DBG("driver type 0x%x", driver->type);
 
                if (driver->type == tag->type) {
+                       /* Stop check presence while writing */
+                       __near_adapter_stop_check_presence(tag->adapter_idx,
+                                                               tag->target_idx);
+
                        if (tag->blank == TRUE && driver->format != NULL) {
                                DBG("Blank tag detected, formatting");
                                err = driver->format(tag->adapter_idx,
                                                tag->target_idx, format_cb);
-                               if (err < 0)
-                                       return err;
                        } else {
-                               return driver->write(tag->adapter_idx,
-                                               tag->target_idx, ndef,
-                                               cb);
+                               err = driver->write(tag->adapter_idx,
+                                                       tag->target_idx, ndef,
+                                                       cb);
                        }
+
+                       break;
                }
        }
 
-       return 0;
+       if (list == NULL)
+               err = -EOPNOTSUPP;
+
+       if (err < 0)
+               __near_adapter_start_check_presence(tag->adapter_idx,
+                                                       tag->target_idx);
+
+       return err;
 }
 
 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)