mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2024-11-04 23:51:17 +00:00
sip: Use per origin IP instead of a global IP
Sofia detects a NAT by presence of the "received" parameter in the Via header in
the response to a REGISTER. Sofia will then update the Contact header to use the
IP as reported by the registrar.
The "received" parameter MUST be included in the response according to
https://datatracker.ietf.org/doc/html/rfc3261#section-18.2.1
when the registrar detects a difference between the domain part of the top Via
header and the packet source address but practice has shown that this will not
always be the case.
Addditionally this change allows us to have origins bound to different network
interfaces which would be useful when a registrar can only be accessed through a
VPN.
This also fixes an issue with SDP introduced in
36880c3d34
which was only seen on some SIP
providers:
The session name ("s=") line is not relevant for establishing a connection,
the connection data (c=") line is.
See https://datatracker.ietf.org/doc/html/rfc4566 section 5.3 and 5.7
This commit is contained in:
parent
ae4053e1c9
commit
8b126484cb
6 changed files with 105 additions and 20 deletions
|
@ -50,6 +50,7 @@
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CALL_HANDLE,
|
PROP_CALL_HANDLE,
|
||||||
|
PROP_IP,
|
||||||
PROP_LAST_PROP
|
PROP_LAST_PROP
|
||||||
};
|
};
|
||||||
static GParamSpec *props[PROP_LAST_PROP];
|
static GParamSpec *props[PROP_LAST_PROP];
|
||||||
|
@ -61,6 +62,8 @@ struct _CallsSipCall
|
||||||
CallsSipMediaManager *manager;
|
CallsSipMediaManager *manager;
|
||||||
CallsSipMediaPipeline *pipeline;
|
CallsSipMediaPipeline *pipeline;
|
||||||
|
|
||||||
|
char *ip;
|
||||||
|
|
||||||
guint lport_rtp;
|
guint lport_rtp;
|
||||||
guint lport_rtcp;
|
guint lport_rtcp;
|
||||||
guint rport_rtp;
|
guint rport_rtp;
|
||||||
|
@ -138,6 +141,7 @@ calls_sip_call_answer (CallsCall *call)
|
||||||
calls_sip_call_setup_local_media_connection (self, local_port, local_port + 1);
|
calls_sip_call_setup_local_media_connection (self, local_port, local_port + 1);
|
||||||
|
|
||||||
local_sdp = calls_sip_media_manager_get_capabilities (self->manager,
|
local_sdp = calls_sip_media_manager_get_capabilities (self->manager,
|
||||||
|
self->ip,
|
||||||
local_port,
|
local_port,
|
||||||
FALSE,
|
FALSE,
|
||||||
self->codecs);
|
self->codecs);
|
||||||
|
@ -205,6 +209,11 @@ calls_sip_call_set_property (GObject *object,
|
||||||
self->nh = g_value_get_pointer (value);
|
self->nh = g_value_get_pointer (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_IP:
|
||||||
|
g_free (self->ip);
|
||||||
|
self->ip = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -243,6 +252,7 @@ calls_sip_call_finalize (GObject *object)
|
||||||
}
|
}
|
||||||
g_clear_pointer (&self->codecs, g_list_free);
|
g_clear_pointer (&self->codecs, g_list_free);
|
||||||
g_clear_pointer (&self->remote, g_free);
|
g_clear_pointer (&self->remote, g_free);
|
||||||
|
g_clear_pointer (&self->ip, g_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (calls_sip_call_parent_class)->finalize (object);
|
G_OBJECT_CLASS (calls_sip_call_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +276,14 @@ calls_sip_call_class_init (CallsSipCallClass *klass)
|
||||||
"NUA handle",
|
"NUA handle",
|
||||||
"The used NUA handler",
|
"The used NUA handler",
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
g_object_class_install_property (object_class, PROP_CALL_HANDLE, props[PROP_CALL_HANDLE]);
|
|
||||||
|
props[PROP_IP] =
|
||||||
|
g_param_spec_string ("own-ip",
|
||||||
|
"Own IP",
|
||||||
|
"Own IP for media and SDP",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
|
||||||
|
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,14 +370,16 @@ calls_sip_call_activate_media (CallsSipCall *self,
|
||||||
CallsSipCall *
|
CallsSipCall *
|
||||||
calls_sip_call_new (const gchar *id,
|
calls_sip_call_new (const gchar *id,
|
||||||
gboolean inbound,
|
gboolean inbound,
|
||||||
|
const char *own_ip,
|
||||||
nua_handle_t *handle)
|
nua_handle_t *handle)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (id, NULL);
|
g_return_val_if_fail (id, NULL);
|
||||||
|
|
||||||
return g_object_new (CALLS_TYPE_SIP_CALL,
|
return g_object_new (CALLS_TYPE_SIP_CALL,
|
||||||
"nua-handle", handle,
|
|
||||||
"id", id,
|
"id", id,
|
||||||
"inbound", inbound,
|
"inbound", inbound,
|
||||||
|
"own-ip", own_ip,
|
||||||
|
"nua-handle", handle,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (CallsSipCall, calls_sip_call, CALLS, SIP_CALL, CallsCall)
|
||||||
|
|
||||||
CallsSipCall *calls_sip_call_new (const gchar *number,
|
CallsSipCall *calls_sip_call_new (const gchar *number,
|
||||||
gboolean inbound,
|
gboolean inbound,
|
||||||
|
const char *own_ip,
|
||||||
nua_handle_t *handle);
|
nua_handle_t *handle);
|
||||||
void calls_sip_call_setup_remote_media_connection (CallsSipCall *self,
|
void calls_sip_call_setup_remote_media_connection (CallsSipCall *self,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
|
|
|
@ -52,6 +52,9 @@ typedef struct _CallsSipMediaManager
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
char *session_ip;
|
char *session_ip;
|
||||||
|
int address_family;
|
||||||
|
struct addrinfo hints;
|
||||||
|
|
||||||
CallsSettings *settings;
|
CallsSettings *settings;
|
||||||
GList *preferred_codecs;
|
GList *preferred_codecs;
|
||||||
} CallsSipMediaManager;
|
} CallsSipMediaManager;
|
||||||
|
@ -59,6 +62,34 @@ typedef struct _CallsSipMediaManager
|
||||||
G_DEFINE_TYPE (CallsSipMediaManager, calls_sip_media_manager, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (CallsSipMediaManager, calls_sip_media_manager, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_address_family_string (CallsSipMediaManager *self,
|
||||||
|
const char *ip)
|
||||||
|
{
|
||||||
|
struct addrinfo *result = NULL;
|
||||||
|
const char *family;
|
||||||
|
|
||||||
|
if (getaddrinfo (ip, NULL, &self->hints, &result) != 0) {
|
||||||
|
g_warning ("Cannot parse session IP %s", ip);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if IP is IPv4 or IPv6. We need to specify this in the c= line of SDP */
|
||||||
|
self->address_family = result->ai_family;
|
||||||
|
|
||||||
|
if (result->ai_family == AF_INET)
|
||||||
|
family = "IP4";
|
||||||
|
else if (result->ai_family == AF_INET6)
|
||||||
|
family = "IP6";
|
||||||
|
else
|
||||||
|
family = NULL;
|
||||||
|
|
||||||
|
freeaddrinfo (result);
|
||||||
|
|
||||||
|
return family;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_preferred_audio_codecs (CallsSipMediaManager *self)
|
on_notify_preferred_audio_codecs (CallsSipMediaManager *self)
|
||||||
{
|
{
|
||||||
|
@ -167,6 +198,10 @@ calls_sip_media_manager_init (CallsSipMediaManager *self)
|
||||||
G_CALLBACK (on_notify_preferred_audio_codecs),
|
G_CALLBACK (on_notify_preferred_audio_codecs),
|
||||||
self);
|
self);
|
||||||
on_notify_preferred_audio_codecs (self);
|
on_notify_preferred_audio_codecs (self);
|
||||||
|
|
||||||
|
/* Hints are used with getaddrinfo() when setting the session IP */
|
||||||
|
self->hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICHOST;
|
||||||
|
self->hints.ai_family = AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,6 +233,7 @@ calls_sip_media_manager_default (void)
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
||||||
|
const char *own_ip,
|
||||||
guint port,
|
guint port,
|
||||||
gboolean use_srtp,
|
gboolean use_srtp,
|
||||||
GList *supported_codecs)
|
GList *supported_codecs)
|
||||||
|
@ -206,6 +242,7 @@ calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
||||||
g_autoptr (GString) media_line = NULL;
|
g_autoptr (GString) media_line = NULL;
|
||||||
g_autoptr (GString) attribute_lines = NULL;
|
g_autoptr (GString) attribute_lines = NULL;
|
||||||
GList *node;
|
GList *node;
|
||||||
|
const char *address_family_string;
|
||||||
|
|
||||||
g_return_val_if_fail (CALLS_IS_SIP_MEDIA_MANAGER (self), NULL);
|
g_return_val_if_fail (CALLS_IS_SIP_MEDIA_MANAGER (self), NULL);
|
||||||
|
|
||||||
|
@ -237,12 +274,16 @@ calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
||||||
g_string_append_printf (attribute_lines, "a=rtcp:%d\r\n", port + 1);
|
g_string_append_printf (attribute_lines, "a=rtcp:%d\r\n", port + 1);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (self->session_ip && *self->session_ip)
|
if (own_ip && *own_ip)
|
||||||
|
address_family_string = get_address_family_string (self, own_ip);
|
||||||
|
|
||||||
|
if (own_ip && *own_ip && address_family_string)
|
||||||
return g_strdup_printf ("v=0\r\n"
|
return g_strdup_printf ("v=0\r\n"
|
||||||
"s=%s\r\n"
|
"c=IN %s %s\r\n"
|
||||||
"%s\r\n"
|
"%s\r\n"
|
||||||
"%s\r\n",
|
"%s\r\n",
|
||||||
self->session_ip,
|
address_family_string,
|
||||||
|
own_ip,
|
||||||
media_line->str,
|
media_line->str,
|
||||||
attribute_lines->str);
|
attribute_lines->str);
|
||||||
else
|
else
|
||||||
|
@ -266,12 +307,14 @@ calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
calls_sip_media_manager_static_capabilities (CallsSipMediaManager *self,
|
calls_sip_media_manager_static_capabilities (CallsSipMediaManager *self,
|
||||||
|
const char *own_ip,
|
||||||
guint port,
|
guint port,
|
||||||
gboolean use_srtp)
|
gboolean use_srtp)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CALLS_IS_SIP_MEDIA_MANAGER (self), NULL);
|
g_return_val_if_fail (CALLS_IS_SIP_MEDIA_MANAGER (self), NULL);
|
||||||
|
|
||||||
return calls_sip_media_manager_get_capabilities (self,
|
return calls_sip_media_manager_get_capabilities (self,
|
||||||
|
own_ip,
|
||||||
port,
|
port,
|
||||||
use_srtp,
|
use_srtp,
|
||||||
self->preferred_codecs);
|
self->preferred_codecs);
|
||||||
|
@ -348,7 +391,21 @@ calls_sip_media_manager_set_session_ip (CallsSipMediaManager *self,
|
||||||
|
|
||||||
g_clear_pointer (&self->session_ip, g_free);
|
g_clear_pointer (&self->session_ip, g_free);
|
||||||
if (session_ip && *session_ip) {
|
if (session_ip && *session_ip) {
|
||||||
|
struct addrinfo *result = NULL;
|
||||||
|
|
||||||
|
if (getaddrinfo (session_ip, NULL, &self->hints, &result) != 0) {
|
||||||
|
g_warning ("Cannot parse session IP %s", session_ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if IP is IPv4 or IPv6. We need to specify this in the c= line of SDP */
|
||||||
|
self->address_family = result->ai_family;
|
||||||
|
|
||||||
g_debug ("Setting session IP to %s", session_ip);
|
g_debug ("Setting session IP to %s", session_ip);
|
||||||
|
|
||||||
|
g_free (self->session_ip);
|
||||||
self->session_ip = g_strdup (session_ip);
|
self->session_ip = g_strdup (session_ip);
|
||||||
|
|
||||||
|
freeaddrinfo (result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,16 @@ G_DECLARE_FINAL_TYPE (CallsSipMediaManager, calls_sip_media_manager, CALLS, SIP_
|
||||||
|
|
||||||
CallsSipMediaManager* calls_sip_media_manager_default (void);
|
CallsSipMediaManager* calls_sip_media_manager_default (void);
|
||||||
gchar* calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
gchar* calls_sip_media_manager_get_capabilities (CallsSipMediaManager *self,
|
||||||
guint port,
|
const char *own_ip,
|
||||||
gboolean use_srtp,
|
guint port,
|
||||||
GList *supported_codecs);
|
gboolean use_srtp,
|
||||||
|
GList *supported_codecs);
|
||||||
gchar* calls_sip_media_manager_static_capabilities (CallsSipMediaManager *self,
|
gchar* calls_sip_media_manager_static_capabilities (CallsSipMediaManager *self,
|
||||||
guint port,
|
const char *own_ip,
|
||||||
gboolean use_srtp);
|
guint port,
|
||||||
|
gboolean use_srtp);
|
||||||
gboolean calls_sip_media_manager_supports_media (CallsSipMediaManager *self,
|
gboolean calls_sip_media_manager_supports_media (CallsSipMediaManager *self,
|
||||||
const char *media_type);
|
const char *media_type);
|
||||||
MediaCodecInfo* get_best_codec (CallsSipMediaManager *self);
|
MediaCodecInfo* get_best_codec (CallsSipMediaManager *self);
|
||||||
GList * calls_sip_media_manager_codec_candidates (CallsSipMediaManager *self);
|
GList * calls_sip_media_manager_codec_candidates (CallsSipMediaManager *self);
|
||||||
GList * calls_sip_media_manager_get_codecs_from_sdp (CallsSipMediaManager *self,
|
GList * calls_sip_media_manager_get_codecs_from_sdp (CallsSipMediaManager *self,
|
||||||
|
|
|
@ -111,6 +111,8 @@ struct _CallsSipOrigin
|
||||||
gboolean auto_connect;
|
gboolean auto_connect;
|
||||||
gboolean direct_mode;
|
gboolean direct_mode;
|
||||||
gboolean can_tel;
|
gboolean can_tel;
|
||||||
|
|
||||||
|
char *own_ip;
|
||||||
gint local_port;
|
gint local_port;
|
||||||
|
|
||||||
const char *protocol_prefix;
|
const char *protocol_prefix;
|
||||||
|
@ -229,7 +231,7 @@ add_call (CallsSipOrigin *self,
|
||||||
call_address = address_split[1];
|
call_address = address_split[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
sip_call = calls_sip_call_new (call_address, inbound, handle);
|
sip_call = calls_sip_call_new (call_address, inbound, self->own_ip, handle);
|
||||||
g_assert (sip_call != NULL);
|
g_assert (sip_call != NULL);
|
||||||
|
|
||||||
if (self->oper->call_handle)
|
if (self->oper->call_handle)
|
||||||
|
@ -251,6 +253,7 @@ add_call (CallsSipOrigin *self,
|
||||||
calls_sip_call_setup_local_media_connection (sip_call, local_port, local_port + 1);
|
calls_sip_call_setup_local_media_connection (sip_call, local_port, local_port + 1);
|
||||||
|
|
||||||
local_sdp = calls_sip_media_manager_static_capabilities (self->media_manager,
|
local_sdp = calls_sip_media_manager_static_capabilities (self->media_manager,
|
||||||
|
self->own_ip,
|
||||||
local_port,
|
local_port,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
|
@ -424,9 +427,10 @@ sip_r_register (int status,
|
||||||
g_debug ("REGISTER successful");
|
g_debug ("REGISTER successful");
|
||||||
origin->state = CALLS_ACCOUNT_ONLINE;
|
origin->state = CALLS_ACCOUNT_ONLINE;
|
||||||
nua_get_params (nua, TAG_ANY (), TAG_END());
|
nua_get_params (nua, TAG_ANY (), TAG_END());
|
||||||
|
|
||||||
if (sip->sip_contact && sip->sip_contact->m_url && sip->sip_contact->m_url->url_host) {
|
if (sip->sip_contact && sip->sip_contact->m_url && sip->sip_contact->m_url->url_host) {
|
||||||
calls_sip_media_manager_set_session_ip (origin->media_manager,
|
g_free (origin->own_ip);
|
||||||
sip->sip_contact->m_url->url_host);
|
origin->own_ip = g_strdup (sip->sip_contact->m_url->url_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (status == 401 || status == 407) {
|
} else if (status == 401 || status == 407) {
|
||||||
|
@ -1317,6 +1321,8 @@ calls_sip_origin_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
CallsSipOrigin *self = CALLS_SIP_ORIGIN (object);
|
CallsSipOrigin *self = CALLS_SIP_ORIGIN (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->own_ip, g_free);
|
||||||
|
|
||||||
if (!self->use_direct_connection && self->state == CALLS_ACCOUNT_ONLINE)
|
if (!self->use_direct_connection && self->state == CALLS_ACCOUNT_ONLINE)
|
||||||
go_online (CALLS_ACCOUNT (self), FALSE);
|
go_online (CALLS_ACCOUNT (self), FALSE);
|
||||||
|
|
||||||
|
|
|
@ -445,7 +445,7 @@ test_sip_media_manager (void)
|
||||||
|
|
||||||
/* PCMA RTP */
|
/* PCMA RTP */
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 40002, FALSE, codecs);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 40002, FALSE, codecs);
|
||||||
|
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
g_assert_true (find_string_in_sdp_message (sdp_message,
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
||||||
|
@ -461,7 +461,7 @@ test_sip_media_manager (void)
|
||||||
|
|
||||||
/* PCMA SRTP */
|
/* PCMA SRTP */
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 42002, TRUE, codecs);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 42002, TRUE, codecs);
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
g_assert_true (find_string_in_sdp_message (sdp_message,
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
||||||
"m=audio 42002 RTP/SAVP 8"));
|
"m=audio 42002 RTP/SAVP 8"));
|
||||||
|
@ -475,7 +475,7 @@ test_sip_media_manager (void)
|
||||||
codecs = g_list_append (NULL, media_codec_by_name ("G722"));
|
codecs = g_list_append (NULL, media_codec_by_name ("G722"));
|
||||||
|
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 42042, FALSE, codecs);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 42042, FALSE, codecs);
|
||||||
|
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
g_assert_true (find_string_in_sdp_message (sdp_message,
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
||||||
|
@ -496,7 +496,7 @@ test_sip_media_manager (void)
|
||||||
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
|
||||||
|
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 33340, FALSE, codecs);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 33340, FALSE, codecs);
|
||||||
|
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
g_assert_true (find_string_in_sdp_message (sdp_message,
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
||||||
|
@ -520,7 +520,7 @@ test_sip_media_manager (void)
|
||||||
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
|
||||||
|
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 18098, TRUE, codecs);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 18098, TRUE, codecs);
|
||||||
|
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
g_assert_true (find_string_in_sdp_message (sdp_message,
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
||||||
|
@ -535,7 +535,7 @@ test_sip_media_manager (void)
|
||||||
g_test_expect_message ("CallsSipMediaManager", G_LOG_LEVEL_WARNING,
|
g_test_expect_message ("CallsSipMediaManager", G_LOG_LEVEL_WARNING,
|
||||||
"No supported codecs found. Can't build meaningful SDP message");
|
"No supported codecs found. Can't build meaningful SDP message");
|
||||||
sdp_message =
|
sdp_message =
|
||||||
calls_sip_media_manager_get_capabilities (manager, 25048, FALSE, NULL);
|
calls_sip_media_manager_get_capabilities (manager, NULL, 25048, FALSE, NULL);
|
||||||
|
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
g_assert_true (sdp_message);
|
g_assert_true (sdp_message);
|
||||||
|
|
Loading…
Reference in a new issue