1
0
Fork 0
mirror of https://gitlab.gnome.org/GNOME/calls.git synced 2024-06-30 15:49:31 +00:00

sip: origin: Use CallsCredentials and adapt to changes

All parts not related to credentials are now being set when creating the nua
handles and then updated with nua_set_params() when the credentials get updated.
This commit is contained in:
Evangelos Ribeiro Tzaras 2021-04-28 00:26:10 +02:00
parent 3f72d34c49
commit 5d0de3d299
5 changed files with 272 additions and 281 deletions

View file

@ -25,6 +25,7 @@
#define G_LOG_DOMAIN "CallsSipOrigin"
#include "calls-credentials.h"
#include "calls-message-source.h"
#include "calls-origin.h"
#include "calls-sip-call.h"
@ -55,14 +56,9 @@
enum {
PROP_0,
PROP_ACC_CREDENTIALS,
PROP_NAME,
PROP_ACC_USER,
PROP_ACC_PASSWORD,
PROP_ACC_HOST,
PROP_ACC_PORT,
PROP_ACC_PROTOCOL,
PROP_ACC_DIRECT,
PROP_ACC_AUTO_CONNECT,
PROP_SIP_CONTEXT,
PROP_SIP_LOCAL_PORT,
PROP_ACC_STATE,
@ -75,15 +71,10 @@ static GParamSpec *props[PROP_LAST_PROP];
struct _CallsSipOrigin
{
GObject parent_instance;
GString *name;
CallsSipContext *ctx;
nua_t *nua;
CallsSipHandles *oper;
/* Maybe it makes sense to have one call handle (nua_handle_t) in
* CallsSipCall (do we need a backpointer to CallsSipOrigin?)
* and define the HMAGIC as a CallsSipOrigin
*/
/* Direct connection mode is useful for debugging purposes */
gboolean use_direct_connection;
@ -95,15 +86,9 @@ struct _CallsSipOrigin
CallsSipMediaManager *media_manager;
gboolean auto_connect;
/* Account information */
gchar *user;
gchar *password;
gchar *host;
gchar *transport_protocol;
CallsCredentials *credentials;
const gchar *protocol_prefix;
gint port;
gint local_port;
GList *calls;
@ -290,15 +275,99 @@ create_inbound (CallsSipOrigin *self,
add_call (self, address, TRUE, handle);
}
static void
update_nua (CallsSipOrigin *self)
{
gboolean use_sips = FALSE;
gboolean use_ipv6 = FALSE; /* TODO make configurable or use DNS to figure out if ipv6 is supported*/
gchar *ipv6_bind = "*";
gchar *ipv4_bind = "0.0.0.0";
g_autofree gchar *sip_url = NULL;
g_autofree gchar *sips_url = NULL;
g_autofree char *user = NULL;
g_autofree char *host = NULL;
g_autofree gchar *address = NULL;
g_assert (CALLS_IS_SIP_ORIGIN (self));
g_assert (self->nua);
g_object_get (self->credentials,
"user", &user,
"host", &host,
NULL);
if (user && host) {
address = g_strconcat (self->protocol_prefix, ":", user, "@", host, NULL);
use_sips = check_sips (address);
use_ipv6 = check_ipv6 (host);
}
if (self->local_port > 0) {
sip_url = g_strdup_printf ("sip:%s:%d",
use_ipv6 ? ipv6_bind : ipv4_bind,
self->local_port);
sips_url = g_strdup_printf ("sips:%s:%d",
use_ipv6 ? ipv6_bind : ipv4_bind,
self->local_port);
} else {
sip_url = g_strdup_printf ("sip:%s:*",
use_ipv6 ? ipv6_bind : ipv4_bind);
sips_url = g_strdup_printf ("sips:%s:*",
use_ipv6 ? ipv6_bind : ipv4_bind);
}
nua_set_params (self->nua,
NUTAG_URL (sip_url),
TAG_IF (use_sips, NUTAG_SIPS_URL (sips_url)),
TAG_IF (address, SIPTAG_FROM_STR (address)),
TAG_NULL ());
}
static void
sip_authenticate (CallsSipOrigin *origin,
update_credentials (CallsSipOrigin *self)
{
g_autofree char *protocol = NULL;
g_assert (CALLS_IS_SIP_ORIGIN (self));
g_debug ("Updating credentials");
g_object_get (self->credentials,
"protocol", &protocol,
NULL);
if (protocol == NULL) {
g_debug ("Protocol not set, falling back to 'UDP'");
g_object_set (self->credentials, "protocol", "UDP", NULL);
self->protocol_prefix = get_protocol_prefix ("UDP");
} else if (!protocol_is_valid (protocol)) {
g_warning ("Tried setting invalid protocol: '%s'\n"
"Falling back to default: '%s'",
protocol, "UDP");
g_object_set (self->credentials, "protocol", "UDP", NULL);
self->protocol_prefix = get_protocol_prefix ("UDP");
} else {
self->protocol_prefix = get_protocol_prefix (protocol);
}
if (self->nua)
update_nua (self);
}
static void
sip_authenticate (CallsSipOrigin *self,
nua_handle_t *nh,
sip_t const *sip)
{
const gchar *scheme = NULL;
const gchar *realm = NULL;
g_autofree gchar *auth = NULL;
g_autofree char *user = NULL;
g_autofree char *password = NULL;
sip_www_authenticate_t *www_auth = sip->sip_www_authenticate;
sip_proxy_authenticate_t *proxy_auth = sip->sip_proxy_authenticate;
@ -316,8 +385,16 @@ sip_authenticate (CallsSipOrigin *origin,
}
g_debug ("need to authenticate to realm %s", realm);
g_object_get (self->credentials,
"user", &user,
"password", &password,
NULL);
/* TODO handle authentication to different realms
* https://source.puri.sm/Librem5/calls/-/issues/266
*/
auth = g_strdup_printf ("%s:%s:%s:%s",
scheme, realm, origin->user, origin->password);
scheme, realm, user, password);
nua_authenticate (nh, NUTAG_AUTH (auth), TAG_END ());
}
@ -449,7 +526,6 @@ sip_i_state (int status,
r_sdp->sdp_media->m_port + 1);
}
/* TODO use CallCallStates with g_object_set (notify!) */
switch (call_state) {
case nua_callstate_init:
return;
@ -636,7 +712,7 @@ setup_nua (CallsSipOrigin *self)
{
g_autofree gchar *address = NULL;
nua_t *nua;
gboolean use_sips;
gboolean use_sips = FALSE;
gboolean use_ipv6 = FALSE; /* TODO make configurable or use DNS to figure out if ipv6 is supported*/
gchar *ipv6_bind = "*";
gchar *ipv4_bind = "0.0.0.0";
@ -644,15 +720,23 @@ setup_nua (CallsSipOrigin *self)
g_autofree gchar *sips_url = NULL;
const gchar *uuid = NULL;
g_autofree gchar* urn_uuid = NULL;
g_autofree char *user = NULL;
g_autofree char *host = NULL;
uuid = nua_generate_instance_identifier (self->ctx->home);
urn_uuid = g_strdup_printf ("urn:uuid:%s", uuid);
address = g_strconcat (self->protocol_prefix, ":", self->user, "@", self->host, NULL);
g_object_get (self->credentials,
"user", &user,
"host", &host,
NULL);
use_sips = check_sips (address);
use_ipv6 = check_ipv6 (self->host);
if (user && host) {
address = g_strconcat (self->protocol_prefix, ":", user, "@", host, NULL);
use_sips = check_sips (address);
use_ipv6 = check_ipv6 (host);
}
if (self->local_port > 0) {
sip_url = g_strdup_printf ("sip:%s:%d",
@ -674,8 +758,9 @@ setup_nua (CallsSipOrigin *self)
NUTAG_USER_AGENT (APP_DATA_NAME),
NUTAG_URL (sip_url),
TAG_IF (use_sips, NUTAG_SIPS_URL (sips_url)),
SIPTAG_FROM_STR (address),
TAG_IF (address, SIPTAG_FROM_STR (address)),
NUTAG_ALLOW ("INVITE, ACK, BYE, CANCEL, OPTIONS, UPDATE"),
NUTAG_SUPPORTED ("replaces, gruu, outbound"),
NTATAG_MAX_FORWARDS (70),
NUTAG_ENABLEINVITE (1),
NUTAG_AUTOANSWER (0),
@ -685,13 +770,31 @@ setup_nua (CallsSipOrigin *self)
NUTAG_INSTANCE (urn_uuid),
TAG_NULL ());
nua_set_params (nua,
NUTAG_SUPPORTED ("replaces, gruu, outbound"),
TAG_END ());
return nua;
}
static char *
get_registrar_url (CallsSipOrigin *self)
{
char *registrar_url = NULL;
g_autofree char *host = NULL;
gint port;
g_assert (CALLS_IS_SIP_ORIGIN (self));
g_object_get (self->credentials,
"host", &host,
"port", &port,
NULL);
if (port > 0 && port <= 65535)
registrar_url =
g_strdup_printf ("%s:%s:%d", self->protocol_prefix, host, port);
else
registrar_url = g_strconcat (self->protocol_prefix, ":", host, NULL);
return registrar_url;
}
static CallsSipHandles *
setup_sip_handles (CallsSipOrigin *self)
@ -706,10 +809,13 @@ setup_sip_handles (CallsSipOrigin *self)
return NULL;
}
registrar_url = g_strconcat (self->protocol_prefix, ":", self->host, NULL);
oper->context = self->ctx;
oper->register_handle = nua_handle (self->nua, self->oper,
NUTAG_REGISTRAR (registrar_url),
SIPTAG_EXPIRES_STR ("180"),
NUTAG_SUPPORTED ("replaces, outbound, gruu"),
NUTAG_OUTBOUND ("outbound natify gruuize validate"), // <- janus uses "no-validate"
NUTAG_M_PARAMS ("user=phone"),
NUTAG_CALLEE_CAPS (1), /* header parameters based on SDP capabilities and Allow header */
TAG_END ());
oper->call_handle = NULL;
return oper;
@ -719,42 +825,53 @@ setup_sip_handles (CallsSipOrigin *self)
static void
setup_account_for_direct_connection (CallsSipOrigin *self)
{
g_autofree char *user = NULL;
g_assert (CALLS_IS_SIP_ORIGIN (self));
g_object_get (self->credentials, "user", &user, NULL);
/* honour username, if previously set */
if (self->user == NULL)
self->user = g_strdup (g_get_user_name ());
if (user == NULL)
g_object_set (self->credentials,
"user", g_get_user_name (),
NULL);
g_free (self->host);
self->host = g_strdup (g_get_host_name ());
g_object_set (self->credentials,
"host", g_get_host_name (),
"password", NULL,
"protocol", "UDP",
NULL);
g_free (self->password);
self->password = NULL;
self->protocol_prefix = get_protocol_prefix ("UDP");
g_free (self->transport_protocol);
self->transport_protocol = g_strdup ("UDP");
self->protocol_prefix = get_protocol_prefix (self->transport_protocol);
g_debug ("Notifying account changed:\n"
"user: %s\nhost URL: %s", self->user, self->host);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACC_USER]);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACC_HOST]);
g_debug ("Account changed:\nuser: %s\nhost URL: %s",
user ?: g_get_user_name (), g_get_host_name ());
}
static gboolean
is_account_complete (CallsSipOrigin *self)
{
g_autofree char *host = NULL;
g_autofree char *user = NULL;
g_autofree char *password = NULL;
g_autofree char *protocol = NULL;
g_assert (CALLS_IS_SIP_ORIGIN (self));
g_object_get (self->credentials,
"host", &host,
"user", &user,
"password", &password,
"protocol", &protocol,
NULL);
/* we need only need to check for password if needing to authenticate over a proxy/UAS */
if (self->user == NULL ||
(!self->use_direct_connection && self->password == NULL) ||
self->host == NULL ||
self->transport_protocol == NULL ||
self->protocol_prefix == NULL)
if (user == NULL ||
(!self->use_direct_connection && password == NULL) ||
host == NULL ||
protocol == NULL)
return FALSE;
return TRUE;
@ -766,6 +883,7 @@ init_sip_account (CallsSipOrigin *self,
GError **error)
{
gboolean recoverable = FALSE;
gboolean auto_connect = FALSE;
if (self->use_direct_connection) {
g_debug ("Direct connection case. Using user and hostname");
@ -802,8 +920,9 @@ init_sip_account (CallsSipOrigin *self,
else {
self->state = SIP_ACCOUNT_OFFLINE;
if (self->auto_connect)
/* try to go online */
g_object_get (self->credentials, "auto-connect", &auto_connect, NULL);
/* try to go online */
if (auto_connect)
calls_sip_origin_go_online (self, TRUE);
}
@ -826,37 +945,9 @@ calls_sip_origin_set_property (GObject *object,
CallsSipOrigin *self = CALLS_SIP_ORIGIN (object);
switch (property_id) {
case PROP_ACC_USER:
g_free (self->user);
self->user = g_value_dup_string (value);
break;
case PROP_ACC_PASSWORD:
g_free (self->password);
self->password = g_value_dup_string (value);
break;
case PROP_ACC_HOST:
g_free (self->host);
self->host = g_value_dup_string (value);
break;
case PROP_ACC_PORT:
self->port = g_value_get_int (value);
break;
case PROP_ACC_PROTOCOL:
if (!protocol_is_valid (g_value_get_string (value))) {
g_warning ("Tried setting invalid protocol: '%s'\n"
"Continue using old protocol: '%s'",
g_value_get_string (value), self->transport_protocol);
return;
}
g_free (self->transport_protocol);
self->transport_protocol = g_value_dup_string (value);
self->protocol_prefix = get_protocol_prefix (self->transport_protocol);
case PROP_ACC_CREDENTIALS:
self->credentials = g_value_get_object (value);
update_credentials (self);
break;
case PROP_ACC_DIRECT:
@ -871,10 +962,6 @@ calls_sip_origin_set_property (GObject *object,
g_warning ("Setting the account state does not yet have any effect");
break;
case PROP_ACC_AUTO_CONNECT:
self->auto_connect = g_value_get_boolean (value);
break;
case PROP_SIP_LOCAL_PORT:
if (g_value_get_int (value) > 0 && g_value_get_int (value) < 1025) {
g_warning ("Tried setting a privileged port as the local port to bind to: %d\n"
@ -899,40 +986,22 @@ calls_sip_origin_get_property (GObject *object,
GParamSpec *pspec)
{
CallsSipOrigin *self = CALLS_SIP_ORIGIN (object);
g_autofree char *name = NULL;
switch (property_id) {
case PROP_NAME:
g_value_set_string (value, self->name->str);
g_object_get (self->credentials, "name", &name, NULL);
g_value_set_string (value, name);
break;
case PROP_CALLS:
g_value_set_pointer (value, g_list_copy (self->calls));
break;
case PROP_ACC_USER:
g_value_set_string (value, self->user);
break;
case PROP_ACC_HOST:
g_value_set_string (value, self->host);
break;
case PROP_ACC_PORT:
g_value_set_int (value, self->port);
break;
case PROP_ACC_PROTOCOL:
g_value_set_string (value, self->transport_protocol);
break;
case PROP_ACC_STATE:
g_value_set_enum (value, self->state);
break;
case PROP_ACC_AUTO_CONNECT:
g_value_set_boolean (value, self->auto_connect);
break;
case PROP_SIP_LOCAL_PORT:
g_value_set_int (value, self->local_port);
break;
@ -960,6 +1029,9 @@ calls_sip_origin_constructed (GObject *object)
self->media_manager = calls_sip_media_manager_default ();
g_signal_connect_swapped (self->credentials, "account-updated",
(GCallback) update_credentials, self);
G_OBJECT_CLASS (calls_sip_origin_parent_class)->constructed (object);
}
@ -1005,11 +1077,7 @@ calls_sip_origin_finalize (GObject *object)
{
CallsSipOrigin *self = CALLS_SIP_ORIGIN (object);
g_string_free (self->name, TRUE);
g_free (self->user);
g_free (self->password);
g_free (self->host);
g_free (self->transport_protocol);
g_object_unref (self->credentials);
g_hash_table_destroy (self->call_handles);
G_OBJECT_CLASS (calls_sip_origin_parent_class)->finalize (object);
@ -1027,45 +1095,14 @@ calls_sip_origin_class_init (CallsSipOriginClass *klass)
object_class->get_property = calls_sip_origin_get_property;
object_class->set_property = calls_sip_origin_set_property;
props[PROP_ACC_USER] =
g_param_spec_string ("user",
"User",
"The username for authentication",
"",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ACC_USER, props[PROP_ACC_USER]);
props[PROP_ACC_CREDENTIALS] =
g_param_spec_object ("credentials",
"Credentials",
"The credentials for this origin",
CALLS_TYPE_CREDENTIALS,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (object_class, PROP_ACC_CREDENTIALS, props[PROP_ACC_CREDENTIALS]);
props[PROP_ACC_PASSWORD] =
g_param_spec_string ("password",
"Password",
"The password for authentication",
"",
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ACC_PASSWORD, props[PROP_ACC_PASSWORD]);
props[PROP_ACC_HOST] =
g_param_spec_string ("host",
"Host",
"The fqdn of the SIP server",
"",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ACC_HOST, props[PROP_ACC_HOST]);
props[PROP_ACC_PORT] =
g_param_spec_int ("port",
"Port",
"Port of the SIP server",
1025, 65535, 5060,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ACC_PORT, props[PROP_ACC_PORT]);
props[PROP_ACC_PROTOCOL] =
g_param_spec_string ("protocol",
"Protocol",
"The protocol used to connect to the SIP server",
"UDP",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_ACC_PROTOCOL, props[PROP_ACC_PROTOCOL]);
props[PROP_ACC_DIRECT] =
g_param_spec_boolean ("direct-connection",
"Direct connection",
@ -1098,14 +1135,6 @@ calls_sip_origin_class_init (CallsSipOriginClass *klass)
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_ACC_STATE, props[PROP_ACC_STATE]);
props[PROP_ACC_AUTO_CONNECT] =
g_param_spec_boolean ("auto-connect",
"Auto connect",
"Automatically try to connect",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (object_class, PROP_ACC_AUTO_CONNECT, props[PROP_ACC_AUTO_CONNECT]);
#define IMPLEMENTS(ID, NAME) \
g_object_class_override_property (object_class, ID, NAME); \
props[ID] = g_object_class_find_property(object_class, NAME);
@ -1134,42 +1163,24 @@ calls_sip_origin_origin_interface_init (CallsOriginInterface *iface)
static void
calls_sip_origin_init (CallsSipOrigin *self)
{
self->name = g_string_new (NULL);
self->call_handles = g_hash_table_new (NULL, NULL);
}
CallsSipOrigin *
calls_sip_origin_new (const gchar *name,
CallsSipContext *sip_context,
const gchar *user,
const gchar *password,
const gchar *host,
gint port,
calls_sip_origin_new (CallsSipContext *sip_context,
CallsCredentials *credentials,
gint local_port,
const gchar *protocol,
gboolean direct_connection,
gboolean auto_connect)
gboolean direct_connection)
{
CallsSipOrigin *origin;
g_return_val_if_fail (sip_context, NULL);
g_return_val_if_fail (credentials, NULL);
g_return_val_if_fail (sip_context != NULL, NULL);
origin = g_object_new (CALLS_TYPE_SIP_ORIGIN,
"sip-context", sip_context,
"user", user,
"password", password,
"host", host,
"port", port,
"local-port", local_port,
"protocol", protocol,
"direct-connection", direct_connection,
"auto-connect", auto_connect,
NULL);
g_string_assign (origin->name, name);
return origin;
return g_object_new (CALLS_TYPE_SIP_ORIGIN,
"sip-context", sip_context,
"credentials", g_object_ref (credentials),
"local-port", local_port,
"direct-connection", direct_connection,
NULL);
}
@ -1185,16 +1196,24 @@ calls_sip_origin_go_online (CallsSipOrigin *self,
g_return_if_fail (CALLS_IS_SIP_ORIGIN (self));
if (online) {
g_autofree char *user = NULL;
g_autofree char *display_name = NULL;
g_autofree char *registrar_url = NULL;
if (self->state == SIP_ACCOUNT_ONLINE)
return;
g_object_get (self->credentials,
"user", &user,
"display-name", &display_name,
NULL);
registrar_url = get_registrar_url (self);
nua_register (self->oper->register_handle,
SIPTAG_EXPIRES_STR ("180"),
NUTAG_SUPPORTED ("replaces, outbound, gruu"),
NUTAG_OUTBOUND ("outbound natify gruuize validate"), // <- janus uses "no-validate"
NUTAG_M_USERNAME (self->user),
NUTAG_M_PARAMS ("user=phone"),
NUTAG_CALLEE_CAPS (1), /* header parameters based on SDP capabilities and Allow header */
NUTAG_M_USERNAME (user),
TAG_IF (display_name, NUTAG_M_DISPLAY (display_name)),
NUTAG_REGISTRAR (registrar_url),
TAG_END ());
}
else {

View file

@ -24,6 +24,7 @@
#pragma once
#include "calls-credentials.h"
#include "calls-sip-util.h"
#include <glib-object.h>
@ -34,16 +35,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CallsSipOrigin, calls_sip_origin, CALLS, SIP_ORIGIN, GObject);
CallsSipOrigin *calls_sip_origin_new (const gchar *name,
CallsSipContext *sip_context,
const gchar *user,
const gchar *password,
const gchar *host,
gint port,
CallsSipOrigin *calls_sip_origin_new (CallsSipContext *sip_context,
CallsCredentials *credentials,
gint local_port,
const gchar *protocol,
gboolean direct_connection,
gboolean auto_connect);
gboolean direct_connection);
void calls_sip_origin_go_online (CallsSipOrigin *self,
gboolean online);
G_END_DECLS

View file

@ -94,44 +94,23 @@ calls_sip_provider_load_accounts (CallsSipProvider *self)
for (gsize i = 0; groups[i] != NULL; i++) {
g_autoptr (CallsCredentials) credentials = calls_credentials_new ();
g_autofree gchar *user = NULL;
g_autofree gchar *password = NULL;
g_autofree gchar *host = NULL;
g_autofree gchar *protocol = NULL;
gint port = 0;
gint local_port = 0;
gboolean auto_connect = TRUE;
gboolean direct_connection =
g_key_file_get_boolean (key_file, groups[i], "Direct", NULL);
if (direct_connection) {
g_object_set (credentials, "name", groups[i], NULL);
local_port = g_key_file_get_integer (key_file, groups[i], "LocalPort", NULL);
/* direct connection mode, needs a local port set */
if (local_port == 0)
local_port = 5060;
protocol = g_strdup ("UDP");
goto skip;
} else {
calls_credentials_update_from_keyfile (credentials, key_file, groups[i]);
}
calls_credentials_update_from_keyfile (credentials, key_file, groups[i]);
g_object_get (G_OBJECT (credentials),
"host", &host,
"user", &user,
"password", &password,
"port", &port,
"protocol", &protocol,
"auto-connect", &auto_connect,
NULL);
skip:
g_debug ("Adding origin for SIP account %s", groups[i]);
calls_sip_provider_add_origin (self, groups[i],
user, password,
host, port, local_port,
protocol,
direct_connection,
auto_connect);
calls_sip_provider_add_origin (self, g_steal_pointer (&credentials), local_port, direct_connection);
}
g_strfreev (groups);
@ -369,50 +348,29 @@ calls_sip_provider_init (CallsSipProvider *self)
/**
* calls_sip_provider_add_origin:
* @self: A #CallsSipProvider
* @name: The name of the origin
* @user: (nullable): The username to use or %NULL
* @password: (nullable): The password to use or %NULL
* @host: (nullable):The host to use or %NULL
* @port: The port of the host to connect to, usually 5060
* @credentials: A #CallsCredentials
* @local_port: The local port to bind to or 0
* @protocol: (nullable): The protocol to use. Can be "TCP", "UDP", "TLS" or %NULL
* @direct_connection: %TRUE to use a direct connection to peers, %FALSE otherwise
* @auto_connect: %TRUE to automatically try to register, %FALSE otherwise
*
* Adds a new origin (SIP account). If @direct_connection is set the nullables
* can be set automatically (f.e. use the local user and hostname).
* Adds a new origin (SIP account). If @direct_connection is set
* some properties of @credentials can be set automatically
* (f.e. use the username and hostname).
*/
void
calls_sip_provider_add_origin (CallsSipProvider *self,
const gchar *name,
const gchar *user,
const gchar *password,
const gchar *host,
gint port,
CallsCredentials *credentials,
gint local_port,
const gchar *protocol,
gboolean direct_connection,
gboolean auto_connect)
gboolean direct_connection)
{
g_autoptr (CallsSipOrigin) origin = NULL;
g_return_if_fail (CALLS_IS_SIP_PROVIDER (self));
g_return_if_fail (CALLS_IS_CREDENTIALS (credentials));
origin = calls_sip_origin_new (name,
self->ctx,
user,
password,
host,
port,
origin = calls_sip_origin_new (self->ctx,
credentials,
local_port,
protocol,
direct_connection,
auto_connect);
if (!origin) {
g_warning ("Could not create CallsSipOrigin");
return;
}
direct_connection);
g_list_store_append (self->origins, origin);
}

View file

@ -26,6 +26,7 @@
#include <glib-object.h>
#include "calls-credentials.h"
#include "calls-provider.h"
G_BEGIN_DECLS
@ -36,14 +37,8 @@ G_DECLARE_FINAL_TYPE (CallsSipProvider, calls_sip_provider, CALLS, SIP_PROVIDER,
CallsSipProvider *calls_sip_provider_new ();
void calls_sip_provider_add_origin (CallsSipProvider *self,
const gchar *name,
const gchar *user,
const gchar *password,
const gchar *host,
gint port,
CallsCredentials *credentials,
gint local_port,
const gchar *protocol,
gboolean direct_connection,
gboolean auto_connect);
gboolean direct_connection);
G_END_DECLS

View file

@ -23,6 +23,9 @@ typedef struct {
CallsSipOrigin *origin_alice;
CallsSipOrigin *origin_bob;
CallsSipOrigin *origin_offline;
CallsCredentials *credentials_alice;
CallsCredentials *credentials_bob;
CallsCredentials *credentials_offline;
} SipFixture;
@ -358,27 +361,43 @@ setup_sip_origins (SipFixture *fixture,
gconstpointer user_data)
{
GListModel *origins;
CallsCredentials *alice = calls_credentials_new ();
CallsCredentials *bob = calls_credentials_new ();
CallsCredentials *offline = calls_credentials_new ();
setup_sip_provider (fixture, user_data);
calls_sip_provider_add_origin (fixture->provider, "Alice",
"alice", NULL, NULL, 5060,
5060, "UDP", TRUE, FALSE);
g_object_set (alice, "name", "Alice", "user", "alice", NULL);
calls_sip_provider_add_origin (fixture->provider, "Bob",
"bob", NULL, NULL, 5060,
5061, "UDP", TRUE, FALSE);
calls_sip_provider_add_origin (fixture->provider, alice, 5060, TRUE);
calls_sip_provider_add_origin (fixture->provider, "Offline",
"someuser", "sip.imaginary-host.org", "password", 5060,
5062, "UDP", FALSE, FALSE);
g_object_set (bob, "name", "Bob", "user", "bob", NULL);
calls_sip_provider_add_origin (fixture->provider, bob, 5061, TRUE);
g_object_set (offline,
"name", "Offline",
"user", "someuser",
"host", "sip.imaginary-host.org",
"password", "password123",
"port", 5060,
"protocol", "UDP",
"auto-connect", FALSE,
NULL);
calls_sip_provider_add_origin (fixture->provider, offline, 0, FALSE);
origins = calls_provider_get_origins
(CALLS_PROVIDER (fixture->provider));
fixture->origin_alice = g_list_model_get_item (origins, 0);
fixture->credentials_alice = alice;
fixture->origin_bob = g_list_model_get_item (origins, 1);
fixture->credentials_bob = bob;
fixture->origin_offline = g_list_model_get_item (origins, 2);
fixture->credentials_offline = offline;
}
static void
@ -386,8 +405,13 @@ tear_down_sip_origins (SipFixture *fixture,
gconstpointer user_data)
{
g_clear_object (&fixture->origin_alice);
g_clear_object (&fixture->credentials_alice);
g_clear_object (&fixture->origin_bob);
g_clear_object (&fixture->credentials_bob);
g_clear_object (&fixture->origin_offline);
g_clear_object (&fixture->credentials_offline);
tear_down_sip_provider (fixture, user_data);
}