[Telepathy-commits] [telepathy-gabble/master] Support location event notifications

Pierre-Luc Beaudoin pierre-luc.beaudoin at collabora.co.uk
Sun Feb 1 05:24:00 PST 2009


---
 src/conn-location.c |  156 ++++++++++++++++++++++++++++++---------------------
 src/conn-location.h |    4 +
 src/pubsub.c        |    2 +
 3 files changed, 99 insertions(+), 63 deletions(-)

diff --git a/src/conn-location.c b/src/conn-location.c
index cb134af..51cafc5 100644
--- a/src/conn-location.c
+++ b/src/conn-location.c
@@ -3,6 +3,7 @@
 #include "conn-location.h"
 #include "presence-cache.h"
 
+#include <string.h>
 #include <stdlib.h>
 
 #define DEBUG_FLAG GABBLE_DEBUG_LOCATION
@@ -36,6 +37,9 @@
 #define LOCATION_VERTICAL_ERROR_M "vertical-error-m"
 #define LOCATION_HORIZONTAL_ERROR_M "horizontal-error-m"
 
+static gboolean update_location (GabbleConnection *conn, const gchar *from,
+    LmMessage *msg);
+
 /* XXX: similar to conn-olpc.c's inspect_contact(), except that it assumes
  * that the handle is valid. (Does tp_handle_inspect check validity anyway?)
  * Reduce duplication.
@@ -50,6 +54,16 @@ inspect_contact (TpBaseConnection *base,
   return tp_handle_inspect (contact_repo, contact);
 }
 
+static guint
+lookup_contact (TpBaseConnection *base,
+                const gchar *from)
+{
+  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
+      base, TP_HANDLE_TYPE_CONTACT);
+
+  return tp_handle_lookup (contact_repo, from, NULL, NULL);
+}
+
 static gboolean
 validate_contacts (TpBaseConnection *base,
                    DBusGMethodInvocation *context,
@@ -88,10 +102,10 @@ lm_message_node_get_double (LmMessageNode *node,
 
   return TRUE;
 }
-/*
+
 static gboolean
 lm_message_node_get_string (LmMessageNode *node,
-                            gchar *s)
+                            gchar **s)
 {
   const gchar *value;
 
@@ -100,10 +114,10 @@ lm_message_node_get_string (LmMessageNode *node,
   if (value == NULL)
     return FALSE;
 
-  s = g_strdup (value);
+  *s = g_strdup (value);
   return TRUE;
 }
-*/
+
 static LmHandlerResult
 pep_reply_cb (GabbleConnection *conn,
               LmMessage *sent_msg,
@@ -111,68 +125,12 @@ pep_reply_cb (GabbleConnection *conn,
               GObject *object,
               gpointer user_data)
 {
-  TpBaseConnection *base = (TpBaseConnection *) conn;
-  TpHandleRepoIface *contact_repo =
-      tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT);
-  LmMessageNode *geoloc;
-  LmMessageNode *lat_node;
-  LmMessageNode *lon_node;
-  GHashTable *result = NULL;
   const gchar *from;
-  gdouble lat;
-  gdouble lon;
-  guint contact;
 
-  result = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_free,
-      (GDestroyNotify) tp_g_value_slice_free);
   from = lm_message_node_get_attribute (reply_msg->node, "from");
 
-  if (from == NULL)
-    goto END;
-
-  contact = tp_handle_lookup (contact_repo, from, NULL, NULL);
-  /* XXX: ref all the handles */
-  g_assert (contact);
-  geoloc = lm_message_node_find_child (reply_msg->node, "geoloc");
-
-  if (geoloc == NULL)
-    goto END;
-
-  lat_node = lm_message_node_find_child (geoloc, "lat");
-  lon_node = lm_message_node_find_child (geoloc, "lon");
-
-  if (lat_node == NULL &&
-      lon_node == NULL)
-    goto END;
-
-  if (lat_node != NULL && lm_message_node_get_double (lat_node, &lat))
-    {
-      GValue *value = g_slice_new0 (GValue);
-
-      g_value_init (value, G_TYPE_DOUBLE);
-      g_value_set_double (value, lat);
-      g_hash_table_insert (result, g_strdup ("lat"), value);
-    }
-
-  if (lon_node != NULL && lm_message_node_get_double (lon_node, &lon))
-    {
-      GValue *value = g_slice_new0 (GValue);
-
-      g_value_init (value, G_TYPE_DOUBLE);
-      g_value_set_double (value, lon);
-      g_hash_table_insert (result, g_strdup ("lon"), value);
-    }
-
-  DEBUG ("LocationsUpdate %s (%f, %f)", from, lat, lon);
-
-  gabble_presence_cache_update_location (conn->presence_cache, contact,
-      result);
-
-  gabble_svc_connection_interface_location_emit_location_updated (conn,
-      contact, result);
-
-END:
-  g_hash_table_destroy (result);
+  if (from != NULL)
+    update_location (conn, from, reply_msg);
 
   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 }
@@ -278,7 +236,6 @@ location_set_location (GabbleSvcConnectionInterfaceLocation *iface,
       return;
     }
 
-
   dbus_g_method_return (context);
 }
 
@@ -344,3 +301,76 @@ conn_location_propeties_getter (GObject *object,
     }
 }
 
+static gboolean
+update_location (GabbleConnection *conn,
+                 const gchar *from,
+                 LmMessage *msg)
+{
+  LmMessageNode *node, *subloc_node;
+  gchar *key, *str;
+  gdouble double_value;
+  GValue *value;
+  GHashTable *location = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_free,
+      (GDestroyNotify) tp_g_value_slice_free);
+  guint contact = lookup_contact ((TpBaseConnection *) conn, from);
+
+  node = lm_message_node_find_child (msg->node, "geoloc");
+  if (node == NULL)
+    return FALSE;
+
+  DEBUG ("LocationsUpdate for %s:", from);
+
+  for (subloc_node = node->children; subloc_node != NULL;
+      subloc_node = subloc_node->next)
+    {
+      key = subloc_node->name;
+
+      if ((strcmp (key, "lat") == 0 ||
+           strcmp (key, "lon") == 0 ||
+           strcmp (key, "alt") == 0 ||
+           strcmp (key, "accuracy") == 0) &&
+          lm_message_node_get_double (subloc_node, &double_value))
+        {
+          value = g_slice_new0 (GValue);
+          g_value_init (value, G_TYPE_DOUBLE);
+          g_value_set_double (value, double_value);
+          DEBUG ("\t - %s: %f", key, double_value);
+        }
+      else if (lm_message_node_get_string (subloc_node, &str))
+        {
+          value = g_slice_new0 (GValue);
+          g_value_init (value, G_TYPE_STRING);
+          g_value_take_string (value, str);
+          DEBUG ("\t - %s: %s", key, str);
+        }
+
+      g_hash_table_insert (location, g_strdup (key), value);
+    }
+
+
+  gabble_presence_cache_update_location (conn->presence_cache, contact,
+      location);
+  gabble_svc_connection_interface_location_emit_location_updated (conn,
+      contact, location);
+  g_hash_table_unref (location);
+
+  return TRUE;
+}
+
+gboolean
+geolocation_event_handler (GabbleConnection *conn,
+                           LmMessage *msg,
+                           TpHandle handle)
+{
+  TpBaseConnection *base = (TpBaseConnection *) conn;
+  const gchar *from;
+
+  if (handle == base->self_handle)
+    /* Ignore echoed pubsub notifications */
+    return TRUE;
+
+  from = lm_message_node_get_attribute (msg->node, "from");
+
+  return update_location (conn, from, msg);
+}
+
diff --git a/src/conn-location.h b/src/conn-location.h
index c041101..32cf0cc 100644
--- a/src/conn-location.h
+++ b/src/conn-location.h
@@ -2,6 +2,7 @@
 #ifndef __CONN_LOCATION_H__
 #define __CONN_LOCATION_H__
 
+#include "connection.h"
 #include <extensions/extensions.h>
 
 G_BEGIN_DECLS
@@ -11,6 +12,9 @@ void location_iface_init (gpointer g_iface, gpointer iface_data);
 void conn_location_propeties_getter (GObject *object, GQuark interface,
     GQuark name, GValue *value, gpointer getter_data);
 
+gboolean geolocation_event_handler (GabbleConnection *conn,
+    LmMessage *msg, TpHandle handle);
+
 G_END_DECLS
 
 #endif /* __CONN_LOCATION_H__ */
diff --git a/src/pubsub.c b/src/pubsub.c
index 3ecd8fd..e6ec305 100644
--- a/src/pubsub.c
+++ b/src/pubsub.c
@@ -29,6 +29,7 @@
 #include "namespaces.h"
 #include "util.h"
 #include "conn-olpc.h"
+#include "conn-location.h"
 
 static const GabblePubsubEventHandler pubsub_event_handlers[] =
 {
@@ -37,6 +38,7 @@ static const GabblePubsubEventHandler pubsub_event_handlers[] =
     { NS_OLPC_ACTIVITIES, olpc_buddy_info_activities_event_handler},
     { NS_OLPC_CURRENT_ACTIVITY, olpc_buddy_info_current_activity_event_handler},
     { NS_OLPC_ACTIVITY_PROPS, olpc_activities_properties_event_handler},
+    { NS_GEOLOC, geolocation_event_handler},
     { NULL, NULL}
 };
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list