From a281b1408fc3b5009704ada135542579410d7670 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 1 Apr 2017 14:37:20 +0200 Subject: [PATCH 1/7] don't enable c++11, as it is used yet. This breaks compilation on centos6. --- configure.ac | 1 - daemon/commands/register-info.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d1f999db8..0a61de025 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,6 @@ case $target in esac -CXXFLAGS="${CXXFLAGS} -std=c++11" AM_CONDITIONAL(BUILD_IOS, test x$ios_found = xyes) diff --git a/daemon/commands/register-info.cc b/daemon/commands/register-info.cc index 67e6ad12f..681d894e3 100644 --- a/daemon/commands/register-info.cc +++ b/daemon/commands/register-info.cc @@ -92,7 +92,7 @@ void RegisterInfoCommand::exec(Daemon *app, const std::string& args) { } else { int id; try { - id = std::stoi(param); + id = atoi(param.c_str()); } catch (std::invalid_argument) { app->sendResponse(Response("Invalid ID.", Response::Error)); return; From 123678b92218bab33f4c37d7c5a3a4db858c7c15 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 1 Apr 2017 14:39:21 +0200 Subject: [PATCH 2/7] fix specfile --- linphone.spec.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linphone.spec.in b/linphone.spec.in index ca4d43a62..d0a721233 100644 --- a/linphone.spec.in +++ b/linphone.spec.in @@ -79,7 +79,7 @@ rm -rf $RPM_BUILD_ROOT %files -f %{name}.lang %defattr(-,root,root) -%doc AUTHORS ChangeLog COPYING NEWS README TODO +%doc AUTHORS ChangeLog COPYING NEWS README.md TODO %{_bindir}/linphone %{_bindir}/linphonec %{_bindir}/linphonecsh From 5e02b53ee66b73e64bfc41e6ac2ed74296f42f60 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 3 Apr 2017 10:54:09 +0200 Subject: [PATCH 3/7] update mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 1e4c039d3..954652074 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1e4c039d348a28cb9fffbcf7beb966976d1add19 +Subproject commit 954652074fd168323c0846d6d8cd6c5b4d859d75 From 351bb97027851aa41ec23c92544ee9a9ad2feaa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Fri, 31 Mar 2017 15:23:36 +0200 Subject: [PATCH 4/7] Reworking of Liblinphone's API around payload types --- coreapi/CMakeLists.txt | 1 + coreapi/call_params.c | 18 +- coreapi/help/CMakeLists.txt | 6 +- coreapi/linphonecall.c | 2 +- coreapi/linphonecore.c | 82 +++++-- coreapi/misc.c | 114 +--------- coreapi/payload_type.c | 307 ++++++++++++++++++++++++++ coreapi/private.h | 16 +- coreapi/quality_reporting.c | 6 +- daemon/commands/audio-codec-set.cc | 4 +- daemon/commands/audio-stream-start.cc | 2 +- daemon/daemon.cc | 4 +- gtk/propertybox.c | 4 +- include/linphone/call_params.h | 55 ++++- include/linphone/core.h | 157 ++++++++++--- include/linphone/payload_type.h | 134 +++++++++-- include/linphone/types.h | 12 +- tester/call_single_tester.c | 2 +- tester/offeranswer_tester.c | 32 +-- wrappers/cpp/abstractapi.py | 1 - 20 files changed, 718 insertions(+), 241 deletions(-) create mode 100644 coreapi/payload_type.c diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index d3d1f6401..2778102aa 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -102,6 +102,7 @@ set(LINPHONE_SOURCE_FILES_C misc.c nat_policy.c offeranswer.c + payload_type.c player.c presence.c proxy.c diff --git a/coreapi/call_params.c b/coreapi/call_params.c index 6cd19b464..568dc0b80 100644 --- a/coreapi/call_params.c +++ b/coreapi/call_params.c @@ -213,15 +213,27 @@ const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp){ return cp->session_name; } -const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) { +LinphonePayloadType *linphone_call_params_get_used_audio_payload_type(const LinphoneCallParams *cp) { + return cp->audio_codec ? linphone_payload_type_new(NULL, cp->audio_codec) : NULL; +} + +LinphonePayloadType *linphone_call_params_get_used_video_payload_type(const LinphoneCallParams *cp) { + return cp->video_codec ? linphone_payload_type_new(NULL, cp->video_codec) : NULL; +} + +LinphonePayloadType *linphone_call_params_get_used_text_payload_type(const LinphoneCallParams *cp) { + return cp->text_codec ? linphone_payload_type_new(NULL, cp->text_codec) : NULL; +} + +const OrtpPayloadType *linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) { return cp->audio_codec; } -const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) { +const OrtpPayloadType *linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) { return cp->video_codec; } -const LinphonePayloadType* linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp) { +const OrtpPayloadType *linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp) { return cp->text_codec; } diff --git a/coreapi/help/CMakeLists.txt b/coreapi/help/CMakeLists.txt index 5520284fc..20409bcc4 100644 --- a/coreapi/help/CMakeLists.txt +++ b/coreapi/help/CMakeLists.txt @@ -27,14 +27,14 @@ if (ENABLE_DOC OR CXX_WRAPPER) set(top_srcdir "${CMAKE_CURRENT_LIST_DIR}/../../") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) set(DOC_INPUT_FILES ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile - ${LINPHONE_HEADER_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.dox + ${LINPHONE_HEADER_FILES} ) - add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html" + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml/index.xml" COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile DEPENDS ${DOC_INPUT_FILES} ) - add_custom_target(linphone-doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html") + add_custom_target(linphone-doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml/index.xml") install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doc/html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/linphone-${LINPHONE_VERSION}") else() diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b3d7a4c80..d1c413301 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -513,7 +513,7 @@ static bctbx_list_t *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, pt->mime_type,pt->clock_rate,hints->bandwidth_limit); continue; } - if (!linphone_core_check_payload_type_usability(lc,pt)){ + if (!_linphone_core_check_payload_type_usability(lc, pt)) { continue; } pt=payload_type_clone(pt); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 9fe02609f..31b7f1158 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2220,6 +2220,53 @@ void linphone_core_unref(LinphoneCore *lc) { belle_sip_object_unref(BELLE_SIP_OBJECT(lc)); } +static bctbx_list_t *ortp_payloads_to_linphone_payloads(const bctbx_list_t *ortp_payloads, LinphoneCore *lc) { + bctbx_list_t *linphone_payloads = NULL; + for (; ortp_payloads!=NULL; ortp_payloads=bctbx_list_next(ortp_payloads)) { + LinphonePayloadType *pt = linphone_payload_type_new(lc, (OrtpPayloadType *)ortp_payloads->data); + linphone_payloads = bctbx_list_append(linphone_payloads, pt); + } + return linphone_payloads; +} + +static void sort_ortp_pt_list(bctbx_list_t **ortp_pt_list, const bctbx_list_t *linphone_pt_list) { + bctbx_list_t *new_list = NULL; + const bctbx_list_t *it; + for (it=bctbx_list_first_elem(linphone_pt_list); it; it=bctbx_list_next(it)) { + OrtpPayloadType *ortp_pt = linphone_payload_type_get_ortp_pt((LinphonePayloadType *)it->data); + bctbx_list_t *elem = bctbx_list_find(*ortp_pt_list, ortp_pt); + if (elem) { + *ortp_pt_list = bctbx_list_unlink(*ortp_pt_list, elem); + new_list = bctbx_list_append_link(new_list, elem); + } + } + *ortp_pt_list = bctbx_list_prepend_link(*ortp_pt_list, new_list); +} + +bctbx_list_t *linphone_core_get_audio_payload_types(LinphoneCore *lc) { + return ortp_payloads_to_linphone_payloads(lc->codecs_conf.audio_codecs, lc); +} + +void linphone_core_set_audio_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { + sort_ortp_pt_list(&lc->codecs_conf.audio_codecs, payload_types); +} + +bctbx_list_t *linphone_core_get_video_payload_types(LinphoneCore *lc) { + return ortp_payloads_to_linphone_payloads(lc->codecs_conf.video_codecs, lc); +} + +void linphone_core_set_video_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { + sort_ortp_pt_list(&lc->codecs_conf.video_codecs, payload_types); +} + +bctbx_list_t *linphone_core_get_text_payload_types(LinphoneCore *lc) { + return ortp_payloads_to_linphone_payloads(lc->codecs_conf.text_codecs, lc); +} + +void linphone_core_set_text_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { + sort_ortp_pt_list(&lc->codecs_conf.text_codecs, payload_types); +} + const bctbx_list_t *linphone_core_get_audio_codecs(const LinphoneCore *lc) { return lc->codecs_conf.audio_codecs; } @@ -4193,7 +4240,7 @@ void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val){ lp_config_set_int(lc->config,"sound","echocancellation",val); } -bool_t linphone_core_echo_cancellation_enabled(LinphoneCore *lc){ +bool_t linphone_core_echo_cancellation_enabled(const LinphoneCore *lc){ return lc->sound_conf.ec; } @@ -5616,7 +5663,7 @@ void _linphone_core_codec_config_write(LinphoneCore *lc){ lp_config_set_string(lc->config,key,"mime",pt->mime_type); lp_config_set_int(lc->config,key,"rate",pt->clock_rate); lp_config_set_int(lc->config,key,"channels",pt->channels); - lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); + lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt)); index++; } sprintf(key,"audio_codec_%i",index); @@ -5628,7 +5675,7 @@ void _linphone_core_codec_config_write(LinphoneCore *lc){ sprintf(key,"video_codec_%i",index); lp_config_set_string(lc->config,key,"mime",pt->mime_type); lp_config_set_int(lc->config,key,"rate",pt->clock_rate); - lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); + lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt)); lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp); index++; } @@ -6003,8 +6050,8 @@ bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc return (bool_t)lp_config_get_int(lc->config, "sound", "ring_during_incoming_early_media", 0); } -LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { - LinphonePayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); +static OrtpPayloadType* _linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { + OrtpPayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); if (result) { return result; } else { @@ -6022,6 +6069,15 @@ LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const cha return NULL; } +OrtpPayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { + return _linphone_core_find_payload_type(lc, type, rate, channels); +} + +LinphonePayloadType *linphone_core_get_payload_type(LinphoneCore *lc, const char *type, int rate, int channels) { + OrtpPayloadType *pt = _linphone_core_find_payload_type(lc, type, rate, channels); + return pt ? linphone_payload_type_new(lc, pt) : NULL; +} + const char* linphone_configuring_state_to_string(LinphoneConfiguringState cs){ switch(cs){ case LinphoneConfiguringSuccessful: @@ -6444,22 +6500,6 @@ void linphone_core_set_avpf_rr_interval(LinphoneCore *lc, int interval){ lp_config_set_int(lc->config,"rtp","avpf_rr_interval",interval); } -int linphone_payload_type_get_type(const LinphonePayloadType *pt) { - return pt->type; -} - -int linphone_payload_type_get_normal_bitrate(const LinphonePayloadType *pt) { - return pt->normal_bitrate; -} - -const char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt) { - return pt->mime_type; -} - -int linphone_payload_type_get_channels(const LinphonePayloadType *pt) { - return pt->channels; -} - int linphone_core_set_audio_multicast_addr(LinphoneCore *lc, const char* ip) { char* new_value; if (ip && !ms_is_multicast(ip)) { diff --git a/coreapi/misc.c b/coreapi/misc.c index bfcffb9c0..8bf5ab4a4 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "mediastreamer2/mediastream.h" #include #include +#include #ifdef HAVE_SIGHANDLER_T #include #endif /*HAVE_SIGHANDLER_T*/ @@ -62,78 +63,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed); -bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){ - if (bctbx_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || bctbx_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || bctbx_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){ - return payload_type_enabled(pt); - } - ms_error("Getting enablement status of codec not in audio or video list of PayloadType !"); - return FALSE; -} - -bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayloadType *pt) { - return linphone_payload_type_is_vbr(pt); -} - -bool_t linphone_payload_type_is_vbr(const LinphonePayloadType *pt) { - if (pt->type == PAYLOAD_VIDEO) return TRUE; - return !!(pt->flags & PAYLOAD_TYPE_IS_VBR); -} - -int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enabled){ - if (bctbx_list_find(lc->codecs_conf.audio_codecs,pt) || bctbx_list_find(lc->codecs_conf.video_codecs,pt) || bctbx_list_find(lc->codecs_conf.text_codecs,pt)){ - payload_type_set_enable(pt,enabled); - _linphone_core_codec_config_write(lc); - linphone_core_update_allocated_audio_bandwidth(lc); - return 0; - } - ms_error("Enabling codec not in audio or video list of PayloadType !"); - return -1; -} - -int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt) { - return linphone_payload_type_get_number(pt); -} - -int linphone_payload_type_get_number(const LinphonePayloadType *pt) { - return payload_type_get_number(pt); -} - -void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number) { - linphone_payload_type_set_number(pt, number); -} - -void linphone_payload_type_set_number(LinphonePayloadType *pt, int number) { - payload_type_set_number(pt, number); -} - -const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt){ - //if (ms_filter_codec_supported(pt->mime_type)){ - if (ms_factory_codec_supported(lc->factory, pt->mime_type)){ - MSFilterDesc *desc=ms_factory_get_encoder(lc->factory, pt->mime_type); -#ifdef ENABLE_NLS - return dgettext("mediastreamer",desc->text); -#else - return desc->text; -#endif - } - return NULL; -} - -void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate){ - if (bctbx_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || bctbx_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || bctbx_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){ - if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){ - pt->normal_bitrate=bitrate*1000; - pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; - linphone_core_update_allocated_audio_bandwidth(lc); - }else{ - ms_error("Cannot set an explicit bitrate for codec %s/%i, because it is not VBR.",pt->mime_type,pt->clock_rate); - return; - } - } else { - ms_error("linphone_core_set_payload_type_bitrate() payload type not in audio or video list !"); - } -} - /* *((codec-birate*ptime/8) + RTP header + UDP header + IP header)*8/ptime; @@ -184,8 +113,8 @@ static int lookup_vbr_typical_bitrate(int maxbw, int clock_rate){ return 32; } -static int get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt, int maxbw){ - if (linphone_payload_type_is_vbr(pt)){ +int get_audio_payload_bandwidth(const LinphoneCore *lc, const PayloadType *pt, int maxbw) { + if (payload_type_is_vbr(pt)) { if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){ ms_debug("PayloadType %s/%i has bitrate override",pt->mime_type,pt->clock_rate); return pt->normal_bitrate/1000; @@ -194,23 +123,6 @@ static int get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt, }else return (int)ceil(get_audio_payload_bandwidth_from_codec_bitrate(pt)/1000.0);/*rounding codec bandwidth should be avoid, specially for AMR*/ } -int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const LinphonePayloadType *pt){ - int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), - linphone_core_get_upload_bandwidth(lc)); - if (pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED){ - return get_audio_payload_bandwidth(lc,pt,maxbw); - }else if (pt->type==PAYLOAD_VIDEO){ - int video_bw; - if (maxbw<=0) { - video_bw=1500; /*default bitrate for video stream when no bandwidth limit is set, around 1.5 Mbit/s*/ - }else{ - video_bw=get_remaining_bandwidth_for_video(maxbw,lc->audio_bw); - } - return video_bw; - } - return 0; -} - void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt, int maxbw){ call->audio_bw=get_audio_payload_bandwidth(call->core,pt,maxbw); ms_message("Audio bandwidth for this call is %i",call->audio_bw); @@ -238,7 +150,7 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){ } } -bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit){ +bool_t linphone_core_is_payload_type_usable_for_bandwidth(const LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit){ double codec_band; const int video_enablement_limit = 99; bool_t ret=FALSE; @@ -263,24 +175,6 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, cons return ret; } -bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt){ - int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), - linphone_core_get_upload_bandwidth(lc)); - bool_t ret=linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, maxbw); - if ((pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED) - && lc->sound_conf.capt_sndcard - && !(ms_snd_card_get_capabilities(lc->sound_conf.capt_sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) - && linphone_core_echo_cancellation_enabled(lc) - && (pt->clock_rate!=16000 && pt->clock_rate!=8000) - && strcasecmp(pt->mime_type,"opus")!=0 - && ms_factory_lookup_filter_by_name(lc->factory, "MSWebRTCAEC")!=NULL){ - ms_warning("Payload type %s/%i cannot be used because software echo cancellation is required but is unable to operate at this rate.", - pt->mime_type,pt->clock_rate); - ret=FALSE; - } - return ret; -} - bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){ #if !defined(_WIN32_WCE) && !defined(LINPHONE_WINDOWS_UNIVERSAL) FILE *f=popen(command,"r"); diff --git a/coreapi/payload_type.c b/coreapi/payload_type.c new file mode 100644 index 000000000..3584b49c3 --- /dev/null +++ b/coreapi/payload_type.c @@ -0,0 +1,307 @@ +/* +payload_type.c +Copyright (C) 2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include "linphone/payload_type.h" +#include "private.h" + +struct _LinphonePayloadType { + belle_sip_object_t base; + OrtpPayloadType *pt; + LinphoneCore *lc; +}; + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphonePayloadType); +BELLE_SIP_DECLARE_VPTR(LinphonePayloadType); + +LinphonePayloadType *linphone_payload_type_new(LinphoneCore *lc, OrtpPayloadType *ortp_pt) { + LinphonePayloadType *pt; + if (ortp_pt == NULL) return NULL; + pt = belle_sip_object_new(LinphonePayloadType); + pt->pt = ortp_pt; + pt->lc = lc; + return pt; +} + +LinphonePayloadType *linphone_payload_type_ref(LinphonePayloadType *pt) { + return (LinphonePayloadType *)belle_sip_object_ref(pt); +} + +void linphone_payload_type_unref(LinphonePayloadType *pt) { + belle_sip_object_unref(pt); +} + +int linphone_payload_type_get_type(const LinphonePayloadType *pt) { + return pt->pt->type; +} + +static bool_t _payload_type_is_in_core(const OrtpPayloadType *pt, const LinphoneCore *lc) { + return (bctbx_list_find(lc->codecs_conf.audio_codecs, pt) != NULL) + || (bctbx_list_find(lc->codecs_conf.video_codecs, pt) != NULL) + || (bctbx_list_find(lc->codecs_conf.text_codecs, pt) != NULL); +} + +static char *_payload_type_get_description(const OrtpPayloadType *pt) { + return bctbx_strdup_printf("%s/%d/%d", pt->mime_type, pt->clock_rate, pt->channels); +} + +static int _linphone_core_enable_payload_type(LinphoneCore *lc, OrtpPayloadType *pt, bool_t enabled) { + payload_type_set_enable(pt,enabled); + _linphone_core_codec_config_write(lc); + linphone_core_update_allocated_audio_bandwidth(lc); + return 0; +} + +int linphone_core_enable_payload_type(LinphoneCore *lc, OrtpPayloadType *pt, bool_t enabled){ + if (!_payload_type_is_in_core(pt, lc)) { + char *desc = _payload_type_get_description(pt); + ms_error("cannot enable '%s' payload type: not in the core", desc); + bctbx_free(desc); + return -1; + } + return _linphone_core_enable_payload_type(lc, pt, enabled); +} + +int linphone_payload_type_enable(LinphonePayloadType *pt, bool_t enabled) { + if (pt->lc == NULL) { + char *desc = linphone_payload_type_get_description(pt); + ms_error("cannot enable '%s' payload type: no core associated", desc); + bctbx_free(desc); + return -1; + } + return _linphone_core_enable_payload_type(pt->lc, pt->pt, enabled); +} + +bool_t linphone_core_payload_type_enabled(const LinphoneCore *lc, const OrtpPayloadType *pt){ + return payload_type_enabled(pt); +} + +bool_t linphone_payload_type_enabled(const LinphonePayloadType *pt) { + return payload_type_enabled(pt->pt); +} + +char *linphone_payload_type_get_description(const LinphonePayloadType *pt) { + return _payload_type_get_description(pt->pt); +} + +static const char *_linphone_core_get_payload_type_codec_description(const LinphoneCore *lc, const OrtpPayloadType *pt) { + if (ms_factory_codec_supported(lc->factory, pt->mime_type)){ + MSFilterDesc *desc=ms_factory_get_encoder(lc->factory, pt->mime_type); +#ifdef ENABLE_NLS + return dgettext("mediastreamer",desc->text); +#else + return desc->text; +#endif + } + return NULL; +} + +const char *linphone_core_get_payload_type_description(LinphoneCore *lc, const OrtpPayloadType *pt){ + if (!_payload_type_is_in_core(pt, lc)) { + char *desc = _payload_type_get_description(pt); + ms_error("cannot get codec description for '%s' payload type: not in the core", desc); + bctbx_free(desc); + return NULL; + } + return _linphone_core_get_payload_type_codec_description(lc, pt); +} + +const char *linphone_payload_type_get_encoder_description(const LinphonePayloadType *pt) { + if (pt->lc == NULL) { + char *desc = linphone_payload_type_get_description(pt); + ms_error("cannot get codec description for '%s' payload type: no associated core", desc); + bctbx_free(desc); + return NULL; + } + return _linphone_core_get_payload_type_codec_description(pt->lc, pt->pt); +} + +static int _linphone_core_get_payload_type_normal_bitrate(const LinphoneCore *lc, const OrtpPayloadType *pt) { + int maxbw = get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + if (pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED){ + return get_audio_payload_bandwidth(lc, pt, maxbw); + }else if (pt->type==PAYLOAD_VIDEO){ + int video_bw; + if (maxbw<=0) { + video_bw=1500; /*default bitrate for video stream when no bandwidth limit is set, around 1.5 Mbit/s*/ + }else{ + video_bw=get_remaining_bandwidth_for_video(maxbw,lc->audio_bw); + } + return video_bw; + } + return 0; +} + +int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const OrtpPayloadType *pt){ + if (_payload_type_is_in_core(pt, lc)) { + return _linphone_core_get_payload_type_normal_bitrate(lc, pt); + } else { + char *desc = _payload_type_get_description(pt); + ms_error("cannot get normal bitrate of payload type '%s': not in the core", desc); + bctbx_free(desc); + return -1; + } +} + +int linphone_payload_type_get_normal_bitrate(const LinphonePayloadType *pt) { + if (pt->lc == NULL) { + char *desc = linphone_payload_type_get_description(pt); + ms_error("cannot get normal bitrate of codec '%s': no associated core", desc); + bctbx_free(desc); + return -1; + } + return _linphone_core_get_payload_type_normal_bitrate(pt->lc, pt->pt); +} + +static void _linphone_core_set_payload_type_normal_bitrate(LinphoneCore *lc, OrtpPayloadType *pt, int bitrate) { + if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){ + pt->normal_bitrate=bitrate*1000; + pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; + linphone_core_update_allocated_audio_bandwidth(lc); + }else{ + char *desc = _payload_type_get_description(pt); + ms_error("Cannot set an explicit bitrate for codec '%s', because it is not VBR.",desc); + bctbx_free(desc); + } +} + +void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, OrtpPayloadType *pt, int bitrate) { + if (_payload_type_is_in_core(pt, lc)) { + _linphone_core_set_payload_type_normal_bitrate(lc, pt, bitrate); + } else { + char *desc = _payload_type_get_description(pt); + ms_error("cannot set normal bitrate of codec '%s': not in the core", desc); + bctbx_free(desc); + } +} + +void linphone_payload_type_set_normal_bitrate(LinphonePayloadType *pt, int bitrate) { + if (pt->lc == NULL) { + ms_error("cannot set bitrate of codec %s/%d: no associated core", pt->pt->mime_type, pt->pt->clock_rate); + return; + } + _linphone_core_set_payload_type_normal_bitrate(pt->lc, pt->pt, bitrate); +} + +const char *linphone_payload_type_get_mime_type(const LinphonePayloadType *pt) { + return pt->pt->mime_type; +} + +int linphone_payload_type_get_channels(const LinphonePayloadType *pt) { + return pt->pt->channels; +} + +int linphone_core_get_payload_type_number(LinphoneCore *lc, const OrtpPayloadType *pt) { + return payload_type_get_number(pt); +} + +int linphone_payload_type_get_number(const LinphonePayloadType *pt) { + return payload_type_get_number(pt->pt); +} + +void linphone_core_set_payload_type_number(LinphoneCore *lc, OrtpPayloadType *pt, int number) { + payload_type_set_number(pt, number); +} + +void linphone_payload_type_set_number(LinphonePayloadType *pt, int number) { + payload_type_set_number(pt->pt, number); +} + +const char *linphone_payload_type_get_recv_fmtp(const LinphonePayloadType *pt) { + return pt->pt->recv_fmtp; +} + +void linphone_payload_type_set_recv_fmtp(LinphonePayloadType *pt, const char *recv_fmtp) { + if (pt->pt->recv_fmtp != NULL) bctbx_free(pt->pt->recv_fmtp); + if (recv_fmtp != NULL) pt->pt->recv_fmtp = bctbx_strdup(recv_fmtp); + else recv_fmtp = NULL; +} + +const char *linphone_payload_type_get_send_fmtp(const LinphonePayloadType *pt) { + return pt->pt->send_fmtp; +} + +void linphone_payload_type_set_send_fmtp(LinphonePayloadType *pt, const char *send_fmtp) { + if (pt->pt->send_fmtp != NULL) bctbx_free(pt->pt->send_fmtp); + if (send_fmtp != NULL) pt->pt->recv_fmtp = bctbx_strdup(send_fmtp); + else send_fmtp = NULL; +} + +int linphone_payload_type_get_clock_rate(const LinphonePayloadType *pt) { + return pt->pt->clock_rate; +} + +bool_t linphone_core_payload_type_is_vbr(const LinphoneCore *lc, const OrtpPayloadType *pt) { + return payload_type_is_vbr(pt); +} + +bool_t linphone_payload_type_is_vbr(const LinphonePayloadType *pt) { + return payload_type_is_vbr(pt->pt); +} + +bool_t _linphone_core_check_payload_type_usability(const LinphoneCore *lc, const OrtpPayloadType *pt) { + int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + bool_t ret=linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, maxbw); + if ((pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED) + && lc->sound_conf.capt_sndcard + && !(ms_snd_card_get_capabilities(lc->sound_conf.capt_sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) + && linphone_core_echo_cancellation_enabled(lc) + && (pt->clock_rate!=16000 && pt->clock_rate!=8000) + && strcasecmp(pt->mime_type,"opus")!=0 + && ms_factory_lookup_filter_by_name(lc->factory, "MSWebRTCAEC")!=NULL){ + ms_warning("Payload type %s/%i cannot be used because software echo cancellation is required but is unable to operate at this rate.", + pt->mime_type,pt->clock_rate); + ret=FALSE; + } + return ret; +} + +bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const OrtpPayloadType *pt) { + if (!_payload_type_is_in_core(pt, lc)) { + char *desc = _payload_type_get_description(pt); + ms_error("cannot check usability of '%s' payload type: not in the core", desc); + bctbx_free(desc); + return FALSE; + } + return _linphone_core_check_payload_type_usability(lc, pt); +} + +bool_t linphone_payload_type_is_usable(const LinphonePayloadType *pt) { + if (pt->lc == NULL) { + char *desc = linphone_payload_type_get_description(pt); + ms_error("cannot check usability of '%s' payload type: no associated core", desc); + bctbx_free(desc); + return FALSE; + } + return _linphone_core_check_payload_type_usability(pt->lc, pt->pt); +} + +OrtpPayloadType *linphone_payload_type_get_ortp_pt(const LinphonePayloadType *pt) { + return pt->pt; +} + +BELLE_SIP_INSTANCIATE_VPTR(LinphonePayloadType, belle_sip_object_t, + NULL, // uninit + NULL, // clone + NULL, // marshale + TRUE // unown +); diff --git a/coreapi/private.h b/coreapi/private.h index ae74b85ef..f4ab0f210 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1176,7 +1176,7 @@ void linphone_call_increment_local_media_description(LinphoneCall *call); void linphone_call_fill_media_multicast_addr(LinphoneCall *call); void linphone_call_update_streams(LinphoneCall *call, SalMediaDescription *new_md, LinphoneCallState target_state); -bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit); +bool_t linphone_core_is_payload_type_usable_for_bandwidth(const LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit); #define linphone_core_ready(lc) ((lc)->state==LinphoneGlobalOn || (lc)->state==LinphoneGlobalShutdown) void _linphone_core_configure_resolver(void); @@ -1667,17 +1667,22 @@ char * linphone_timestamp_to_rfc3339_string(time_t timestamp); void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op); -static MS2_INLINE void payload_type_set_enable(PayloadType *pt,int value) +static MS2_INLINE void payload_type_set_enable(OrtpPayloadType *pt,int value) { if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \ else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED); } -static MS2_INLINE bool_t payload_type_enabled(const PayloadType *pt) { +static MS2_INLINE bool_t payload_type_enabled(const OrtpPayloadType *pt) { return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0); } -bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore); +bool_t is_payload_type_number_available(const MSList *l, int number, const OrtpPayloadType *ignore); +int get_audio_payload_bandwidth(const LinphoneCore *lc, const PayloadType *pt, int maxbw); +LinphonePayloadType *linphone_payload_type_new(LinphoneCore *lc, OrtpPayloadType *ortp_pt); +bool_t _linphone_core_check_payload_type_usability(const LinphoneCore *lc, const OrtpPayloadType *pt); +OrtpPayloadType *linphone_payload_type_get_ortp_pt(const LinphonePayloadType *pt); + const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc); MsZrtpCryptoTypesCount linphone_core_get_zrtp_key_agreement_suites(LinphoneCore *lc, MSZrtpKeyAgreement keyAgreements[MS_MAX_ZRTP_CRYPTO_TYPES]); @@ -1759,7 +1764,8 @@ BELLE_SIP_TYPE_ID(LinphonePresenceNote), BELLE_SIP_TYPE_ID(LinphoneErrorInfo), BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConference), -BELLE_SIP_TYPE_ID(LinphoneInfoMessage) +BELLE_SIP_TYPE_ID(LinphoneInfoMessage), +BELLE_SIP_TYPE_ID(LinphonePayloadType) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index f320811a6..dc3678689 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -539,15 +539,15 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { /*yet we use the same payload config for local and remote, since this is the largest use case*/ if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) { stream = &call->audiostream->ms; - local_payload = linphone_call_params_get_used_audio_codec(current_params); + local_payload = current_params->audio_codec; remote_payload = local_payload; } else if (stats_type == LINPHONE_CALL_STATS_VIDEO && call->videostream != NULL) { stream = &call->videostream->ms; - local_payload = linphone_call_params_get_used_video_codec(current_params); + local_payload = current_params->video_codec; remote_payload = local_payload; } else if (stats_type == LINPHONE_CALL_STATS_TEXT && call->textstream != NULL) { stream = &call->textstream->ms; - local_payload = linphone_call_params_get_used_text_codec(current_params); + local_payload = current_params->text_codec; remote_payload = local_payload; } diff --git a/daemon/commands/audio-codec-set.cc b/daemon/commands/audio-codec-set.cc index 3d52cd843..a3730b9fc 100644 --- a/daemon/commands/audio-codec-set.cc +++ b/daemon/commands/audio-codec-set.cc @@ -71,7 +71,7 @@ static PayloadType *findPayload(LinphoneCore *lc, int payload_type, int *index){ for (const bctbx_list_t *node = linphone_core_get_audio_codecs(lc); node != NULL; node = bctbx_list_next(node)) { PayloadType *payload = reinterpret_cast(node->data); if (index) (*index)++; - if (payload_type == linphone_payload_type_get_number(payload)) { + if (payload_type == payload_type_get_number(payload)) { return payload; } } @@ -127,7 +127,7 @@ void AudioCodecSetCommand::exec(Daemon *app, const string& args) { if (conflict) { app->sendResponse(Response("New payload type number is already used.", Response::Error)); } else { - linphone_payload_type_set_number(payload, idx); + payload_type_set_number(payload, idx); app->sendResponse(PayloadTypeResponse(app->getCore(), payload, parser.getPosition())); } return; diff --git a/daemon/commands/audio-stream-start.cc b/daemon/commands/audio-stream-start.cc index 406669b19..b1a2e5bc0 100644 --- a/daemon/commands/audio-stream-start.cc +++ b/daemon/commands/audio-stream-start.cc @@ -33,7 +33,7 @@ static PayloadType *getPayloadType(LinphoneCore *lc, const MSList *codecs, int n const MSList *elem; for (elem = codecs; elem != NULL; elem = elem->next) { PayloadType *pt = (PayloadType*)elem->data; - if (linphone_payload_type_get_number(pt) == number) + if (payload_type_get_number(pt) == number) return pt; } return NULL; diff --git a/daemon/daemon.cc b/daemon/daemon.cc index dc1980e60..01f44e7c4 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -219,7 +219,7 @@ PayloadTypeResponse::PayloadTypeResponse(LinphoneCore *core, const PayloadType * if (payloadType != NULL) { if (index >= 0) ostr << prefix << "Index: " << index << "\n"; - ostr << prefix << "Payload-type-number: " << linphone_payload_type_get_number(payloadType) << "\n"; + ostr << prefix << "Payload-type-number: " << payload_type_get_number(payloadType) << "\n"; ostr << prefix << "Clock-rate: " << payloadType->clock_rate << "\n"; ostr << prefix << "Bitrate: " << payloadType->normal_bitrate << "\n"; ostr << prefix << "Mime: " << payloadType->mime_type << "\n"; @@ -252,7 +252,7 @@ PayloadTypeParser::PayloadTypeParser(LinphoneCore *core, const string &mime_type }else if (number!=-1){ const bctbx_list_t *elem; for(elem=linphone_core_get_audio_codecs(core);elem!=NULL;elem=elem->next){ - if (number==linphone_payload_type_get_number((PayloadType*)elem->data)){ + if (number==payload_type_get_number((PayloadType*)elem->data)){ mPayloadType=(PayloadType*)elem->data; break; } diff --git a/gtk/propertybox.c b/gtk/propertybox.c index a14c34be3..9e417f88f 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -647,7 +647,7 @@ static void linphone_gtk_init_codec_list(GtkTreeView *listview){ } -const char *get_codec_color(LinphoneCore *lc, PayloadType *pt){ +const char *get_codec_color(LinphoneCore *lc, OrtpPayloadType *pt){ const gchar *color; if (linphone_core_check_payload_type_usability(lc,pt)) color="blue"; else color="red"; @@ -673,7 +673,7 @@ static void linphone_gtk_show_codecs(GtkTreeView *listview, const bctbx_list_t * const gchar *color; const char *params=""; - struct _PayloadType *pt=(struct _PayloadType *)elem->data; + OrtpPayloadType *pt=(OrtpPayloadType *)elem->data; color=get_codec_color(linphone_gtk_get_core(),pt); if (linphone_core_payload_type_enabled(linphone_gtk_get_core(),pt)) status=_("Enabled"); diff --git a/include/linphone/call_params.h b/include/linphone/call_params.h index 2220f595c..1b828a77d 100644 --- a/include/linphone/call_params.h +++ b/include/linphone/call_params.h @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/types.h" +#include "linphone/payload_type.h" #ifdef __cplusplus @@ -175,25 +176,55 @@ LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_sent_video_size(const Linph LINPHONE_PUBLIC const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp); /** - * Get the audio codec used in the call, described as a LinphonePayloadType object. - * @param[in] cp LinphoneCallParams object - * @return The LinphonePayloadType object corresponding to the audio codec being used in the call. + * Get the audio payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no audio payload type has been seleced + * by the call. If a payload type is returned, it must be released with linphone_payload_type_unref() after use. **/ -LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp); +LINPHONE_PUBLIC LinphonePayloadType *linphone_call_params_get_used_audio_payload_type(const LinphoneCallParams *cp); /** - * Get the video codec used in the call, described as a LinphonePayloadType structure. - * @param[in] cp LinphoneCallParams object - * @return The LinphonePayloadType object corresponding to the video codec being used in the call. + * Get the video payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no video payload type has been seleced + * by the call. If a payload type is returned, it must be released with linphone_payload_type_unref() after use. **/ -LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp); +LINPHONE_PUBLIC LinphonePayloadType *linphone_call_params_get_used_video_payload_type(const LinphoneCallParams *cp); /** - * Get the text codec used in the call, described as a LinphonePayloadType structure. - * @param[in] cp LinphoneCallParams object - * @return The LinphonePayloadType object corresponding to the text codec being used in the call. + * Get the text payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no text payload type has been seleced + * by the call. If a payload type is returned, it must be released with linphone_payload_type_unref() after use. **/ -LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp); +LINPHONE_PUBLIC LinphonePayloadType *linphone_call_params_get_used_text_payload_type(const LinphoneCallParams *cp); + +/** + * Get the audio payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no audio payload type has been seleced by the call. + * @deprecated Use linphone_call_params_get_used_audio_payload_type() instead. + * @donotwrap +**/ +LINPHONE_PUBLIC LINPHONE_DEPRECATED const OrtpPayloadType *linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp); + +/** + * Get the video payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no video payload type has been seleced by the call. + * @deprecated Use linphone_call_params_get_used_video_payload_type() instead. + * @donotwrap +**/ +LINPHONE_PUBLIC LINPHONE_DEPRECATED const OrtpPayloadType *linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp); + +/** + * Get the text payload type that has been selected by a call. + * @param[in] cp The call. + * @return The selected payload type. NULL is returned if no text payload type has been seleced by the call. + * @deprecated Use linphone_call_params_get_used_text_payload_type() instead. + * @donotwrap +**/ +LINPHONE_PUBLIC LINPHONE_DEPRECATED const OrtpPayloadType *linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp); /** * Tell whether the call has been configured in low bandwidth mode or not. diff --git a/include/linphone/core.h b/include/linphone/core.h index b4aca8002..52f8f0ae6 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -1570,67 +1570,131 @@ LINPHONE_PUBLIC bool_t linphone_core_dns_search_enabled(const LinphoneCore *lc); */ LINPHONE_PUBLIC void linphone_core_set_dns_servers(LinphoneCore *lc, const bctbx_list_t *servers); +/** + * Return the list of the available audio payload types. + * @param[in] lc The core. + * @return \bctbx_list{LinphonePayloadType} A freshly allocated list of the available payload types. It must be released + * with bctbx_list_free_with_data() calling linphone_payload_type_unref() on each element. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC bctbx_list_t *linphone_core_get_audio_payload_types(LinphoneCore *lc); + +/** + * Redefine the list of the available payload types. + * @param[in] lc The core. + * @param[in] payload_types \bctbx_list{LinphonePayloadType} The new list of payload types. The core does not take + * ownership on it. + * @ingroup media_paremeters + */ +LINPHONE_PUBLIC void linphone_core_set_audio_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types); + /** * Returns the list of available audio codecs. * @param[in] lc The LinphoneCore object - * @return \bctbx_list{LinphonePayloadType} + * @return \bctbx_list{OrtpPayloadType} * * This list is unmodifiable. The ->data field of the bctbx_list_t points a PayloadType * structure holding the codec information. * It is possible to make copy of the list with bctbx_list_copy() in order to modify it * (such as the order of codecs). * @ingroup media_parameters + * @deprecated Use linphone_core_get_audio_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_audio_codecs(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_audio_codecs(const LinphoneCore *lc); /** * Sets the list of audio codecs. * @param[in] lc The LinphoneCore object - * @param[in] codecs \bctbx_list{LinphonePayloadType} + * @param[in] codecs \bctbx_list{OrtpPayloadType} * @return 0 * The list is taken by the LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters + * @deprecated Use linphone_core_set_audio_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC int linphone_core_set_audio_codecs(LinphoneCore *lc, bctbx_list_t *codecs); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_set_audio_codecs(LinphoneCore *lc, bctbx_list_t *codecs); + +/** + * Return the list of the available video payload types. + * @param[in] lc The core. + * @return \bctbx_list{LinphonePayloadType} A freshly allocated list of the available payload types. It must be released + * with bctbx_list_free_with_data() calling linphone_payload_type_unref() on each element. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC bctbx_list_t *linphone_core_get_video_payload_types(LinphoneCore *lc); + +/** + * Redefine the list of the available video payload types. + * @param[in] lc The core. + * @param[in] payload_types \bctbx_list{LinphonePayloadType} The new list of codecs. The core does not take + * ownership on it. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_set_video_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types); /** * Returns the list of available video codecs. * @param[in] lc The LinphoneCore object - * @return \bctbx_list{LinphonePayloadType} + * @return \bctbx_list{OrtpPayloadType} * * This list is unmodifiable. The ->data field of the bctbx_list_t points a PayloadType * structure holding the codec information. * It is possible to make copy of the list with bctbx_list_copy() in order to modify it * (such as the order of codecs). * @ingroup media_parameters + * @deprecated Use linphone_core_get_video_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_video_codecs(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_video_codecs(const LinphoneCore *lc); /** * Sets the list of video codecs. * @param[in] lc The LinphoneCore object - * @param[in] codecs \bctbx_list{LinphonePayloadType} + * @param[in] codecs \bctbx_list{OrtpPayloadType} * @return 0 * * The list is taken by the LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters + * @deprecated Use linphone_core_set_video_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, bctbx_list_t *codecs); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_set_video_codecs(LinphoneCore *lc, bctbx_list_t *codecs); + +/** + * Return the list of the available text payload types. + * @param[in] lc The core. + * @return \bctbx_list{LinphonePayloadType} A freshly allocated list of the available payload types. It must be released + * with bctbx_list_free_with_data() calling linphone_payload_type_unref() on each element. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC bctbx_list_t *linphone_core_get_text_payload_types(LinphoneCore *lc); + +/** + * Redefine the list of the available payload types. + * @param[in] lc The core. + * @param[in] payload_types \bctbx_list{LinphonePayloadType} The new list of payload types. The core does not take + * ownership on it. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_set_text_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types); /** * Returns the list of available text codecs. * @param[in] lc The LinphoneCore object - * @return \bctbx_list{LinphonePayloadType} + * @return \bctbx_list{OrtpPayloadType} * * This list is unmodifiable. The ->data field of the bctbx_list_t points a PayloadType * structure holding the codec information. * It is possible to make copy of the list with bctbx_list_copy() in order to modify it * (such as the order of codecs). * @ingroup media_parameters + * @deprecated Use linphone_core_get_text_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_text_codecs(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_text_codecs(const LinphoneCore *lc); /** * Sets the list of text codecs. @@ -1641,8 +1705,10 @@ LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_text_codecs(const Linphone * The list is taken by the LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters + * @deprecated Use linphone_core_set_text_payload_types() instead. + * @donotwrap **/ -LINPHONE_PUBLIC int linphone_core_set_text_codecs(LinphoneCore *lc, bctbx_list_t *codecs); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_set_text_codecs(LinphoneCore *lc, bctbx_list_t *codecs); /** * Enable RFC3389 generic comfort noise algorithm (CN payload type). @@ -1679,50 +1745,58 @@ LINPHONE_PUBLIC bool_t linphone_core_generic_comfort_noise_enabled(const Linphon /** * Tells whether the specified payload type is enabled. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #LinphonePayloadType we want to know is enabled or not. + * @param[in] pt The payload type to check. * @return TRUE if the payload type is enabled, FALSE if disabled. * @ingroup media_parameters + * @deprecated Use linphone_payload_type_enabled() instead. + * @donotwrap */ -LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt); +LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_core_payload_type_enabled(const LinphoneCore *lc, const OrtpPayloadType *pt); /** * Tells whether the specified payload type represents a variable bitrate codec. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #LinphonePayloadType we want to know + * @param[in] pt The payload type to check. * @return TRUE if the payload type represents a VBR codec, FALSE if disabled. * @ingroup media_parameters - * @deprecated Use linphone_payload_type_is_vbr() instead + * @deprecated Use linphone_payload_type_is_vbr() instead. * @donotwrap */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayloadType *pt); +LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_core_payload_type_is_vbr(const LinphoneCore *lc, const OrtpPayloadType *pt); /** * Set an explicit bitrate (IP bitrate, not codec bitrate) for a given codec, in kbit/s. * @param[in] lc the #LinphoneCore object - * @param[in] pt the #LinphonePayloadType to modify. + * @param[in] pt the payload type to modify. * @param[in] bitrate the IP bitrate in kbit/s. * @ingroup media_parameters + * @deprecated Use linphone_payload_type_set_normal_bitrate() instead. + * @donotwrap **/ -LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, OrtpPayloadType *pt, int bitrate); /** * Get the bitrate explicitely set with linphone_core_set_payload_type_bitrate(). * @param[in] lc the #LinphoneCore object - * @param[in] pt the #LinphonePayloadType to modify. + * @param[in] pt the payload type to modify. * @return bitrate the IP bitrate in kbit/s, or -1 if an error occured. * @ingroup media_parameters + * @deprecated Use linphone_payload_type_get_bitrate(). + * @donotwrap **/ -LINPHONE_PUBLIC int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const LinphonePayloadType *pt); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const OrtpPayloadType *pt); /** * Enable or disable the use of the specified payload type. * @param[in] lc #LinphoneCore object. - * @param[in] pt The #LinphonePayloadType to enable or disable. It can be retrieved using #linphone_core_find_payload_type + * @param[in] pt The payload type to enable or disable. It can be retrieved using #linphone_core_find_payload_type * @param[in] enable TRUE to enable the payload type, FALSE to disable it. * @return 0 if successful, any other value otherwise. * @ingroup media_parameters + * @deprecated Use linphone_payload_type_enable(). + * @donotwrap */ -LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enable); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_enable_payload_type(LinphoneCore *lc, OrtpPayloadType *pt, bool_t enable); /** * Wildcard value used by #linphone_core_find_payload_type to ignore rate in search algorithm @@ -1737,7 +1811,7 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, Linphone #define LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS -1 /** - * Get payload type from mime type and clock rate + * Get payload type from mime type and clock rate. * @ingroup media_parameters * This function searches in audio and video codecs for the given payload type name and clockrate. * @param lc #LinphoneCore object @@ -1745,8 +1819,23 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, Linphone * @param rate can be #LINPHONE_FIND_PAYLOAD_IGNORE_RATE * @param channels number of channels, can be #LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS * @return Returns NULL if not found. + * @deprecated Use linphone_core_get_payload_type() instead. + * @donotwrap */ -LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels); +LINPHONE_PUBLIC LINPHONE_DEPRECATED OrtpPayloadType *linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels); + +/** + * Get payload type from mime type and clock rate. + * @ingroup media_parameters + * This function searches in audio and video codecs for the given payload type name and clockrate. + * @param lc #LinphoneCore object + * @param type payload mime type (I.E SPEEX, PCMU, VP8) + * @param rate can be #LINPHONE_FIND_PAYLOAD_IGNORE_RATE + * @param channels number of channels, can be #LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS + * @return Returns NULL if not found. If a #LinphonePayloadType is returned, it must be released with + * linphone_payload_type_unref() after using it. + */ +LINPHONE_PUBLIC LinphonePayloadType *linphone_core_get_payload_type(LinphoneCore *lc, const char *type, int rate, int channels); /** * Returns the payload type number assigned for this codec. @@ -1754,7 +1843,7 @@ LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCor * @deprecated Use linphone_payload_type_get_number() instead * @donotwrap **/ -LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_payload_type_number(LinphoneCore *lc, const OrtpPayloadType *pt); /** * Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order @@ -1763,15 +1852,25 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_payload_type_number(Li * @deprecated Use linphone_payload_type_set_number() instead * @donotwrap **/ -LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_payload_type_number(LinphoneCore *lc, OrtpPayloadType *pt, int number); -LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt); +/** + * Get a description of the encoder used to supply a payload type. + * @param[in] lc The core. + * @param[in] pt The payload type. + * @return The description of the encoder. Can be NULL if the format is not supported by Mediastreamer2. + * @deprecated Use linphone_payload_type_get_encoder_description() instead. + * @donotwrap + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_payload_type_description(LinphoneCore *lc, const OrtpPayloadType *pt); /** * Return TRUE if codec can be used with bandwidth, FALSE else * @ingroup media_parameters + * @deprecated Use linphone_payload_type_is_usable() instead. + * @donotwrap */ -LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const OrtpPayloadType *pt); /** * @addtogroup proxies @@ -2729,7 +2828,7 @@ LINPHONE_PUBLIC void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bo * @return A boolean value telling whether echo cancellation is enabled or disabled * @ingroup media_parameters **/ -LINPHONE_PUBLIC bool_t linphone_core_echo_cancellation_enabled(LinphoneCore *lc); +LINPHONE_PUBLIC bool_t linphone_core_echo_cancellation_enabled(const LinphoneCore *lc); /** * Enables or disable echo limiter. diff --git a/include/linphone/payload_type.h b/include/linphone/payload_type.h index a48a85aca..8fb848851 100644 --- a/include/linphone/payload_type.h +++ b/include/linphone/payload_type.h @@ -20,77 +20,163 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef LINPHONE_PAYLOAD_TYPE_H_ #define LINPHONE_PAYLOAD_TYPE_H_ - #include "linphone/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /** * @addtogroup media_parameters * @{ **/ + +#ifdef __cplusplus +extern "C" { +#endif + /** - * Get the type of payload. - * @param[in] pt LinphonePayloadType object - * @return The type of payload. + * Take a reference on a #LinphonePayloadType. + */ +LINPHONE_PUBLIC LinphonePayloadType *linphone_payload_type_ref(LinphonePayloadType *pt); + +/** + * Release a reference on a #LinphonePayloadType. + */ +LINPHONE_PUBLIC void linphone_payload_type_unref(LinphonePayloadType *pt); + +/** + * Get the type of a payload type. + * @param[in] pt The payload type. + * @return The type of the payload e.g. PAYLOAD_AUDIO_CONTINUOUS or PAYLOAD_VIDEO. */ LINPHONE_PUBLIC int linphone_payload_type_get_type(const LinphonePayloadType *pt); +/** + * Enable/disable a payload type. + * @param[in] pt The payload type to enable/disable. + * @param[in] enabled Set TRUE for enabling and FALSE for disabling. + * @return 0 for success, -1 for failure. + */ +LINPHONE_PUBLIC int linphone_payload_type_enable(LinphonePayloadType *pt, bool_t enabled); + +/** + * Check whether a palyoad type is enabled. + * @return TRUE if enabled, FALSE if disabled. + */ +LINPHONE_PUBLIC bool_t linphone_payload_type_enabled(const LinphonePayloadType *pt); + +/** + * Return a string describing a payload type. The format of the string is + * <mime_type>/<clock_rate>/<channels>. + * @param[in] pt The payload type. + * @return The description of the payload type. Must be release after use. + */ +LINPHONE_PUBLIC char *linphone_payload_type_get_description(const LinphonePayloadType *pt); + +/** + * Get a description of the encoder used to provide a payload type. + * @param[in] pt The payload type. + * @return The description of the encoder. Can be NULL if the payload type is not supported by Mediastreamer2. + */ +LINPHONE_PUBLIC const char *linphone_payload_type_get_encoder_description(const LinphonePayloadType *pt); + /** * Get the normal bitrate in bits/s. - * @param[in] pt LinphonePayloadType object - * @return The normal bitrate in bits/s. + * @param[in] pt The payload type. + * @return The normal bitrate in bits/s or -1 if an error has occured. */ LINPHONE_PUBLIC int linphone_payload_type_get_normal_bitrate(const LinphonePayloadType *pt); +/** + * Change the normal bitrate of a payload type.. + * @param[in] pt The payload type to change. + * @param[in] bitrate The new bitrate in bits/s. + */ +LINPHONE_PUBLIC void linphone_payload_type_set_normal_bitrate(LinphonePayloadType *pt, int bitrate); + /** * Get the mime type. - * @param[in] pt LinphonePayloadType object + * @param[in] pt The payload type. * @return The mime type. */ LINPHONE_PUBLIC const char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt); /** * Get the number of channels. - * @param[in] pt LinphonePayloadType object + * @param[in] pt The payload type. * @return The number of channels. */ LINPHONE_PUBLIC int linphone_payload_type_get_channels(const LinphonePayloadType *pt); /** * Returns the payload type number assigned for this codec. - * @param[in] pt LinphonePayloadType object - * @return The number of the payload type + * @param[in] pt The payload type. + * @return The number of the payload type. **/ LINPHONE_PUBLIC int linphone_payload_type_get_number(const LinphonePayloadType *pt); /** - * Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order - * to override the automatic assignment mechanism. - * @param[in] pt LinphonePayloadType object - * @param[in] number The number to assign to the payload type + * Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. + * This function is mainly to be used for tests, in order to override the automatic assignment mechanism. + * @param[in] pt The payload type. + * @param[in] number The number to assign to the payload type. **/ LINPHONE_PUBLIC void linphone_payload_type_set_number(LinphonePayloadType *pt, int number); +/** + * Get the format parameters for incoming streams. + * @param[in] pt The payload type. + * @return The format parameters as string. + */ +LINPHONE_PUBLIC const char *linphone_payload_type_get_recv_fmtp(const LinphonePayloadType *pt); + +/** + * Set the format parameters for incoming streams. + * @param[in] pt The payload type. + * @param[in] recv_fmtp The new format parameters as string. The string will be copied. + */ +LINPHONE_PUBLIC void linphone_payload_type_set_recv_fmtp(LinphonePayloadType *pt, const char *recv_fmtp); + +/** + * Get the format parameters for outgoing streams. + * @param[in] pt The payload type. + * @return The format parameters as string. + */ +LINPHONE_PUBLIC const char *linphone_payload_type_get_send_fmtp(const LinphonePayloadType *pt); + +/** + * Set the format parameters for outgoing streams. + * @param[in] pt The payload type. + * @param[in] send_fmtp The new format parameters as string. The string will be copied. + */ +LINPHONE_PUBLIC void linphone_payload_type_set_send_fmtp(LinphonePayloadType *pt, const char *send_fmtp); + +/** + * Get the clock rate of a payload type. + * @param[in] pt The payload type. + * @return[in] The clock rate in Hz. + */ +LINPHONE_PUBLIC int linphone_payload_type_get_clock_rate(const LinphonePayloadType *pt); + /** * Tells whether the specified payload type represents a variable bitrate codec. - * @param[in] pt LinphonePayloadType object - * @return TRUE if the payload type represents a VBR codec, FALSE if disabled. + * @param[in] pt The payload type. + * @return TRUE if the payload type represents a VBR codec, FALSE instead. */ LINPHONE_PUBLIC bool_t linphone_payload_type_is_vbr(const LinphonePayloadType *pt); /** - * @} -**/ + * Check whether the payload is usable according the bandwidth targets set in the core. + * @param[in] pt The payload type to test. + * @return TRUE if the payload type is usable. + */ +LINPHONE_PUBLIC bool_t linphone_payload_type_is_usable(const LinphonePayloadType *pt); #ifdef __cplusplus } #endif +/** + * @} +**/ + #endif /* LINPHONE_PAYLOAD_TYPE_H_ */ diff --git a/include/linphone/types.h b/include/linphone/types.h index 0f7969d60..da699ccdf 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -685,12 +685,6 @@ typedef enum _LinphoneOnlineStatus{ LinphoneStatusEnd } LinphoneOnlineStatus; -/** - * Object representing an RTP payload type. - * @ingroup media_parameters - */ -typedef PayloadType LinphonePayloadType; - /** * Player interface. * @ingroup call_control @@ -1177,6 +1171,12 @@ typedef enum _LinphoneXmlRpcStatus { typedef struct _LsdPlayer LsdPlayer; +/** + * Object representing an RTP payload type. + * @ingroup media_parameters + */ +typedef struct _LinphonePayloadType LinphonePayloadType; + /** * Structure describing a range of integers diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 43d260803..5b9d12f7f 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -3189,7 +3189,7 @@ static void call_with_in_dialog_codec_change_base(bool_t no_sdp) { BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1)); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); - BC_ASSERT_STRING_EQUAL("PCMA",linphone_payload_type_get_mime_type(linphone_call_params_get_used_audio_codec(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))))); + BC_ASSERT_STRING_EQUAL("PCMA",payload_type_get_mime(linphone_call_params_get_used_audio_codec(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))))); wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%i"); BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline),70,int,"%i"); diff --git a/tester/offeranswer_tester.c b/tester/offeranswer_tester.c index d921373b5..78b612c44 100644 --- a/tester/offeranswer_tester.c +++ b/tester/offeranswer_tester.c @@ -58,13 +58,13 @@ static void check_payload_type_numbers(LinphoneCall *call1, LinphoneCall *call2, const PayloadType *pt=linphone_call_params_get_used_audio_codec(params); BC_ASSERT_PTR_NOT_NULL(pt); if (pt){ - BC_ASSERT_EQUAL(linphone_payload_type_get_number(pt),expected_number, int, "%d"); + BC_ASSERT_EQUAL(payload_type_get_number(pt),expected_number, int, "%d"); } params=linphone_call_get_current_params(call2); pt=linphone_call_params_get_used_audio_codec(params); BC_ASSERT_PTR_NOT_NULL(pt); if (pt){ - BC_ASSERT_EQUAL(linphone_payload_type_get_number(pt),expected_number, int, "%d"); + BC_ASSERT_EQUAL(payload_type_get_number(pt),expected_number, int, "%d"); } } @@ -80,7 +80,7 @@ static void simple_call_with_different_codec_mappings(void) { disable_all_audio_codecs_except_one(pauline->lc,"pcmu",-1); /*marie set a fantasy number to PCMU*/ - linphone_payload_type_set_number(linphone_core_find_payload_type(marie->lc, "PCMU", 8000, -1), 104); + payload_type_set_number(linphone_core_find_payload_type(marie->lc, "PCMU", 8000, -1), 104); BC_ASSERT_TRUE(call(marie,pauline)); pauline_call=linphone_core_get_current_call(pauline->lc); @@ -398,9 +398,9 @@ static void savpf_dtls_to_avpf_video_call(void) { #endif #ifdef VIDEO_ENABLED -static LinphonePayloadType * configure_core_for_avpf_and_video(LinphoneCore *lc) { +static OrtpPayloadType * configure_core_for_avpf_and_video(LinphoneCore *lc) { LinphoneProxyConfig *lpc; - LinphonePayloadType *lpt; + OrtpPayloadType *pt; LinphoneVideoPolicy policy = { 0 }; policy.automatically_initiate = TRUE; @@ -412,13 +412,13 @@ static LinphonePayloadType * configure_core_for_avpf_and_video(LinphoneCore *lc) linphone_core_enable_video_capture(lc, TRUE); linphone_core_enable_video_display(lc, TRUE); linphone_core_set_video_policy(lc, &policy); - lpt = linphone_core_find_payload_type(lc, "VP8", 90000, -1); - if (lpt == NULL) { + 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 lpt; + return pt; } static void check_avpf_features(LinphoneCore *lc, unsigned char expected_features) { @@ -441,19 +441,20 @@ static void check_avpf_features(LinphoneCore *lc, unsigned char expected_feature static void compatible_avpf_features(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); - LinphonePayloadType *lpt; + OrtpPayloadType *pt; bool_t call_ok; if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end; - lpt = configure_core_for_avpf_and_video(pauline->lc); + + 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)); - check_avpf_features(marie->lc, lpt->avpf.features); - check_avpf_features(pauline->lc, lpt->avpf.features); + check_avpf_features(marie->lc, pt->avpf.features); + check_avpf_features(pauline->lc, pt->avpf.features); end_call(marie,pauline); end: @@ -464,12 +465,13 @@ end: static void incompatible_avpf_features(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); - LinphonePayloadType *lpt; + OrtpPayloadType *pt; bool_t call_ok; if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end; - lpt = configure_core_for_avpf_and_video(pauline->lc); - lpt->avpf.features = PAYLOAD_TYPE_AVPF_NONE; + + 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; diff --git a/wrappers/cpp/abstractapi.py b/wrappers/cpp/abstractapi.py index 01489ba41..d7ac56f29 100644 --- a/wrappers/cpp/abstractapi.py +++ b/wrappers/cpp/abstractapi.py @@ -440,7 +440,6 @@ class CParser(object): 'linphone_vcard_get_belcard'] # manualy wrapped self.classBl = ['LpConfig', - 'LinphonePayloadType', 'LinphonePlayer'] # temporarly blacklisted # list of classes that must be concidered as refcountable even if From 54cb45b248f7309c621a31de70d603c83d3e03d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Mon, 3 Apr 2017 13:04:17 +0200 Subject: [PATCH 5/7] Update oRTP --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index f9099f6b2..67c0672e2 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit f9099f6b2d8f95c6d4237524e66e47b76c26ecca +Subproject commit 67c0672e2680baa85a74d8966b813fac259649df From 5a46392c98b577c941f576d00d96c4c66119a4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Mon, 3 Apr 2017 13:49:57 +0200 Subject: [PATCH 6/7] Fix memory leak in C++ wrapper --- include/linphone/core.h | 2 +- wrappers/cpp/tools.hh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linphone/core.h b/include/linphone/core.h index 52f8f0ae6..39256ef5c 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -1584,7 +1584,7 @@ LINPHONE_PUBLIC bctbx_list_t *linphone_core_get_audio_payload_types(LinphoneCore * @param[in] lc The core. * @param[in] payload_types \bctbx_list{LinphonePayloadType} The new list of payload types. The core does not take * ownership on it. - * @ingroup media_paremeters + * @ingroup media_parameters */ LINPHONE_PUBLIC void linphone_core_set_audio_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types); diff --git a/wrappers/cpp/tools.hh b/wrappers/cpp/tools.hh index 4ef512992..f46e398eb 100644 --- a/wrappers/cpp/tools.hh +++ b/wrappers/cpp/tools.hh @@ -58,6 +58,11 @@ namespace linphone { } return cppList; } + static std::list> bctbxListToCppList(::bctbx_list_t *bctbxList) { + std::list> cppList = bctbxListToCppList((const ::bctbx_list_t *)bctbxList); + bctbx_list_free(bctbxList); + return cppList; + } static ::bctbx_list_t *cppListToBctbxList(const std::list > &cppList) { bctbx_list_t *cList = NULL; for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { From e0def942a9b06f2d8f728ddcb45f31f287ea9e5c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 3 Apr 2017 15:30:20 +0200 Subject: [PATCH 7/7] Report call logs for calls aborted before they are notified to the application. --- coreapi/account_creator.c | 8 ++-- coreapi/bellesip_sal/sal_op_call.c | 21 +++++---- coreapi/call_log.c | 6 +++ coreapi/callbacks.c | 73 ++++++++++++++++++++---------- coreapi/linphonecall.c | 27 ++--------- coreapi/linphonecore.c | 4 +- coreapi/misc.c | 38 ++++++++++++++++ coreapi/private.h | 8 +++- coreapi/proxy.c | 4 +- include/linphone/call_log.h | 7 +++ include/linphone/proxy_config.h | 4 +- include/linphone/types.h | 3 +- include/sal/sal.h | 1 + tester/accountmanager.c | 7 +-- tester/call_single_tester.c | 45 +++++++++++++++--- 15 files changed, 173 insertions(+), 83 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index d32b2248b..3ec020f9b 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -291,7 +291,7 @@ static void _linphone_account_creator_destroy(LinphoneAccountCreator *creator) { if (creator->service != NULL && linphone_account_creator_service_get_destructor_cb(creator->service) != NULL) linphone_account_creator_service_get_destructor_cb(creator->service)(creator); linphone_account_creator_cbs_unref(creator->cbs); - linphone_proxy_config_destroy(creator->proxy_cfg); + linphone_proxy_config_unref(creator->proxy_cfg); if (creator->username) ms_free(creator->username); if (creator->display_name) ms_free(creator->display_name); if (creator->password) ms_free(creator->password); @@ -626,11 +626,13 @@ LinphoneAccountCreatorStatus linphone_account_creator_update_account(LinphoneAcc /************************** Start Account Creator Linphone **************************/ LinphoneAccountCreatorStatus linphone_account_creator_constructor_linphone(LinphoneAccountCreator *creator) { + LinphoneAddress *addr; linphone_proxy_config_set_realm(creator->proxy_cfg, "sip.linphone.org"); linphone_proxy_config_set_route(creator->proxy_cfg, "sip.linphone.org"); linphone_proxy_config_set_server_addr(creator->proxy_cfg, "sip.linphone.org"); - linphone_proxy_config_set_identity(creator->proxy_cfg, "sip:username@sip.linphone.org"); - + addr = linphone_address_new("sip:username@sip.linphone.org"); + linphone_proxy_config_set_identity_address(creator->proxy_cfg, addr); + linphone_address_unref(addr); return LinphoneAccountCreatorStatusRequestOk; } diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 6b4bc13d6..86c5460ee 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -507,10 +507,9 @@ static int is_media_description_acceptable(SalMediaDescription *md){ return TRUE; } -static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { +static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { belle_sdp_session_description_t* sdp; - int err=0; - SalReason reason; + SalReason reason = SalReasonNone; if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) { if (sdp){ @@ -519,17 +518,16 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { sdp_to_media_description(sdp,op->base.remote_media); /*make some sanity check about the SDP received*/ if (!is_media_description_acceptable(op->base.remote_media)){ - err=-1; reason=SalReasonNotAcceptable; } belle_sip_object_unref(sdp); }else op->sdp_offering=TRUE; /*INVITE without SDP*/ - }else err=-1; + } - if (err==-1){ + if (reason != SalReasonNone){ sal_call_decline(op,reason,NULL); } - return err; + return reason; } static void sal_op_reset_descriptions(SalOp *op) { @@ -550,6 +548,7 @@ static bool_t is_a_pending_invite_incoming_transaction(belle_sip_transaction_t * static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; + SalReason reason; belle_sip_server_transaction_t* server_transaction=NULL; belle_sdp_session_description_t* sdp; belle_sip_request_t* req = belle_sip_request_event_get_request(event); @@ -594,7 +593,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t ms_warning("replace header already set"); } - if (process_sdp_for_invite(op,req) == 0) { + if ( (reason = process_sdp_for_invite(op,req)) == SalReasonNone) { if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) { if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) { op->auto_answer_asked=TRUE; @@ -603,6 +602,8 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } op->base.root->callbacks.call_received(op); }else{ + sal_error_info_set(&op->error_info, reason, "SIP", 0, NULL, NULL); + op->base.root->callbacks.call_rejected(op); /*the INVITE was declined by process_sdp_for_invite(). As we are not inside an established dialog, we can drop the op immediately*/ drop_op = TRUE; } @@ -631,7 +632,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("UPDATE",method)==0) { sal_op_reset_descriptions(op); - if (process_sdp_for_invite(op,req)==0) + if (process_sdp_for_invite(op,req)==SalReasonNone) op->base.root->callbacks.call_updating(op,TRUE); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req)); @@ -680,7 +681,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } else { /*re-invite*/ sal_op_reset_descriptions(op); - if (process_sdp_for_invite(op,req)==0) + if (process_sdp_for_invite(op,req)==SalReasonNone) op->base.root->callbacks.call_updating(op,is_update); } } else if (strcmp("INFO",method)==0){ diff --git a/coreapi/call_log.c b/coreapi/call_log.c index 4087e77ae..6e9184f77 100644 --- a/coreapi/call_log.c +++ b/coreapi/call_log.c @@ -259,6 +259,10 @@ bool_t linphone_call_log_was_conference(LinphoneCallLog *cl) { return cl->was_conference; } +const LinphoneErrorInfo *linphone_call_log_get_error_info(LinphoneCallLog *cl){ + return cl->error_info; +} + /******************************************************************************* * Reference and user data handling functions * @@ -293,6 +297,7 @@ static void _linphone_call_log_destroy(LinphoneCallLog *cl) { if (cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]); if (cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]); if (cl->reporting.reports[LINPHONE_CALL_STATS_TEXT]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_TEXT]); + if (cl->error_info) linphone_error_info_unref(cl->error_info); } LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to) { @@ -313,6 +318,7 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *fr return cl; } + /* DEPRECATED */ void linphone_call_log_destroy(LinphoneCallLog *cl) { belle_sip_object_unref(cl); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 68da7e6f6..1e0e3b165 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -269,6 +269,7 @@ static void call_received(SalOp *h){ LinphoneAddress *from_address_to_search_if_me=NULL; /*address used to know if I'm the caller*/ SalMediaDescription *md; const char * p_asserted_id; + LinphoneErrorInfo *ei = NULL; /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ replaced_call = look_for_broken_call_to_replace(h, lc); @@ -276,31 +277,7 @@ static void call_received(SalOp *h){ linphone_call_replace_op(replaced_call, h); return; } - - /* first check if we can answer successfully to this invite */ - if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) { - LinphonePresenceActivity *activity = linphone_presence_model_get_activity(lc->presence_model); - switch (linphone_presence_activity_get_type(activity)) { - case LinphonePresenceActivityPermanentAbsence: - alt_contact = linphone_presence_model_get_contact(lc->presence_model); - if (alt_contact != NULL) { - sal_call_decline(h,SalReasonRedirect,alt_contact); - ms_free(alt_contact); - sal_op_release(h); - return; - } - break; - default: - /*nothing special to be done*/ - break; - } - } - - if (!linphone_core_can_we_add_call(lc)){/*busy*/ - sal_call_decline(h,SalReasonBusy,NULL); - sal_op_release(h); - return; - } + p_asserted_id = sal_custom_header_find(sal_op_get_recv_custom_header(h),"P-Asserted-Identity"); /*in some situation, better to trust the network rather than the UAC*/ if (lp_config_get_int(lc->config,"sip","call_logs_use_asserted_id_instead_of_from",0)) { @@ -322,6 +299,38 @@ static void call_received(SalOp *h){ from_addr=linphone_address_new(sal_op_get_from(h)); to_addr=linphone_address_new(sal_op_get_to(h)); + /* first check if we can answer successfully to this invite */ + if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) { + LinphonePresenceActivity *activity = linphone_presence_model_get_activity(lc->presence_model); + switch (linphone_presence_activity_get_type(activity)) { + case LinphonePresenceActivityPermanentAbsence: + alt_contact = linphone_presence_model_get_contact(lc->presence_model); + if (alt_contact != NULL) { + sal_call_decline(h,SalReasonRedirect,alt_contact); + ms_free(alt_contact); + ei = linphone_error_info_new(); + linphone_error_info_set(ei, LinphoneReasonMovedPermanently, 302, "Moved permanently", NULL); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); + sal_op_release(h); + return; + } + break; + default: + /*nothing special to be done*/ + break; + } + } + + if (!linphone_core_can_we_add_call(lc)){/*busy*/ + sal_call_decline(h,SalReasonBusy,NULL); + ei = linphone_error_info_new(); + linphone_error_info_set(ei, LinphoneReasonBusy, 486, "Busy - too many calls", NULL); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); + sal_op_release(h); + return; + } + + if (sal_op_get_privacy(h) == SalPrivacyNone) { from_address_to_search_if_me=linphone_address_clone(from_addr); } else if (p_asserted_id) { @@ -334,6 +343,9 @@ static void call_received(SalOp *h){ char *addr = linphone_address_as_string(from_addr); ms_warning("Receiving a call while one with same address [%s] is initiated, refusing this one with busy message.",addr); sal_call_decline(h,SalReasonBusy,NULL); + ei = linphone_error_info_new(); + linphone_error_info_set(ei, LinphoneReasonBusy, 486, "Busy - duplicated call", NULL); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); linphone_address_unref(from_addr); linphone_address_unref(to_addr); @@ -351,6 +363,9 @@ static void call_received(SalOp *h){ md=sal_call_get_final_media_description(call->op); if (md){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ + ei = linphone_error_info_new(); + linphone_error_info_set(ei, LinphoneReasonNotAcceptable, 488, "Not acceptable here", NULL); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_ref(from_addr), linphone_address_ref(to_addr), ei); sal_call_decline(call->op,SalReasonNotAcceptable,NULL); linphone_call_unref(call); return; @@ -379,6 +394,13 @@ static void call_received(SalOp *h){ linphone_core_notify_incoming_call(lc,call); } +static void call_rejected(SalOp *h){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); + LinphoneErrorInfo *ei = linphone_error_info_new(); + linphone_error_info_from_sal_op(ei, h); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_new(sal_op_get_from(h)), linphone_address_new(sal_op_get_to(h)), ei); +} + static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md){ SalMediaDescription *cur_md=call->resultdesc; int i; @@ -1457,6 +1479,7 @@ static void on_notify_response(SalOp *op){ SalCallbacks linphone_sal_callbacks={ call_received, + call_rejected, call_ringing, call_accepted, call_ack, diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index d1c413301..13af249ce 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4690,9 +4690,9 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse void linphone_call_log_completed(LinphoneCall *call){ LinphoneCore *lc=call->core; - bool_t call_logs_sqlite_db_found = FALSE; - + call->log->duration=_linphone_call_get_duration(call); /*store duration since connected*/ + call->log->error_info = linphone_error_info_ref((LinphoneErrorInfo*)linphone_call_get_error_info(call)); if (call->log->status==LinphoneCallMissed){ char *info; @@ -4703,28 +4703,7 @@ void linphone_call_log_completed(LinphoneCall *call){ linphone_core_notify_display_status(lc,info); ms_free(info); } - -#ifdef SQLITE_STORAGE_ENABLED - if (lc->logs_db) { - call_logs_sqlite_db_found = TRUE; - linphone_core_store_call_log(lc, call->log); - } -#endif - if (!call_logs_sqlite_db_found) { - lc->call_logs=bctbx_list_prepend(lc->call_logs,linphone_call_log_ref(call->log)); - if (bctbx_list_size(lc->call_logs)>(size_t)lc->max_call_logs){ - bctbx_list_t *elem,*prevelem=NULL; - /*find the last element*/ - for(elem=lc->call_logs;elem!=NULL;elem=elem->next){ - prevelem=elem; - } - elem=prevelem; - linphone_call_log_unref((LinphoneCallLog*)elem->data); - lc->call_logs=bctbx_list_erase_link(lc->call_logs,elem); - } - call_logs_write_to_config_file(lc); - } - linphone_core_notify_call_log_updated(lc,call->log); + linphone_core_report_call_log(lc, call->log); } LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 31b7f1158..9eaacc71a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2759,7 +2759,7 @@ bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTra return sal_transport_available(lc->sal,(SalTransport)tp); } -int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * tr_config /*config to be saved*/){ +int linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports * tr_config /*config to be saved*/){ LinphoneSipTransports tr=*tr_config; if (lp_config_get_int(lc->config,"sip","sip_random_port",0)==1) { @@ -3568,7 +3568,7 @@ static LinphoneCall * get_unique_call(LinphoneCore *lc) { } int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) { - return linphone_core_accept_call_with_params(lc, call, NULL); + return linphone_call_accept_with_params(call, NULL); } int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params) { diff --git a/coreapi/misc.c b/coreapi/misc.c index 8bf5ab4a4..5f0d018f4 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1781,6 +1781,7 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, } + /* Functions to mainpulate the LinphoneIntRange structure */ int linphone_int_range_get_min(const LinphoneIntRange *range) { @@ -1798,3 +1799,40 @@ void linphone_int_range_set_min(LinphoneIntRange *range, int min) { void linphone_int_range_set_max(LinphoneIntRange *range, int max) { range->max = max; } + +void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){ + bool_t call_logs_sqlite_db_found = FALSE; + +#ifdef SQLITE_STORAGE_ENABLED + if (lc->logs_db) { + call_logs_sqlite_db_found = TRUE; + linphone_core_store_call_log(lc, call_log); + } +#endif + if (!call_logs_sqlite_db_found) { + lc->call_logs=bctbx_list_prepend(lc->call_logs,linphone_call_log_ref(call_log)); + if (bctbx_list_size(lc->call_logs)>(size_t)lc->max_call_logs){ + bctbx_list_t *elem,*prevelem=NULL; + /*find the last element*/ + for(elem=lc->call_logs;elem!=NULL;elem=elem->next){ + prevelem = elem; + } + elem = prevelem; + linphone_call_log_unref((LinphoneCallLog*)elem->data); + lc->call_logs = bctbx_list_erase_link(lc->call_logs,elem); + } + call_logs_write_to_config_file(lc); + } + + linphone_core_notify_call_log_updated(lc,call_log); +} + +void linphone_core_report_early_failed_call(LinphoneCore *lc, LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to, LinphoneErrorInfo *ei){ + LinphoneCallLog *l = linphone_call_log_new(dir, from, to); + l->error_info = ei; + l->status = LinphoneCallEarlyAborted; + linphone_core_report_call_log(lc, l); + linphone_call_log_unref(l); +} + + diff --git a/coreapi/private.h b/coreapi/private.h index f4ab0f210..f4e87ee1d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -201,9 +201,10 @@ struct _LinphoneCallLog{ time_t connected_date_time; /**Connecting date of the call in seconds as expressed in a time_t */ char* call_id; /**unique id of a call*/ struct _LinphoneQualityReporting reporting; + unsigned int storage_id; + LinphoneErrorInfo *error_info; bool_t video_enabled; bool_t was_conference; /**lc); if (linphone_core_should_subscribe_friends_only_when_registered(lc) && cfg->state!=state && state == LinphoneRegistrationOk){ - ms_message("Updating friends for identity [%s] on core [%p]",linphone_proxy_config_get_identity(cfg),cfg->lc); + ms_message("Updating friends for identity [%s] on core [%p]",cfg->reg_identity,cfg->lc); /* state must be updated before calling linphone_core_update_friends_subscriptions*/ cfg->state=state; linphone_core_update_friends_subscriptions(lc); @@ -1358,7 +1358,7 @@ const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg) } else if(linphone_proxy_config_get_addr(cfg)) { addr=linphone_proxy_config_get_addr(cfg); } else { - ms_error("Cannot guess transport for proxy with identity [%s]",linphone_proxy_config_get_identity(cfg)); + ms_error("Cannot guess transport for proxy with identity [%s]", cfg->reg_identity); return NULL; } diff --git a/include/linphone/call_log.h b/include/linphone/call_log.h index 914fab331..4320cb72b 100644 --- a/include/linphone/call_log.h +++ b/include/linphone/call_log.h @@ -158,6 +158,13 @@ LINPHONE_PUBLIC char * linphone_call_log_to_str(LinphoneCallLog *cl); */ LINPHONE_PUBLIC bool_t linphone_call_log_was_conference(LinphoneCallLog *cl); +/** + * When the call was failed, return an object describing the failure. + * @param[in] cl #LinphoneCallLog object + * @return information about the error encountered by the call associated with this call log. +**/ +LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_log_get_error_info(LinphoneCallLog *cl); + /******************************************************************************* * Reference and user data handling functions * diff --git a/include/linphone/proxy_config.h b/include/linphone/proxy_config.h index 6c305140b..ba93f4919 100644 --- a/include/linphone/proxy_config.h +++ b/include/linphone/proxy_config.h @@ -486,10 +486,8 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(Linph * Indicates whether AVPF/SAVPF is being used for calls using this proxy config. * @param[in] cfg #LinphoneProxyConfig object. * @return True if AVPF/SAVPF is enabled, false otherwise. - * @deprecated use linphone_proxy_config_set_avpf_mode() - * @donotwrap */ -LINPHONE_DEPRECATED LINPHONE_PUBLIC bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg); +LINPHONE_PUBLIC bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg); /** * Set the interval between regular RTCP reports when using AVPF/SAVPF. diff --git a/include/linphone/types.h b/include/linphone/types.h index da699ccdf..a7aaa9e9a 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -324,7 +324,8 @@ typedef enum _LinphoneCallStatus { LinphoneCallSuccess, /**< The call was sucessful */ LinphoneCallAborted, /**< The call was aborted */ LinphoneCallMissed, /**< The call was missed (unanswered) */ - LinphoneCallDeclined /**< The call was declined, either locally or by remote end */ + LinphoneCallDeclined, /**< The call was declined, either locally or by remote end */ + LinphoneCallEarlyAborted /**modified_identity)); - tmp=linphone_address_as_string(id_addr); - linphone_proxy_config_set_identity(cfg,tmp); - ms_free(tmp); + linphone_proxy_config_set_identity_address(cfg, id_addr); if (create_account){ account_create_on_server(account,cfg,phone_alias); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 5b9d12f7f..2c08c73c5 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -535,7 +535,7 @@ static void simple_call(void) { static void simple_call_with_no_sip_transport(void){ LinphoneCoreManager* marie; LinphoneCoreManager* pauline; - LCSipTransports tr={0}; + LinphoneSipTransports tr={0}; LinphoneCall *call; marie = linphone_core_manager_new( "marie_rc"); @@ -657,7 +657,7 @@ static void direct_call_over_ipv6(void){ LinphoneCoreManager* pauline; if (liblinphone_tester_ipv6_available()){ - LCSipTransports pauline_transports; + LinphoneSipTransports pauline_transports; LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp"); marie = linphone_core_manager_new( "marie_rc"); pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); @@ -930,7 +930,7 @@ static void simple_call_compatibility_mode(void) { const LinphoneAddress* identity; LinphoneAddress* proxy_address; char*tmp; - LCSipTransports transport; + LinphoneSipTransports transport; proxy = linphone_core_get_default_proxy_config(lc_marie); BC_ASSERT_PTR_NOT_NULL (proxy); @@ -1033,7 +1033,7 @@ void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mime) { static void call_with_dns_time_out(void) { LinphoneCoreManager* marie = linphone_core_manager_new2( "empty_rc", FALSE); - LCSipTransports transport = {9773,0,0,0}; + LinphoneSipTransports transport = {9773,0,0,0}; int i; linphone_core_set_sip_transports(marie->lc,&transport); @@ -1816,6 +1816,8 @@ static void audio_call_with_ice_no_matching_audio_codecs(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *out_call; + const bctbx_list_t *logs; + LinphoneCallLog *cl; linphone_core_enable_payload_type(marie->lc, linphone_core_find_payload_type(marie->lc, "PCMU", 8000, 1), FALSE); /* Disable PCMU */ linphone_core_enable_payload_type(marie->lc, linphone_core_find_payload_type(marie->lc, "PCMA", 8000, 1), TRUE); /* Enable PCMA */ @@ -1833,6 +1835,21 @@ static void audio_call_with_ice_no_matching_audio_codecs(void) { BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallError, 1, 6000)); BC_ASSERT_EQUAL(linphone_call_get_reason(out_call), LinphoneReasonNotAcceptable, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + + logs = linphone_core_get_call_logs(pauline->lc); + + BC_ASSERT_EQUAL(bctbx_list_size(logs), 1, int, "%d"); + if (logs){ + const LinphoneErrorInfo *ei; + cl = (LinphoneCallLog*)logs->data; + BC_ASSERT_EQUAL(linphone_call_log_get_status(cl), LinphoneCallEarlyAborted, int, "%d"); + BC_ASSERT_TRUE(linphone_call_log_get_start_date(cl) != 0); + ei = linphone_call_log_get_error_info(cl); + BC_ASSERT_PTR_NOT_NULL(ei); + if (ei){ + BC_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonNotAcceptable, int, "%d"); + } + } linphone_call_unref(out_call); linphone_core_manager_destroy(marie); @@ -3282,6 +3299,8 @@ static void incoming_invite_with_invalid_sdp(void) { LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* callee = linphone_core_manager_new( "marie_rc"); LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; + LinphoneCallLog *cl; + const bctbx_list_t *logs; callee_test_params.sdp_simulate_error = TRUE; BC_ASSERT_FALSE(call_with_params2(caller,callee,&caller_test_params, &callee_test_params, FALSE)); @@ -3290,6 +3309,20 @@ static void incoming_invite_with_invalid_sdp(void) { BC_ASSERT_EQUAL(caller->stat.number_of_LinphoneCallError,1, int, "%d"); /*call will be drop before presented to the application, because it is invalid*/ BC_ASSERT_EQUAL(callee->stat.number_of_LinphoneCallIncomingReceived,0, int, "%d"); + + logs = linphone_core_get_call_logs(callee->lc); + BC_ASSERT_EQUAL(bctbx_list_size(logs), 1, int, "%i"); + if (logs){ + const LinphoneErrorInfo *ei; + cl = (LinphoneCallLog*)logs->data; + BC_ASSERT_EQUAL(linphone_call_log_get_status(cl), LinphoneCallEarlyAborted, int, "%d"); + BC_ASSERT_TRUE(linphone_call_log_get_start_date(cl) != 0); + ei = linphone_call_log_get_error_info(cl); + BC_ASSERT_PTR_NOT_NULL(ei); + if (ei){ + BC_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonNotAcceptable, int, "%d"); + } + } linphone_core_manager_destroy(callee); linphone_core_manager_destroy(caller); @@ -3497,7 +3530,7 @@ static void call_with_generic_cn(void) { } static void call_state_changed_2(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ - LCSipTransports sip_tr; + LinphoneSipTransports sip_tr; if (cstate==LinphoneCallReleased) { /*to make sure transport is changed*/ sip_tr.udp_port = 0; @@ -3521,7 +3554,7 @@ static void call_state_changed_3(LinphoneCore *lc, LinphoneCall *call, LinphoneC } static void call_with_transport_change_base(bool_t succesfull_call) { - LCSipTransports sip_tr; + LinphoneSipTransports sip_tr; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCoreVTable * v_table;