An error occurred while loading the file. Please try again.
-
Tero Rintaluoma authored
Adds following targets to configure script to support RVCT compilation without operating system support (for Profiler or bare metal images). - armv5te-none-rvct - armv6-none-rvct - armv7-none-rvct To strip OS specific parts from the code "os_support"-config was added to script and CONFIG_OS_SUPPORT flag is used in the code to exclude OS specific parts such as OS specific includes and function calls for timers and threads etc. This was done to enable RVCT compilation for profiling purposes or running the image on bare metal target with Lauterbach. Removed separate AREA directives for READONLY data in armv6 and neon assembly files to fix the RVCT compilation. Otherwise "ldr <reg>, =label" syntax would have been needed to prevent linker errors. This syntax is not supported by older gnu assemblers. Change-Id: I14f4c68529e8c27397502fbc3010a54e505ddb43
11a222f5
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of Liblinphone
* (see https://gitlab.linphone.org/BC/public/liblinphone).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "liblinphone_tester.h"
#include "linphone/core.h"
#include "linphone/lpconfig.h"
#include "linphone/utils/utils.h"
#include "sal/sal_media_description.h"
#include "sal/sal_stream_description.h"
#include "shared_tester_functions.h"
#include "tester_utils.h"
#include <sys/stat.h>
#include <sys/types.h>
using namespace LinphonePrivate;
static int get_codec_position(const MSList *l, const char *mime_type, int rate) {
const MSList *elem;
int i;
for (elem = l, i = 0; elem != NULL; elem = elem->next, i++) {
PayloadType *pt = (PayloadType *)elem->data;
if (strcasecmp(pt->mime_type, mime_type) == 0 && pt->clock_rate == rate) return i;
}
return -1;
}
/*check basic things about codecs at startup: order and enablement*/
static void start_with_no_config(void) {
LinphoneCore *lc =
linphone_factory_create_core_3(linphone_factory_get(), NULL, liblinphone_tester_get_empty_rc(), system_context);
const MSList *codecs = linphone_core_get_audio_codecs(lc);
int opus_codec_pos;
int speex_codec_pos = get_codec_position(codecs, "speex", 8000);
int speex16_codec_pos = get_codec_position(codecs, "speex", 16000);
PayloadType *pt;
opus_codec_pos = get_codec_position(codecs, "opus", 48000);
if (opus_codec_pos != -1) BC_ASSERT_EQUAL(opus_codec_pos, 0, int, "%d");
BC_ASSERT_LOWER(speex16_codec_pos, speex_codec_pos, int, "%d");
pt = linphone_core_find_payload_type(lc, "speex", 16000, 1);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
BC_ASSERT_TRUE(linphone_core_payload_type_enabled(lc, pt));
}
linphone_core_unref(lc);
}
static void check_payload_type_numbers(LinphoneCall *call1, LinphoneCall *call2, int expected_number) {
const LinphoneCallParams *params = linphone_call_get_current_params(call1);
if (!BC_ASSERT_PTR_NOT_NULL(params)) return;
const LinphonePayloadType *pt = linphone_call_params_get_used_audio_payload_type(params);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
BC_ASSERT_EQUAL(linphone_payload_type_get_number(pt), expected_number, int, "%d");
}
params = linphone_call_get_current_params(call2);
pt = linphone_call_params_get_used_audio_payload_type(params);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
BC_ASSERT_EQUAL(linphone_payload_type_get_number(pt), expected_number, int, "%d");
}
}
static void simple_call_with_different_codec_mappings_and_config_supplied_sdp_addresses(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
const char *marie4 = "10.0.0.56";
const char *marie6 = "fd00:0bad:f00d::56";
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
disable_all_audio_codecs_except_one(marie->lc, "pcmu", -1);
disable_all_audio_codecs_except_one(pauline->lc, "pcmu", -1);
/*marie set a fantasy number to PCMU*/
payload_type_set_number(linphone_core_find_payload_type(marie->lc, "PCMU", 8000, -1), 104);
LinphoneConfig *cfg = linphone_core_get_config(marie->lc);
linphone_config_set_string(cfg, "rtp", "ipv4_sdp_address", marie4);
linphone_config_set_string(cfg, "rtp", "ipv6_sdp_address", marie6);
cfg = linphone_core_get_config(pauline->lc);
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call) {
LinphoneCallParams *params;
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
std::string sdp_address = _linphone_call_get_remote_desc(pauline_call)->getConnectionAddress();
BC_ASSERT_TRUE(sdp_address == marie4 || sdp_address == marie6);
/*make a reinvite in the other direction*/
linphone_call_update(pauline_call, params = linphone_core_create_call_params(pauline->lc, pauline_call));
linphone_call_params_unref(params);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallUpdating, 1));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallUpdatedByRemote, 1));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2));
/*payload type numbers shall remain the same*/
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
}
end_call(marie, pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void simple_call_with_fmtps(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
disable_all_audio_codecs_except_one(marie->lc, "pcmu", -1);
disable_all_audio_codecs_except_one(pauline->lc, "pcmu", -1);
/*marie set a fantasy fmtp to PCMU*/
LinphonePayloadType *marie_pt = linphone_core_get_payload_type(marie->lc, "PCMU", 8000, -1);
linphone_payload_type_set_recv_fmtp(marie_pt, "parles-plus-fort=1");
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
linphone_payload_type_unref(marie_pt);
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call) {
const LinphonePayloadType *pt =
linphone_call_params_get_used_audio_payload_type(linphone_call_get_current_params(pauline_call));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
BC_ASSERT_STRING_EQUAL(linphone_payload_type_get_send_fmtp(pt), "parles-plus-fort=1");
}
pt = linphone_call_params_get_used_audio_payload_type(
linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
ms_message("send_fmtp=%s, recv_fmtp=%s", linphone_payload_type_get_send_fmtp(pt),
linphone_payload_type_get_recv_fmtp(pt));
BC_ASSERT_STRING_EQUAL(linphone_payload_type_get_recv_fmtp(pt), "parles-plus-fort=1");
}
}
end_call(marie, pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
#ifdef VIDEO_ENABLED
static void h264_call_with_fmtps(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
OrtpPayloadType *pt_1 = NULL, *pt_2 = NULL;
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
bctbx_list_t *video_codecs = NULL;
OrtpPayloadType *origin_h264_pt = NULL;
linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
LinphoneVideoActivationPolicy *pol = linphone_factory_create_video_activation_policy(linphone_factory_get());
linphone_video_activation_policy_set_automatically_accept(pol, TRUE);
linphone_video_activation_policy_set_automatically_initiate(pol, TRUE);
linphone_core_set_video_activation_policy(marie->lc, pol);
linphone_core_set_video_activation_policy(pauline->lc, pol);
linphone_video_activation_policy_unref(pol);
LinphonePayloadType *marie_pt = linphone_core_get_payload_type(marie->lc, "h264", 90000, -1);
if (!marie_pt) {
ms_warning("H264 not available on this platform, skeeping");
goto end;
}
linphone_payload_type_unref(marie_pt);
disable_all_video_codecs_except_one(marie->lc, "H264");
disable_all_video_codecs_except_one(pauline->lc, "H264");
origin_h264_pt = linphone_core_find_payload_type(pauline->lc, "H264", 90000, -1);
pt_1 = payload_type_clone(origin_h264_pt);
pt_2 = payload_type_clone(pt_1);
payload_type_set_recv_fmtp(pt_1, "profile-level-id=42801F; packetization-mode=0");
payload_type_set_recv_fmtp(pt_2, "profile-level-id=42801F; packetization-mode=1");
video_codecs = bctbx_list_copy(linphone_core_get_video_codecs(marie->lc));
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
for (bctbx_list_t *it = video_codecs; it != NULL; it = bctbx_list_next(it)) {
OrtpPayloadType *pt = (OrtpPayloadType *)bctbx_list_get_data(it);
if (strcasecmp(payload_type_get_mime(pt), "H264") == 0) {
video_codecs = bctbx_list_remove(video_codecs, pt);
break; // one
}
}
video_codecs = bctbx_list_append(video_codecs, pt_1);
video_codecs = bctbx_list_append(video_codecs, pt_2);
linphone_core_set_video_codecs(marie->lc, video_codecs);
/*marie set packetization-mode=1*/
// linphone_payload_type_set_recv_fmtp(linphone_core_get_payload_type(marie->lc, "h264", 90000, -1),
// "profile-level-id=42801F ");
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call) {
const LinphonePayloadType *pt =
linphone_call_params_get_used_video_payload_type(linphone_call_get_current_params(pauline_call));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode=1"));
}
pt = linphone_call_params_get_used_video_payload_type(
linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
ms_message("send_fmtp=%s, recv_fmtp=%s", linphone_payload_type_get_send_fmtp(pt),
linphone_payload_type_get_recv_fmtp(pt));
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode=1"));
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode=1"));
}
}
end_call(marie, pauline);
end:
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
if (pt_1) payload_type_destroy(pt_1);
if (pt_2) payload_type_destroy(pt_2);
}
static void enable_rtp_bundle(LinphoneCore *lc, bool_t enable) {
if (enable == false) {
linphone_config_set_bool(linphone_core_get_config(lc), "rtp", "accept_bundle", FALSE);
}
LinphoneAccount *account = linphone_core_get_default_account(lc);
LinphoneAccountParams *account_params = linphone_account_params_clone(linphone_account_get_params(account));
linphone_account_params_enable_rtp_bundle(account_params, enable);
linphone_account_set_params(account, account_params);
linphone_account_params_unref(account_params);
}
static void enable_video_stream(LinphoneCore *lc, LinphoneVideoActivationPolicy *policy) {
linphone_core_set_video_device(lc, "Mire: Mire (synthetic moving picture)");
linphone_core_enable_video_capture(lc, TRUE);
linphone_core_enable_video_display(lc, TRUE);
linphone_core_set_video_activation_policy(lc, policy);
}
typedef struct flexfec_scenarios_t {
bool_t bundle_proposed;
bool_t fec_proposed;
bool_t bundle_accepted;
bool_t fec_accepted;
} flexfec_scenarios;
static void _base_video_call_for_fec(flexfec_scenarios params) {
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_rc");
LinphoneVideoActivationPolicy *pol = linphone_factory_create_video_activation_policy(linphone_factory_get());
linphone_video_activation_policy_set_automatically_accept(pol, TRUE);
linphone_video_activation_policy_set_automatically_initiate(pol, TRUE);
enable_rtp_bundle(marie->lc, params.bundle_proposed);
enable_rtp_bundle(pauline->lc, params.bundle_accepted);
linphone_core_enable_fec(marie->lc, params.fec_proposed);
linphone_core_enable_fec(pauline->lc, params.fec_accepted);
enable_video_stream(marie->lc, pol);
enable_video_stream(pauline->lc, pol);
linphone_video_activation_policy_unref(pol);
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
if (pauline_call) {
const LinphoneCallParams *call_params = linphone_call_get_current_params(pauline_call);
bool_t bundle_enabled = linphone_call_params_rtp_bundle_enabled(call_params);
if (params.bundle_proposed && params.bundle_accepted) BC_ASSERT_TRUE(bundle_enabled);
else {
BC_ASSERT_FALSE(bundle_enabled);
}
}
end_call(marie, pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
void flexfec_test_both_proposed_both_accepted(void) {
flexfec_scenarios params = {TRUE, TRUE, TRUE, TRUE};
_base_video_call_for_fec(params);
}
void flexfec_test_both_proposed_bundle_accepted(void) {
flexfec_scenarios params = {TRUE, TRUE, TRUE, FALSE};
_base_video_call_for_fec(params);
}
void flexfec_test_both_proposed_nothing_accepted(void) {
flexfec_scenarios params = {TRUE, TRUE, FALSE, FALSE};
_base_video_call_for_fec(params);
}
void flexfec_test_both_poposed_only_fec_accepted(void) {
flexfec_scenarios params = {TRUE, TRUE, FALSE, TRUE};
_base_video_call_for_fec(params);
}
void flexfec_test_only_fec_proposed_and_accepted(void) {
flexfec_scenarios params = {FALSE, TRUE, FALSE, TRUE};
_base_video_call_for_fec(params);
}
static void h264_call_receiver_with_no_h264_support(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
linphone_core_enable_video_capture(marie->lc, TRUE);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
LinphoneVideoActivationPolicy *pol = linphone_factory_create_video_activation_policy(linphone_factory_get());
linphone_video_activation_policy_set_automatically_accept(pol, TRUE);
linphone_video_activation_policy_set_automatically_initiate(pol, TRUE);
linphone_core_set_video_activation_policy(marie->lc, pol);
linphone_core_set_video_activation_policy(pauline->lc, pol);
linphone_video_activation_policy_unref(pol);
LinphonePayloadType *marie_pt = linphone_core_get_payload_type(marie->lc, "h264", 90000, -1);
if (!marie_pt) {
ms_warning("H264 not available on this platform, skeeping");
goto end;
}
linphone_payload_type_unref(marie_pt);
disable_all_video_codecs_except_one(marie->lc, "H264");
disable_all_video_codecs_except_one(pauline->lc, "VP8");
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call) {
const LinphonePayloadType *pt =
linphone_call_params_get_used_video_payload_type(linphone_call_get_current_params(pauline_call));
BC_ASSERT_PTR_NULL(pt);
pt = linphone_call_params_get_used_video_payload_type(
linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)));
BC_ASSERT_PTR_NULL(pt);
}
end_call(marie, pauline);
end:
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void h264_call_without_packetization_mode(void) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *pauline_call;
OrtpPayloadType *pt_1 = NULL, *pt_2 = NULL;
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
LinphoneVideoActivationPolicy *pol = linphone_factory_create_video_activation_policy(linphone_factory_get());
linphone_video_activation_policy_set_automatically_accept(pol, TRUE);
linphone_video_activation_policy_set_automatically_initiate(pol, TRUE);
linphone_core_set_video_activation_policy(marie->lc, pol);
linphone_core_set_video_activation_policy(pauline->lc, pol);
linphone_video_activation_policy_unref(pol);
LinphonePayloadType *marie_pt = linphone_core_get_payload_type(marie->lc, "h264", 90000, -1);
if (!marie_pt) {
ms_warning("H264 not available on this platform, skeeping");
goto end;
}
linphone_payload_type_unref(marie_pt);
disable_all_video_codecs_except_one(marie->lc, "H264");
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
disable_all_video_codecs_except_one(pauline->lc, "H264");
BC_ASSERT_TRUE(call(marie, pauline));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call) {
const LinphonePayloadType *pt =
linphone_call_params_get_used_video_payload_type(linphone_call_get_current_params(pauline_call));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
BC_ASSERT_PTR_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode"));
}
pt = linphone_call_params_get_used_video_payload_type(
linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)));
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
ms_message("send_fmtp=%s, recv_fmtp=%s", linphone_payload_type_get_send_fmtp(pt),
linphone_payload_type_get_recv_fmtp(pt));
BC_ASSERT_PTR_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode"));
BC_ASSERT_PTR_NULL(strstr(linphone_payload_type_get_recv_fmtp(pt), "packetization-mode"));
}
}
end_call(marie, pauline);
end:
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
if (pt_1) payload_type_destroy(pt_1);
if (pt_2) payload_type_destroy(pt_2);
}
#endif
static void call_failed_because_of_codecs(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneCall *out_call;
disable_all_audio_codecs_except_one(marie->lc, "pcmu", -1);
disable_all_audio_codecs_except_one(pauline->lc, "pcma", -1);
out_call = linphone_core_invite_address(pauline->lc, marie->identity);
linphone_call_ref(out_call);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallOutgoingInit, 1));
/*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallError, 1, 7000));
BC_ASSERT_EQUAL(linphone_call_get_reason(out_call), LinphoneReasonNotAcceptable, int, "%d");
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d");
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased, 0, int, "%d");
linphone_call_unref(out_call);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void profile_call_base(bool_t avpf1,
LinphoneMediaEncryption srtp1,
bool_t avpf2,
LinphoneMediaEncryption srtp2,
bool_t encryption_mandatory,
const char *expected_profile,
bool_t enable_video) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneProxyConfig *lpc;
const LinphoneCallParams *params;
if (avpf1) {
lpc = linphone_core_get_default_proxy_config(marie->lc);
linphone_proxy_config_edit(lpc);
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
linphone_proxy_config_set_avpf_mode(lpc, LinphoneAVPFEnabled);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
linphone_proxy_config_done(lpc);
}
if (avpf2) {
lpc = linphone_core_get_default_proxy_config(pauline->lc);
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_avpf_mode(lpc, LinphoneAVPFEnabled);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
linphone_proxy_config_done(lpc);
}
if (encryption_mandatory) {
linphone_core_set_media_encryption_mandatory(marie->lc, TRUE);
linphone_core_set_media_encryption_mandatory(pauline->lc, TRUE);
}
if (enable_video && linphone_core_video_supported(marie->lc)) {
LinphoneVideoPolicy policy;
policy.automatically_accept = TRUE;
policy.automatically_initiate = TRUE;
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_set_video_policy(marie->lc, &policy);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
linphone_core_set_video_policy(pauline->lc, &policy);
}
if (linphone_core_media_encryption_supported(marie->lc, srtp1)) {
linphone_core_set_media_encryption(marie->lc, srtp1);
} else {
ms_message("Unsupported [%s] encryption type, cannot test", linphone_media_encryption_to_string(srtp1));
goto end;
}
if (linphone_core_media_encryption_supported(pauline->lc, srtp2)) {
linphone_core_set_media_encryption(pauline->lc, srtp2);
} else {
ms_message("Unsupported [%s] encryption type, cannot test", linphone_media_encryption_to_string(srtp2));
goto end;
}
if (!BC_ASSERT_TRUE(call(marie, pauline))) goto end;
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); /*wait 1 second for streams to start flowing*/
if (linphone_core_get_current_call(marie->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
if (linphone_core_get_current_call(pauline->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
linphone_core_terminate_all_calls(marie->lc);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1, int, "%d");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1, int, "%d");
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
#ifdef VIDEO_ENABLED
/*This test simulates a case where an audio/video call is sent with AVPF only for video, not audio. */
static void avp_avpf_video_call(void) {
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneProxyConfig *lpc;
const LinphoneCallParams *params;
const char *expected_profile = "RTP/AVPF";
linphone_config_set_bool(linphone_core_get_config(marie->lc), "misc", "no_avpf_for_audio", TRUE);
lpc = linphone_core_get_default_proxy_config(marie->lc);
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_avpf_mode(lpc, LinphoneAVPFEnabled);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
linphone_proxy_config_done(lpc);
lpc = linphone_core_get_default_proxy_config(pauline->lc);
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_avpf_mode(lpc, LinphoneAVPFEnabled);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
linphone_proxy_config_done(lpc);
if (linphone_core_video_supported(marie->lc)) {
LinphoneVideoPolicy policy;
policy.automatically_accept = TRUE;
policy.automatically_initiate = TRUE;
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_set_video_policy(marie->lc, &policy);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
linphone_core_set_video_policy(pauline->lc, &policy);
}
if (!BC_ASSERT_TRUE(call(marie, pauline))) goto end;
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); /*wait 1 second for streams to start flowing*/
if (linphone_core_get_current_call(marie->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
if (linphone_core_get_current_call(pauline->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
BC_ASSERT_TRUE(linphone_call_params_audio_enabled(
linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
BC_ASSERT_TRUE(linphone_call_params_audio_enabled(
linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
linphone_core_terminate_all_calls(marie->lc);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1, int, "%d");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1, int, "%d");
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
#endif
static void profile_call(bool_t avpf1,
LinphoneMediaEncryption srtp1,
bool_t avpf2,
LinphoneMediaEncryption srtp2,
const char *expected_profile,
bool_t enable_video) {
profile_call_base(avpf1, srtp1, avpf2, srtp2, FALSE, expected_profile, enable_video);
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
}
static void avp_to_avp_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void avp_to_avp_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVP", TRUE);
}
#endif
static void avp_to_avpf_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void avp_to_avpf_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVP", TRUE);
}
#endif
static void avp_to_savp_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void avp_to_savp_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVP", TRUE);
}
#endif
static void avp_to_savpf_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void avp_to_savpf_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVP", TRUE);
}
#endif
static void avpf_to_avp_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void avpf_to_avp_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVPF", TRUE);
}
#endif
static void avpf_to_avpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void avpf_to_avpf_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVPF", TRUE);
}
#endif
static void avpf_to_savp_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void avpf_to_savp_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVPF", TRUE);
}
#endif
static void avpf_to_savpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void avpf_to_savpf_video_call(void) {
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVPF", TRUE);
}
#endif
static void savp_to_avp_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void savp_to_avp_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVP", TRUE);
}
#endif
static void savp_to_avpf_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void savp_to_avpf_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVP", TRUE);
}
#endif
static void savp_to_savp_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void savp_to_savp_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVP", TRUE);
}
#endif
static void savp_to_savpf_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVP", FALSE);
}
#ifdef VIDEO_ENABLED
static void savp_to_savpf_video_call(void) {
profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVP", TRUE);
}
#endif
static void savpf_to_avp_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_to_avp_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVPF", TRUE);
}
#endif
static void savpf_to_avpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_to_avpf_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVPF", TRUE);
}
#endif
static void savpf_to_savp_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_to_savp_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF", TRUE);
}
#endif
static void savpf_to_savpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
static void savpf_to_savpf_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF", TRUE);
}
#endif
static void savpf_dtls_to_savpf_dtls_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, "UDP/TLS/RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_dtls_to_savpf_dtls_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, "UDP/TLS/RTP/SAVPF", TRUE);
}
#endif
static void savpf_dtls_to_savpf_dtls_encryption_mandatory_call(void) {
profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, TRUE, "UDP/TLS/RTP/SAVPF",
FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_dtls_to_savpf_dtls_encryption_mandatory_video_call(void) {
profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, TRUE, "UDP/TLS/RTP/SAVPF",
TRUE);
}
#endif
static void savpf_dtls_to_savpf_encryption_mandatory_call(void) {
/*profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, TRUE,
* "UDP/TLS/RTP/SAVPF",FALSE); not sure of result*/
}
#ifdef VIDEO_ENABLED
static void savpf_dtls_to_savpf_encryption_mandatory_video_call(void) {
/*profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, TRUE,
* "UDP/TLS/RTP/SAVPF",TRUE); not sure of result*/
}
#endif
static void savpf_dtls_to_savpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, "UDP/TLS/RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_dtls_to_savpf_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, "UDP/TLS/RTP/SAVPF", TRUE);
}
#endif
static void savpf_dtls_to_avpf_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionNone, "UDP/TLS/RTP/SAVPF", FALSE);
}
#ifdef VIDEO_ENABLED
static void savpf_dtls_to_avpf_video_call(void) {
profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionNone, "UDP/TLS/RTP/SAVPF", TRUE);
}
#endif
#ifdef VIDEO_ENABLED
static OrtpPayloadType *configure_core_for_avpf_and_video(LinphoneCore *lc) {
LinphoneProxyConfig *lpc;
OrtpPayloadType *pt;
LinphoneVideoPolicy policy = {0};
policy.automatically_initiate = TRUE;
policy.automatically_accept = TRUE;
lpc = linphone_core_get_default_proxy_config(lc);
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_avpf_mode(lpc, LinphoneAVPFEnabled);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
linphone_proxy_config_done(lpc);
linphone_core_set_video_device(lc, "StaticImage: Static picture");
linphone_core_enable_video_capture(lc, TRUE);
linphone_core_enable_video_display(lc, TRUE);
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
linphone_core_set_video_policy(lc, &policy);
pt = linphone_core_find_payload_type(lc, "VP8", 90000, -1);
if (pt == NULL) {
ms_warning("VP8 codec not available.");
} else {
disable_all_video_codecs_except_one(lc, "VP8");
}
return pt;
}
static void check_avpf_features(LinphoneCore *lc, unsigned char expected_features) {
LinphoneCall *lcall = linphone_core_get_current_call(lc);
BC_ASSERT_PTR_NOT_NULL(lcall);
if (lcall != NULL) {
SalMediaDescription *resultDesc = _linphone_call_get_result_desc(lcall);
const auto &desc = resultDesc->findStream(SalProtoRtpAvpf, SalVideo);
BC_ASSERT_TRUE(desc != Utils::getEmptyConstRefObject<SalStreamDescription>());
if (desc != Utils::getEmptyConstRefObject<SalStreamDescription>()) {
const auto &payloads = desc.getPayloads();
BC_ASSERT_FALSE(payloads.empty());
if (!payloads.empty()) {
PayloadType *pt = payloads.front();
BC_ASSERT_STRING_EQUAL(pt->mime_type, "VP8");
BC_ASSERT_EQUAL(pt->avpf.features, expected_features, int, "%d");
}
}
}
}
static void compatible_avpf_features(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
OrtpPayloadType *pt;
bool_t call_ok;
if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end;
pt = configure_core_for_avpf_and_video(pauline->lc);
BC_ASSERT_TRUE((call_ok = call(marie, pauline)));
if (!call_ok) goto end;
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); /*wait 1 second for streams to start flowing*/
check_avpf_features(marie->lc, pt->avpf.features);
check_avpf_features(pauline->lc, pt->avpf.features);
end_call(marie, pauline);
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
static void incompatible_avpf_features(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
OrtpPayloadType *pt;
bool_t call_ok;
if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end;
pt = configure_core_for_avpf_and_video(pauline->lc);
pt->avpf.features = PAYLOAD_TYPE_AVPF_NONE;
BC_ASSERT_TRUE(call_ok = call(marie, pauline));
if (!call_ok) goto end;
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); /*wait 1 second for streams to start flowing*/
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
check_avpf_features(marie->lc, PAYLOAD_TYPE_AVPF_NONE);
check_avpf_features(pauline->lc, PAYLOAD_TYPE_AVPF_NONE);
end_call(marie, pauline);
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
static void call_with_two_audio_streams(void) {
const char *crashing_invite =
"INVITE sip:631453@212.55.48.36:51230;transport=udp SIP/2.0\r\n"
"Via: SIP/2.0/UDP 212.55.48.2:5060;branch=z9hG4bKac1473882254\r\n"
"Max-Forwards: 19\r\n"
"From: \"Mickey Mouse\" <sip:mickey@example.com;user=phone>;tag=1c849167855\r\n"
"To: \"Bugs Bunny\" <sip:bunny@example.com>\r\n"
"Call-ID: 9771187781832022142418@212.55.48.2\r\n"
"CSeq: 1 INVITE\r\n"
"Contact: <sip:212.55.48.2:5060>\r\n"
"Supported: 100rel,sdp-anat\r\n"
"Allow: ACK,BYE,CANCEL,INFO,INVITE,OPTIONS,PRACK,REFER,NOTIFY,UPDATE\r\n"
"User-Agent: vSBC PROD/v.7.20A.258.459\r\n"
"Accept:application/media_control+xml,application/sdp,multipart/mixed\r\n"
"Recv-Info:x-broadworks-client-session-info\r\n"
"Content-Type: application/sdp\r\n"
"Content-Length: 860\r\n"
"\r\n"
"v=0\r\n"
"o=BroadWorks 1693848685 415741525 IN IP4 212.55.48.2\r\n"
"s=-\r\n"
"c=IN IP4 212.55.48.2\r\n"
"t=0 0\r\n"
"m=audio 15536 RTP/AVP 8 0 18 116\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:116 telephone-event/8000\r\n"
"a=ptime:20\r\n"
"a=3gOoBTC\r\n"
"a=rtpmap:18 G729/8000\r\n"
"a=fmtp:18 annexb=yes\r\n"
"m=audio 15536 RTP/SAVP 8 0 18 116\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:116 telephone-event/8000\r\n"
"a=ptime:20\r\n"
"a=3gOoBTC\r\n"
"a=rtpmap:18 G729/8000\r\n"
"a=fmtp:18 annexb=yes\r\n"
"a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:zc409/eT1JuwUPQAswLkF878WJvn5Rpo+aLUt+SI|2^31\r\n"
"a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:ebHN/WPPcu2E+Jm4kdx9YK58jVFDKD4uRgwFu18k|2^31\r\n"
"a=crypto:3 AES_256_CM_HMAC_SHA1_80 "
"inline:M9UR+6n8F8DZ5mh/V5vh2VKdYZ+5Hb4K3mwepx8oM9aIQYb7RzdfJE42ezOTcQ==|2^31\r\n"
"a=crypto:4 AES_256_CM_HMAC_SHA1_32 "
"inline:AIsXIk2O8tsCefUYXpqP96hNZKJR+nJZcXlCOiXZW6TDEtg/g5HQD7lcj0KJPA==|2^31\r\n";
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc_udp");
LinphoneTransports *tp = linphone_core_get_transports_used(laure->lc);
BC_ASSERT_TRUE(liblinphone_tester_send_data(crashing_invite, strlen(crashing_invite), "127.0.0.1",
linphone_transports_get_udp_port(tp), SOCK_DGRAM) > 0);
linphone_transports_unref(tp);
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallIncomingReceived, 1));
LinphoneCall *laure_call = linphone_core_get_current_call(laure->lc);
BC_ASSERT_PTR_NOT_NULL(laure_call);
if (laure_call) {
linphone_call_accept(laure_call);
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallStreamsRunning, 1));
const LinphoneCallParams *laure_call_param = linphone_call_get_current_params(laure_call);
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
const LinphoneMediaEncryption laure_enc = linphone_call_params_get_media_encryption(laure_call_param);
BC_ASSERT_EQUAL(laure_enc, LinphoneMediaEncryptionNone, int, "%d");
linphone_call_terminate(laure_call);
}
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for_until(laure->lc, NULL, &laure->stat.number_of_LinphoneCallReleased, 1, 36000));
linphone_core_manager_destroy(laure);
}
static void _call_with_unknown_stream(bool_t accepted, bool_t unknown_at_end) {
const char *unsupported_invite_base =
"INVITE sip:3827m@192.168.50.222:54989;transport=udp SIP/2.0\r\n"
"Via: SIP/2.0/UDP 5.135.31.160:5060;branch=z9hG4bKsAOMEtSQmuUlZRFV268653\r\n"
"Accept-Language: en\r\n"
"Call-ID: 20220209215755041746-3e68c7f9f40b7da9df92cf4b0e08742e\r\n"
"Contact: <sip:5.135.31.160:5060;transport=udp>\r\n"
"CSeq: 201 INVITE\r\n"
"From: \"Donald duck\" <sip:7956@example.com>;tag=gOobZHXFNJsMD6aT268645\r\n"
"Max-Forwards: 19\r\n"
"To: <sip:mickey@example.com>\r\n"
"Date: Wed, 09 Feb 2022 21:57:58 GMT\r\n"
"Server: unknown server\r\n"
"Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,INFO,MESSAGE,SUBSCRIBE,NOTIFY,PRACK,UPDATE,REFER\r\n"
"Allow-Events: conference,talk,hold\r\n"
"Supported: timer\r\n"
"Content-Type: application/sdp\r\n"
"Content-Length: 908\r\n"
"\r\n"
"v=0\r\n"
"o=PouetPouet_Tra 1644443875 1644443878181 IN IP4 5.135.31.160\r\n"
"s=kokokok IP Phone\r\n"
"c=IN IP4 5.135.31.160\r\n"
"b=AS:2048\r\n"
"t=0 0\r\n"
"a=sendrecv\r\n"
"m=audio 26192 RTP/AVP 0 8 9 18 101\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:8 PCMA/8000\r\n"
"a=rtpmap:9 G722/8000\r\n"
"a=rtpmap:18 G729/8000\r\n"
"a=fmtp:18 annexb=no\r\n"
"a=rtpmap:101 telephone-event/8000\r\n";
const char *application_stream_sdp = "m=application 2244 RTP/AVP 124\r\n"
"a=rtpmap:124 H224/4800\r\n";
const char *video_stream_sdp =
"m=video 26592 RTP/AVP 100 113 109 99\r\n"
"a=rtcp-fb:* ccm fir\r\n"
"a=rtpmap:100 H264/90000\r\n"
"a=fmtp:100 profile-level-id=64001f; packetization-mode=1; max-mbps=108000; max-fs=3600\r\n"
"a=rtpmap:113 H264/90000\r\n"
"a=fmtp:113 profile-level-id=64001f; packetization-mode=0; max-mbps=108000; max-fs=3600\r\n"
"a=rtpmap:109 H264/90000\r\n"
"a=fmtp:109 profile-level-id=42801f; packetization-mode=1; max-mbps=108000; max-fs=3600\r\n"
"a=rtpmap:99 H264/90000\r\n"
"a=fmtp:99 profile-level-id=42801f; packetization-mode=0; max-mbps=108000; max-fs=3600\r\n"
"a=rtcp-fb:* ccm fir\r\n";
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc_udp");
LinphoneTransports *tp = linphone_core_get_transports_used(laure->lc);
char *unsupported_invite;
if (unknown_at_end) {
unsupported_invite =
bctbx_strdup_printf("%s%s%s", unsupported_invite_base, video_stream_sdp, application_stream_sdp);
} else {
unsupported_invite =
bctbx_strdup_printf("%s%s%s", unsupported_invite_base, application_stream_sdp, video_stream_sdp);
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
}
BC_ASSERT_TRUE(liblinphone_tester_send_data(unsupported_invite, strlen(unsupported_invite), "127.0.0.1",
linphone_transports_get_udp_port(tp), SOCK_DGRAM) > 0);
linphone_transports_unref(tp);
bctbx_free(unsupported_invite);
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallIncomingReceived, 1));
if (accepted) {
linphone_call_accept(linphone_core_get_current_call(laure->lc));
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallStreamsRunning, 1));
auto resultDesc = _linphone_call_get_result_desc(linphone_core_get_current_call(laure->lc));
std::string streamType = resultDesc->getStreamIdx(unknown_at_end ? 2 : 1).getTypeAsString();
BC_ASSERT_STRING_EQUAL(streamType.c_str(), "application");
linphone_call_terminate(linphone_core_get_current_call(laure->lc));
} else {
linphone_call_decline(linphone_core_get_current_call(laure->lc), LinphoneReasonDeclined);
}
BC_ASSERT_TRUE(wait_for(laure->lc, NULL, &laure->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for_until(laure->lc, NULL, &laure->stat.number_of_LinphoneCallReleased, 1, 36000));
linphone_core_manager_destroy(laure);
}
static void call_with_unknown_stream(void) {
_call_with_unknown_stream(FALSE, FALSE);
}
static void call_with_unknown_stream_accepted(void) {
_call_with_unknown_stream(TRUE, FALSE);
}
static void call_with_unknown_stream_accepted_2(void) {
_call_with_unknown_stream(TRUE, TRUE);
}
static void activate_video_and_ice(LinphoneCoreManager *m) {
LinphoneVideoActivationPolicy *pol = linphone_factory_create_video_activation_policy(linphone_factory_get());
LinphoneNatPolicy *nat_policy;
LinphoneAccountParams *account_params;
LinphoneAccount *account;
linphone_video_activation_policy_set_automatically_initiate(pol, TRUE);
linphone_video_activation_policy_set_automatically_accept(pol, TRUE);
linphone_core_set_video_activation_policy(m->lc, pol);
linphone_video_activation_policy_unref(pol);
linphone_core_enable_video_capture(m->lc, TRUE);
linphone_core_enable_video_display(m->lc, TRUE);
nat_policy = linphone_core_create_nat_policy(m->lc);
linphone_nat_policy_enable_ice(nat_policy, TRUE);
account = linphone_core_get_default_account(m->lc);
account_params = linphone_account_params_clone(linphone_account_get_params(account));
linphone_account_params_set_nat_policy(account_params, nat_policy);
linphone_account_set_params(account, account_params);
linphone_account_params_unref(account_params);
linphone_nat_policy_unref(nat_policy);
linphone_core_set_video_device(m->lc, liblinphone_tester_static_image_id);
}
static bool_t codec_appears_first(LinphoneCore *lc, const char *codec) {
bctbx_list_t *codec_list = linphone_core_get_video_payload_types(lc);
LinphonePayloadType *pt = (LinphonePayloadType *)codec_list->data;
bool_t ret = strcasecmp(codec, linphone_payload_type_get_mime_type(pt)) == 0;
bctbx_list_free_with_data(codec_list, (bctbx_list_free_func)linphone_payload_type_unref);
return ret;
}
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
static const char *call_selected_codec(LinphoneCall *call) {
const LinphoneCallParams *current_params = linphone_call_get_current_params(call);
const LinphonePayloadType *pt = linphone_call_params_get_used_video_payload_type(current_params);
if (BC_ASSERT_PTR_NOT_NULL(pt)) {
return linphone_payload_type_get_mime_type(pt);
}
return "";
}
static void check_linphonerc_config(const char *rcfile) {
char *path = bc_tester_res(rcfile);
if (BC_ASSERT_PTR_NOT_NULL(path)) {
LinphoneConfig *config = linphone_factory_create_config(linphone_factory_get(), path);
if (BC_ASSERT_PTR_NOT_NULL(config)) {
BC_ASSERT_STRING_EQUAL(linphone_config_get_string(config, "video", "codec_priority_policy", "unset"),
"unset");
linphone_config_unref(config);
}
bc_free(path);
}
}
static void call_with_video_codec_priority_policy(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphonePayloadType *vp8, *av1;
LinphoneCall *marie_call, *pauline_call;
vp8 = linphone_core_get_payload_type(pauline->lc, "VP8", 90000, -1);
av1 = linphone_core_get_payload_type(pauline->lc, "AV1", 90000, -1);
if (!vp8 || !av1) {
ms_warning("This test requires both VP8 and AV1 video codecs, skipped.");
goto end;
}
activate_video_and_ice(marie);
activate_video_and_ice(pauline);
/* Make sure that configuration files do not mention codec_priority_policy.*/
check_linphonerc_config("rcfiles/marie_rc");
check_linphonerc_config("rcfiles/pauline_tcp_rc");
/* PolicyAuto is the default one. However Marie has a video codec list defined, so in absence of
[video]video_priority_policy item written in its configuration file, we must assume it is using the basic policy.
*/
BC_ASSERT_TRUE(linphone_core_get_video_codec_priority_policy(marie->lc) == LinphoneCodecPriorityPolicyBasic);
BC_ASSERT_TRUE(linphone_core_get_video_codec_priority_policy(pauline->lc) == LinphoneCodecPriorityPolicyAuto);
BC_ASSERT_TRUE(codec_appears_first(marie->lc, "AV1"));
BC_ASSERT_TRUE(codec_appears_first(pauline->lc, "AV1"));
/* this is to force to re-compute the codec list order: */
linphone_core_set_video_codec_priority_policy(pauline->lc, LinphoneCodecPriorityPolicyBasic);
/* AV1 is before VP8 by default. Give an artificial bonus to VP8. Normally this is done at startup*/
linphone_payload_type_set_priority_bonus(vp8, TRUE); // this function is not public, apps should not do this.
linphone_core_set_video_codec_priority_policy(pauline->lc, LinphoneCodecPriorityPolicyAuto);
/* now vp8 shall appear first */
BC_ASSERT_TRUE(codec_appears_first(pauline->lc, "VP8"));
marie_call = linphone_core_invite_address(marie->lc, pauline->identity);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1));
pauline_call = linphone_core_get_current_call(pauline->lc);
if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end;
linphone_call_accept(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_STRING_EQUAL(call_selected_codec(marie_call), "VP8");
BC_ASSERT_STRING_EQUAL(call_selected_codec(pauline_call), "VP8");
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
/* Now comes the ICE re-INVITE */
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2));
/* Assert that the ICE re-invite did not change the selected codec */
BC_ASSERT_STRING_EQUAL(call_selected_codec(marie_call), "VP8");
BC_ASSERT_STRING_EQUAL(call_selected_codec(pauline_call), "VP8");
wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000);
linphone_call_terminate(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
/* Assert the priority policy for pauline is now set */
BC_ASSERT_STRING_EQUAL(
linphone_config_get_string(linphone_core_get_config(pauline->lc), "video", "codec_priority_policy", "unset"),
"1");
end:
if (av1) linphone_payload_type_unref(av1);
if (vp8) linphone_payload_type_unref(vp8);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
#endif
static test_t offeranswer_tests[] = {
TEST_NO_TAG("Start with no config", start_with_no_config),
TEST_NO_TAG("Call failed because of codecs", call_failed_because_of_codecs),
TEST_NO_TAG("Simple call with different codec mappings and config-supplied sdp address",
simple_call_with_different_codec_mappings_and_config_supplied_sdp_addresses),
TEST_NO_TAG("Simple call with fmtps", simple_call_with_fmtps),
TEST_NO_TAG("AVP to AVP call", avp_to_avp_call),
TEST_NO_TAG("AVP to AVPF call", avp_to_avpf_call),
TEST_NO_TAG("AVP to SAVP call", avp_to_savp_call),
TEST_NO_TAG("AVP to SAVPF call", avp_to_savpf_call),
TEST_NO_TAG("AVPF to AVP call", avpf_to_avp_call),
TEST_NO_TAG("AVPF to AVPF call", avpf_to_avpf_call),
TEST_NO_TAG("AVPF to SAVP call", avpf_to_savp_call),
TEST_NO_TAG("AVPF to SAVPF call", avpf_to_savpf_call),
TEST_NO_TAG("SAVP to AVP call", savp_to_avp_call),
TEST_NO_TAG("SAVP to AVPF call", savp_to_avpf_call),
TEST_NO_TAG("SAVP to SAVP call", savp_to_savp_call),
TEST_NO_TAG("SAVP to SAVPF call", savp_to_savpf_call),
TEST_NO_TAG("SAVPF to AVP call", savpf_to_avp_call),
TEST_NO_TAG("SAVPF to AVPF call", savpf_to_avpf_call),
TEST_NO_TAG("SAVPF to SAVP call", savpf_to_savp_call),
TEST_NO_TAG("SAVPF to SAVPF call", savpf_to_savpf_call),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF/DTLS call", savpf_dtls_to_savpf_dtls_call, "DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF/DTLS encryption mandatory call",
savpf_dtls_to_savpf_dtls_encryption_mandatory_call,
"DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF call", savpf_dtls_to_savpf_call, "DTLS"),
TEST_ONE_TAG(
"SAVPF/DTLS to SAVPF encryption mandatory call", savpf_dtls_to_savpf_encryption_mandatory_call, "DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to AVPF call", savpf_dtls_to_avpf_call, "DTLS"),
#ifdef VIDEO_ENABLED
TEST_NO_TAG("AVP to AVP video call", avp_to_avp_video_call),
TEST_NO_TAG("AVP to AVPF video call", avp_to_avpf_video_call),
TEST_NO_TAG("AVP to SAVP video call", avp_to_savp_video_call),
TEST_NO_TAG("AVP to SAVPF video call", avp_to_savpf_video_call),
TEST_NO_TAG("AVPF to AVP video call", avpf_to_avp_video_call),
TEST_NO_TAG("AVPF to AVPF video call", avpf_to_avpf_video_call),
TEST_NO_TAG("AVPF to SAVP video call", avpf_to_savp_video_call),
TEST_NO_TAG("AVPF to SAVPF video call", avpf_to_savpf_video_call),
TEST_NO_TAG("SAVP to AVP video call", savp_to_avp_video_call),
TEST_NO_TAG("SAVP to AVPF video call", savp_to_avpf_video_call),
TEST_NO_TAG("SAVP to SAVP video call", savp_to_savp_video_call),
TEST_NO_TAG("SAVP to SAVPF video call", savp_to_savpf_video_call),
126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
TEST_NO_TAG("SAVPF to AVP video call", savpf_to_avp_video_call),
TEST_NO_TAG("SAVPF to AVPF video call", savpf_to_avpf_video_call),
TEST_NO_TAG("SAVPF to SAVP video call", savpf_to_savp_video_call),
TEST_NO_TAG("SAVPF to SAVPF video call", savpf_to_savpf_video_call),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF/DTLS video call", savpf_dtls_to_savpf_dtls_video_call, "DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF/DTLS encryption mandatory video call",
savpf_dtls_to_savpf_dtls_encryption_mandatory_video_call,
"DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF video call", savpf_dtls_to_savpf_video_call, "DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to SAVPF encryption mandatory video call",
savpf_dtls_to_savpf_encryption_mandatory_video_call,
"DTLS"),
TEST_ONE_TAG("SAVPF/DTLS to AVPF video call", savpf_dtls_to_avpf_video_call, "DTLS"),
TEST_NO_TAG("Compatible AVPF features", compatible_avpf_features),
TEST_NO_TAG("Incompatible AVPF features", incompatible_avpf_features),
TEST_NO_TAG("H264 packetization-mode set to 1 on sender", h264_call_with_fmtps),
TEST_NO_TAG("H264 on sender, but not on receiver", h264_call_receiver_with_no_h264_support),
TEST_NO_TAG("H264 packetization-mode not set", h264_call_without_packetization_mode),
TEST_NO_TAG("Mixed AVP+AVPF video call", avp_avpf_video_call),
TEST_NO_TAG("flexfec both proposed both accepted", flexfec_test_both_proposed_both_accepted),
TEST_NO_TAG("flexfec both proposed bundle accepted", flexfec_test_both_proposed_bundle_accepted),
TEST_NO_TAG("flexfec both proposed nothing accepted", flexfec_test_both_proposed_nothing_accepted),
TEST_NO_TAG("flexfec both proposed only fec accepted", flexfec_test_both_poposed_only_fec_accepted),
TEST_NO_TAG("flexfec only fec proposed and accepted", flexfec_test_only_fec_proposed_and_accepted),
TEST_NO_TAG("Call with unknown stream", call_with_unknown_stream),
TEST_NO_TAG("Call with unknown stream, accepted", call_with_unknown_stream_accepted),
TEST_NO_TAG("Call with unknown stream, accepted 2", call_with_unknown_stream_accepted_2),
TEST_NO_TAG("Call with 2 audio streams", call_with_two_audio_streams),
TEST_NO_TAG("Call with video codec priority policy auto", call_with_video_codec_priority_policy)
#endif
};
test_suite_t offeranswer_test_suite = {"Offer-answer",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
sizeof(offeranswer_tests) / sizeof(offeranswer_tests[0]),
offeranswer_tests,
0};