summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Pessi <Pekka.Pessi@nokia.com>2011-02-07 19:58:07 +0200
committerPekka Pessi <Pekka.Pessi@nokia.com>2011-02-07 19:58:07 +0200
commit262656c55e4112d36005426cd5985df3c94a74f7 (patch)
treea9431f1236a8ace7f49273517f0f56162c55c7e8
parent26eae76d331cfa19edfc35dabf258a353904bd2a (diff)
parent9b8b2a7a9d0a39557394c19d932603ac3a37dd40 (diff)
Merge branch 'tpsip-base-connection'
-rw-r--r--src/Makefile.am6
-rw-r--r--src/conn-aliasing.h33
-rw-r--r--src/media-factory.c28
-rw-r--r--src/protocol.c1
-rw-r--r--src/sip-connection-helpers.c306
-rw-r--r--src/sip-connection-helpers.h27
-rw-r--r--src/sip-connection-private.h1
-rw-r--r--src/sip-connection-sofia.h48
-rw-r--r--src/sip-connection.c107
-rw-r--r--src/sip-connection.h17
-rw-r--r--src/sip-media-channel.c15
-rw-r--r--src/sip-media-session.c7
-rw-r--r--src/sip-text-channel.c12
-rw-r--r--src/text-factory.c31
-rw-r--r--tests/twisted/Makefile.am3
-rw-r--r--tests/twisted/test-self-alias.py10
-rw-r--r--tpsip/Makefile.am9
-rw-r--r--tpsip/base-connection-sofia.c (renamed from src/sip-connection-sofia.c)23
-rw-r--r--tpsip/base-connection.c205
-rw-r--r--tpsip/base-connection.h92
-rw-r--r--tpsip/connection-aliasing.c (renamed from src/conn-aliasing.c)117
-rw-r--r--tpsip/connection-aliasing.h58
-rw-r--r--tpsip/handles.c345
-rw-r--r--tpsip/handles.h47
-rw-r--r--tpsip/sofia-decls.h9
25 files changed, 974 insertions, 583 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ca15a87..a8c6c4e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,8 +86,6 @@ libtpsip_convenience_la_SOURCES = \
sip-connection.c \
sip-connection-manager.h \
sip-connection-manager.c \
- conn-aliasing.h \
- conn-aliasing.c \
debug.h \
debug.c \
media-factory.h \
@@ -98,9 +96,7 @@ libtpsip_convenience_la_SOURCES = \
text-factory.c \
sip-connection-helpers.h \
sip-connection-helpers.c \
- sip-connection-private.h \
- sip-connection-sofia.h \
- sip-connection-sofia.c
+ sip-connection-private.h
nodist_libtpsip_convenience_la_SOURCES = \
$(BUILT_SOURCES)
diff --git a/src/conn-aliasing.h b/src/conn-aliasing.h
deleted file mode 100644
index 953ba0a..0000000
--- a/src/conn-aliasing.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * conn-aliasing.h - Aliasing interface implementation for TpsipConnection
- * Copyright (C) 2008 Nokia Corporation
- * @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
- */
-
-#ifndef __TPSIP_CONN_ALIASING_H__
-#define __TPSIP_CONN_ALIASING_H__
-
-#include "sip-connection.h"
-
-G_BEGIN_DECLS
-
-void tpsip_conn_aliasing_init (TpsipConnection *conn);
-void tpsip_conn_aliasing_iface_init (gpointer g_iface, gpointer iface_data);
-
-G_END_DECLS
-
-#endif /*__TPSIP_CONN_ALIASING_H__*/
diff --git a/src/media-factory.c b/src/media-factory.c
index 1e941fe..14e13b7 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -27,8 +27,8 @@
#include <telepathy-glib/interfaces.h>
#include "sip-media-channel.h"
-#include "sip-connection.h"
-#include "sip-connection-helpers.h"
+#include <tpsip/base-connection.h>
+#include <tpsip/handles.h>
#include <sofia-sip/sip_status.h>
@@ -61,7 +61,7 @@ typedef struct _TpsipMediaFactoryPrivate TpsipMediaFactoryPrivate;
struct _TpsipMediaFactoryPrivate
{
/* unreferenced (since it owns this factory) */
- TpsipConnection *conn;
+ TpBaseConnection *conn;
/* array of referenced (TpsipMediaChannel *) */
GPtrArray *channels;
/* for unique channel object paths, currently always increments */
@@ -181,9 +181,10 @@ tpsip_media_factory_class_init (TpsipMediaFactoryClass *klass)
object_class->dispose = tpsip_media_factory_dispose;
object_class->finalize = tpsip_media_factory_finalize;
- param_spec = g_param_spec_object ("connection", "TpsipConnection object",
+ param_spec = g_param_spec_object ("connection",
+ "TpsipBaseConnection object",
"SIP connection that owns this media channel factory",
- TPSIP_TYPE_CONNECTION,
+ TPSIP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
@@ -265,7 +266,6 @@ new_media_channel (TpsipMediaFactory *fac,
{
TpsipMediaFactoryPrivate *priv;
TpsipMediaChannel *chan = NULL;
- TpBaseConnection *conn;
gchar *object_path;
const gchar *nat_traversal = "none";
gboolean initial_audio;
@@ -275,9 +275,8 @@ new_media_channel (TpsipMediaFactory *fac,
g_assert (initiator != 0);
priv = TPSIP_MEDIA_FACTORY_GET_PRIVATE (fac);
- conn = (TpBaseConnection *)priv->conn;
- object_path = g_strdup_printf ("%s/MediaChannel%u", conn->object_path,
+ object_path = g_strdup_printf ("%s/MediaChannel%u", priv->conn->object_path,
priv->channel_index++);
DEBUG("channel object path %s", object_path);
@@ -285,7 +284,7 @@ new_media_channel (TpsipMediaFactory *fac,
initial_audio = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_AUDIO) != 0);
initial_video = ((flags & TPSIP_MEDIA_CHANNEL_CREATE_WITH_VIDEO) != 0);
- g_object_get (conn,
+ g_object_get (priv->conn,
"immutable-streams", &immutable_streams,
NULL);
@@ -338,15 +337,12 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
TpsipMediaFactory *fac)
{
TpsipMediaChannel *channel;
- TpHandleRepoIface *contact_repo;
TpHandle handle;
guint channel_flags = 0;
/* figure out a handle for the identity */
- contact_repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
-
- handle = tpsip_handle_parse_from (contact_repo, ev->sip);
+ handle = tpsip_handle_by_requestor (conn, ev->sip);
if (!handle)
{
MESSAGE ("incoming INVITE with invalid sender information");
@@ -355,7 +351,7 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
}
DEBUG("Got incoming invite from <%s>",
- tp_handle_inspect (contact_repo, handle));
+ tpsip_handle_inspect (conn, handle));
if (handle == conn->self_handle)
{
@@ -366,7 +362,7 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
channel = new_media_channel (fac, handle, handle, channel_flags);
- tp_handle_unref (contact_repo, handle);
+ tpsip_handle_unref (conn, handle);
/* We delay emission of NewChannel(s) until we have the data on
* initial media */
@@ -379,7 +375,7 @@ tpsip_nua_i_invite_cb (TpBaseConnection *conn,
}
static void
-connection_status_changed_cb (TpsipConnection *conn,
+connection_status_changed_cb (TpsipBaseConnection *conn,
guint status,
guint reason,
TpsipMediaFactory *self)
diff --git a/src/protocol.c b/src/protocol.c
index d9c2383..df9a890 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -26,6 +26,7 @@
#include <dbus/dbus-glib.h>
#include <tpsip/sofia-decls.h>
+#include <tpsip/handles.h>
#include <sofia-sip/su_glib.h>
#define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
diff --git a/src/sip-connection-helpers.c b/src/sip-connection-helpers.c
index 8ad9b42..da192eb 100644
--- a/src/sip-connection-helpers.c
+++ b/src/sip-connection-helpers.c
@@ -31,6 +31,7 @@
#include <telepathy-glib/svc-connection.h>
#include <tpsip/util.h>
+#include <tpsip/handles.h>
#include "sip-connection-helpers.h"
@@ -63,7 +64,7 @@ priv_sip_to_url_make (TpsipConnection *conn,
{
const url_t *url;
- url = tpsip_conn_get_contact_url (conn, contact);
+ url = tpsip_handle_inspect_uri (TP_BASE_CONNECTION (conn), contact);
return sip_to_create (home, (const url_string_t *) url);
}
@@ -152,14 +153,6 @@ tpsip_conn_create_request_handle (TpsipConnection *conn,
}
void
-tpsip_conn_save_event (TpsipConnection *conn,
- nua_saved_event_t ret_saved [1])
-{
- TpsipConnectionPrivate *priv = TPSIP_CONNECTION_GET_PRIVATE (conn);
- nua_save_event (priv->sofia_nua, ret_saved);
-}
-
-void
tpsip_conn_update_proxy_and_transport (TpsipConnection *conn)
{
TpsipConnectionPrivate *priv = TPSIP_CONNECTION_GET_PRIVATE (conn);
@@ -528,13 +521,17 @@ tpsip_conn_resolv_stun_server (TpsipConnection *conn, const gchar *stun_host)
tpsip_conn_set_stun_server_address (conn, stun_host);
return;
}
-
+
if (NULL == priv->sofia_resolver)
{
- priv->sofia_resolver =
- sres_resolver_create (priv->sofia_root, NULL, TAG_END());
+ su_root_t *root = NULL;
+
+ g_object_get (conn, "sofia-root", &root, NULL);
+
+ priv->sofia_resolver = sres_resolver_create (root, NULL, TAG_END());
+
+ g_return_if_fail (priv->sofia_resolver != NULL);
}
- g_return_if_fail (priv->sofia_resolver != NULL);
DEBUG("creating a new resolver query for STUN host name %s", stun_host);
@@ -656,10 +653,13 @@ tpsip_conn_discover_stun_server (TpsipConnection *conn)
if (NULL == priv->sofia_resolver)
{
- priv->sofia_resolver =
- sres_resolver_create (priv->sofia_root, NULL, TAG_END());
+ su_root_t *root = NULL;
+
+ g_object_get (conn, "sofia-root", &root, NULL);
+
+ priv->sofia_resolver = sres_resolver_create (root, NULL, TAG_END());
+ g_return_if_fail (priv->sofia_resolver != NULL);
}
- g_return_if_fail (priv->sofia_resolver != NULL);
DEBUG("creating a new STUN SRV query for domain %s", priv->account_url->url_host);
@@ -674,208 +674,6 @@ tpsip_conn_discover_stun_server (TpsipConnection *conn)
g_free (srv_domain);
}
-static gboolean
-priv_is_host (const gchar* str)
-{
- static GRegex *host_regex = NULL;
-
-#define DOMAIN "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
-#define TLD "[a-z]([-a-z0-9]*[a-z0-9])?"
-
- if (host_regex == NULL)
- {
- GError *error = NULL;
-
- host_regex = g_regex_new ("^("
- "("DOMAIN"\\.)*"TLD"\\.?|" /* host name */
- "[0-9]{1,3}(\\.[0-9]{1,3}){3}|" /* IPv4 address */
- "\\[[0-9a-f:.]\\]" /* IPv6 address, sloppily */
- ")$",
- G_REGEX_CASELESS | G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
-
- if (error != NULL)
- g_error ("failed to compile the host regex: %s", error->message);
- }
-
-#undef DOMAIN
-#undef TLD
-
- return g_regex_match (host_regex, str, 0, NULL);
-}
-
-static gboolean
-priv_is_tel_num (const gchar *str)
-{
- static GRegex *tel_num_regex = NULL;
-
- if (tel_num_regex == NULL)
- {
- GError *error = NULL;
-
- tel_num_regex = g_regex_new (
- "^\\s*[\\+(]?\\s*[0-9][-.0-9()\\s]*$",
- G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
-
- if (error != NULL)
- g_error ("failed to compile the telephone number regex: %s", error->message);
- }
-
- return g_regex_match (tel_num_regex, str, 0, NULL);
-}
-
-/* Strip the non-essential characters from a string regarded as
- * a telephone number */
-static gchar *
-priv_strip_tel_num (const gchar *fuzzy)
-{
- static GRegex *cruft_regex = NULL;
-
- if (cruft_regex == NULL)
- {
- GError *error = NULL;
-
- cruft_regex = g_regex_new ("[^+0-9]+",
- G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
-
- if (error != NULL)
- g_error ("failed to compile the non-essential telephone number cruft regex: %s", error->message);
- }
-
- return g_regex_replace_literal (cruft_regex, fuzzy, -1, 0, "", 0, NULL);
-}
-
-static const char *
-priv_lowercase_url_part (su_home_t *home, const char *src)
-{
- size_t n = 0;
- size_t i;
- char *res;
-
- for (i = 0; src[i]; i++)
- {
- if (g_ascii_isupper (src[i]))
- {
- n = i + strlen (src + i);
- break;
- }
- }
-
- if (!src[i])
- return src;
-
- res = su_alloc (home, n + 1);
- memcpy (res, src, i);
- for (; i < n; i++)
- res[i] = g_ascii_tolower (src[i]);
- res[i] = '\0';
-
- return (const char *) res;
-}
-
-#define TPSIP_RESERVED_CHARS_ALLOWED_IN_USERNAME "!*'()&=+$,;?/"
-
-gchar *
-tpsip_normalize_contact (const gchar *sipuri,
- const url_t *base_url,
- const gchar *transport,
- GError **error)
-{
- su_home_t home[1] = { SU_HOME_INIT(home) };
- url_t *url;
- gchar *retval = NULL;
- char *c;
-
- url = url_make (home, sipuri);
-
- if (url == NULL ||
- (url->url_scheme == NULL && url->url_user == NULL))
- {
- /* we got username or phone number, local to our domain */
- gchar *user;
-
- if (base_url == NULL || base_url->url_host == NULL)
- {
- WARNING ("bare name given, but no account URL is set");
- goto error;
- }
-
- if (priv_is_tel_num (sipuri))
- {
- user = priv_strip_tel_num (sipuri);
- }
- else
- {
- user = g_uri_escape_string (sipuri,
- TPSIP_RESERVED_CHARS_ALLOWED_IN_USERNAME, FALSE);
- }
-
- if (base_url->url_type == url_sips)
- url = url_format (home, "sips:%s@%s",
- user, base_url->url_host);
- else
- url = url_format (home, "sip:%s@%s",
- user, base_url->url_host);
-
- g_free (user);
-
- if (!url) goto error;
- }
- else if (url->url_scheme == NULL)
- {
- /* Set the scheme to SIP or SIPS accordingly to the connection's
- * transport preference */
- if (transport != NULL
- && g_ascii_strcasecmp (transport, "tls") == 0)
- {
- url->url_type = url_sips;
- url->url_scheme = "sips";
- }
- else
- {
- url->url_type = url_sip;
- url->url_scheme = "sip";
- }
- }
-
- if (url_sanitize (url) != 0) goto error;
-
- /* scheme should've been set by now */
- if (url->url_scheme == NULL || (url->url_scheme[0] == 0))
- goto error;
-
- /* convert the scheme to lowercase */
- /* Note: we can't do it in place because url->url_scheme may point to
- * a static string */
- url->url_scheme = priv_lowercase_url_part (home, url->url_scheme);
-
- /* Check that if we have '@', the username isn't empty.
- * Note that we rely on Sofia-SIP to canonize the user name */
- if (url->url_user)
- {
- if (url->url_user[0] == 0) goto error;
- }
-
- /* host should be set and valid */
- if (url->url_host == NULL || !priv_is_host (url->url_host))
- goto error;
-
- /* convert host to lowercase */
- for (c = (char *) url->url_host; *c; c++)
- {
- *c = g_ascii_tolower (*c);
- }
-
- retval = g_strdup (url_as_string (home, url));
-
-error:
- if (retval == NULL)
- g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_HANDLE,
- "invalid SIP URI");
-
- su_home_deinit (home);
- return retval;
-}
-
gchar *
tpsip_handle_normalize (TpHandleRepoIface *repo,
const gchar *sipuri,
@@ -889,78 +687,6 @@ tpsip_handle_normalize (TpHandleRepoIface *repo,
error);
}
-static GQuark
-tpsip_handle_url_quark ()
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY (quark == 0))
- quark = g_quark_from_static_string ("tpsip-handle-url");
-
- return quark;
-}
-
-const url_t*
-tpsip_conn_get_contact_url (TpsipConnection *self,
- TpHandle handle)
-{
- TpBaseConnection *base = (TpBaseConnection *) self;
- TpsipConnectionPrivate *priv = TPSIP_CONNECTION_GET_PRIVATE (self);
- TpHandleRepoIface *contact_handles;
- GQuark url_quark;
- url_t *url;
- GError *error;
-
- contact_handles = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
-
- if (!tp_handle_is_valid (contact_handles, handle, &error))
- {
- DEBUG("invalid handle %u: %s", handle, error->message);
- g_error_free (error);
- return NULL;
- }
-
- url_quark = tpsip_handle_url_quark ();
-
- url = tp_handle_get_qdata (contact_handles, handle, url_quark);
-
- if (url == NULL)
- {
- url = url_make (priv->sofia_home,
- tp_handle_inspect (contact_handles, handle));
-
- tp_handle_set_qdata (contact_handles, handle, url_quark, url, NULL);
- }
-
- return url;
-}
-
-TpHandle
-tpsip_handle_parse_from (TpHandleRepoIface *contact_repo,
- const sip_t *sip)
-{
- TpHandle handle = 0;
- gchar *url_str;
-
- g_return_val_if_fail (sip != NULL, 0);
-
- if (sip->sip_from)
- {
- su_home_t tmphome[1] = { SU_HOME_INIT(tmphome) };
-
- url_str = url_as_string (tmphome, sip->sip_from->a_url);
-
- handle = tp_handle_ensure (contact_repo, url_str, NULL, NULL);
-
- /* TODO: set qdata for the display name */
-
- su_home_deinit (tmphome);
- }
-
- return handle;
-}
-
#ifdef HAVE_LIBIPHB
static int
diff --git a/src/sip-connection-helpers.h b/src/sip-connection-helpers.h
index 4644908..97896b9 100644
--- a/src/sip-connection-helpers.h
+++ b/src/sip-connection-helpers.h
@@ -51,33 +51,6 @@ void tpsip_conn_resolv_stun_server (TpsipConnection *conn, const gchar *stun_hos
void tpsip_conn_discover_stun_server (TpsipConnection *conn);
/***********************************************************************
- * Functions for saving NUA events
- ***********************************************************************/
-
-void tpsip_conn_save_event (TpsipConnection *conn,
- nua_saved_event_t ret_saved [1]);
-
-/***********************************************************************
- * SIP URI helpers
- ***********************************************************************/
-
-gchar * tpsip_handle_normalize (TpHandleRepoIface *repo,
- const gchar *sipuri,
- gpointer context,
- GError **error);
-
-gchar *tpsip_normalize_contact (const gchar *sipuri,
- const url_t *base_url,
- const gchar *transport,
- GError **error);
-
-const url_t* tpsip_conn_get_contact_url (TpsipConnection *conn,
- TpHandle handle);
-
-TpHandle tpsip_handle_parse_from (TpHandleRepoIface *contact_repo,
- const sip_t *sip);
-
-/***********************************************************************
* Heartbeat management for keepalives
***********************************************************************/
diff --git a/src/sip-connection-private.h b/src/sip-connection-private.h
index 2250694..c312109 100644
--- a/src/sip-connection-private.h
+++ b/src/sip-connection-private.h
@@ -35,7 +35,6 @@
struct _TpsipConnectionPrivate
{
- su_root_t *sofia_root;
nua_t *sofia_nua;
su_home_t *sofia_home;
nua_handle_t *register_op;
diff --git a/src/sip-connection-sofia.h b/src/sip-connection-sofia.h
deleted file mode 100644
index a56b1cb..0000000
--- a/src/sip-connection-sofia.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * sip-connection-sofia.h - Header for TpsipConnection Sofia event handling
- * Copyright (C) 2006-2008 Nokia Corporation
- * @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
- */
-
-#ifndef __TPSIP_CONNECTION_SOFIA_H__
-#define __TPSIP_CONNECTION_SOFIA_H__
-
-#include <tpsip/sofia-decls.h>
-#include <tpsip/event-target.h>
-#include "sip-connection.h"
-
-G_BEGIN_DECLS
-
-/**
- * Callback for events delivered by the SIP stack.
- *
- * See libsofia-sip-ua/nua/nua.h documentation.
- */
-void tpsip_connection_sofia_callback (nua_event_t event,
- int status,
- char const *phrase,
- nua_t *nua,
- TpsipConnection *conn,
- nua_handle_t *nh,
- TpsipEventTarget *target,
- sip_t const *sip,
- tagi_t tags[]);
-
-G_END_DECLS
-
-#endif /* #ifndef __TPSIP_CONNECTION_SOFIA_H__*/
diff --git a/src/sip-connection.c b/src/sip-connection.c
index b515699..2751a44 100644
--- a/src/sip-connection.c
+++ b/src/sip-connection.c
@@ -36,46 +36,30 @@
#include <telepathy-glib/svc-generic.h>
#include <tpsip/event-target.h>
+#include <tpsip/handles.h>
+#include <tpsip/connection-aliasing.h>
#include "sip-connection.h"
#include "media-factory.h"
#include "text-factory.h"
-#include "conn-aliasing.h"
-
#include "sip-connection-enumtypes.h"
#include "sip-connection-helpers.h"
#include "sip-connection-private.h"
-#include "sip-connection-sofia.h"
#include <sofia-sip/msg_header.h>
#define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
#include "debug.h"
-static void event_target_iface_init (gpointer, gpointer);
-static void conn_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE(TpsipConnection, tpsip_connection,
- TP_TYPE_BASE_CONNECTION,
- G_IMPLEMENT_INTERFACE (TPSIP_TYPE_EVENT_TARGET, event_target_iface_init);
+G_DEFINE_TYPE_WITH_CODE (TpsipConnection, tpsip_connection,
+ TPSIP_TYPE_BASE_CONNECTION,
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
- tp_contacts_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING,
- tpsip_conn_aliasing_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION, conn_iface_init))
-
-#define ERROR_IF_NOT_CONNECTED_ASYNC(BASE, CONTEXT) \
- if ((BASE)->status != TP_CONNECTION_STATUS_CONNECTED) \
- { \
- GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, \
- "Connection is disconnected" }; \
- DEBUG ("rejected request as disconnected"); \
- dbus_g_method_return_error ((CONTEXT), &e); \
- return; \
- }
+ tpsip_connection_aliasing_svc_iface_init);
+ G_IMPLEMENT_INTERFACE (TPSIP_TYPE_CONNECTION_ALIASING, NULL);
+);
/* properties */
@@ -102,7 +86,7 @@ enum
PROP_LOCAL_PORT, /**< Local port for SIP (normally not needed, chosen by stack) */
PROP_EXTRA_AUTH_USER, /**< User name to use for extra authentication challenges */
PROP_EXTRA_AUTH_PASSWORD,/**< Password to use for extra authentication challenges */
- PROP_SOFIA_ROOT, /**< Event root pointer from the Sofia-SIP stack */
+ PROP_SOFIA_NUA, /**< Base class accessing nua_t */
LAST_PROPERTY
};
@@ -174,12 +158,7 @@ tpsip_connection_init (TpsipConnection *self)
priv->sofia_home = su_home_new(sizeof (su_home_t));
- tp_contacts_mixin_init ((GObject *) self,
- G_STRUCT_OFFSET (TpsipConnection, contacts));
-
- tp_base_connection_register_with_contacts_mixin ((TpBaseConnection *) self);
-
- tpsip_conn_aliasing_init (self);
+ tpsip_connection_aliasing_init (self);
}
static void
@@ -307,10 +286,6 @@ tpsip_connection_set_property (GObject *object,
priv->extra_auth_password = g_value_dup_string (value);
break;
}
- case PROP_SOFIA_ROOT: {
- priv->sofia_root = g_value_get_pointer (value);
- break;
- }
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
@@ -396,8 +371,8 @@ tpsip_connection_get_property (GObject *object,
g_value_set_uint (value, priv->local_port);
break;
}
- case PROP_SOFIA_ROOT: {
- g_value_set_pointer (value, priv->sofia_root);
+ case PROP_SOFIA_NUA: {
+ g_value_set_pointer (value, priv->sofia_nua);
break;
}
default:
@@ -439,15 +414,23 @@ tpsip_connection_get_implemented_interfaces (void)
return interfaces_always_present;
}
+static nua_handle_t *tpsip_connection_create_nua_handle (TpsipBaseConnection *,
+ TpHandle);
+static void tpsip_connection_add_auth_handler (TpsipBaseConnection *,
+ TpsipEventTarget *);
+
static void
tpsip_connection_class_init (TpsipConnectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- TpBaseConnectionClass *base_class =
- (TpBaseConnectionClass *)klass;
+ TpBaseConnectionClass *base_class = TP_BASE_CONNECTION_CLASS (klass);
+ TpsipBaseConnectionClass *sip_class = TPSIP_BASE_CONNECTION_CLASS (klass);
GParamSpec *param_spec;
/* Implement pure-virtual methods */
+ sip_class->create_handle = tpsip_connection_create_nua_handle;
+ sip_class->add_auth_handler = tpsip_connection_add_auth_handler;
+
base_class->create_handle_repos = tpsip_create_handle_repos;
base_class->get_unique_connection_name = tpsip_connection_unique_name;
base_class->create_channel_managers =
@@ -469,10 +452,7 @@ tpsip_connection_class_init (TpsipConnectionClass *klass)
#define INST_PROP(x) \
g_object_class_install_property (object_class, x, param_spec)
- param_spec = g_param_spec_pointer ("sofia-root", "Sofia root",
- "Event root from Sofia-SIP stack",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- INST_PROP(PROP_SOFIA_ROOT);
+ g_object_class_override_property (object_class, PROP_SOFIA_NUA, "sofia-nua");
param_spec = g_param_spec_string ("address", "SIP address",
"SIP AoR URI",
@@ -493,11 +473,7 @@ tpsip_connection_class_init (TpsipConnectionClass *klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
INST_PROP(PROP_PASSWORD);
- param_spec = g_param_spec_string ("alias", "Alias",
- "User's display name",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- INST_PROP(PROP_ALIAS);
+ g_object_class_override_property (object_class, PROP_ALIAS, "alias");
param_spec = g_param_spec_string ("transport", "Transport protocol",
"Preferred transport protocol (auto, udp, tcp)",
@@ -599,9 +575,6 @@ tpsip_connection_class_init (TpsipConnectionClass *klass)
tp_dbus_properties_mixin_class_init (object_class,
G_STRUCT_OFFSET (TpsipConnectionClass, properties_class));
-
- tp_contacts_mixin_class_init (object_class,
- G_STRUCT_OFFSET (TpsipConnectionClass, contacts_class));
}
typedef struct {
@@ -855,9 +828,9 @@ tpsip_connection_auth_cb (TpsipEventTarget *target,
FALSE);
}
-void
-tpsip_connection_connect_auth_handler (TpsipConnection *self,
- TpsipEventTarget *target)
+static void
+tpsip_connection_add_auth_handler (TpsipBaseConnection *self,
+ TpsipEventTarget *target)
{
g_signal_connect_object (target,
"nua-event",
@@ -866,6 +839,12 @@ tpsip_connection_connect_auth_handler (TpsipConnection *self,
0);
}
+static nua_handle_t *
+tpsip_connection_create_nua_handle (TpsipBaseConnection *base, TpHandle handle)
+{
+ return tpsip_conn_create_request_handle (TPSIP_CONNECTION (base), handle);
+}
+
static gboolean
tpsip_connection_nua_r_register_cb (TpsipConnection *self,
const TpsipNuaEvent *ev,
@@ -1014,11 +993,13 @@ tpsip_connection_start_connecting (TpBaseConnection *base,
TpHandleRepoIface *contact_repo;
const gchar *sip_address;
const url_t *local_url;
+ su_root_t *root = NULL;
g_assert (base->status == TP_INTERNAL_CONNECTION_STATUS_NEW);
/* the construct parameters will be non-empty */
- g_assert (priv->sofia_root != NULL);
+ g_object_get (self, "sofia-root", &root, NULL);
+ g_assert (root != NULL);
g_return_val_if_fail (priv->address != NULL, FALSE);
contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT);
@@ -1033,7 +1014,7 @@ tpsip_connection_start_connecting (TpBaseConnection *base,
DEBUG("self_handle = %d, sip_address = %s", base->self_handle, sip_address);
- priv->account_url = tpsip_conn_get_contact_url (self, base->self_handle);
+ priv->account_url = tpsip_handle_inspect_uri (base, base->self_handle);
if (priv->account_url == NULL)
{
g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
@@ -1044,9 +1025,9 @@ tpsip_connection_start_connecting (TpBaseConnection *base,
local_url = tpsip_conn_get_local_url (self);
/* step: create stack instance */
- priv->sofia_nua = nua_create (priv->sofia_root,
- tpsip_connection_sofia_callback,
- self,
+ priv->sofia_nua = nua_create (root,
+ tpsip_base_connection_sofia_callback,
+ TPSIP_BASE_CONNECTION (self),
SOATAG_AF(SOA_AF_IP4_IP6),
SIPTAG_FROM_STR(sip_address),
NUTAG_URL(local_url),
@@ -1131,13 +1112,3 @@ tpsip_connection_disconnected (TpBaseConnection *base)
priv->register_op = NULL;
}
}
-
-static void
-conn_iface_init(gpointer g_iface, gpointer iface_data)
-{
-}
-
-static void
-event_target_iface_init (gpointer g_iface, gpointer iface_data)
-{
-}
diff --git a/src/sip-connection.h b/src/sip-connection.h
index 2280be9..dffbf6f 100644
--- a/src/sip-connection.h
+++ b/src/sip-connection.h
@@ -23,20 +23,11 @@
#include <glib-object.h>
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/contacts-mixin.h>
+#include <tpsip/base-connection.h>
#include <telepathy-glib/dbus-properties-mixin.h>
-#include <tpsip/event-target.h>
-
-
G_BEGIN_DECLS
-#define TPSIP_DEFAULT_STUN_PORT 3478
-
-/* Maximum defer timeout for deferrable Sofia timers */
-#define TPSIP_DEFER_TIMEOUT 30
-
typedef enum
{
TPSIP_CONNECTION_KEEPALIVE_AUTO = 0, /** Keepalive management is up to the implementation */
@@ -51,14 +42,12 @@ typedef struct _TpsipConnectionClass TpsipConnectionClass;
typedef struct _TpsipConnectionPrivate TpsipConnectionPrivate;
struct _TpsipConnectionClass {
- TpBaseConnectionClass parent_class;
+ TpsipBaseConnectionClass parent_class;
TpDBusPropertiesMixinClass properties_class;
- TpContactsMixinClass contacts_class;
};
struct _TpsipConnection {
- TpBaseConnection parent;
- TpContactsMixin contacts;
+ TpsipBaseConnection parent;
};
/* TYPE MACROS */
diff --git a/src/sip-media-channel.c b/src/sip-media-channel.c
index b78a57f..cf07564 100644
--- a/src/sip-media-channel.c
+++ b/src/sip-media-channel.c
@@ -39,8 +39,9 @@
#define DEBUG_FLAG TPSIP_DEBUG_MEDIA
#include "debug.h"
-#include "sip-connection.h"
-#include "sip-connection-helpers.h"
+
+#include <tpsip/base-connection.h>
+
#include "sip-media-session.h"
#define TPSIP_CHANNEL_CALL_STATE_PROCEEDING_MASK \
@@ -145,7 +146,7 @@ typedef struct _TpsipMediaChannelPrivate TpsipMediaChannelPrivate;
struct _TpsipMediaChannelPrivate
{
- TpsipConnection *conn;
+ TpsipBaseConnection *conn;
TpsipMediaSession *session;
gchar *object_path;
TpHandle handle;
@@ -322,7 +323,7 @@ tpsip_media_channel_class_init (TpsipMediaChannelClass *klass)
param_spec = g_param_spec_object ("connection", "TpsipConnection object",
"SIP connection object that owns this SIP media channel object.",
- TPSIP_TYPE_CONNECTION,
+ TPSIP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
@@ -580,7 +581,7 @@ tpsip_media_channel_set_property (GObject *object,
* meaningfully changable on this channel, so we do nothing */
break;
case PROP_CONNECTION:
- priv->conn = TPSIP_CONNECTION (g_value_dup_object (value));
+ priv->conn = g_value_dup_object (value);
break;
case PROP_OBJECT_PATH:
g_free (priv->object_path);
@@ -1578,7 +1579,7 @@ tpsip_media_channel_attach_to_nua_handle (TpsipMediaChannel *self,
/* have the connection handle authentication, before all other
* response callbacks */
- tpsip_connection_connect_auth_handler (priv->conn, TPSIP_EVENT_TARGET (self));
+ tpsip_base_connection_add_auth_handler (priv->conn, TPSIP_EVENT_TARGET (self));
g_signal_connect (self,
"nua-event::nua_i_invite",
@@ -1704,7 +1705,7 @@ priv_outbound_call (TpsipMediaChannel *channel,
{
DEBUG("making outbound call - setting peer handle to %u", peer);
- nh = tpsip_conn_create_request_handle (priv->conn, peer);
+ nh = tpsip_base_connection_create_handle (priv->conn, peer);
priv_create_session (channel, nh, peer);
/* Bind the channel object to the handle to handle NUA events */
diff --git a/src/sip-media-session.c b/src/sip-media-session.c
index 8272200..988a990 100644
--- a/src/sip-media-session.c
+++ b/src/sip-media-session.c
@@ -38,10 +38,11 @@
#include "config.h"
+#include <tpsip/base-connection.h>
+
#include "sip-media-session.h"
#include "sip-media-channel.h"
#include "sip-media-stream.h"
-#include "sip-connection-helpers.h"
#include "signals-marshal.h"
#define DEBUG_FLAG TPSIP_DEBUG_MEDIA
@@ -1022,7 +1023,7 @@ static void
priv_save_event (TpsipMediaSession *self)
{
TpsipMediaSessionPrivate *priv = TPSIP_MEDIA_SESSION_GET_PRIVATE (self);
- TpsipConnection *conn = NULL;
+ TpsipBaseConnection *conn = NULL;
priv_zap_event (self);
@@ -1030,7 +1031,7 @@ priv_save_event (TpsipMediaSession *self)
g_return_if_fail (conn != NULL);
- tpsip_conn_save_event (conn, priv->saved_event);
+ tpsip_base_connection_save_event (conn, priv->saved_event);
g_object_unref (conn);
diff --git a/src/sip-text-channel.c b/src/sip-text-channel.c
index aeb0209..71be195 100644
--- a/src/sip-text-channel.c
+++ b/src/sip-text-channel.c
@@ -39,9 +39,7 @@
#include <telepathy-glib/svc-generic.h>
#include <tpsip/event-target.h>
-
-#include "sip-connection.h"
-#include "sip-connection-helpers.h"
+#include <tpsip/base-connection.h>
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/sip_status.h>
@@ -112,7 +110,7 @@ typedef struct _TpsipTextChannelPrivate TpsipTextChannelPrivate;
struct _TpsipTextChannelPrivate
{
- TpsipConnection *conn;
+ TpsipBaseConnection *conn;
gchar *object_path;
TpHandle handle;
TpHandle initiator;
@@ -186,7 +184,7 @@ tpsip_text_channel_constructed (GObject *obj)
g_assert (priv->initiator != 0);
tp_handle_ref (contact_handles, priv->initiator);
- tpsip_connection_connect_auth_handler (priv->conn, TPSIP_EVENT_TARGET (obj));
+ tpsip_base_connection_add_auth_handler (priv->conn, TPSIP_EVENT_TARGET (obj));
g_signal_connect (obj,
"nua-event::nua_r_message",
@@ -271,7 +269,7 @@ tpsip_text_channel_class_init(TpsipTextChannelClass *klass)
param_spec = g_param_spec_object("connection", "TpsipConnection object",
"SIP connection object that owns this SIP media channel object.",
- TPSIP_TYPE_CONNECTION,
+ TPSIP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class, PROP_CONNECTION, param_spec);
@@ -690,7 +688,7 @@ tpsip_text_channel_send_message (GObject *object,
/* Okay, it's valid. Let's send it. */
- msg_nh = tpsip_conn_create_request_handle (priv->conn, priv->handle);
+ msg_nh = tpsip_base_connection_create_handle (priv->conn, priv->handle);
if (msg_nh == NULL)
{
g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
diff --git a/src/text-factory.c b/src/text-factory.c
index d62b2b6..4b8d0b3 100644
--- a/src/text-factory.c
+++ b/src/text-factory.c
@@ -27,8 +27,8 @@
#include <telepathy-glib/interfaces.h>
#include "sip-text-channel.h"
-#include "sip-connection.h"
-#include "sip-connection-helpers.h"
+#include "tpsip/base-connection.h"
+#include "tpsip/handles.h"
#include <sofia-sip/msg_header.h>
#include <sofia-sip/sip_tag.h>
@@ -39,7 +39,7 @@
static void channel_manager_iface_init (gpointer g_iface, gpointer iface_data);
-static void connection_status_changed_cb (TpsipConnection *conn,
+static void connection_status_changed_cb (TpBaseConnection *conn,
guint status, guint reason, TpsipTextFactory *self);
static void tpsip_text_factory_close_all (TpsipTextFactory *self);
@@ -57,7 +57,7 @@ enum
typedef struct _TpsipTextFactoryPrivate TpsipTextFactoryPrivate;
struct _TpsipTextFactoryPrivate
{
- TpsipConnection *conn;
+ TpBaseConnection *conn;
/* guint handle => TpsipTextChannel *channel */
GHashTable *channels;
@@ -144,7 +144,7 @@ tpsip_text_factory_set_property (GObject *object,
switch (property_id) {
case PROP_CONNECTION:
- priv->conn = g_value_get_object (value);
+ priv->conn = TP_BASE_CONNECTION (g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -165,9 +165,10 @@ tpsip_text_factory_class_init (TpsipTextFactoryClass *klass)
object_class->set_property = tpsip_text_factory_set_property;
object_class->dispose = tpsip_text_factory_dispose;
- param_spec = g_param_spec_object ("connection", "TpsipConnection object",
+ param_spec = g_param_spec_object ("connection",
+ "TpsipBaseConnection object",
"SIP connection that owns this text channel factory",
- TPSIP_TYPE_CONNECTION,
+ TPSIP_TYPE_BASE_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
}
@@ -281,7 +282,7 @@ tpsip_text_factory_new_channel (TpsipTextFactory *fac,
GSList *request_tokens;
priv = TPSIP_TEXT_FACTORY_GET_PRIVATE (fac);
- conn = (TpBaseConnection *)(priv->conn);
+ conn = priv->conn;
object_path = g_strdup_printf ("%s/TextChannel%u",
conn->object_path, handle);
@@ -463,7 +464,6 @@ tpsip_nua_i_message_cb (TpBaseConnection *conn,
TpsipTextFactory *fac)
{
TpsipTextChannel *channel;
- TpHandleRepoIface *contact_repo;
TpHandle handle;
const sip_t *sip = ev->sip;
const char *text = "";
@@ -556,10 +556,7 @@ tpsip_nua_i_message_cb (TpBaseConnection *conn,
}
}
- contact_repo = tp_base_connection_get_handles (
- conn, TP_HANDLE_TYPE_CONTACT);
-
- handle = tpsip_handle_parse_from (contact_repo, sip);
+ handle = tpsip_handle_by_requestor (conn, sip);
if (!handle)
{
@@ -577,7 +574,7 @@ tpsip_nua_i_message_cb (TpBaseConnection *conn,
TAG_END());
DEBUG("Got incoming message from <%s>",
- tp_handle_inspect (contact_repo, handle));
+ tpsip_handle_inspect (conn, handle));
channel = tpsip_text_factory_lookup_channel (fac, handle);
@@ -588,7 +585,7 @@ tpsip_nua_i_message_cb (TpBaseConnection *conn,
tpsip_text_channel_receive (channel,
sip, handle, text, len);
- tp_handle_unref (contact_repo, handle);
+ tpsip_handle_unref (conn, handle);
end:
g_free (allocated_text);
@@ -597,7 +594,7 @@ end:
}
static void
-connection_status_changed_cb (TpsipConnection *conn,
+connection_status_changed_cb (TpBaseConnection *conn,
guint status,
guint reason,
TpsipTextFactory *self)
@@ -608,7 +605,7 @@ connection_status_changed_cb (TpsipConnection *conn,
{
case TP_CONNECTION_STATUS_CONNECTING:
- priv->message_received_id = g_signal_connect (priv->conn,
+ priv->message_received_id = g_signal_connect (conn,
"nua-event::nua_i_message",
G_CALLBACK (tpsip_nua_i_message_cb),
self);
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 04b14f2..e1d03b3 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -30,7 +30,8 @@ check-twisted:
--sleep=$(CHECK_TWISTED_SLEEP) \
-- $(MAKE) check-TESTS \
TESTS="$(TWISTED_TESTS)" \
- TESTS_ENVIRONMENT="$(TESTS_ENVIRONMENT) $(PYTHON)"
+ TESTS_ENVIRONMENT="$(TESTS_ENVIRONMENT) $(PYTHON)" 2>&1 | \
+ fgrep -v -e DeprecationWarning -e DigestAuthorizer
EXTRA_DIST = \
$(TWISTED_TESTS) \
diff --git a/tests/twisted/test-self-alias.py b/tests/twisted/test-self-alias.py
index 2eb4e7f..6c2e0a8 100644
--- a/tests/twisted/test-self-alias.py
+++ b/tests/twisted/test-self-alias.py
@@ -8,6 +8,8 @@ from servicetest import tp_name_prefix
import dbus
TEXT_TYPE = tp_name_prefix + '.Channel.Type.Text'
+ALIASING_INTERFACE = tp_name_prefix + '.Connection.Interface.Aliasing'
+CONTACTS_INTERFACE = tp_name_prefix + '.Connection.Interface.Contacts'
def test(q, bus, conn, sip_proxy):
conn.Connect()
@@ -23,6 +25,14 @@ def test(q, bus, conn, sip_proxy):
args=[[(self_handle, u'foo@bar.baz')]])
handle = conn.RequestHandles(1, ['sip:user@somewhere.com'])[0]
+
+ assert ALIASING_INTERFACE in \
+ conn.Properties.Get(CONTACTS_INTERFACE, "ContactAttributeInterfaces")
+ attrs = conn.Contacts.GetContactAttributes([self_handle, handle],
+ [ALIASING_INTERFACE], False)
+ assert ALIASING_INTERFACE + "/alias" in attrs[self_handle]
+ assert attrs[self_handle][ALIASING_INTERFACE + "/alias"] == u'foo@bar.baz'
+
conn.RequestChannel(TEXT_TYPE, 1, handle, True)
event = q.expect('dbus-signal', signal='NewChannel')
diff --git a/tpsip/Makefile.am b/tpsip/Makefile.am
index 1186664..2a9df4d 100644
--- a/tpsip/Makefile.am
+++ b/tpsip/Makefile.am
@@ -13,12 +13,15 @@ AM_CPPFLAGS = @GLIB_CFLAGS@ @TELEPATHY_GLIB_CFLAGS@ @SOFIA_SIP_UA_CFLAGS@ \
AM_CFLAGS = $(ERROR_CFLAGS) $(COVERAGE_CFLAGS)
-tpsip_includedir = $(includedir)/telepathy-sofiasip-0.6/tpsip
+tpsip_includedir = $(includedir)/telepathy-sofiasip-0.7/tpsip
tpsip_include_HEADERS = \
+ base-connection.h \
+ connection-aliasing.h
sofia-decls.h \
codec-param-formats.h \
event-target.h \
+ handles.h \
util.h
BUILT_SOURCES = \
@@ -26,8 +29,12 @@ BUILT_SOURCES = \
signals-marshal.c
libtpsip_la_SOURCES = \
+ base-connection.c \
+ base-connection-sofia.c \
+ connection-aliasing.c \
codec-param-formats.c \
event-target.c \
+ handles.c \
util.c
nodist_libtpsip_la_SOURCES = \
diff --git a/src/sip-connection-sofia.c b/tpsip/base-connection-sofia.c
index 29772fe..4c04eae 100644
--- a/src/sip-connection-sofia.c
+++ b/tpsip/base-connection-sofia.c
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "sip-connection-sofia.h"
+#include "config.h"
+#include <tpsip/base-connection.h>
#include <sofia-sip/su_tag_io.h>
#define DEBUG_FLAG TPSIP_DEBUG_EVENTS
-#include "debug.h"
+#include "src/debug.h"
static void
priv_r_shutdown(int status,
@@ -104,15 +105,15 @@ priv_r_get_params (int status,
* See libsofia-sip-ua/nua/nua.h documentation.
*/
void
-tpsip_connection_sofia_callback (nua_event_t event,
- int status,
- char const *phrase,
- nua_t *nua,
- TpsipConnection *conn,
- nua_handle_t *nh,
- TpsipEventTarget *target,
- sip_t const *sip,
- tagi_t tags[])
+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);
diff --git a/tpsip/base-connection.c b/tpsip/base-connection.c
new file mode 100644
index 0000000..e437b00
--- /dev/null
+++ b/tpsip/base-connection.c
@@ -0,0 +1,205 @@
+/*
+ * sip-base-connection.c - source for SipBaseConnection
+ * Copyright (C) 2011 Nokia Corporation.
+ * Copyright (C) 2005-2007 Collabora Ltd.
+ * Copyright (C) 2005-2011 Nokia Corporation
+ * @author Kai Vehmanen <first.surname@nokia.com>
+ * @author Martti Mela <first.surname@nokia.com>
+ * @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
+ * @author Pekka Pessi <pekka.pessi@nokia.com>
+ *
+ * Based on tpsip-connection and gabble implementation (gabble-connection).
+ * @author See gabble-connection.c
+ *
+ * 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 <telepathy-glib/telepathy-glib.h>
+#include <tpsip/sofia-decls.h>
+
+struct _TpsipBaseConnectionPrivate
+{
+ su_root_t *sofia_root;
+
+ unsigned dispose_has_run:1; unsigned :0;
+};
+
+enum {
+ PROP_NONE,
+ PROP_SOFIA_ROOT,
+ PROP_SOFIA_NUA,
+};
+
+/* ---------------------------------------------------------------------- */
+/* GObject implementation */
+
+static void event_target_iface_init (gpointer iface, gpointer data) {}
+
+G_DEFINE_TYPE_WITH_CODE (TpsipBaseConnection,
+ tpsip_base_connection, TP_TYPE_BASE_CONNECTION,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
+ tp_contacts_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (TPSIP_TYPE_EVENT_TARGET, event_target_iface_init);
+);
+
+static void
+tpsip_base_connection_init (TpsipBaseConnection *self)
+{
+ GObject *object = G_OBJECT (self);
+ TpBaseConnection *base = TP_BASE_CONNECTION (self);
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TPSIP_TYPE_BASE_CONNECTION,
+ TpsipBaseConnectionPrivate);
+
+ tp_contacts_mixin_init (object,
+ G_STRUCT_OFFSET (TpsipBaseConnection, contacts_mixin));
+
+ /* org.freedesktop.Telepathy.Connection attributes */
+ tp_base_connection_register_with_contacts_mixin (base);
+}
+
+static void
+tpsip_base_connection_constructed(GObject *object)
+{
+ if (G_OBJECT_CLASS(tpsip_base_connection_parent_class)->constructed)
+ G_OBJECT_CLASS(tpsip_base_connection_parent_class)->constructed(object);
+}
+
+static void
+tpsip_base_connection_dispose(GObject *object)
+{
+ TpsipBaseConnection *self = TPSIP_BASE_CONNECTION(object);
+
+ if (self->priv->dispose_has_run)
+ return;
+ self->priv->dispose_has_run = 1;
+
+ G_OBJECT_CLASS(tpsip_base_connection_parent_class)->dispose(object);
+}
+
+void
+tpsip_base_connection_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(tpsip_base_connection_parent_class)->finalize(object);
+}
+
+static void
+tpsip_base_connection_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpsipBaseConnection *self = TPSIP_BASE_CONNECTION (object);
+ TpsipBaseConnectionPrivate *priv = self->priv;
+
+ switch (property_id)
+ {
+ case PROP_SOFIA_ROOT:
+ priv->sofia_root = g_value_get_pointer (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tpsip_base_connection_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpsipBaseConnection *self = TPSIP_BASE_CONNECTION (object);
+ TpsipBaseConnectionPrivate *priv = self->priv;
+
+ switch (property_id)
+ {
+ case PROP_SOFIA_ROOT:
+ g_value_set_pointer (value, priv->sofia_root);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void
+tpsip_base_connection_class_init (TpsipBaseConnectionClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ g_type_class_add_private (klass, sizeof (TpsipBaseConnectionPrivate));
+
+ object_class->constructed = tpsip_base_connection_constructed;
+ object_class->dispose = tpsip_base_connection_dispose;
+ object_class->finalize = tpsip_base_connection_finalize;
+ object_class->get_property = tpsip_base_connection_get_property;
+ object_class->set_property = tpsip_base_connection_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_SOFIA_ROOT,
+ g_param_spec_pointer ("sofia-root",
+ "Sofia-SIP root",
+ "The root object for Sofia-SIP",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class,
+ PROP_SOFIA_NUA,
+ g_param_spec_pointer ("sofia-nua",
+ "Sofia-SIP UA",
+ "The UA object for Sofia-SIP",
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ tp_contacts_mixin_class_init (object_class,
+ G_STRUCT_OFFSET(TpsipBaseConnectionClass, contacts_mixin_class));
+}
+
+nua_handle_t *
+tpsip_base_connection_create_handle (TpsipBaseConnection *self,
+ TpHandle tphandle)
+{
+ TpsipBaseConnectionClass *cls = TPSIP_BASE_CONNECTION_GET_CLASS (self);
+
+ return cls->create_handle (self, tphandle);
+}
+
+void
+tpsip_base_connection_add_auth_handler (TpsipBaseConnection *self,
+ TpsipEventTarget *target)
+{
+ TpsipBaseConnectionClass *cls = TPSIP_BASE_CONNECTION_GET_CLASS (self);
+
+ if (cls->add_auth_handler)
+ cls->add_auth_handler (self, target);
+}
+
+void
+tpsip_base_connection_save_event (TpsipBaseConnection *self,
+ nua_saved_event_t ret_saved [1])
+{
+ nua_t *nua;
+
+ g_object_get (self, "sofia-nua", &nua, NULL);
+
+ nua_save_event (nua, ret_saved);
+}
diff --git a/tpsip/base-connection.h b/tpsip/base-connection.h
new file mode 100644
index 0000000..b444aa2
--- /dev/null
+++ b/tpsip/base-connection.h
@@ -0,0 +1,92 @@
+/*
+ * sip-base-connection.h - Header for SipBaseConnection
+ * Copyright (C) 2005 Collabora Ltd.
+ * Copyright (C) 2005-2009 Nokia Corporation
+ *
+ * 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
+ */
+
+#ifndef __TPSIP_BASE_CONNECTION_H__
+#define __TPSIP_BASE_CONNECTION_H__
+
+#include <glib-object.h>
+
+#include <telepathy-glib/base-connection.h>
+#include <telepathy-glib/contacts-mixin.h>
+
+#include <tpsip/sofia-decls.h>
+#include <tpsip/event-target.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpsipBaseConnection TpsipBaseConnection;
+typedef struct _TpsipBaseConnectionClass TpsipBaseConnectionClass;
+typedef struct _TpsipBaseConnectionPrivate TpsipBaseConnectionPrivate;
+
+struct _TpsipBaseConnectionClass {
+ TpBaseConnectionClass parent_class;
+ TpContactsMixinClass contacts_mixin_class;
+
+ nua_handle_t *(*create_handle) (TpsipBaseConnection *, TpHandle contact);
+ void (*add_auth_handler) (TpsipBaseConnection *, TpsipEventTarget *);
+};
+
+struct _TpsipBaseConnection {
+ TpBaseConnection parent;
+ TpContactsMixin contacts_mixin;
+ TpsipBaseConnectionPrivate *priv;
+};
+
+GType tpsip_base_connection_get_type (void) G_GNUC_CONST;
+
+/* TYPE MACROS */
+#define TPSIP_TYPE_BASE_CONNECTION \
+ (tpsip_base_connection_get_type())
+#define TPSIP_BASE_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ TPSIP_TYPE_BASE_CONNECTION, TpsipBaseConnection))
+#define TPSIP_BASE_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ TPSIP_TYPE_BASE_CONNECTION, TpsipBaseConnectionClass))
+#define TPSIP_IS_BASE_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TPSIP_TYPE_BASE_CONNECTION))
+#define TPSIP_IS_BASE_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TPSIP_TYPE_BASE_CONNECTION))
+#define TPSIP_BASE_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TPSIP_TYPE_BASE_CONNECTION, TpsipBaseConnectionClass))
+
+/***********************************************************************
+ * Functions for accessing Sofia-SIP interface handles
+ ***********************************************************************/
+
+nua_handle_t *tpsip_base_connection_create_handle (TpsipBaseConnection *,
+ TpHandle contact);
+void tpsip_base_connection_add_auth_handler (TpsipBaseConnection *self,
+ TpsipEventTarget *target);
+void tpsip_base_connection_save_event (TpsipBaseConnection *self,
+ nua_saved_event_t ret_saved [1]);
+
+/** Callback for events delivered by the SIP stack. */
+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[]);
+
+G_END_DECLS
+
+#endif /* #ifndef __TPSIP_BASE_CONNECTION_H__*/
diff --git a/src/conn-aliasing.c b/tpsip/connection-aliasing.c
index 4b4a8a4..d8af0ef 100644
--- a/src/conn-aliasing.c
+++ b/tpsip/connection-aliasing.c
@@ -1,7 +1,8 @@
/*
- * conn-aliasing.c - Aliasing interface implementation for TpsipConnection
- * Copyright (C) 2008, 2009 Nokia Corporation
+ * connection-aliasing.c - Implementation for TpsipConnectionAliasing interface
+ * Copyright (C) 2008-2011 Nokia Corporation
* @author Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
+ * @author Pekka Pessi <pekka.pessi@nokia.com>
*
* This work is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,19 +19,76 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "conn-aliasing.h"
+#include "config.h"
+
+#include <tpsip/connection-aliasing.h>
+#include <tpsip/base-connection.h>
+#include <tpsip/handles.h>
#include <telepathy-glib/errors.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>
#include <telepathy-glib/svc-connection.h>
+#include <telepathy-glib/contacts-mixin.h>
-#include "sip-connection-helpers.h"
+#include "tpsip/handles.h"
#include <string.h>
#define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
-#include "debug.h"
+#include "src/debug.h"
+
+enum {
+ PROP_NONE,
+ PROP_ALIAS,
+};
+
+static void
+tpsip_connection_aliasing_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized)
+ {
+ initialized = TRUE;
+
+ g_object_interface_install_property (klass,
+ g_param_spec_string ("alias", "Alias",
+ "User's display name",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ }
+}
+
+GType
+tpsip_connection_aliasing_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo info = {
+ sizeof (TpsipConnectionAliasingInterface),
+ tpsip_connection_aliasing_base_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL /* instance_init */
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "TpsipConnectionAliasingInterface", &info, 0);
+
+ g_type_interface_add_prerequisite (type, TPSIP_TYPE_BASE_CONNECTION);
+ g_type_interface_add_prerequisite (type,
+ TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING);
+ }
+
+ return type;
+}
static void
tpsip_connection_get_alias_flags (TpSvcConnectionInterfaceAliasing *iface,
@@ -46,7 +104,7 @@ tpsip_connection_get_alias_flags (TpSvcConnectionInterfaceAliasing *iface,
}
static gchar *
-conn_get_default_alias (TpsipConnection *self,
+conn_get_default_alias (TpBaseConnection *base,
TpHandleRepoIface *contact_handles,
TpHandle handle)
{
@@ -55,7 +113,7 @@ conn_get_default_alias (TpsipConnection *self,
/* TODO: create our custom handle repo to be able to get the URL off it.
* Then we can reuse the contact_handles parameter */
- url = tpsip_conn_get_contact_url (self, handle);
+ url = tpsip_handle_inspect_uri (base, handle);
switch (url->url_type)
{
@@ -79,21 +137,20 @@ conn_get_default_alias (TpsipConnection *self,
}
static gchar *
-conn_get_alias (TpsipConnection *self,
+conn_get_alias (TpBaseConnection *base,
TpHandleRepoIface *contact_handles,
TpHandle handle)
{
- TpBaseConnection *base = (TpBaseConnection *) self;
gchar *alias = NULL;
if (handle == base->self_handle)
{
/* Get our user-settable alias from the connection property */
- g_object_get (self, "alias", &alias, NULL);
+ g_object_get (base, "alias", &alias, NULL);
}
if (alias == NULL)
- alias = conn_get_default_alias (self, contact_handles, handle);
+ alias = conn_get_default_alias (base, contact_handles, handle);
g_assert (alias != NULL);
DEBUG("handle %u got alias %s", handle, alias);
@@ -106,8 +163,7 @@ tpsip_connection_request_aliases (TpSvcConnectionInterfaceAliasing *iface,
const GArray *contacts,
DBusGMethodInvocation *context)
{
- TpsipConnection *self = TPSIP_CONNECTION (iface);
- TpBaseConnection *base = (TpBaseConnection *) self;
+ TpBaseConnection *base = TP_BASE_CONNECTION (iface);
TpHandleRepoIface *contact_handles;
GArray *aliases;
gchar **res;
@@ -135,7 +191,7 @@ tpsip_connection_request_aliases (TpSvcConnectionInterfaceAliasing *iface,
handle = g_array_index (contacts, TpHandle, i);
- alias = conn_get_alias (self, contact_handles, handle);
+ alias = conn_get_alias (base, contact_handles, handle);
g_array_append_val (aliases, alias);
}
@@ -153,8 +209,7 @@ tpsip_connection_get_aliases (TpSvcConnectionInterfaceAliasing *iface,
const GArray *contacts,
DBusGMethodInvocation *context)
{
- TpsipConnection *self = TPSIP_CONNECTION (iface);
- TpBaseConnection *base = (TpBaseConnection *) self;
+ TpBaseConnection *base = TP_BASE_CONNECTION (iface);
TpHandleRepoIface *contact_handles;
GHashTable *result;
GError *error = NULL;
@@ -182,7 +237,7 @@ tpsip_connection_get_aliases (TpSvcConnectionInterfaceAliasing *iface,
handle = g_array_index (contacts, TpHandle, i);
- alias = conn_get_alias (self, contact_handles, handle);
+ alias = conn_get_alias (base, contact_handles, handle);
g_hash_table_insert (result, GUINT_TO_POINTER (handle), alias);
}
@@ -194,9 +249,8 @@ tpsip_connection_get_aliases (TpSvcConnectionInterfaceAliasing *iface,
}
static void
-emit_self_alias_change (TpsipConnection *self, const gchar *alias)
+emit_self_alias_change (TpBaseConnection *base, const gchar *alias)
{
- TpBaseConnection *base = (TpBaseConnection *) self;
GPtrArray *change_data;
GValue change_pair = { 0, };
@@ -210,7 +264,7 @@ emit_self_alias_change (TpsipConnection *self, const gchar *alias)
change_data = g_ptr_array_sized_new (1);
g_ptr_array_add (change_data, g_value_get_boxed (&change_pair));
- tp_svc_connection_interface_aliasing_emit_aliases_changed (self, change_data);
+ tp_svc_connection_interface_aliasing_emit_aliases_changed (base, change_data);
g_ptr_array_free (change_data, TRUE);
g_value_unset (&change_pair);
@@ -246,8 +300,7 @@ tpsip_connection_set_aliases (TpSvcConnectionInterfaceAliasing *iface,
GHashTable *aliases,
DBusGMethodInvocation *context)
{
- TpsipConnection *self = TPSIP_CONNECTION (iface);
- TpBaseConnection *base = (TpBaseConnection *) self;
+ TpBaseConnection *base = TP_BASE_CONNECTION (iface);
TpHandleRepoIface *contact_handles;
const gchar *alias;
gchar *default_alias;
@@ -271,21 +324,21 @@ tpsip_connection_set_aliases (TpSvcConnectionInterfaceAliasing *iface,
contact_handles = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
- default_alias = conn_get_default_alias (self,
+ default_alias = conn_get_default_alias (base,
contact_handles, base->self_handle);
if (strcmp (alias, default_alias) == 0)
{
DEBUG("using default alias for self");
- g_object_set (self, "alias", NULL, NULL);
+ g_object_set (base, "alias", NULL, NULL);
}
else
{
DEBUG("setting alias for self: %s", alias);
- g_object_set (self, "alias", alias, NULL);
+ g_object_set (base, "alias", alias, NULL);
}
- emit_self_alias_change (self, alias);
+ emit_self_alias_change (base, alias);
g_free (default_alias);
g_free (to_free);
@@ -297,8 +350,7 @@ static void
tpsip_conn_aliasing_fill_contact_attributes (GObject *obj,
const GArray *contacts, GHashTable *attributes_hash)
{
- TpsipConnection *self = TPSIP_CONNECTION (obj);
- TpBaseConnection *base = (TpBaseConnection *) self;
+ TpBaseConnection *base = TP_BASE_CONNECTION (obj);
TpHandleRepoIface *contact_handles;
guint i;
@@ -315,7 +367,7 @@ tpsip_conn_aliasing_fill_contact_attributes (GObject *obj,
val = tp_g_value_slice_new (G_TYPE_STRING);
g_value_take_string (val,
- conn_get_alias (self, contact_handles, handle));
+ conn_get_alias (base, contact_handles, handle));
tp_contacts_mixin_set_contact_attribute (attributes_hash, handle,
TP_IFACE_CONNECTION_INTERFACE_ALIASING "/alias", val);
@@ -323,15 +375,16 @@ tpsip_conn_aliasing_fill_contact_attributes (GObject *obj,
}
void
-tpsip_conn_aliasing_init (TpsipConnection *conn)
+tpsip_connection_aliasing_init (gpointer instance)
{
- tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (conn),
+ tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (instance),
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
tpsip_conn_aliasing_fill_contact_attributes);
}
+
void
-tpsip_conn_aliasing_iface_init (gpointer g_iface, gpointer iface_data)
+tpsip_connection_aliasing_svc_iface_init (gpointer g_iface, gpointer iface_data)
{
TpSvcConnectionInterfaceAliasingClass *klass =
(TpSvcConnectionInterfaceAliasingClass *) g_iface;
diff --git a/tpsip/connection-aliasing.h b/tpsip/connection-aliasing.h
new file mode 100644
index 0000000..1b674d4
--- /dev/null
+++ b/tpsip/connection-aliasing.h
@@ -0,0 +1,58 @@
+/*
+ * tpsip/connection-aliasing.h - Aliasing interface implementation for SIP
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * @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
+ */
+
+#ifndef __TPSIP_CONNECTION_ALIASING_H__
+#define __TPSIP_CONNECTION_ALIASING_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpsipConnectionAliasing TpsipConnectionAliasing;
+
+typedef struct _TpsipConnectionAliasingInterface
+TpsipConnectionAliasingInterface;
+
+/* TYPE MACROS */
+#define TPSIP_TYPE_CONNECTION_ALIASING \
+ (tpsip_connection_aliasing_get_type ())
+#define TPSIP_CONNECTION_ALIASING(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ TPSIP_TYPE_CONNECTION_ALIASING, TpsipConnectionAliasing))
+#define TPSIP_IS_CONNECTION_ALIASING(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TPSIP_TYPE_CONNECTION_ALIASING))
+#define TPSIP_CONNECTION_ALIASING_GET_INTERFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE((obj), \
+ TPSIP_TYPE_CONNECTION_ALIASING, TpsipConnectionAliasingInterface))
+
+struct _TpsipConnectionAliasingInterface {
+ GTypeInterface base_iface;
+};
+
+GType tpsip_connection_aliasing_get_type (void) G_GNUC_CONST;
+
+void tpsip_connection_aliasing_init (gpointer instance);
+
+void tpsip_connection_aliasing_svc_iface_init (gpointer g_iface,
+ gpointer iface_data);
+
+G_END_DECLS
+
+#endif /*__TPSIP_CONN_ALIASING_H__*/
diff --git a/tpsip/handles.c b/tpsip/handles.c
new file mode 100644
index 0000000..55eb7e2
--- /dev/null
+++ b/tpsip/handles.c
@@ -0,0 +1,345 @@
+/*
+ * tpsip/handles.c - Handler helpers
+ * Copyright (C) 2005 Collabora Ltd.
+ * Copyright (C) 2006-2011 Nokia Corporation
+ *
+ * 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 <stdlib.h>
+
+#include <tpsip/handles.h>
+#include <sofia-sip/sip_header.h>
+
+#define DEBUG_FLAG TPSIP_DEBUG_CONNECTION
+#include "src/debug.h"
+
+static GQuark
+tpsip_handle_url_quark ()
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string ("tpsip-handle-url");
+
+ return quark;
+}
+
+const url_t*
+tpsip_handle_inspect_uri (TpBaseConnection *base,
+ TpHandle handle)
+{
+ TpHandleRepoIface *repo;
+ GQuark url_quark;
+ url_t *url;
+ GError *error;
+
+ repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT);
+
+ if (!tp_handle_is_valid (repo, handle, &error))
+ {
+ DEBUG("invalid handle %u: %s", handle, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ url_quark = tpsip_handle_url_quark ();
+
+ url = tp_handle_get_qdata (repo, handle, url_quark);
+
+ if (url == NULL)
+ {
+ url = url_make (NULL, tp_handle_inspect (repo, handle));
+
+ tp_handle_set_qdata (repo, handle, url_quark, url, free);
+ }
+
+ return url;
+}
+
+TpHandle
+tpsip_handle_ensure (TpBaseConnection *conn,
+ url_t const *uri,
+ char const *alias)
+{
+ TpHandleRepoIface *repo;
+ gchar *str;
+ TpHandle handle;
+
+ g_return_val_if_fail (TP_IS_BASE_CONNECTION (conn), 0);
+ g_return_val_if_fail (uri != NULL, 0);
+
+ repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
+
+ str = url_as_string (NULL, uri);
+
+ handle = tp_handle_ensure (repo, str, NULL, NULL);
+
+ su_free (NULL, str);
+
+ /* TODO: set qdata for the alias */
+
+ return handle;
+}
+
+TpHandle
+tpsip_handle_by_requestor (TpBaseConnection *conn,
+ sip_t const *sip)
+{
+ url_t const *uri;
+ char const *display;
+
+ g_return_val_if_fail (sip != NULL, 0);
+ g_return_val_if_fail (sip->sip_from != NULL, 0);
+
+ uri = sip->sip_from->a_url;
+ display = sip->sip_from->a_display;
+
+ return tpsip_handle_ensure (conn, uri, display);
+}
+
+void
+tpsip_handle_unref (TpBaseConnection *conn,
+ TpHandle handle)
+{
+ TpHandleRepoIface *repo;
+
+ g_return_if_fail (TP_IS_BASE_CONNECTION (conn));
+ g_return_if_fail (handle != 0);
+
+ repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
+
+ tp_handle_unref (repo, handle);
+}
+
+char const *
+tpsip_handle_inspect (TpBaseConnection *conn,
+ TpHandle handle)
+{
+ TpHandleRepoIface *repo;
+
+ g_return_val_if_fail (TP_IS_BASE_CONNECTION (conn), NULL);
+ g_return_val_if_fail (handle != 0, NULL);
+
+ repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
+
+ return tp_handle_inspect (repo, handle);
+}
+
+static gboolean
+priv_is_host (const gchar* str)
+{
+ static GRegex *host_regex = NULL;
+
+#define DOMAIN "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
+#define TLD "[a-z]([-a-z0-9]*[a-z0-9])?"
+
+ if (host_regex == NULL)
+ {
+ GError *error = NULL;
+
+ host_regex = g_regex_new ("^("
+ "("DOMAIN"\\.)*"TLD"\\.?|" /* host name */
+ "[0-9]{1,3}(\\.[0-9]{1,3}){3}|" /* IPv4 address */
+ "\\[[0-9a-f:.]\\]" /* IPv6 address, sloppily */
+ ")$",
+ G_REGEX_CASELESS | G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
+
+ if (error != NULL)
+ g_error ("failed to compile the host regex: %s", error->message);
+ }
+
+#undef DOMAIN
+#undef TLD
+
+ return g_regex_match (host_regex, str, 0, NULL);
+}
+
+static gboolean
+priv_is_tel_num (const gchar *str)
+{
+ static GRegex *tel_num_regex = NULL;
+
+ if (tel_num_regex == NULL)
+ {
+ GError *error = NULL;
+
+ tel_num_regex = g_regex_new (
+ "^\\s*[\\+(]?\\s*[0-9][-.0-9()\\s]*$",
+ G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
+
+ if (error != NULL)
+ g_error ("failed to compile the telephone number regex: %s",
+ error->message);
+ }
+
+ return g_regex_match (tel_num_regex, str, 0, NULL);
+}
+
+/* Strip the non-essential characters from a string regarded as
+ * a telephone number */
+static gchar *
+priv_strip_tel_num (const gchar *fuzzy)
+{
+ static GRegex *cruft_regex = NULL;
+
+ if (cruft_regex == NULL)
+ {
+ GError *error = NULL;
+
+ cruft_regex = g_regex_new ("[^+0-9]+",
+ G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &error);
+
+ if (error != NULL)
+ g_error ("failed to compile the non-essential "
+ "telephone number cruft regex: %s", error->message);
+ }
+
+ return g_regex_replace_literal (cruft_regex, fuzzy, -1, 0, "", 0, NULL);
+}
+
+static const char *
+priv_lowercase_url_part (su_home_t *home, const char *src)
+{
+ size_t n = 0;
+ size_t i;
+ char *res;
+
+ for (i = 0; src[i]; i++)
+ {
+ if (g_ascii_isupper (src[i]))
+ {
+ n = i + strlen (src + i);
+ break;
+ }
+ }
+
+ if (!src[i])
+ return src;
+
+ res = su_alloc (home, n + 1);
+ memcpy (res, src, i);
+ for (; i < n; i++)
+ res[i] = g_ascii_tolower (src[i]);
+ res[i] = '\0';
+
+ return (const char *) res;
+}
+
+#define TPSIP_RESERVED_CHARS_ALLOWED_IN_USERNAME "!*'()&=+$,;?/"
+
+gchar *
+tpsip_normalize_contact (const gchar *sipuri,
+ const url_t *base_url,
+ const gchar *transport,
+ GError **error)
+{
+ su_home_t home[1] = { SU_HOME_INIT(home) };
+ url_t *url;
+ gchar *retval = NULL;
+ char *c;
+
+ url = url_make (home, sipuri);
+
+ if (url == NULL ||
+ (url->url_scheme == NULL && url->url_user == NULL))
+ {
+ /* we got username or phone number, local to our domain */
+ gchar *user;
+
+ if (base_url == NULL || base_url->url_host == NULL)
+ {
+ WARNING ("bare name given, but no account URL is set");
+ goto error;
+ }
+
+ if (priv_is_tel_num (sipuri))
+ {
+ user = priv_strip_tel_num (sipuri);
+ }
+ else
+ {
+ user = g_uri_escape_string (sipuri,
+ TPSIP_RESERVED_CHARS_ALLOWED_IN_USERNAME, FALSE);
+ }
+
+ if (base_url->url_type == url_sips)
+ url = url_format (home, "sips:%s@%s",
+ user, base_url->url_host);
+ else
+ url = url_format (home, "sip:%s@%s",
+ user, base_url->url_host);
+
+ g_free (user);
+
+ if (!url) goto error;
+ }
+ else if (url->url_scheme == NULL)
+ {
+ /* Set the scheme to SIP or SIPS accordingly to the connection's
+ * transport preference */
+ if (transport != NULL
+ && g_ascii_strcasecmp (transport, "tls") == 0)
+ {
+ url->url_type = url_sips;
+ url->url_scheme = "sips";
+ }
+ else
+ {
+ url->url_type = url_sip;
+ url->url_scheme = "sip";
+ }
+ }
+
+ if (url_sanitize (url) != 0) goto error;
+
+ /* scheme should've been set by now */
+ if (url->url_scheme == NULL || (url->url_scheme[0] == 0))
+ goto error;
+
+ /* convert the scheme to lowercase */
+ /* Note: we can't do it in place because url->url_scheme may point to
+ * a static string */
+ url->url_scheme = priv_lowercase_url_part (home, url->url_scheme);
+
+ /* Check that if we have '@', the username isn't empty.
+ * Note that we rely on Sofia-SIP to canonize the user name */
+ if (url->url_user)
+ {
+ if (url->url_user[0] == 0) goto error;
+ }
+
+ /* host should be set and valid */
+ if (url->url_host == NULL || !priv_is_host (url->url_host))
+ goto error;
+
+ /* convert host to lowercase */
+ for (c = (char *) url->url_host; *c; c++)
+ {
+ *c = g_ascii_tolower (*c);
+ }
+
+ retval = g_strdup (url_as_string (home, url));
+
+error:
+ if (retval == NULL)
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_HANDLE,
+ "invalid SIP URI");
+
+ su_home_deinit (home);
+ return retval;
+}
diff --git a/tpsip/handles.h b/tpsip/handles.h
new file mode 100644
index 0000000..53dbf93
--- /dev/null
+++ b/tpsip/handles.h
@@ -0,0 +1,47 @@
+/*
+ * tpsip/handle.h - Telepathy SIP handle management
+ * Copyright (C) 2011 Nokia Corporation
+ * @author Pekka Pessi <pekka.pessi@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
+ */
+
+#ifndef TPSIP_HANDLE_H
+#define TPSIP_HANDLE_H
+
+#include <telepathy-glib/base-connection.h>
+#include <sofia-sip/sip.h>
+
+G_BEGIN_DECLS
+
+TpHandle tpsip_handle_ensure (TpBaseConnection *, url_t const *, char const *);
+TpHandle tpsip_handle_by_requestor (TpBaseConnection *, sip_t const *sip);
+void tpsip_handle_unref (TpBaseConnection *, TpHandle handle);
+char const *tpsip_handle_inspect (TpBaseConnection *, TpHandle handle);
+const url_t *tpsip_handle_inspect_uri (TpBaseConnection *, TpHandle handle);
+
+gchar * tpsip_handle_normalize (TpHandleRepoIface *repo,
+ const gchar *sipuri,
+ gpointer context,
+ GError **error);
+
+gchar *tpsip_normalize_contact (const gchar *sipuri,
+ const url_t *base_url,
+ const gchar *transport,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* !TPSIP_HANDLE_H */
diff --git a/tpsip/sofia-decls.h b/tpsip/sofia-decls.h
index a24ed15..d58b3fe 100644
--- a/tpsip/sofia-decls.h
+++ b/tpsip/sofia-decls.h
@@ -33,12 +33,17 @@
* pointing to an event target object attached to this handle.
*/
-#define NUA_MAGIC_T struct _TpsipConnection
+#define NUA_MAGIC_T struct _TpsipBaseConnection
#define NUA_HMAGIC_T struct _TpsipEventTarget
#define SU_ROOT_MAGIC_T struct _TpsipConnectionManager
-#define SU_TIMER_ARG_T struct _TpsipConnection
+#define SU_TIMER_ARG_T struct _TpsipBaseConnection
#define SU_WAKEUP_ARG_T void
+#define TPSIP_DEFAULT_STUN_PORT 3478
+
+/* Maximum defer timeout for deferrable Sofia timers */
+#define TPSIP_DEFER_TIMEOUT 30
+
#include <sofia-sip/nua.h>
#include <sofia-sip/su.h>