adapter: Implement TagFound signal
authorSamuel Ortiz <sameo@linux.intel.com>
Sun, 13 Oct 2013 22:56:44 +0000 (00:56 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Sun, 13 Oct 2013 22:58:28 +0000 (00:58 +0200)
And TagLost as well. Those signals fix the current racy behaviour where
apps get a Tags property change notification and then ask for the tag
properties. The tag may have disappeared in the meantime.
Eventually, the Tags property should disappear.

src/adapter.c
src/near.h
src/tag.c
test/monitor-near

index e91fc30..674d8ef 100644 (file)
@@ -756,6 +756,7 @@ void __near_adapter_remove(struct near_adapter *adapter)
 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
 {
        struct near_adapter *adapter;
+       struct near_tag *tag;
 
        DBG("status %d", status);
 
@@ -774,6 +775,10 @@ static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
 
        __near_adapter_tags_changed(adapter_idx);
 
+       tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx));
+       if (tag)
+               __near_tag_found_signal(adapter, tag);
+
        adapter->presence_timeout =
                g_timeout_add_seconds(CHECK_PRESENCE_PERIOD,
                                        check_presence, adapter);
@@ -914,6 +919,7 @@ int __near_adapter_add_target(uint32_t idx, uint32_t target_idx,
 int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx)
 {
        struct near_adapter *adapter;
+       struct near_tag *tag;
 
        DBG("idx %d", idx);
 
@@ -924,8 +930,11 @@ int __near_adapter_remove_target(uint32_t idx, uint32_t target_idx)
        adapter->rf_mode = NEAR_ADAPTER_RF_MODE_IDLE;
        rf_mode_changed(adapter);
 
-       if (g_hash_table_remove(adapter->tags,
-                       GINT_TO_POINTER(target_idx))) {
+       tag = g_hash_table_lookup(adapter->tags, GINT_TO_POINTER(target_idx));
+       if (tag) {
+               __near_tag_lost_signal(adapter, tag);
+               g_hash_table_remove(adapter->tags, GINT_TO_POINTER(target_idx));
+
                __near_adapter_tags_changed(idx);
 
                return 0;
index 5459702..883ac59 100644 (file)
@@ -136,6 +136,8 @@ int __near_tag_write(struct near_tag *tag,
                                struct near_ndef_message *ndef,
                                near_tag_io_cb cb);
 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb);
+void __near_tag_found_signal(struct near_adapter *adapter, struct near_tag *tag);
+void __near_tag_lost_signal(struct near_adapter *adapter, struct near_tag *tag);
 
 #include <near/device.h>
 
index 28518f2..fbc71c3 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -181,24 +181,13 @@ static const char *protocol_string(struct near_tag *tag)
        return protocol;
 }
 
-static DBusMessage *get_properties(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
+static void append_properties(DBusMessageIter *iter, struct near_tag *tag)
 {
-       struct near_tag *tag = data;
-       const char *protocol, *type;
-       DBusMessage *reply;
-       DBusMessageIter array, dict;
+       DBusMessageIter dict;
        dbus_bool_t readonly;
+       const char *protocol, *type;
 
-       DBG("conn %p", conn);
-
-       reply = dbus_message_new_method_return(msg);
-       if (!reply)
-               return NULL;
-
-       dbus_message_iter_init_append(reply, &array);
-
-       near_dbus_dict_open(&array, &dict);
+       near_dbus_dict_open(iter, &dict);
 
        type = type_string(tag);
        if (type)
@@ -217,7 +206,25 @@ static DBusMessage *get_properties(DBusConnection *conn,
        near_dbus_dict_append_array(&dict, "Records",
                                DBUS_TYPE_OBJECT_PATH, append_records, tag);
 
-       near_dbus_dict_close(&array, &dict);
+       near_dbus_dict_close(iter, &dict);
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct near_tag *tag = data;
+       DBusMessage *reply;
+       DBusMessageIter array;
+
+       DBG("conn %p", conn);
+
+       reply = dbus_message_new_method_return(msg);
+       if (!reply)
+               return NULL;
+
+       dbus_message_iter_init_append(reply, &array);
+
+       append_properties(&array, tag);
 
        return reply;
 }
@@ -230,6 +237,44 @@ static DBusMessage *set_property(DBusConnection *conn,
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
+void __near_tag_found_signal(struct near_adapter *adapter,
+                                               struct near_tag *tag)
+{
+       const char *path;
+       DBusMessage *signal;
+       DBusMessageIter iter;
+
+       path = __near_adapter_get_path(adapter);
+       if (!path)
+               return;
+
+       signal = dbus_message_new_signal(path, NFC_ADAPTER_INTERFACE,
+                                                               "TagFound");
+       if (!signal)
+               return;
+
+       dbus_message_iter_init_append(signal, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+                                                               &tag->path);
+       append_properties(&iter, tag);
+
+       dbus_connection_send(connection, signal, NULL);
+       dbus_message_unref(signal);
+}
+
+void __near_tag_lost_signal(struct near_adapter *adapter, struct near_tag *tag)
+{
+       const char *path;
+
+       path = __near_adapter_get_path(adapter);
+       if (!path)
+               return;
+
+       g_dbus_emit_signal(connection, path, NFC_ADAPTER_INTERFACE,
+                       "TagLost", DBUS_TYPE_OBJECT_PATH, &tag->path,
+                       DBUS_TYPE_INVALID);
+}
+
 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
 {
        struct near_tag *tag;
index a8cf948..98bb64f 100755 (executable)
@@ -21,14 +21,6 @@ def extract_bool(b):
                val = "false"
        return val      
 
-
-def property_changed_tag(name, value, path):
-    tag = path[path.rfind("/") + 1:]
-    if name in ["Records"]:
-           val = extract_list(value)
-
-    print "[Tag] [%s] %s = %s" % (tag, name, val)
-
 def property_changed_device(name, value, path):
     device = path[path.rfind("/") + 1:]
     if name in ["Records"]:
@@ -47,6 +39,43 @@ def property_changed_adapter(name, value, path):
 
     print "[Adapter] [%s] %s = %s" % (adapter, name, val)
 
+def extract_record(key, list):
+       for i in list:
+               record = dbus.Interface(bus.get_object("org.neard", i),
+                                               "org.neard.Record")
+
+               properties = record.GetProperties()
+               print "        Record = [ %s ]" % (str(i))
+
+               for key in properties.keys():
+                       if key in ["Representation"]:
+                               val = unicode(properties[key])
+                       else:
+                               val = str(properties[key])
+                       print "              %s = %s" % (key, val)
+
+def tag_found(path, properties, adapter_path):
+    tag = path[path.rfind("/") + 1:]
+    adapter = adapter_path[adapter_path.rfind("/") + 1:]
+
+    print "[Adapter] [%s] TagFound %s" % (adapter, path)
+    for key in properties.keys():
+           if key in ["Type"]:
+                   val = str(properties[key])
+                   print "        %s = %s" % (key, val)
+           elif key in ["Protocol"]:
+                   val = str(properties[key])
+                   print "        %s = %s" % (key, val)
+
+           elif key in ["Records"]:
+                   extract_record(key, properties[key])
+
+def tag_lost(path, adapter_path):
+    tag = path[path.rfind("/") + 1:]
+    adapter = adapter_path[adapter_path.rfind("/") + 1:]
+
+    print "[Adapter] [%s] TagLost %s" % (adapter, path)
+
 def property_changed_manager(name, value, path):
     manager = path[path.rfind("/") + 1:]
     if name in ["Adapters"]:
@@ -72,11 +101,17 @@ if __name__ == '__main__':
                                signal_name = "PropertyChanged",
                                path_keyword="path")
 
-       bus.add_signal_receiver(property_changed_tag,
+       bus.add_signal_receiver(tag_found,
                                bus_name="org.neard",
-                               dbus_interface="org.neard.Tag",
-                               signal_name = "PropertyChanged",
-                               path_keyword="path")
+                               dbus_interface="org.neard.Adapter",
+                               signal_name = "TagFound",
+                               path_keyword="adapter_path")
+
+       bus.add_signal_receiver(tag_lost,
+                               bus_name="org.neard",
+                               dbus_interface="org.neard.Adapter",
+                               signal_name = "TagLost",
+                               path_keyword="adapter_path")
 
        bus.add_signal_receiver(property_changed_device,
                                bus_name="org.neard",