2022-03-01 16:05:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2022 Purism SPC
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-3.0+
|
|
|
|
*
|
|
|
|
* Author: Evangelos Ribeiro Tzaras <evangelos.tzaras@puri.sm>
|
|
|
|
*/
|
|
|
|
|
2022-03-01 17:00:52 +00:00
|
|
|
#include "calls-sip-call.h"
|
2022-03-01 16:05:55 +00:00
|
|
|
#include "calls-sip-media-manager.h"
|
|
|
|
#include "gst-rfc3551.h"
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
#include <gst/gst.h>
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
find_string_in_sdp_message (const char *sdp,
|
|
|
|
const char *string)
|
|
|
|
{
|
|
|
|
char **split_string = NULL;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
|
|
|
split_string = g_strsplit (sdp, "\r\n", -1);
|
|
|
|
|
|
|
|
for (guint i = 0; split_string[i] != NULL; i++) {
|
|
|
|
if (g_strcmp0 (split_string[i], string) == 0) {
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (split_string);
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_sip_media_manager_caps (void)
|
|
|
|
{
|
2022-03-01 17:00:52 +00:00
|
|
|
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
|
2022-03-01 16:05:55 +00:00
|
|
|
char *sdp_message = NULL;
|
|
|
|
GList *codecs = NULL;
|
|
|
|
|
|
|
|
/* Check single codecs */
|
|
|
|
codecs = g_list_append (NULL, media_codec_by_name ("PCMA"));
|
|
|
|
|
|
|
|
g_debug ("Testing generated SDP messages");
|
|
|
|
|
|
|
|
/* PCMA RTP */
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 40002, 40003, FALSE, codecs);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 40002 RTP/AVP 8"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtpmap:8 PCMA/8000"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtcp:40003"));
|
|
|
|
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("PCMA RTP test OK");
|
|
|
|
|
|
|
|
/* PCMA SRTP */
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 42002, 42003, TRUE, codecs);
|
2022-03-01 16:05:55 +00:00
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 42002 RTP/SAVP 8"));
|
|
|
|
|
|
|
|
g_clear_pointer (&codecs, g_list_free);
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("PCMA SRTP test OK");
|
|
|
|
|
|
|
|
/* G722 RTP */
|
|
|
|
codecs = g_list_append (NULL, media_codec_by_name ("G722"));
|
|
|
|
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 42042, 55543, FALSE, codecs);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 42042 RTP/AVP 9"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtpmap:9 G722/8000"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
2022-02-28 10:38:06 +00:00
|
|
|
"a=rtcp:55543"));
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_clear_pointer (&codecs, g_list_free);
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("G722 RTP test OK");
|
|
|
|
|
|
|
|
/* G722 PCMU PCMA RTP (in this order) */
|
|
|
|
codecs = g_list_append (NULL, media_codec_by_name ("G722"));
|
|
|
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
|
|
|
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
|
|
|
|
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 33340, 33341, FALSE, codecs);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 33340 RTP/AVP 9 0 8"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtpmap:9 G722/8000"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtpmap:0 PCMU/8000"));
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"a=rtpmap:8 PCMA/8000"));
|
|
|
|
|
|
|
|
g_clear_pointer (&codecs, g_list_free);
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("multiple codecs RTP test OK");
|
|
|
|
|
|
|
|
/* GSM PCMA G722 PCMU SRTP (in this order) */
|
|
|
|
codecs = g_list_append (NULL, media_codec_by_name ("GSM"));
|
|
|
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMA"));
|
|
|
|
codecs = g_list_append (codecs, media_codec_by_name ("G722"));
|
|
|
|
codecs = g_list_append (codecs, media_codec_by_name ("PCMU"));
|
|
|
|
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 18098, 18099, TRUE, codecs);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 18098 RTP/SAVP 3 8 9 0"));
|
|
|
|
|
|
|
|
g_clear_pointer (&codecs, g_list_free);
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("multiple codecs SRTP test OK");
|
|
|
|
|
|
|
|
/* no codecs */
|
|
|
|
g_test_expect_message ("CallsSipMediaManager", G_LOG_LEVEL_WARNING,
|
|
|
|
"No supported codecs found. Can't build meaningful SDP message");
|
|
|
|
sdp_message =
|
2022-02-28 10:38:06 +00:00
|
|
|
calls_sip_media_manager_get_capabilities (manager, NULL, 25048, 25049, FALSE, NULL);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
g_assert_true (sdp_message);
|
|
|
|
g_assert_true (find_string_in_sdp_message (sdp_message,
|
|
|
|
"m=audio 0 RTP/AVP"));
|
|
|
|
|
|
|
|
g_free (sdp_message);
|
|
|
|
|
|
|
|
g_debug ("no codecs test OK");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-01 17:00:52 +00:00
|
|
|
static void
|
|
|
|
test_media_pipeline_states (void)
|
|
|
|
{
|
|
|
|
CallsSipMediaPipeline *pipeline = calls_sip_media_pipeline_new (NULL);
|
|
|
|
MediaCodecInfo *codec = media_codec_by_name ("PCMA");
|
|
|
|
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_set_codec (pipeline, codec);
|
|
|
|
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_READY);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_start (pipeline);
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_PLAY_PENDING);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_pause (pipeline, TRUE);
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_PAUSE_PENDING);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_pause (pipeline, FALSE);
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_PLAY_PENDING);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_stop (pipeline);
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_STOP_PENDING);
|
|
|
|
|
|
|
|
g_assert_finalize_object (pipeline);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_media_pipeline_setup_codecs (void)
|
|
|
|
{
|
|
|
|
const char * const codec_names[] = {"PCMA", "PCMU", "GSM", "G722"};
|
|
|
|
|
|
|
|
for (uint i = 0; i < G_N_ELEMENTS (codec_names); i++) {
|
|
|
|
g_autoptr (CallsSipMediaPipeline) pipeline = calls_sip_media_pipeline_new (NULL);
|
|
|
|
MediaCodecInfo *codec = media_codec_by_name ("PCMA");
|
|
|
|
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_set_codec (pipeline, codec);
|
|
|
|
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_READY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_media_pipeline_start_no_codec (void)
|
|
|
|
{
|
|
|
|
g_autoptr (CallsSipMediaPipeline) pipeline = calls_sip_media_pipeline_new (NULL);
|
|
|
|
|
|
|
|
g_assert_cmpint (calls_sip_media_pipeline_get_state (pipeline), ==,
|
|
|
|
CALLS_MEDIA_PIPELINE_STATE_NEED_CODEC);
|
|
|
|
|
|
|
|
g_test_expect_message ("CallsSipMediaPipeline", G_LOG_LEVEL_WARNING,
|
|
|
|
"Cannot start pipeline because it's not ready");
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_start (pipeline);
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
|
|
|
|
g_test_expect_message ("CallsSipMediaPipeline", G_LOG_LEVEL_WARNING,
|
|
|
|
"Cannot pause or unpause pipeline because it's not currently active");
|
|
|
|
|
|
|
|
calls_sip_media_pipeline_pause (pipeline, TRUE);
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_media_pipeline_finalized_in_call (void)
|
|
|
|
{
|
|
|
|
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
|
|
|
|
CallsSipMediaPipeline *pipeline = calls_sip_media_pipeline_new (NULL);
|
|
|
|
CallsSipCall *call = calls_sip_call_new ("sip:alice@example.org",
|
|
|
|
TRUE,
|
|
|
|
"127.0.0.1",
|
|
|
|
pipeline,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_unref (call);
|
|
|
|
g_assert_finalize_object (pipeline);
|
|
|
|
|
|
|
|
pipeline = calls_sip_media_manager_get_pipeline (manager);
|
|
|
|
call = calls_sip_call_new ("sip:bob@example.org",
|
|
|
|
TRUE,
|
|
|
|
"127.0.0.1",
|
|
|
|
pipeline,
|
|
|
|
NULL);
|
|
|
|
g_object_unref (call);
|
|
|
|
g_assert_finalize_object (pipeline);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-01 16:05:55 +00:00
|
|
|
int
|
|
|
|
main (int argc,
|
|
|
|
char *argv[])
|
|
|
|
{
|
2022-03-01 17:00:52 +00:00
|
|
|
CallsSipMediaManager *manager = calls_sip_media_manager_default ();
|
2022-03-01 16:05:55 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
gtk_test_init (&argc, &argv, NULL);
|
|
|
|
|
|
|
|
gst_init (NULL, NULL);
|
|
|
|
|
2022-04-06 15:35:24 +00:00
|
|
|
g_test_add_func ("/Calls/media/media_manager/capabilities", test_sip_media_manager_caps);
|
|
|
|
g_test_add_func ("/Calls/media/pipeline/states", test_media_pipeline_states);
|
|
|
|
g_test_add_func ("/Calls/media/pipeline/setup_codecs", test_media_pipeline_setup_codecs);
|
|
|
|
g_test_add_func ("/Calls/media/pipeline/start_no_codec", test_media_pipeline_start_no_codec);
|
|
|
|
g_test_add_func ("/Calls/media/pipeline/finalized_in_call", test_media_pipeline_finalized_in_call);
|
2022-03-01 16:05:55 +00:00
|
|
|
|
|
|
|
ret = g_test_run();
|
|
|
|
|
2022-03-01 17:00:52 +00:00
|
|
|
g_assert_finalize_object (manager);
|
|
|
|
|
2022-03-01 16:05:55 +00:00
|
|
|
gst_deinit ();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|