diff --git a/plugins/sip/calls-sip-origin.c b/plugins/sip/calls-sip-origin.c index 091383c..a105b6f 100644 --- a/plugins/sip/calls-sip-origin.c +++ b/plugins/sip/calls-sip-origin.c @@ -26,7 +26,6 @@ #include "calls-account.h" -#include "calls-credentials.h" #include "calls-message-source.h" #include "calls-origin.h" #include "calls-sip-call.h" @@ -59,11 +58,17 @@ enum { PROP_0, - PROP_ACC_CREDENTIALS, PROP_NAME, + PROP_ACC_HOST, + PROP_ACC_USER, + PROP_ACC_PASSWORD, + PROP_ACC_DISPLAY_NAME, + PROP_ACC_PORT, + PROP_ACC_PROTOCOL, + PROP_ACC_AUTO_CONNECT, PROP_ACC_DIRECT, + PROP_ACC_LOCAL_PORT, PROP_SIP_CONTEXT, - PROP_SIP_LOCAL_PORT, PROP_ACC_STATE, PROP_CALLS, PROP_COUNTRY_CODE, @@ -93,10 +98,20 @@ struct _CallsSipOrigin CallsSipMediaManager *media_manager; /* Account information */ - CallsCredentials *credentials; - const gchar *protocol_prefix; + char *host; + char *user; + char *password; + char *display_name; + gint port; + char *transport_protocol; + gboolean auto_connect; + gboolean direct_mode; gint local_port; + const char *protocol_prefix; + char *address; + char *name; + GList *calls; GHashTable *call_handles; }; @@ -296,28 +311,23 @@ 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; + char *ipv6_bind = "*"; + char *ipv4_bind = "0.0.0.0"; + g_autofree char *sip_url = NULL; + g_autofree char *sips_url = NULL; + g_autofree char *from_str = NULL; g_assert (CALLS_IS_SIP_ORIGIN (self)); g_assert (self->nua); - g_object_get (self->credentials, - "user", &user, - "host", &host, - NULL); + self->protocol_prefix = get_protocol_prefix (self->transport_protocol); - if (user && host) { - address = g_strconcat (self->protocol_prefix, ":", user, "@", host, NULL); + g_free (self->address); + self->address = g_strconcat (self->user, "@", self->host, NULL); + from_str = g_strconcat (self->protocol_prefix, ":", self->address, NULL); - use_sips = check_sips (address); - use_ipv6 = check_ipv6 (host); - } + use_sips = check_sips (from_str); + use_ipv6 = check_ipv6 (self->host); if (self->local_port > 0) { sip_url = g_strdup_printf ("sip:%s:%d", @@ -334,43 +344,10 @@ update_nua (CallsSipOrigin *self) } 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 -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); + NUTAG_URL (sip_url), + TAG_IF (use_sips, NUTAG_SIPS_URL (sips_url)), + SIPTAG_FROM_STR (from_str), + TAG_NULL ()); } @@ -382,8 +359,6 @@ sip_authenticate (CallsSipOrigin *self, 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; @@ -401,16 +376,11 @@ sip_authenticate (CallsSipOrigin *self, } 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, user, password); + scheme, realm, self->user, self->password); nua_authenticate (nh, NUTAG_AUTH (auth), TAG_END ()); } @@ -802,33 +772,27 @@ sip_callback (nua_event_t event, static nua_t * setup_nua (CallsSipOrigin *self) { - g_autofree gchar *address = NULL; nua_t *nua; 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; - const gchar *uuid = NULL; - g_autofree gchar* urn_uuid = NULL; - g_autofree char *user = NULL; - g_autofree char *host = NULL; + const char *ipv6_bind = "*"; + const char *ipv4_bind = "0.0.0.0"; + const char *uuid = NULL; + g_autofree char *urn_uuid = NULL; + g_autofree char *sip_url = NULL; + g_autofree char *sips_url = NULL; + g_autofree char *from_str = NULL; uuid = nua_generate_instance_identifier (self->ctx->home); urn_uuid = g_strdup_printf ("urn:uuid:%s", uuid); - g_object_get (self->credentials, - "user", &user, - "host", &host, - NULL); + self->protocol_prefix = get_protocol_prefix (self->transport_protocol); - if (user && host) { - address = g_strconcat (self->protocol_prefix, ":", user, "@", host, NULL); + self->address = g_strconcat (self->user, "@", self->host, NULL); + from_str = g_strconcat (self->protocol_prefix, ":", self->address, NULL); - use_sips = check_sips (address); - use_ipv6 = check_ipv6 (host); - } + use_sips = check_sips (self->address); + use_ipv6 = check_ipv6 (self->host); if (self->local_port > 0) { sip_url = g_strdup_printf ("sip:%s:%d", @@ -850,7 +814,7 @@ setup_nua (CallsSipOrigin *self) NUTAG_USER_AGENT (APP_DATA_NAME), NUTAG_URL (sip_url), TAG_IF (use_sips, NUTAG_SIPS_URL (sips_url)), - TAG_IF (address, SIPTAG_FROM_STR (address)), + SIPTAG_FROM_STR (from_str), NUTAG_ALLOW ("INVITE, ACK, BYE, CANCEL, OPTIONS, UPDATE"), NUTAG_SUPPORTED ("replaces, gruu, outbound"), NTATAG_MAX_FORWARDS (70), @@ -868,31 +832,19 @@ setup_nua (CallsSipOrigin *self) 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); + if (self->port > 0 && self->port <= 65535) + return g_strdup_printf ("%s:%s:%d", self->protocol_prefix, self->host, self->port); else - registrar_url = g_strconcat (self->protocol_prefix, ":", host, NULL); - - return registrar_url; + return g_strconcat (self->protocol_prefix, ":", self->host, NULL); } static CallsSipHandles * setup_sip_handles (CallsSipOrigin *self) { CallsSipHandles *oper; - g_autofree gchar *registrar_url = NULL; + g_autofree char *registrar_url = NULL; g_assert (CALLS_IS_SIP_ORIGIN (self)); @@ -916,7 +868,7 @@ setup_sip_handles (CallsSipOrigin *self) static void go_online (CallsAccount *account, - gboolean online) + gboolean online) { CallsSipOrigin *self; @@ -927,23 +879,16 @@ go_online (CallsAccount *account, self = CALLS_SIP_ORIGIN (account); if (online) { - g_autofree char *user = NULL; - g_autofree char *display_name = NULL; g_autofree char *registrar_url = NULL; if (self->state == CALLS_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, - NUTAG_M_USERNAME (user), - TAG_IF (display_name, NUTAG_M_DISPLAY (display_name)), + NUTAG_M_USERNAME (self->user), + TAG_IF (self->display_name, NUTAG_M_DISPLAY (self->display_name)), NUTAG_REGISTRAR (registrar_url), TAG_END ()); @@ -960,53 +905,35 @@ go_online (CallsAccount *account, 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 (user == NULL) - g_object_set (self->credentials, - "user", g_get_user_name (), - NULL); + if (self->user == NULL) + self->user = g_strdup (g_get_user_name ()); - g_object_set (self->credentials, - "host", g_get_host_name (), - "password", NULL, - "protocol", "UDP", - NULL); + g_free (self->host); + self->host = g_strdup (g_get_host_name ()); + + g_clear_pointer (&self->password, g_free); + + g_free (self->transport_protocol); + self->transport_protocol = g_strdup ("UDP"); self->protocol_prefix = get_protocol_prefix ("UDP"); - g_debug ("Account changed:\nuser: %s\nhost URL: %s", - user ?: g_get_user_name (), g_get_host_name ()); + g_debug ("Account changed:\nuser: %s\nhost: %s", + self->user, self->host); } 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 (user == NULL || - (!self->use_direct_connection && password == NULL) || - host == NULL || - protocol == NULL) + if (self->user == NULL || + (!self->use_direct_connection && self->password == NULL) || + self->host == NULL || + self->transport_protocol == NULL) return FALSE; return TRUE; @@ -1017,8 +944,6 @@ static gboolean init_sip_account (CallsSipOrigin *self, GError **error) { - gboolean auto_connect = FALSE; - if (self->use_direct_connection) { g_debug ("Direct connection case. Using user and hostname"); setup_account_for_direct_connection (self); @@ -1026,8 +951,8 @@ init_sip_account (CallsSipOrigin *self, if (!is_account_complete (self)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Must have completed account setup before calling" - "init_sip_account ()" + "Must have completed account setup before calling " + "init_sip_account (). " "Try again when account is setup"); self->state = CALLS_ACCOUNT_NO_CREDENTIALS; @@ -1059,9 +984,7 @@ init_sip_account (CallsSipOrigin *self, else { self->state = CALLS_ACCOUNT_OFFLINE; - g_object_get (self->credentials, "auto-connect", &auto_connect, NULL); - /* try to go online */ - if (auto_connect) + if (self->auto_connect) go_online (CALLS_ACCOUNT (self), TRUE); } @@ -1103,9 +1026,37 @@ calls_sip_origin_set_property (GObject *object, CallsSipOrigin *self = CALLS_SIP_ORIGIN (object); switch (property_id) { - case PROP_ACC_CREDENTIALS: - self->credentials = g_value_get_object (value); - update_credentials (self); + case PROP_ACC_HOST: + g_free (self->host); + self->host = g_value_dup_string (value); + break; + + case PROP_ACC_DISPLAY_NAME: + g_free (self->display_name); + self->display_name = g_value_dup_string (value); + break; + + 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_PORT: + self->port = g_value_get_int (value); + break; + + case PROP_ACC_PROTOCOL: + g_free (self->transport_protocol); + self->transport_protocol = g_value_dup_string (value); + break; + + case PROP_ACC_AUTO_CONNECT: + self->auto_connect = g_value_get_boolean (value); break; case PROP_ACC_DIRECT: @@ -1116,11 +1067,7 @@ calls_sip_origin_set_property (GObject *object, self->ctx = g_value_get_pointer (value); break; - case PROP_ACC_STATE: - g_warning ("Setting the account state does not yet have any effect"); - break; - - case PROP_SIP_LOCAL_PORT: + case PROP_ACC_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" "Continue using old 'local-port' value: %d (using 0 let's the OS decide)", @@ -1148,8 +1095,42 @@ calls_sip_origin_get_property (GObject *object, switch (property_id) { case PROP_NAME: - g_object_get (self->credentials, "name", &name, NULL); - g_value_set_string (value, name); + g_value_set_string (value, self->name); + break; + case PROP_ACC_HOST: + g_value_set_string (value, self->host); + break; + + case PROP_ACC_DISPLAY_NAME: + g_value_set_string (value, self->display_name); + break; + + case PROP_ACC_USER: + g_value_set_string (value, self->user); + break; + + case PROP_ACC_PASSWORD: + g_value_set_string (value, self->password); + 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_AUTO_CONNECT: + g_value_set_boolean (value, self->auto_connect); + break; + + case PROP_ACC_DIRECT: + g_value_set_boolean (value, self->direct_mode); + break; + + case PROP_ACC_LOCAL_PORT: + g_value_set_int (value, self->local_port); break; case PROP_CALLS: @@ -1160,10 +1141,6 @@ calls_sip_origin_get_property (GObject *object, g_value_set_enum (value, self->state); break; - case PROP_SIP_LOCAL_PORT: - g_value_set_int (value, self->local_port); - break; - case PROP_COUNTRY_CODE: g_value_set_string (value, NULL); break; @@ -1197,9 +1174,6 @@ 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); } @@ -1240,7 +1214,6 @@ calls_sip_origin_finalize (GObject *object) { CallsSipOrigin *self = CALLS_SIP_ORIGIN (object); - g_object_unref (self->credentials); g_hash_table_destroy (self->call_handles); G_OBJECT_CLASS (calls_sip_origin_parent_class)->finalize (object); @@ -1258,31 +1231,85 @@ 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_HOST] = + g_param_spec_string ("host", + "Host", + "The host to connect to", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_HOST, props[PROP_ACC_HOST]); + + props[PROP_ACC_USER] = + g_param_spec_string ("user", + "User", + "The username", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_USER, props[PROP_ACC_USER]); + + props[PROP_ACC_PASSWORD] = + g_param_spec_string ("password", + "Password", + "The password", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_PASSWORD, props[PROP_ACC_PASSWORD]); + + props[PROP_ACC_DISPLAY_NAME] = + g_param_spec_string ("display-name", + "Display name", + "The display name", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_DISPLAY_NAME, props[PROP_ACC_DISPLAY_NAME]); + + props[PROP_ACC_PORT] = + g_param_spec_int ("port", + "Port", + "The port to connect to", + 0, 65535, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_PORT, props[PROP_ACC_PORT]); + + props[PROP_ACC_PROTOCOL] = + g_param_spec_string ("transport-protocol", + "Transport protocol", + "The transport protocol to use for the connection", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_PROTOCOL, props[PROP_ACC_PROTOCOL]); + + props[PROP_ACC_AUTO_CONNECT] = + g_param_spec_boolean ("auto-connect", + "Auto connect", + "Whether to connect automatically", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_ACC_AUTO_CONNECT, props[PROP_ACC_AUTO_CONNECT]); + + props[PROP_ACC_DIRECT] = - g_param_spec_boolean ("direct-connection", - "Direct connection", + g_param_spec_boolean ("direct-mode", + "Direct mode", "Whether to use a direct connection (no SIP server)", FALSE, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_ACC_DIRECT, props[PROP_ACC_DIRECT]); - props[PROP_SIP_CONTEXT] = - g_param_spec_pointer ("sip-context", - "SIP context", - "The SIP context (sofia) used for our sip handles", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property (object_class, PROP_SIP_CONTEXT, props[PROP_SIP_CONTEXT]); - - props[PROP_SIP_LOCAL_PORT] = + props[PROP_ACC_LOCAL_PORT] = g_param_spec_int ("local-port", "Local port", "The local port to which the SIP stack binds to", 0, 65535, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property (object_class, PROP_SIP_LOCAL_PORT, props[PROP_SIP_LOCAL_PORT]); + g_object_class_install_property (object_class, PROP_ACC_LOCAL_PORT, props[PROP_ACC_LOCAL_PORT]); - g_object_class_override_property (object_class, PROP_ACC_CREDENTIALS, "account-credentials"); - props[PROP_ACC_CREDENTIALS] = g_object_class_find_property (object_class, "account-credentials"); + props[PROP_SIP_CONTEXT] = + g_param_spec_pointer ("sip-context", + "SIP context", + "The SIP context (sofia) used for our sip handles", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SIP_CONTEXT, props[PROP_SIP_CONTEXT]); g_object_class_override_property (object_class, PROP_ACC_STATE, "account-state"); props[PROP_ACC_STATE] = g_object_class_find_property (object_class, "account-state"); @@ -1325,19 +1352,48 @@ calls_sip_origin_init (CallsSipOrigin *self) self->call_handles = g_hash_table_new (NULL, NULL); } -CallsSipOrigin * -calls_sip_origin_new (CallsSipContext *sip_context, - CallsCredentials *credentials, - gint local_port, - gboolean direct_connection) +void +calls_sip_origin_set_credentials (CallsSipOrigin *self, + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gboolean auto_connect) { - g_return_val_if_fail (sip_context, NULL); - g_return_val_if_fail (credentials, NULL); + g_return_if_fail (CALLS_IS_SIP_ORIGIN (self)); - return g_object_new (CALLS_TYPE_SIP_ORIGIN, - "sip-context", sip_context, - "account-credentials", g_object_ref (credentials), - "local-port", local_port, - "direct-connection", direct_connection, - NULL); + if (self->direct_mode) { + g_warning ("Not allowed to update credentials when using direct mode"); + return; + } + + g_return_if_fail (host); + g_return_if_fail (user); + g_return_if_fail (password); + + if (transport_protocol) + g_return_if_fail (protocol_is_valid (transport_protocol)); + + g_free (self->host); + self->host = g_strdup (host); + + g_free (self->user); + self->user = g_strdup (user); + + g_free (self->password); + self->password = g_strdup (self->password); + + g_clear_pointer (&self->display_name, g_free); + if (display_name) + self->display_name = g_strdup (display_name); + + g_free (self->transport_protocol); + if (transport_protocol) + self->transport_protocol = g_strdup (transport_protocol); + else + self->transport_protocol = g_strdup ("UDP"); + + /* Propagate changes to nua stack */ + update_nua (self); } diff --git a/plugins/sip/calls-sip-origin.h b/plugins/sip/calls-sip-origin.h index 0164f92..e224047 100644 --- a/plugins/sip/calls-sip-origin.h +++ b/plugins/sip/calls-sip-origin.h @@ -24,21 +24,20 @@ #pragma once -#include "calls-credentials.h" -#include "calls-sip-util.h" - #include G_BEGIN_DECLS #define CALLS_TYPE_SIP_ORIGIN (calls_sip_origin_get_type ()) -G_DECLARE_FINAL_TYPE (CallsSipOrigin, calls_sip_origin, CALLS, SIP_ORIGIN, GObject); +G_DECLARE_FINAL_TYPE (CallsSipOrigin, calls_sip_origin, CALLS, SIP_ORIGIN, GObject) + +void calls_sip_origin_set_credentials (CallsSipOrigin *self, + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gboolean auto_connect); -CallsSipOrigin *calls_sip_origin_new (CallsSipContext *sip_context, - CallsCredentials *credentials, - gint local_port, - gboolean direct_connection); -void calls_sip_origin_go_online (CallsSipOrigin *self, - gboolean online); G_END_DECLS diff --git a/plugins/sip/calls-sip-provider.c b/plugins/sip/calls-sip-provider.c index 841f3d0..1bb5388 100644 --- a/plugins/sip/calls-sip-provider.c +++ b/plugins/sip/calls-sip-provider.c @@ -27,7 +27,6 @@ #define SIP_ACCOUNT_FILE "sip-account.cfg" #include "calls-account-provider.h" -#include "calls-credentials.h" #include "calls-message-source.h" #include "calls-provider.h" #include "calls-sip-enums.h" @@ -68,7 +67,6 @@ struct _CallsSipProvider CallsProvider parent_instance; GListStore *origins; - GHashTable *credentials; /* key = credentials, value = origin */ /* SIP */ CallsSipContext *ctx; SipEngineState sip_state; @@ -105,24 +103,20 @@ calls_sip_provider_load_accounts (CallsSipProvider *self) groups = g_key_file_get_groups (key_file, NULL); for (gsize i = 0; groups[i] != NULL; i++) { - g_autoptr (CallsCredentials) credentials = calls_credentials_new (); gint local_port = 0; 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; - } else { - calls_credentials_update_from_keyfile (credentials, key_file, groups[i]); } g_debug ("Adding origin for SIP account %s", groups[i]); - calls_sip_provider_add_origin (self, g_steal_pointer (&credentials), local_port, direct_connection); + /* TODO rewrite */ } g_strfreev (groups); @@ -302,9 +296,6 @@ calls_sip_provider_dispose (GObject *object) g_list_store_remove_all (self->origins); g_clear_object (&self->origins); - g_hash_table_remove_all (self->credentials); - g_clear_pointer (&self->credentials, g_hash_table_unref); - g_clear_pointer (&self->filename, g_free); calls_sip_provider_deinit_sip (self); @@ -351,79 +342,9 @@ calls_sip_provider_message_source_interface_init (CallsMessageSourceInterface *i { } -static gboolean -add_account (CallsAccountProvider *acc_provider, - CallsCredentials *credentials) -{ - CallsSipProvider *self; - - g_assert (CALLS_IS_ACCOUNT_PROVIDER (acc_provider)); - g_assert (CALLS_IS_SIP_PROVIDER (acc_provider)); - g_assert (CALLS_IS_CREDENTIALS (credentials)); - - self = CALLS_SIP_PROVIDER (acc_provider); - - g_object_ref (acc_provider); - - return !!calls_sip_provider_add_origin (self, credentials, 0, FALSE); -} - -static gboolean -remove_account (CallsAccountProvider *acc_provider, - CallsCredentials *credentials) -{ - CallsSipProvider *self; - CallsSipOrigin *origin; - guint position; - - g_assert (CALLS_IS_ACCOUNT_PROVIDER (acc_provider)); - g_assert (CALLS_IS_SIP_PROVIDER (acc_provider)); - g_assert (CALLS_IS_CREDENTIALS (credentials)); - - self = CALLS_SIP_PROVIDER (acc_provider); - - origin = g_hash_table_lookup (self->credentials, credentials); - - if (origin == NULL) - return FALSE; - - if (!g_list_store_find (self->origins, origin, &position)) - return FALSE; - - g_hash_table_remove (self->credentials, credentials); - g_list_store_remove (self->origins, position); - - g_object_unref (acc_provider); - - return TRUE; -} - -static CallsAccount * -get_account (CallsAccountProvider *acc_provider, - CallsCredentials *credentials) -{ - CallsSipProvider *self; - CallsSipOrigin *origin; - - g_assert (CALLS_IS_ACCOUNT_PROVIDER (acc_provider)); - g_assert (CALLS_IS_SIP_PROVIDER (acc_provider)); - g_assert (CALLS_IS_CREDENTIALS (credentials)); - - self = CALLS_SIP_PROVIDER (acc_provider); - - origin = g_hash_table_lookup (self->credentials, credentials); - if (origin) - return CALLS_ACCOUNT (origin); - else - return NULL; -} - static void calls_sip_provider_account_provider_interface_init (CallsAccountProviderInterface *iface) { - iface->add_account = add_account; - iface->remove_account = remove_account; - iface->get_account = get_account; } static void @@ -431,9 +352,6 @@ calls_sip_provider_init (CallsSipProvider *self) { const char *filename_env = g_getenv ("CALLS_SIP_ACCOUNT_FILE"); - self->credentials = - g_hash_table_new_full (NULL, NULL, g_object_unref, g_object_unref); - self->origins = g_list_store_new (CALLS_TYPE_ORIGIN); if (filename_env && filename_env[0] != '\0') @@ -448,43 +366,97 @@ calls_sip_provider_init (CallsSipProvider *self) /** * calls_sip_provider_add_origin: * @self: A #CallsSipProvider - * @credentials: A #CallsCredentials - * @local_port: The local port to bind to or 0 - * @direct_connection: %TRUE to use a direct connection to peers, %FALSE otherwise + * @host: The host to connect to + * @user: The username to use + * @password: The password to use + * @display_name: The display name + * @transport_protocol: The transport protocol to use, can be one of "UDP", "TCP" or "TLS" * - * 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). + * Adds a new origin (SIP account) * * Return: (transfer none): A #CallsSipOrigin */ CallsSipOrigin * calls_sip_provider_add_origin (CallsSipProvider *self, - CallsCredentials *credentials, - gint local_port, - gboolean direct_connection) + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gint port) +{ + return calls_sip_provider_add_origin_full (self, + host, + user, + password, + display_name, + transport_protocol, + port, + TRUE, + FALSE, + 0); +} + +/** + * calls_sip_provider_add_origin_full: + * @self: A #CallsSipProvider + * @host: The host to connect to + * @user: The username to use + * @password: The password to use + * @display_name: The display name + * @transport_protocol: The transport protocol to use, can be one of "UDP", "TCP" or "TLS" + * @auto_connect: Whether to automatically try going online + * @direct_mode: Whether to use direct connection mode. Useful when you don't want to + * connect to a SIP server. Mostly useful for testing and debugging. + * + * Adds a new origin (SIP account). If @direct_mode is %TRUE then @host, @user and + * @password do not have to be set. + * + * Return: (transfer none): A #CallsSipOrigin + */ +CallsSipOrigin * +calls_sip_provider_add_origin_full (CallsSipProvider *self, + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gint port, + gboolean auto_connect, + gboolean direct_mode, + gint local_port) { g_autoptr (CallsSipOrigin) origin = NULL; + g_autofree char *protocol = NULL; g_return_val_if_fail (CALLS_IS_SIP_PROVIDER (self), NULL); - g_return_val_if_fail (CALLS_IS_CREDENTIALS (credentials), NULL); - if (g_hash_table_contains (self->credentials, credentials)) { - g_autofree char *name = NULL; - g_object_get (credentials, "name", &name, NULL); - - /* This could be a INFO level log once we have improved logging */ - g_debug ("Cannot add credentials with name '%s' multiple times", name); - return NULL; + /* direct-mode is mostly useful for testing without a SIP server */ + if (!direct_mode) { + g_return_val_if_fail (host, NULL); + g_return_val_if_fail (user, NULL); + g_return_val_if_fail (password, NULL); } - origin = calls_sip_origin_new (self->ctx, - credentials, - local_port, - direct_connection); + if (transport_protocol) { + g_return_val_if_fail (protocol_is_valid (transport_protocol), NULL); + + protocol = g_ascii_strup (transport_protocol, -1); + } + + origin = g_object_new (CALLS_TYPE_SIP_ORIGIN, + "sip-context", self->ctx, + "host", host, + "user", user, + "password", password, + "display-name", display_name, + "transport-protocol", protocol ?: "UDP", + "port", port, + "auto-connect", auto_connect, + "direct-mode", direct_mode, + "local-port", local_port, + NULL); - g_hash_table_insert (self->credentials, - g_object_ref (credentials), g_object_ref (origin)); g_list_store_append (self->origins, origin); return origin; diff --git a/plugins/sip/calls-sip-provider.h b/plugins/sip/calls-sip-provider.h index 1cfc837..a1ca0a5 100644 --- a/plugins/sip/calls-sip-provider.h +++ b/plugins/sip/calls-sip-provider.h @@ -24,7 +24,6 @@ #pragma once -#include "calls-credentials.h" #include "calls-provider.h" #include "calls-sip-origin.h" @@ -39,9 +38,22 @@ G_DECLARE_FINAL_TYPE (CallsSipProvider, calls_sip_provider, CALLS, SIP_PROVIDER, CallsSipProvider *calls_sip_provider_new (void); CallsSipOrigin *calls_sip_provider_add_origin (CallsSipProvider *self, - CallsCredentials *credentials, - gint local_port, - gboolean direct_connection); + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gint port); +CallsSipOrigin *calls_sip_provider_add_origin_full (CallsSipProvider *self, + const char *host, + const char *user, + const char *password, + const char *display_name, + const char *transport_protocol, + gint port, + gboolean auto_connect, + gboolean direct_mode, + gint local_port); void peas_register_types (PeasObjectModule *module); G_END_DECLS diff --git a/src/calls-account-provider.c b/src/calls-account-provider.c index 606d83c..92239c3 100644 --- a/src/calls-account-provider.c +++ b/src/calls-account-provider.c @@ -44,75 +44,3 @@ calls_account_provider_default_init (CallsAccountProviderInterface *iface) { } -/** - * calls_account_provider_add_account: - * @self: A #CallsAccountProvider - * @credentials: A #CallsCredentials - * - * Add an account. - * - * Returns: %TRUE if successfully added, %FALSE otherwise - */ -gboolean -calls_account_provider_add_account (CallsAccountProvider *self, - CallsCredentials *credentials) -{ - CallsAccountProviderInterface *iface; - - g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (self), FALSE); - - iface = CALLS_ACCOUNT_PROVIDER_GET_IFACE (self); - g_return_val_if_fail (iface->add_account != NULL, FALSE); - - g_debug ("Trying to add account for %s", calls_credentials_get_name (credentials)); - - return iface->add_account (self, credentials); -} - -/** - * calls_account_provider_remove_account: - * @self: A #CallsAccountProvider - * @credentials: A #CallsCredentials - * - * Removes an account. - * - * Returns: %TRUE if successfully removed, %FALSE otherwise - */ -gboolean -calls_account_provider_remove_account (CallsAccountProvider *self, - CallsCredentials *credentials) -{ - CallsAccountProviderInterface *iface; - - g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (self), FALSE); - - iface = CALLS_ACCOUNT_PROVIDER_GET_IFACE (self); - g_return_val_if_fail (iface->remove_account != NULL, FALSE); - - g_debug ("Trying to remove account from %s", calls_credentials_get_name (credentials)); - - return iface->remove_account (self, credentials); -} - -/** - * calls_account_provider_get_account: - * @self: A #CallsAccountProvider - * @credentials: A #CallsCredentials - * - * Get the account which is using #CallsCredentials - */ -CallsAccount * -calls_account_provider_get_account (CallsAccountProvider *self, - CallsCredentials *credentials) -{ - CallsAccountProviderInterface *iface; - - g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (self), NULL); - - iface = CALLS_ACCOUNT_PROVIDER_GET_IFACE (self); - g_return_val_if_fail (iface->get_account != NULL, NULL); - - g_debug ("Trying to get account from %s", calls_credentials_get_name (credentials)); - - return iface->get_account (self, credentials); -} diff --git a/src/calls-account-provider.h b/src/calls-account-provider.h index 7bd8bbf..82907e5 100644 --- a/src/calls-account-provider.h +++ b/src/calls-account-provider.h @@ -24,8 +24,6 @@ #pragma once -#include "calls-account.h" -#include "calls-credentials.h" #include "calls-provider.h" #include @@ -40,19 +38,7 @@ struct _CallsAccountProviderInterface { GTypeInterface parent_iface; - gboolean (*add_account) (CallsAccountProvider *self, - CallsCredentials *credentials); - gboolean (*remove_account) (CallsAccountProvider *self, - CallsCredentials *credentials); - CallsAccount *(*get_account) (CallsAccountProvider *self, - CallsCredentials *credentials); }; -gboolean calls_account_provider_add_account (CallsAccountProvider *self, - CallsCredentials *credentials); -gboolean calls_account_provider_remove_account (CallsAccountProvider *self, - CallsCredentials *credentials); -CallsAccount *calls_account_provider_get_account (CallsAccountProvider *self, - CallsCredentials *credentials); G_END_DECLS diff --git a/src/calls-account.c b/src/calls-account.c index 216413c..b41aec8 100644 --- a/src/calls-account.c +++ b/src/calls-account.c @@ -22,7 +22,6 @@ * */ -#include "calls-credentials.h" #include "calls-account.h" #include "enum-types.h" @@ -31,37 +30,15 @@ * @short_description: An interface for online accounts * @Title: CallsAccount * - * #CallsAccount is meant to be implemented by a #CallsOrigin when - * the #CallsOrigin uses #CallsCredentials to connect to the internet. + * #CallsAccount is a type of #CallsOrigin for online accounts. */ -enum { - SIGNAL_ACCOUNT_STATE_CHANGED, - SIGNAL_LAST_SIGNAL -}; -static guint signals[SIGNAL_LAST_SIGNAL]; - G_DEFINE_INTERFACE (CallsAccount, calls_account, CALLS_TYPE_ORIGIN) static void calls_account_default_init (CallsAccountInterface *iface) { - signals[SIGNAL_ACCOUNT_STATE_CHANGED] = - g_signal_new ("account-state-changed", - G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, - 2, CALLS_TYPE_ACCOUNT_STATE, CALLS_TYPE_ACCOUNT_STATE); - - g_object_interface_install_property (iface, - g_param_spec_object ("account-credentials", - "Account credentials", - "The credentials to be used for authentication", - CALLS_TYPE_CREDENTIALS, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_interface_install_property (iface, g_param_spec_enum ("account-state", "Account state", diff --git a/src/calls-credentials.c b/src/calls-credentials.c deleted file mode 100644 index 504c6f7..0000000 --- a/src/calls-credentials.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2021 Purism SPC - * - * This file is part of Calls. - * - * Calls is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calls 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calls. If not, see . - * - * Author: Evangelos Ribeiro Tzaras - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#define G_LOG_DOMAIN "CallsCredentials" - -#include "calls-credentials.h" - -/** - * SECTION:Credentials - * @short_description: Credentials for online accounts - * @Title: CallsCredentials - * - * #CallsCredentials represents account credentials f.e. for SIP. - */ - -enum { - PROP_0, - PROP_NAME, - PROP_ACC_HOST, - PROP_ACC_DISPLAY_NAME, - PROP_ACC_USER, - PROP_ACC_PASSWORD, - PROP_ACC_PORT, - PROP_ACC_PROTOCOL, - PROP_ACC_AUTO_CONNECT, - PROP_LAST_PROP, -}; -static GParamSpec *props[PROP_LAST_PROP]; - -enum { - SIGNAL_ACCOUNT_UPDATED, - SIGNAL_LAST_SIGNAL, -}; -static guint signals[SIGNAL_LAST_SIGNAL]; - -struct _CallsCredentials -{ - GObject parent_instance; - - char *name; - - /* Account information */ - char *host; - char *display_name; - char *user; - char *password; - gint port; - char *transport_protocol; - - gboolean auto_connect; -}; - - -G_DEFINE_TYPE (CallsCredentials, calls_credentials, G_TYPE_OBJECT) - -static gboolean -check_required_keys (GKeyFile *key_file, - const gchar *group_name) -{ - gchar *keys[] = { - "User", - "Password", - "Host", - }; - - g_assert (group_name); - g_assert (g_key_file_has_group (key_file, group_name)); - - for (gsize i = 0; i < G_N_ELEMENTS (keys); i++) { - if (!g_key_file_has_key (key_file, group_name, keys[i], NULL)) - return FALSE; - } - - return TRUE; -} - - -static void -calls_credentials_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - CallsCredentials *self = CALLS_CREDENTIALS (object); - - switch (property_id) { - case PROP_NAME: - g_free (self->name); - self->name = 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_DISPLAY_NAME: - g_free (self->display_name); - self->display_name = g_value_dup_string (value); - break; - - 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_PORT: - self->port = g_value_get_int (value); - break; - - case PROP_ACC_PROTOCOL: - g_free (self->transport_protocol); - self->transport_protocol = g_value_dup_string (value); - break; - - case PROP_ACC_AUTO_CONNECT: - self->auto_connect = g_value_get_boolean (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -static void -calls_credentials_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - CallsCredentials *self = CALLS_CREDENTIALS (object); - - switch (property_id) { - case PROP_NAME: - g_value_set_string (value, self->name); - break; - - case PROP_ACC_HOST: - g_value_set_string (value, self->host); - break; - - case PROP_ACC_DISPLAY_NAME: - g_value_set_string (value, self->display_name); - break; - - case PROP_ACC_USER: - g_value_set_string (value, self->user); - break; - - case PROP_ACC_PASSWORD: - g_value_set_string (value, self->password); - 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_AUTO_CONNECT: - g_value_set_boolean (value, self->auto_connect); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -static void -calls_credentials_finalize (GObject *object) -{ - CallsCredentials *self = CALLS_CREDENTIALS (object); - - g_free (self->name); - g_free (self->host); - g_free (self->display_name); - g_free (self->user); - g_free (self->password); - g_free (self->transport_protocol); - - G_OBJECT_CLASS (calls_credentials_parent_class)->finalize (object); -} - - -static void -calls_credentials_class_init (CallsCredentialsClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = calls_credentials_set_property; - object_class->get_property = calls_credentials_get_property; - object_class->finalize = calls_credentials_finalize; - - props[PROP_NAME] = - g_param_spec_string ("name", - "Name", - "The name for this set of credentials", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_HOST] = - g_param_spec_string ("host", - "Host", - "The host to connect to", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_DISPLAY_NAME] = - g_param_spec_string ("display-name", - "Display name", - "The display name", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_USER] = - g_param_spec_string ("user", - "User", - "The username", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_PASSWORD] = - g_param_spec_string ("password", - "Password", - "The password", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_PORT] = - g_param_spec_int ("port", - "Port", - "The port to connect to", - 0, 65535, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_PROTOCOL] = - g_param_spec_string ("protocol", - "Protocol", - "The transport protocol to use for the connection", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - props[PROP_ACC_AUTO_CONNECT] = - g_param_spec_boolean ("auto-connect", - "Auto connect", - "Whether to connect automatically", - TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, PROP_LAST_PROP, props); - - signals[SIGNAL_ACCOUNT_UPDATED] = - g_signal_new ("account-updated", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, - 0); -} - - -static void -calls_credentials_init (CallsCredentials *self) -{ -} - - -CallsCredentials * -calls_credentials_new (void) -{ - return g_object_new (CALLS_TYPE_CREDENTIALS, NULL); -} - -/** - * calls_credentials_update_from_keyfile: - * @self: A #CallsCredentials - * @key_file: A #GKeyFile - * @name: The name of the credentials which doubles as the option group - * - * Updates the credentials from a given keyfile. - * - * Returns: %TRUE if credentials were updated, %FALSE otherwise - */ -gboolean -calls_credentials_update_from_keyfile (CallsCredentials *self, - GKeyFile *key_file, - const char *name) -{ - char *user = NULL; - char *password = NULL; - char *host = NULL; - char *protocol = NULL; - char *display_name = NULL; - gint port = 0; - gboolean auto_connect = TRUE; - - g_return_val_if_fail (CALLS_IS_CREDENTIALS (self), FALSE); - g_return_val_if_fail (name, FALSE); - g_return_val_if_fail (g_key_file_has_group (key_file, name), FALSE); - - if (!check_required_keys (key_file, name)) { - g_warning ("Not all required keys found in section %s", name); - return FALSE; - } - - user = g_key_file_get_string (key_file, name, "User", NULL); - password = g_key_file_get_string (key_file, name, "Password", NULL); - host = g_key_file_get_string (key_file, name, "Host", NULL); - protocol = g_key_file_get_string (key_file, name, "Protocol", NULL); - port = g_key_file_get_integer (key_file, name, "Port", NULL); - display_name = g_key_file_get_string (key_file, name, "DisplayName", NULL); - - if (g_key_file_has_key (key_file, name, "AutoConnect", NULL)) - auto_connect = g_key_file_get_boolean (key_file, name, "AutoConnect", NULL); - - if (protocol == NULL) - protocol = g_strdup ("UDP"); - - if (g_strcmp0 (host, "") == 0 || - g_strcmp0 (user, "") == 0 || - g_strcmp0 (password, "") == 0) { - g_warning ("Host, user and password must not be empty"); - - g_free (user); - g_free (password); - g_free (host); - g_free (protocol); - g_free (display_name); - - return FALSE; - } - - g_free (self->name); - self->name = g_strdup (name); - - g_free (self->host); - self->host = host; - - g_free (self->user); - self->user = user; - - g_free (self->password); - self->password = password; - - g_free (self->transport_protocol); - self->transport_protocol = protocol; - - g_free (self->display_name); - self->display_name = display_name; - - self->port = port; - self->auto_connect = auto_connect; - - g_debug ("Updated credentials with name %s", name); - - g_signal_emit (self, signals[SIGNAL_ACCOUNT_UPDATED], 0); - - return TRUE; -} - -const char * -calls_credentials_get_name (CallsCredentials *self) -{ - g_return_val_if_fail (CALLS_IS_CREDENTIALS (self), NULL); - - return self->name; -} - -void -calls_credentials_set_name (CallsCredentials *self, - const char *name) -{ - g_return_if_fail (CALLS_IS_CREDENTIALS (self)); - - if (!name) - return; - - if (g_strcmp0 (name, self->name) == 0) - return; - - g_free (self->name); - self->name = g_strdup (name); - - g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NAME]); -} diff --git a/src/calls-credentials.h b/src/calls-credentials.h deleted file mode 100644 index d110fa6..0000000 --- a/src/calls-credentials.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2021 Purism SPC - * - * This file is part of Calls. - * - * Calls is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calls 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calls. If not, see . - * - * Author: Evangelos Ribeiro Tzaras - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -#define CALLS_TYPE_CREDENTIALS (calls_credentials_get_type ()) - -G_DECLARE_FINAL_TYPE (CallsCredentials, calls_credentials, CALLS, CREDENTIALS, GObject); - - -CallsCredentials *calls_credentials_new (void); -gboolean calls_credentials_update_from_keyfile (CallsCredentials *self, - GKeyFile *key_file, - const char *name); -void calls_credentials_set_name (CallsCredentials *self, - const char *name); -const char *calls_credentials_get_name (CallsCredentials *self); - -G_END_DECLS - diff --git a/src/calls-manager.c b/src/calls-manager.c index e3002a0..9e50016 100644 --- a/src/calls-manager.c +++ b/src/calls-manager.c @@ -17,6 +17,7 @@ * along with Calls. If not, see . * * Author: Julian Sparber + * Evangelos Ribeiro Tzaras * * SPDX-License-Identifier: GPL-3.0-or-later * @@ -791,58 +792,6 @@ calls_manager_is_modem_provider (CallsManager *self, return calls_provider_is_modem (provider); } -/** - * calls_manager_provder_add_accounts: - * @self: A #CallsManager - * @name: The name of the provider to add the account to - * @credentials: A #CallsCredentials storing the credentials of the account - * - * Returns: %TRUE if account successfully added, %FALSE otherwise - */ -gboolean -calls_manager_provider_add_account (CallsManager *self, - const char *name, - CallsCredentials *credentials) -{ - CallsProvider *provider = NULL; - - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - g_return_val_if_fail (name, FALSE); - g_return_val_if_fail (CALLS_IS_CREDENTIALS (credentials), FALSE); - - provider = g_hash_table_lookup (self->providers, name); - g_return_val_if_fail (CALLS_IS_PROVIDER (provider), FALSE); - g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (provider), FALSE); - - return calls_account_provider_add_account (CALLS_ACCOUNT_PROVIDER (provider), - credentials); -} -/** - * calls_manager_provder_remove_accounts: - * @self: A #CallsManager - * @name: The name of the provider to add the account to - * @credentials: A #CallsCredentials storing the credentials of the account - * - * Returns: %TRUE if account successfully removed, %FALSE otherwise - */ -gboolean -calls_manager_provider_remove_account (CallsManager *self, - const char *name, - CallsCredentials *credentials) -{ - CallsProvider *provider = NULL; - - g_return_val_if_fail (CALLS_IS_MANAGER (self), FALSE); - g_return_val_if_fail (name, FALSE); - g_return_val_if_fail (CALLS_IS_CREDENTIALS (credentials), FALSE); - - provider = g_hash_table_lookup (self->providers, name); - g_return_val_if_fail (CALLS_IS_PROVIDER (provider), FALSE); - g_return_val_if_fail (CALLS_IS_ACCOUNT_PROVIDER (provider), FALSE); - - return calls_account_provider_remove_account (CALLS_ACCOUNT_PROVIDER (provider), - credentials); -} CallsManagerState calls_manager_get_state (CallsManager *self) diff --git a/src/calls-manager.h b/src/calls-manager.h index c2a81e1..d7f6261 100644 --- a/src/calls-manager.h +++ b/src/calls-manager.h @@ -1,6 +1,6 @@ /* calls-manager.c * - * Copyright (C) 2020 Purism SPC + * Copyright (C) 2020, 2021 Purism SPC * * This file is part of Calls. * @@ -18,6 +18,7 @@ * along with Calls. If not, see . * * Authors: Julian Sparber + * Evangelos Ribeiro Tzaras * * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -26,7 +27,6 @@ #include "calls-contacts-provider.h" #include "calls-origin.h" -#include "calls-credentials.h" #include @@ -49,34 +49,28 @@ typedef enum CallsManager *calls_manager_new (void); CallsManager *calls_manager_get_default (void); -CallsContactsProvider *calls_manager_get_contacts_provider (CallsManager *self); -void calls_manager_add_provider (CallsManager *self, - const char *name); -void calls_manager_remove_provider (CallsManager *self, - const char *name); -gboolean calls_manager_has_provider (CallsManager *self, - const char *name); -gboolean calls_manager_is_modem_provider (CallsManager *self, - const char *name); -gboolean calls_manager_provider_add_account (CallsManager *self, - const char *provider, - CallsCredentials *credentials); -gboolean calls_manager_provider_remove_account (CallsManager *self, - const char *provider, - CallsCredentials *credentials); -CallsManagerState calls_manager_get_state (CallsManager *self); -GListModel *calls_manager_get_origins (CallsManager *self); -GList *calls_manager_get_calls (CallsManager *self); -void calls_manager_dial (CallsManager *self, - CallsOrigin *origin, - const char *target); -GListModel *calls_manager_get_suitable_origins (CallsManager *self, - const char *target); -const gchar *calls_manager_get_contact_name (CallsCall *call); -gboolean calls_manager_has_active_call (CallsManager *self); -void calls_manager_hang_up_all_calls (CallsManager *self); -gboolean calls_manager_has_any_provider (CallsManager *self); -const char **calls_manager_get_provider_names (CallsManager *self, - guint *length); +CallsContactsProvider *calls_manager_get_contacts_provider (CallsManager *self); +void calls_manager_add_provider (CallsManager *self, + const char *name); +void calls_manager_remove_provider (CallsManager *self, + const char *name); +gboolean calls_manager_has_provider (CallsManager *self, + const char *name); +gboolean calls_manager_is_modem_provider (CallsManager *self, + const char *name); +CallsManagerState calls_manager_get_state (CallsManager *self); +GListModel *calls_manager_get_origins (CallsManager *self); +GList *calls_manager_get_calls (CallsManager *self); +void calls_manager_dial (CallsManager *self, + CallsOrigin *origin, + const char *target); +GListModel *calls_manager_get_suitable_origins (CallsManager *self, + const char *target); +const gchar *calls_manager_get_contact_name (CallsCall *call); +gboolean calls_manager_has_active_call (CallsManager *self); +void calls_manager_hang_up_all_calls (CallsManager *self); +gboolean calls_manager_has_any_provider (CallsManager *self); +const char **calls_manager_get_provider_names (CallsManager *self, + guint *length); G_END_DECLS diff --git a/src/meson.build b/src/meson.build index 14adde6..7a15fc9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -106,7 +106,6 @@ calls_sources = files(['calls-message-source.c', 'calls-message-source.h', 'calls-notifier.c', 'calls-notifier.h', 'calls-contacts-box.c', 'calls-contacts-box.h', 'calls-contacts-row.c', 'calls-contacts-row.h', - 'calls-credentials.c', 'calls-credentials.h', 'calls-account.c', 'calls-account.h', 'calls-account-provider.c', 'calls-account-provider.h', 'calls-settings.c', 'calls-settings.h', diff --git a/tests/meson.build b/tests/meson.build index c0df8ac..091d2a3 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -101,20 +101,6 @@ t = executable('sip', test_sources, ) test('sip', t, env: test_env) -test_sources = [ 'test-account.c' ] -t = executable('account', test_sources, - c_args : test_cflags, - link_args: test_link_args, - pie: true, - link_with : [calls_vala, calls_sip, libcalls], - dependencies: [calls_deps, sip_deps], - include_directories : [ - calls_includes, - sip_include, - ] - ) -test('account', t, env: test_env) - test_sources = [ 'test-util.c' ] t = executable('util', test_sources, c_args : test_cflags, diff --git a/tests/test-account.c b/tests/test-account.c deleted file mode 100644 index 4ece23a..0000000 --- a/tests/test-account.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2021 Purism SPC - * - * SPDX-License-Identifier: GPL-3.0+ - * - * Author: Evangelos Ribeiro Tzaras - */ - -#include "calls-account.h" -#include "calls-account-provider.h" -#include "calls-provider.h" -#include "calls-sip-provider.h" - -#include - -#include -#include - -static void -test_account_basic (void) -{ - CallsCredentials *alice = calls_credentials_new (); - CallsCredentials *bob = calls_credentials_new (); - CallsSipProvider *sip = - CALLS_SIP_PROVIDER (calls_provider_load_plugin ("sip")); - CallsAccountProvider *acc_provider; - GListModel *origins; - CallsOrigin *origin_alice; - CallsOrigin *origin_bob; - - g_assert_true (CALLS_IS_ACCOUNT_PROVIDER (sip)); - acc_provider = CALLS_ACCOUNT_PROVIDER (sip); - - g_object_set (alice, - "name", "Alice", - "user", "alice", - "host", "example.org", - "password", "password123", - NULL); - g_object_set (bob, - "name", "Bob", - "user", "bob", - "host", "example.org", - "password", "password123", - NULL); - - /* Add credentials */ - g_assert_true (calls_account_provider_add_account (acc_provider, alice)); - g_assert_true (calls_account_provider_add_account (acc_provider, bob)); - - /* Are the returned accounts of the correct types? */ - g_assert_true (CALLS_IS_ACCOUNT (calls_account_provider_get_account (acc_provider, alice))); - g_assert_true (CALLS_IS_ORIGIN (calls_account_provider_get_account (acc_provider, alice))); - - g_assert_true (CALLS_IS_ACCOUNT (calls_account_provider_get_account (acc_provider, bob))); - g_assert_true (CALLS_IS_ORIGIN (calls_account_provider_get_account (acc_provider, bob))); - - /* Are we getting the correct corresponding origins back? */ - origins = calls_provider_get_origins (CALLS_PROVIDER (sip)); - - g_assert_cmpint (g_list_model_get_n_items (origins), ==, 2); - - origin_alice = g_list_model_get_item (origins, 0); - origin_bob = g_list_model_get_item (origins, 1); - - g_assert_true (origin_alice == - CALLS_ORIGIN (calls_account_provider_get_account (acc_provider, alice))); - g_assert_true (origin_bob == - CALLS_ORIGIN (calls_account_provider_get_account (acc_provider, bob))); - - g_object_unref (origin_alice); - g_object_unref (origin_bob); - - /* Try adding credentials a second time */ - g_assert_false (calls_account_provider_add_account (acc_provider, alice)); - - /* Remove credentials */ - g_assert_true (calls_account_provider_remove_account (acc_provider, alice)); - g_assert_false (calls_account_provider_remove_account (acc_provider, alice)); - g_assert_true (calls_account_provider_remove_account (acc_provider, bob)); - g_assert_false (calls_account_provider_remove_account (acc_provider, bob)); - - g_assert_cmpint (g_list_model_get_n_items (origins), ==, 0); -} - -gint -main (gint argc, - gchar *argv[]) -{ - gtk_test_init (&argc, &argv, NULL); - -#ifdef PLUGIN_BUILDDIR - peas_engine_add_search_path (peas_engine_get_default (), PLUGIN_BUILDDIR, NULL); -#endif - /* this is a workaround for an issue with sofia: https://github.com/freeswitch/sofia-sip/issues/58 */ - su_random64 (); - - g_test_add_func ("/Calls/Account/basic", test_account_basic); - - return g_test_run(); -} diff --git a/tests/test-manager.c b/tests/test-manager.c index 4185db1..337205e 100644 --- a/tests/test-manager.c +++ b/tests/test-manager.c @@ -5,7 +5,6 @@ */ #include "calls-manager.h" -#include "calls-credentials.h" #include #include @@ -130,8 +129,6 @@ test_calls_manager_mm_provider (void) static void test_calls_manager_multiple_providers_mm_sip (void) { - g_autoptr (CallsCredentials) alice = NULL; - g_autoptr (CallsCredentials) bob = NULL; g_autoptr (CallsOrigin) origin_alice = NULL; g_autoptr (CallsOrigin) origin_bob = NULL; g_autoptr (CallsManager) manager = calls_manager_new (); @@ -171,39 +168,6 @@ test_calls_manager_multiple_providers_mm_sip (void) g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_ORIGIN); - /* Add Alice SIP account */ - alice = calls_credentials_new (); - g_object_set (alice, - "name", "Alice", - "user", "alice", - "host", "example.org", - "password", "password123", - NULL); - g_assert_true (calls_manager_provider_add_account (manager, "sip", alice)); - g_assert_false (calls_manager_provider_add_account (manager, "sip", alice)); - - g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); - g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 1); - - /** - * Add a second SIP origin to mix things up. - * TODO We can expand on this later to test the call routing - * starting with a simple "default" mechanism for now - * needs https://source.puri.sm/Librem5/calls/-/issues/259 first though - */ - bob = calls_credentials_new (); - g_object_set (bob, - "name", "Bob", - "user", "bob", - "host", "example.org", - "password", "password123", - NULL); - - g_assert_true (calls_manager_provider_add_account (manager, "sip", bob)); - - g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); - g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 2); - /** * If we now load the MM plugin, the manager state should be *_STATE_NO_VOICE_MODEM * (unless run on a phone I guess?) @@ -216,19 +180,6 @@ test_calls_manager_multiple_providers_mm_sip (void) g_assert_true (calls_manager_has_provider (manager, "mm")); g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_VOICE_MODEM); - /* Remove alice */ - g_assert_true (calls_manager_provider_remove_account (manager, "sip", alice)); - g_assert_false (calls_manager_provider_remove_account (manager, "sip", alice)); - g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_NO_VOICE_MODEM); - g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 1); - - /* Unload MM plugin, since we still have Bob we should be ready (and bob should be the default sip origin) */ - calls_manager_remove_provider (manager, "mm"); - g_assert_true (calls_manager_has_any_provider (manager)); - g_assert_cmpuint (calls_manager_get_state (manager), ==, CALLS_MANAGER_STATE_READY); - - g_assert_true (calls_manager_provider_remove_account (manager, "sip", bob)); - g_assert_cmpuint (g_list_model_get_n_items (origins_sip), ==, 0); } gint diff --git a/tests/test-sip.c b/tests/test-sip.c index d33b8a5..d01504f 100644 --- a/tests/test-sip.c +++ b/tests/test-sip.c @@ -21,12 +21,9 @@ typedef struct { CallsSipProvider *provider; - CallsSipOrigin *origin_alice; - CallsSipOrigin *origin_bob; - CallsSipOrigin *origin_offline; - CallsCredentials *credentials_alice; - CallsCredentials *credentials_bob; - CallsCredentials *credentials_offline; + CallsSipOrigin *origin_alice; + CallsSipOrigin *origin_bob; + CallsSipOrigin *origin_offline; } SipFixture; @@ -361,59 +358,50 @@ static void 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); - g_object_set (alice, "name", "Alice", "user", "alice", NULL); + fixture->origin_alice = + calls_sip_provider_add_origin_full (fixture->provider, + NULL, + "alice", + NULL, + NULL, + NULL, + 0, + FALSE, + TRUE, + 5060); - calls_sip_provider_add_origin (fixture->provider, alice, 5060, TRUE); + fixture->origin_bob = + calls_sip_provider_add_origin_full (fixture->provider, + NULL, + "bob", + NULL, + NULL, + NULL, + 0, + FALSE, + TRUE, + 5061); - g_object_set (bob, "name", "Bob", "user", "bob", NULL); + fixture->origin_offline = + calls_sip_provider_add_origin_full (fixture->provider, + "sip.imaginary-host.org", + "username", + "password", + NULL, + "UDP", + 0, + FALSE, + FALSE, + 0); - 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 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); }