offeranswer_tester.cpp 55.67 KiB
/*
 * 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));