summaryrefslogtreecommitdiff
path: root/src/avahi-olpc-activity-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/avahi-olpc-activity-manager.c')
-rw-r--r--src/avahi-olpc-activity-manager.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/src/avahi-olpc-activity-manager.c b/src/avahi-olpc-activity-manager.c
new file mode 100644
index 00000000..f7ae90fd
--- /dev/null
+++ b/src/avahi-olpc-activity-manager.c
@@ -0,0 +1,376 @@
+/*
+ * avahi-avahi_olpc-activity-manager.c - Source for
+ * SalutAvahiOlpcActivityManager
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "avahi-olpc-activity-manager.h"
+
+#include <dbus/dbus-glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <avahi-gobject/ga-service-browser.h>
+
+#include "avahi-olpc-activity.h"
+#include "avahi-discovery-client.h"
+#include "olpc-activity.h"
+
+#define DEBUG_FLAG DEBUG_OLPC_ACTIVITY
+#include "debug.h"
+
+G_DEFINE_TYPE (SalutAvahiOlpcActivityManager, salut_avahi_olpc_activity_manager,
+ SALUT_TYPE_OLPC_ACTIVITY_MANAGER);
+
+/* properties */
+enum {
+ PROP_CLIENT = 1,
+ LAST_PROP
+};
+
+/* private structure */
+typedef struct _SalutAvahiOlpcActivityManagerPrivate SalutAvahiOlpcActivityManagerPrivate;
+
+struct _SalutAvahiOlpcActivityManagerPrivate
+{
+ SalutAvahiDiscoveryClient *discovery_client;
+ GaServiceBrowser *browser;
+
+ gboolean dispose_has_run;
+};
+
+#define SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SALUT_TYPE_AVAHI_OLPC_ACTIVITY_MANAGER, SalutAvahiOlpcActivityManagerPrivate))
+
+static void
+salut_avahi_olpc_activity_manager_init (SalutAvahiOlpcActivityManager *self)
+{
+ SalutAvahiOlpcActivityManagerPrivate *priv =
+ SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ priv->browser = ga_service_browser_new (SALUT_DNSSD_OLPC_ACTIVITY);
+}
+
+static void
+salut_avahi_olpc_activity_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SalutAvahiOlpcActivityManager *self = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER (object);
+ SalutAvahiOlpcActivityManagerPrivate *priv = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->discovery_client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+salut_avahi_olpc_activity_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SalutAvahiOlpcActivityManager *self = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER (object);
+ SalutAvahiOlpcActivityManagerPrivate *priv = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_CLIENT:
+ priv->discovery_client = g_value_get_object (value);
+ g_object_ref (priv->discovery_client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+split_activity_name (const gchar *name,
+ gchar **room_name,
+ gchar **contact_name)
+{
+ gchar **tmp;
+
+ tmp = g_strsplit (name, ":", 2);
+ if (tmp[0] == NULL || tmp[1] == NULL)
+ {
+ DEBUG ("Ignoring invalid OLPC activity DNS-SD with no ':': %s", name);
+ return FALSE;
+ }
+
+ if (room_name != NULL)
+ *room_name = g_strdup (tmp[0]);
+ if (contact_name != NULL)
+ *contact_name = g_strdup (tmp[1]);
+
+ g_strfreev (tmp);
+ return TRUE;
+}
+
+static void
+browser_found (GaServiceBrowser *browser,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ const char *name,
+ const char *type,
+ const char *domain,
+ GaLookupResultFlags flags,
+ SalutAvahiOlpcActivityManager *self)
+{
+ SalutOlpcActivityManager *mgr = SALUT_OLPC_ACTIVITY_MANAGER (self);
+ SalutOlpcActivity *activity;
+ gchar *room_name = NULL;
+ gchar *contact_name = NULL;
+ TpBaseConnection *base_conn = (TpBaseConnection *) mgr->connection;
+ TpHandleRepoIface *room_repo = tp_base_connection_get_handles (
+ base_conn, TP_HANDLE_TYPE_ROOM);
+ TpHandle room;
+ GError *error = NULL;
+ SalutContactManager *contact_manager;
+ SalutContact *contact;
+
+ if (flags & AVAHI_LOOKUP_RESULT_OUR_OWN)
+ return;
+
+ if (tp_base_connection_is_destroyed (base_conn))
+ return;
+
+ if (!split_activity_name (name, &room_name, &contact_name))
+ return;
+
+ room = tp_handle_ensure (room_repo, room_name, NULL, &error);
+ if (room == 0)
+ {
+ DEBUG ("invalid room name %s: %s", room_name, error->message);
+ g_free (room_name);
+ g_free (contact_name);
+ return;
+ }
+
+ activity = salut_olpc_activity_manager_ensure_activity_by_room (mgr,
+ room);
+
+ salut_avahi_olpc_activity_add_service (SALUT_AVAHI_OLPC_ACTIVITY (activity),
+ interface, protocol, name, type, domain);
+
+ g_object_get (mgr->connection,
+ "contact-manager", &contact_manager, NULL);
+ g_assert (contact_manager != NULL);
+
+ contact = salut_contact_manager_ensure_contact (contact_manager,
+ contact_name);
+ salut_olpc_activity_manager_contact_joined (mgr, contact, activity);
+
+ g_object_unref (activity);
+ g_free (contact_name);
+ g_free (room_name);
+ g_object_unref (contact);
+ g_object_unref (contact_manager);
+}
+
+static void
+browser_removed (GaServiceBrowser *browser,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ const char *name,
+ const char *type,
+ const char *domain,
+ GaLookupResultFlags flags,
+ SalutAvahiOlpcActivityManager *self)
+{
+ SalutOlpcActivityManager *mgr = SALUT_OLPC_ACTIVITY_MANAGER (self);
+ SalutOlpcActivity *activity;
+ gchar *room_name = NULL;
+ gchar *contact_name = NULL;
+ TpHandleRepoIface *room_repo = tp_base_connection_get_handles
+ ((TpBaseConnection *) mgr->connection, TP_HANDLE_TYPE_ROOM);
+ TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
+ ((TpBaseConnection *) mgr->connection, TP_HANDLE_TYPE_CONTACT);
+ TpHandle room;
+ TpHandle contact_handle;
+ GError *error = NULL;
+ SalutContactManager *contact_manager;
+ SalutContact *contact;
+
+ if (!split_activity_name (name, &room_name, &contact_name))
+ return;
+
+ room = tp_handle_ensure (room_repo, room_name, NULL, &error);
+ g_free (room_name);
+ if (room == 0)
+ {
+ DEBUG ("invalid room name %s: %s", room_name, error->message);
+ g_free (contact_name);
+ g_error_free (error);
+ return;
+ }
+
+ contact_handle = tp_handle_ensure (contact_repo, contact_name, NULL, &error);
+ if (contact_handle == 0)
+ {
+ DEBUG ("Invalid contact name %s: %s", contact_name, error->message);
+ g_error_free (error);
+ g_free (contact_name);
+ return;
+ }
+ g_free (contact_name);
+
+ activity = salut_olpc_activity_manager_get_activity_by_room (mgr, room);
+ if (activity == NULL)
+ return;
+
+ salut_avahi_olpc_activity_remove_service (SALUT_AVAHI_OLPC_ACTIVITY (activity),
+ interface, protocol, name, type, domain);
+
+ g_object_get (mgr->connection,
+ "contact-manager", &contact_manager, NULL);
+ g_assert (contact_manager != NULL);
+
+ contact = salut_contact_manager_get_contact (contact_manager,
+ contact_handle);
+ g_object_unref (contact_manager);
+ if (contact == NULL)
+ return;
+
+ salut_olpc_activity_manager_contact_left (mgr, contact, activity);
+ g_object_unref (contact);
+}
+
+static void
+browser_failed (GaServiceBrowser *browser,
+ GError *error,
+ SalutAvahiOlpcActivityManager *self)
+{
+ g_warning ("browser failed -> %s", error->message);
+}
+
+static gboolean
+salut_avahi_olpc_activity_manager_start (SalutOlpcActivityManager *mgr,
+ GError **error)
+{
+ SalutAvahiOlpcActivityManager *self = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER (mgr);
+ SalutAvahiOlpcActivityManagerPrivate *priv =
+ SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ g_signal_connect (priv->browser, "new-service",
+ G_CALLBACK (browser_found), self);
+ g_signal_connect (priv->browser, "removed-service",
+ G_CALLBACK (browser_removed), self);
+ g_signal_connect (priv->browser, "failure",
+ G_CALLBACK (browser_failed), self);
+
+ if (!ga_service_browser_attach (priv->browser,
+ priv->discovery_client->avahi_client, error))
+ {
+ DEBUG ("browser attach failed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static SalutOlpcActivity *
+salut_avahi_olpc_activity_manager_create_activity (
+ SalutOlpcActivityManager *mgr)
+{
+ SalutAvahiOlpcActivityManager *self = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER (mgr);
+ SalutAvahiOlpcActivityManagerPrivate *priv =
+ SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ return SALUT_OLPC_ACTIVITY (salut_avahi_olpc_activity_new (
+ mgr->connection, priv->discovery_client));
+}
+
+static void salut_avahi_olpc_activity_manager_dispose (GObject *object);
+
+static void
+salut_avahi_olpc_activity_manager_class_init (SalutAvahiOlpcActivityManagerClass *salut_avahi_olpc_activity_manager_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (salut_avahi_olpc_activity_manager_class);
+ SalutOlpcActivityManagerClass *activity_manager_class = SALUT_OLPC_ACTIVITY_MANAGER_CLASS (
+ salut_avahi_olpc_activity_manager_class);
+
+ GParamSpec *param_spec;
+
+ g_type_class_add_private (salut_avahi_olpc_activity_manager_class,
+ sizeof (SalutAvahiOlpcActivityManagerPrivate));
+
+ object_class->get_property = salut_avahi_olpc_activity_manager_get_property;
+ object_class->set_property = salut_avahi_olpc_activity_manager_set_property;
+
+ object_class->dispose = salut_avahi_olpc_activity_manager_dispose;
+
+ activity_manager_class->start = salut_avahi_olpc_activity_manager_start;
+ activity_manager_class->create_activity =
+ salut_avahi_olpc_activity_manager_create_activity;
+
+ param_spec = g_param_spec_object (
+ "discovery-client",
+ "SalutAvahiDiscoveryClient object",
+ "The Salut Avahi Discovery client associated with this manager",
+ SALUT_TYPE_AVAHI_DISCOVERY_CLIENT,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CLIENT,
+ param_spec);
+}
+
+static void
+salut_avahi_olpc_activity_manager_dispose (GObject *object)
+{
+ SalutAvahiOlpcActivityManager *self = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER (object);
+ SalutAvahiOlpcActivityManagerPrivate *priv = SALUT_AVAHI_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
+
+ if (priv->dispose_has_run)
+ return;
+
+ priv->dispose_has_run = TRUE;
+
+ if (priv->discovery_client != NULL)
+ {
+ g_object_unref (priv->discovery_client);
+ priv->discovery_client = NULL;
+ }
+
+ if (priv->browser != NULL)
+ {
+ g_object_unref (priv->browser);
+ priv->browser = NULL;
+ }
+
+ if (G_OBJECT_CLASS (salut_avahi_olpc_activity_manager_parent_class)->dispose)
+ G_OBJECT_CLASS (salut_avahi_olpc_activity_manager_parent_class)->dispose (object);
+}
+
+SalutAvahiOlpcActivityManager *
+salut_avahi_olpc_activity_manager_new (SalutConnection *connection,
+ SalutAvahiDiscoveryClient *discovery_client)
+{
+ return g_object_new (SALUT_TYPE_AVAHI_OLPC_ACTIVITY_MANAGER,
+ "connection", connection,
+ "discovery-client", discovery_client,
+ NULL);
+}