summaryrefslogtreecommitdiff
path: root/tpsip/base-connection-sofia.c
diff options
context:
space:
mode:
Diffstat (limited to 'tpsip/base-connection-sofia.c')
-rw-r--r--tpsip/base-connection-sofia.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/tpsip/base-connection-sofia.c b/tpsip/base-connection-sofia.c
new file mode 100644
index 0000000..4c04eae
--- /dev/null
+++ b/tpsip/base-connection-sofia.c
@@ -0,0 +1,169 @@
+/*
+ * sip-connection-sofia.c - Source for TpsipConnection Sofia event handling
+ * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Collabora Ltd.
+ * @author Kai Vehmanen <first.surname@nokia.com>
+ * @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
+ *
+ * This work 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 work 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 work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <tpsip/base-connection.h>
+#include <sofia-sip/su_tag_io.h>
+
+#define DEBUG_FLAG TPSIP_DEBUG_EVENTS
+#include "src/debug.h"
+
+static void
+priv_r_shutdown(int status,
+ nua_t *nua)
+{
+ GSource *source;
+ gboolean source_recursive;
+
+ if (status < 200)
+ return;
+
+ /* Should be the source of the Sofia root */
+ source = g_main_current_source ();
+
+ /* XXX: temporarily allow recursion in the Sofia source to work around
+ * nua_destroy() requiring nested mainloop iterations to complete
+ * (Sofia-SIP bug #1624446). Actual recursion safety of the source is to be
+ * examined. */
+ source_recursive = g_source_get_can_recurse (source);
+ if (!source_recursive)
+ {
+ DEBUG("forcing Sofia root GSource to be recursive");
+ g_source_set_can_recurse (source, TRUE);
+ }
+
+ DEBUG("destroying Sofia-SIP NUA at address %p", nua);
+ nua_destroy (nua);
+
+ if (!source_recursive)
+ g_source_set_can_recurse (source, FALSE);
+}
+
+#if 0
+static void
+priv_r_unregister (int status,
+ char const *phrase,
+ nua_handle_t *nh)
+{
+ DEBUG("un-REGISTER got response: %03d %s", status, phrase);
+
+ if (status < 200)
+ return;
+
+ if (status == 401 || status == 407)
+ {
+ /* In SIP, de-registration can fail! However, there's not a lot we can
+ * do about this in the Telepathy model - once you've gone DISCONNECTED
+ * you're really not meant to go "oops, I'm still CONNECTED after all".
+ * So we ignore it and hope it goes away. */
+ WARNING ("Registrar won't let me unregister: %d %s", status, phrase);
+ }
+}
+#endif
+
+#ifdef ENABLE_DEBUG
+static void
+priv_r_get_params (int status,
+ nua_t *nua,
+ nua_handle_t *nh,
+ tagi_t tags[])
+{
+ if (status < 200)
+ return;
+
+ if (nh != NULL)
+ return;
+
+ /* note: print contents of all tags to stdout */
+ tl_print(stdout, "Sofia-SIP NUA stack parameters:\n", tags);
+}
+#endif
+
+/**
+ * Callback for events delivered by the SIP stack.
+ *
+ * See libsofia-sip-ua/nua/nua.h documentation.
+ */
+void
+tpsip_base_connection_sofia_callback (nua_event_t event,
+ int status,
+ char const *phrase,
+ nua_t *nua,
+ TpsipBaseConnection *conn,
+ nua_handle_t *nh,
+ TpsipEventTarget *target,
+ sip_t const *sip,
+ tagi_t tags[])
+{
+ DEBUG("event %s: %03d %s",
+ nua_event_name (event), status, phrase);
+
+ switch (event)
+ {
+#ifdef ENABLE_DEBUG
+ case nua_r_get_params:
+ priv_r_get_params (status, nua, nh, tags);
+ return;
+#endif
+ case nua_r_shutdown:
+ priv_r_shutdown (status, nua);
+ return;
+ default:
+ break;
+ }
+
+ g_assert (conn != NULL);
+
+ DEBUG("connection %p, refcount %d", conn, ((GObject *)conn)->ref_count);
+
+ {
+ TpsipNuaEvent ev = {
+ event,
+ status,
+ phrase,
+ nua,
+ nh,
+ sip
+ };
+
+ if (target == NULL)
+ {
+ target = (TpsipEventTarget *) conn;
+ DEBUG("dispatching to connection %p (unbound handle %p)", conn, nh);
+ }
+ else
+ {
+ g_assert (nh != NULL);
+ DEBUG("dispatching to target %p (handle %p)", target, nh);
+ }
+
+ if (!tpsip_event_target_emit_nua_event (target,
+ &ev,
+ tags))
+ {
+ DEBUG("event %s for target %p was not consumed", nua_event_name (event), target);
+ }
+ }
+
+ DEBUG ("exit");
+}