mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Merge remote-tracking branch 'origin/master' into dev_dtls
This commit is contained in:
commit
219451388d
41 changed files with 1025 additions and 517 deletions
12
Makefile.am
12
Makefile.am
|
|
@ -7,6 +7,8 @@ SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
|
|||
coreapi console gtk share scripts tools tester include
|
||||
|
||||
|
||||
GITVERSION=`cd $(top_srcdir) && git describe --always || echo $(VERSION)`
|
||||
|
||||
|
||||
ACLOCAL_FLAGS=-I$(top_srcdir)/m4
|
||||
|
||||
|
|
@ -20,11 +22,11 @@ OPTIONAL_SOUNDS=\
|
|||
|
||||
INSTALLDIR=$(abs_top_builddir)/linphone-install
|
||||
INSTALLDIR_WITH_PREFIX=$(INSTALLDIR)/$(prefix)
|
||||
ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(VERSION).zip
|
||||
ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(GITVERSION).zip
|
||||
ZIP_EXCLUDED=include lib \
|
||||
$(OPTIONAL_SOUNDS)
|
||||
|
||||
SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-$(VERSION).zip
|
||||
SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-sdk-$(GITVERSION).zip
|
||||
SDK_EXCLUDED= \
|
||||
bin/linphone.exe \
|
||||
lib/*.la \
|
||||
|
|
@ -173,7 +175,7 @@ setup.exe: filelist
|
|||
cp $(ISS_SCRIPT) $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cd $(INSTALLDIR_WITH_PREFIX) && \
|
||||
$(ISCC) $(ISS_SCRIPT)
|
||||
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-$(VERSION)-setup.exe
|
||||
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-setup-$(GITVERSION).exe
|
||||
rm -rf $(INSTALLDIR_WITH_PREFIX)/Output
|
||||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(PACKAGE_WIN32_FILELIST)
|
||||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(ISS_SCRIPT)
|
||||
|
|
@ -201,8 +203,8 @@ Portfile-devel: $(top_srcdir)/scripts/Portfile-devel.tmpl dist
|
|||
### MAC
|
||||
|
||||
MACAPPNAME=Linphone.app
|
||||
MACAPPZIP=$(PACKAGE)-$(VERSION).app.zip
|
||||
MACAPPDMG=$(PACKAGE)-$(VERSION).dmg
|
||||
MACAPPZIP=$(PACKAGE)-$(GITVERSION).app.zip
|
||||
MACAPPDMG=$(PACKAGE)-$(GITVERSION).dmg
|
||||
BUNDLEPREFIX=./
|
||||
BUNDLEDIR=$(BUNDLEPREFIX)$(MACAPPNAME)
|
||||
#a path prefix where additional libs can be cherry-picked by the bundler.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Install `GTK`. It is recommended to use the `quartz` backend for better integrat
|
|||
|
||||
brew install cairo --without-x11
|
||||
brew install gtk+ --without-x11
|
||||
brew install gettext gtk-mac-integration libsoup
|
||||
brew install gettext gtk-mac-integration libsoup hicolor-icon-theme
|
||||
#readline is required from linphonec.c otherwise compilation will fail
|
||||
brew link readline --force
|
||||
|
||||
|
|
@ -148,6 +148,15 @@ If you don't need plugins, remove or comment out this line from the bundler file
|
|||
${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so
|
||||
</binary>
|
||||
|
||||
If using HomeBrew, this is not working yet. However you will at least need to:
|
||||
|
||||
brew install shared-mime-info glib-networking hicolor-icon-theme
|
||||
update-mime-database /usr/local/share/mime
|
||||
|
||||
And modify also:
|
||||
|
||||
<prefix name="default">/usr/local</prefix>
|
||||
|
||||
Then run, inside Linphone source tree configure as told before but with `--enable-relativeprefix` appended.
|
||||
|
||||
make && make bundle
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ fi
|
|||
|
||||
INTLTOOLIZE=$(which intltoolize)
|
||||
|
||||
#workaround for mingw bug in intltoolize script.
|
||||
if test "$INTLTOOLIZE" = "/bin/intltoolize" ; then
|
||||
INTLTOOLIZE=/usr/bin/intltoolize
|
||||
fi
|
||||
|
||||
echo "Generating build scripts in linphone..."
|
||||
set -x
|
||||
$LIBTOOLIZE --copy --force
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ common_SRC_FILES := \
|
|||
transport_tester.c \
|
||||
player_tester.c \
|
||||
dtmf_tester.c \
|
||||
accountmanager.c
|
||||
accountmanager.c \
|
||||
offeranswer_tester.c
|
||||
|
||||
common_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
<string>Copyright 2011 Belledonne Communications</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.4</string>
|
||||
<key>NSAppSleepDisabled</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,10 @@ case $target in
|
|||
*mingw*)
|
||||
CFLAGS="$CFLAGS -DORTP_STATIC -D_WIN32_WINNT=0x0501 "
|
||||
CXXFLAGS="$CXXFLAGS -DORTP_STATIC -D_WIN32_WINNT=0x0501"
|
||||
LIBS="$LIBS -L/lib -lws2_32"
|
||||
dnl Workaround for mingw, whose compiler does not check in /usr/include ...
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/lib"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
GUI_FLAGS="-mwindows"
|
||||
CONSOLE_FLAGS="-mconsole"
|
||||
mingw_found=yes
|
||||
|
|
@ -298,7 +301,7 @@ if test "$build_zlib" != "false" ; then
|
|||
AC_MSG_NOTICE([zlib library and headers not found])
|
||||
else
|
||||
AC_DEFINE( HAVE_ZLIB, 1, [ZLIB support] )
|
||||
ZLIBS_LIBS='-z'
|
||||
ZLIB_LIBS='-lz'
|
||||
AC_SUBST(ZLIB_LIBS)
|
||||
fi
|
||||
else
|
||||
|
|
|
|||
|
|
@ -159,6 +159,13 @@ bool_t linphone_address_is_secure(const LinphoneAddress *uri){
|
|||
return sal_address_is_secure(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if address is a routable sip address
|
||||
*/
|
||||
bool_t linphone_address_is_sip(const LinphoneAddress *uri){
|
||||
return sal_address_is_sip(uri);
|
||||
}
|
||||
|
||||
static bool_t strings_equals(const char *s1, const char *s2){
|
||||
if (s1==NULL && s2==NULL) return TRUE;
|
||||
if (s1!=NULL && s2!=NULL && strcmp(s1,s2)==0) return TRUE;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,11 @@ char *sal_address_as_string(const SalAddress *addr){
|
|||
return ms_strdup(tmp);
|
||||
}
|
||||
|
||||
bool_t sal_address_is_sip(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
return belle_sip_header_address_get_uri(header_addr) != NULL;
|
||||
}
|
||||
|
||||
char *sal_address_as_string_uri_only(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
belle_sip_uri_t* sip_uri = belle_sip_header_address_get_uri(header_addr);
|
||||
|
|
@ -210,7 +215,7 @@ void sal_address_unref(SalAddress *addr){
|
|||
belle_sip_object_unref(BELLE_SIP_HEADER_ADDRESS(addr));
|
||||
}
|
||||
|
||||
bool_t sal_address_is_ipv6(SalAddress *addr){
|
||||
bool_t sal_address_is_ipv6(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
|
||||
if (uri){
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* ses
|
|||
error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length);
|
||||
if( error != BELLE_SIP_OK ){
|
||||
bufLen *= 2;
|
||||
length = 0;
|
||||
buff = belle_sip_realloc(buff,bufLen);
|
||||
}
|
||||
}
|
||||
|
|
@ -687,6 +688,11 @@ int sal_call(SalOp *op, const char *from, const char *to){
|
|||
ms_message("[%s] calling [%s] on op [%p]", from, to, op);
|
||||
invite=sal_op_build_request(op,"INVITE");
|
||||
|
||||
if( invite == NULL ){
|
||||
/* can happen if the op has an invalid address */
|
||||
return -1;
|
||||
}
|
||||
|
||||
sal_op_fill_invite(op,invite);
|
||||
|
||||
sal_op_call_fill_cbs(op);
|
||||
|
|
|
|||
|
|
@ -198,6 +198,9 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
|
|||
sal_op_subscribe_fill_cbs(op);
|
||||
/*???sal_exosip_fix_route(op); make sure to ha ;lr*/
|
||||
req=sal_op_build_request(op,"SUBSCRIBE");
|
||||
if( req == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
if (eventname){
|
||||
if (op->event) belle_sip_object_unref(op->event);
|
||||
op->event=belle_sip_header_create("Event",eventname);
|
||||
|
|
|
|||
|
|
@ -150,20 +150,37 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
|
|||
belle_sip_provider_t* prov=op->base.root->prov;
|
||||
belle_sip_request_t *req;
|
||||
belle_sip_uri_t* req_uri;
|
||||
belle_sip_uri_t* to_uri;
|
||||
|
||||
const SalAddress* to_address;
|
||||
const MSList *elem=sal_op_get_route_addresses(op);
|
||||
char token[10];
|
||||
|
||||
/* check that the op has a correct to address */
|
||||
to_address = sal_op_get_to_address(op);
|
||||
if( to_address == NULL ){
|
||||
ms_error("No To: address, cannot build request");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_uri = belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to_address));
|
||||
if( to_uri == NULL ){
|
||||
ms_error("To: address is invalid, cannot build request");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp("REGISTER",method)==0 || op->privacy==SalPrivacyNone) {
|
||||
from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op))
|
||||
,belle_sip_random_token(token,sizeof(token)));
|
||||
,belle_sip_random_token(token,sizeof(token)));
|
||||
} else {
|
||||
from_header=belle_sip_header_from_create2("Anonymous <sip:anonymous@anonymous.invalid>",belle_sip_random_token(token,sizeof(token)));
|
||||
}
|
||||
/*make sure to preserve components like headers or port*/
|
||||
req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(sal_op_get_to_address(op))));
|
||||
|
||||
req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)to_uri);
|
||||
belle_sip_uri_set_secure(req_uri,sal_op_is_secure(op));
|
||||
|
||||
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_to_address(op)),NULL);
|
||||
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(to_address),NULL);
|
||||
|
||||
req=belle_sip_request_create(
|
||||
req_uri,
|
||||
|
|
@ -218,7 +235,10 @@ int sal_ping(SalOp *op, const char *from, const char *to){
|
|||
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message) {
|
||||
belle_sip_header_user_agent_t* user_agent=belle_sip_message_get_header_by_type(message,belle_sip_header_user_agent_t);
|
||||
char user_agent_string[256];
|
||||
if(user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
|
||||
if (user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
|
||||
if (op->base.remote_ua!=NULL){
|
||||
ms_free(op->base.remote_ua);
|
||||
}
|
||||
op->base.remote_ua=ms_strdup(user_agent_string);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,9 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
|
|||
op->dir=SalOpDirOutgoing;
|
||||
|
||||
req=sal_op_build_request(op,"MESSAGE");
|
||||
if (req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,8 +306,10 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expi
|
|||
belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.from_address),"tag");
|
||||
belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.to_address),"tag");
|
||||
req=sal_op_build_request(op,"SUBSCRIBE");
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
if( req ){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
}
|
||||
|
||||
return sal_op_send_request(op,req);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expire
|
|||
|
||||
op->type=SalOpPublish;
|
||||
req=sal_op_build_request(op,"PUBLISH");
|
||||
|
||||
if( req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
@ -101,6 +106,10 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
|
|||
|
||||
sal_op_publish_fill_cbs(op);
|
||||
req=sal_op_build_request(op,"PUBLISH");
|
||||
if( req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,23 @@ static void prepare_early_media_forking(LinphoneCall *call){
|
|||
if (call->videostream){
|
||||
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_call_update_frozen_payloads(LinphoneCall *call, SalMediaDescription *result_desc){
|
||||
SalMediaDescription *local=call->localdesc;
|
||||
int i;
|
||||
for(i=0;i<result_desc->nb_streams;++i){
|
||||
MSList *elem;
|
||||
for (elem=result_desc->streams[i].payloads;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if (is_payload_type_number_available(local->streams[i].already_assigned_payloads, payload_type_get_number(pt), NULL)){
|
||||
/*new codec, needs to be added to the list*/
|
||||
local->streams[i].already_assigned_payloads=ms_list_append(local->streams[i].already_assigned_payloads, payload_type_clone(pt));
|
||||
ms_message("LinphoneCall[%p] : payload type %i %s/%i fmtp=%s added to frozen list.",
|
||||
call, payload_type_get_number(pt), pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
|
||||
|
|
@ -181,6 +197,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){
|
||||
linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
|
||||
}
|
||||
linphone_call_update_frozen_payloads(call, new_md);
|
||||
end:
|
||||
if (oldmd)
|
||||
sal_media_description_unref(oldmd);
|
||||
|
|
@ -597,7 +614,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
|
|||
}
|
||||
}
|
||||
|
||||
if (call->state==LinphoneCallStreamsRunning) {
|
||||
if ( call->state == LinphoneCallStreamsRunning) {
|
||||
/*reINVITE and in-dialogs UPDATE go here*/
|
||||
linphone_core_notify_display_status(lc,_("Call is updated by remote."));
|
||||
call->defer_update=FALSE;
|
||||
|
|
@ -605,8 +622,21 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
|
|||
if (call->defer_update==FALSE){
|
||||
linphone_core_accept_call_update(lc,call,NULL);
|
||||
}
|
||||
if (rmd==NULL)
|
||||
if (rmd==NULL){
|
||||
call->expect_media_in_ack=TRUE;
|
||||
}
|
||||
|
||||
} else if( call->state == LinphoneCallPausedByRemote ){
|
||||
/* Case where no SDP is present and we were paused by remote.
|
||||
* We send back an ACK with our SDP and expect the remote to send its own.
|
||||
* No state change here until an answer is received. */
|
||||
call->defer_update=FALSE;
|
||||
if (call->defer_update==FALSE){
|
||||
_linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state));
|
||||
}
|
||||
if (rmd==NULL){
|
||||
call->expect_media_in_ack=TRUE;
|
||||
}
|
||||
} else if (is_update){ /*SIP UPDATE case, can occur in early states*/
|
||||
linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote");
|
||||
_linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
|
|
|
|||
|
|
@ -234,35 +234,154 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t
|
|||
propagate_encryption_changed(call);
|
||||
}
|
||||
|
||||
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit,int* max_sample_rate, int nb_codecs_limit){
|
||||
MSList *l=NULL;
|
||||
static int get_max_codec_sample_rate(const MSList *codecs){
|
||||
int max_sample_rate=0;
|
||||
const MSList *it;
|
||||
int nb = 0;
|
||||
if (max_sample_rate) *max_sample_rate=0;
|
||||
for(it=codecs;it!=NULL;it=it->next){
|
||||
PayloadType *pt=(PayloadType*)it->data;
|
||||
if (pt->flags & PAYLOAD_TYPE_ENABLED){
|
||||
int sample_rate = payload_type_get_rate(pt);
|
||||
int sample_rate;
|
||||
|
||||
if( strcasecmp("G722",pt->mime_type) == 0 ){
|
||||
/* G722 spec says 8000 but the codec actually requires 16000 */
|
||||
sample_rate = 16000;
|
||||
}else sample_rate=pt->clock_rate;
|
||||
if (sample_rate>max_sample_rate) max_sample_rate=sample_rate;
|
||||
}
|
||||
return max_sample_rate;
|
||||
}
|
||||
|
||||
if( strcasecmp("G722",pt->mime_type) == 0 ){
|
||||
/* G722 spec says 8000 but the codec actually requires 16000 */
|
||||
ms_debug("Correcting sample rate for G722");
|
||||
sample_rate = 16000;
|
||||
}
|
||||
|
||||
if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){
|
||||
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s",
|
||||
pt->mime_type,pt->clock_rate,bandwidth_limit);
|
||||
continue;
|
||||
}
|
||||
if (linphone_core_check_payload_type_usability(lc,pt)){
|
||||
l=ms_list_append(l,payload_type_clone(pt));
|
||||
nb++;
|
||||
if (max_sample_rate && sample_rate>*max_sample_rate) *max_sample_rate=sample_rate;
|
||||
static int find_payload_type_number(const MSList *assigned, const PayloadType *pt){
|
||||
const MSList *elem;
|
||||
const PayloadType *candidate=NULL;
|
||||
for(elem=assigned;elem!=NULL;elem=elem->next){
|
||||
const PayloadType *it=(const PayloadType*)elem->data;
|
||||
if ((strcasecmp(pt->mime_type, payload_type_get_mime(it)) == 0)
|
||||
&& (it->clock_rate==pt->clock_rate)
|
||||
&& (it->channels==pt->channels || pt->channels<=0)) {
|
||||
candidate=it;
|
||||
if ((it->recv_fmtp!=NULL && pt->recv_fmtp!=NULL && strcasecmp(it->recv_fmtp, pt->recv_fmtp)==0)
|
||||
|| (it->recv_fmtp==NULL && pt->recv_fmtp==NULL)){
|
||||
break;/*exact match*/
|
||||
}
|
||||
}
|
||||
if ((nb_codecs_limit > 0) && (nb >= nb_codecs_limit)) break;
|
||||
}
|
||||
return candidate ? payload_type_get_number(candidate) : -1;
|
||||
}
|
||||
|
||||
bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore){
|
||||
const MSList *elem;
|
||||
for (elem=l; elem!=NULL; elem=elem->next){
|
||||
const PayloadType *pt=(PayloadType*)elem->data;
|
||||
if (pt!=ignore && payload_type_get_number(pt)==number) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList *codecs){
|
||||
MSList *elem;
|
||||
int dyn_number=lc->codecs_conf.dyn_pt;
|
||||
for (elem=codecs; elem!=NULL; elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
int number=payload_type_get_number(pt);
|
||||
|
||||
/*check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer*/
|
||||
if (number!=-1 && !(pt->flags & PAYLOAD_TYPE_FROZEN_NUMBER)){
|
||||
if (!is_payload_type_number_available(codecs, number, pt)){
|
||||
ms_message("Reassigning payload type %i %s/%i because already offered.", number, pt->mime_type, pt->clock_rate);
|
||||
number=-1; /*need to be re-assigned*/
|
||||
}
|
||||
}
|
||||
|
||||
if (number==-1){
|
||||
while(dyn_number<127){
|
||||
if (is_payload_type_number_available(codecs, dyn_number, NULL)){
|
||||
payload_type_set_number(pt, dyn_number);
|
||||
dyn_number++;
|
||||
break;
|
||||
}
|
||||
dyn_number++;
|
||||
}
|
||||
if (dyn_number==127){
|
||||
ms_error("Too many payload types configured ! codec %s/%i is disabled.", pt->mime_type, pt->clock_rate);
|
||||
payload_type_set_enable(pt, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t has_telephone_event_at_rate(const MSList *tev, int rate){
|
||||
const MSList *it;
|
||||
for(it=tev;it!=NULL;it=it->next){
|
||||
const PayloadType *pt=(PayloadType*)it->data;
|
||||
if (pt->clock_rate==rate) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MSList * create_telephone_events(LinphoneCore *lc, const MSList *codecs){
|
||||
const MSList *it;
|
||||
MSList *ret=NULL;
|
||||
for(it=codecs;it!=NULL;it=it->next){
|
||||
const PayloadType *pt=(PayloadType*)it->data;
|
||||
if (!has_telephone_event_at_rate(ret,pt->clock_rate)){
|
||||
PayloadType *tev=payload_type_clone(&payload_type_telephone_event);
|
||||
tev->clock_rate=pt->clock_rate;
|
||||
/*let it choose the number dynamically as for normal codecs*/
|
||||
payload_type_set_number(tev, -1);
|
||||
if (ret==NULL){
|
||||
/*But for first telephone-event, prefer the number that was configured in the core*/
|
||||
if (is_payload_type_number_available(codecs, lc->codecs_conf.telephone_event_pt, NULL)){
|
||||
payload_type_set_number(tev, lc->codecs_conf.telephone_event_pt);
|
||||
}
|
||||
}
|
||||
ret=ms_list_append(ret,tev);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct _CodecConstraints{
|
||||
int bandwidth_limit;
|
||||
int max_codecs;
|
||||
MSList *previously_used;
|
||||
}CodecConstraints;
|
||||
|
||||
static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, const MSList *codecs){
|
||||
MSList *l=NULL;
|
||||
MSList *tevs=NULL;
|
||||
const MSList *it;
|
||||
int nb = 0;
|
||||
|
||||
for(it=codecs;it!=NULL;it=it->next){
|
||||
PayloadType *pt=(PayloadType*)it->data;
|
||||
int num;
|
||||
|
||||
if (!(pt->flags & PAYLOAD_TYPE_ENABLED))
|
||||
continue;
|
||||
if (hints->bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,hints->bandwidth_limit)){
|
||||
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s",
|
||||
pt->mime_type,pt->clock_rate,hints->bandwidth_limit);
|
||||
continue;
|
||||
}
|
||||
if (!linphone_core_check_payload_type_usability(lc,pt)){
|
||||
continue;
|
||||
}
|
||||
pt=payload_type_clone(pt);
|
||||
|
||||
/*look for a previously assigned number for this codec*/
|
||||
num=find_payload_type_number(hints->previously_used, pt);
|
||||
if (num!=-1){
|
||||
payload_type_set_number(pt,num);
|
||||
payload_type_set_flag(pt, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
}
|
||||
|
||||
l=ms_list_append(l, pt);
|
||||
nb++;
|
||||
if ((hints->max_codecs > 0) && (nb >= hints->max_codecs)) break;
|
||||
}
|
||||
tevs=create_telephone_events(lc,l);
|
||||
l=ms_list_concat(l,tevs);
|
||||
linphone_core_assign_payload_type_numbers(lc, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
|
@ -401,9 +520,16 @@ void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall
|
|||
#endif //BUILD_UPNP
|
||||
}
|
||||
|
||||
static void transfer_already_assigned_payload_types(SalMediaDescription *old, SalMediaDescription *md){
|
||||
int i;
|
||||
for(i=0;i<old->nb_streams;++i){
|
||||
md->streams[i].already_assigned_payloads=old->streams[i].already_assigned_payloads;
|
||||
old->streams[i].already_assigned_payloads=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
SalMediaDescription *old_md=call->localdesc;
|
||||
int i;
|
||||
int nb_active_streams = 0;
|
||||
|
|
@ -412,6 +538,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
LinphoneAddress *addr;
|
||||
char* local_ip=call->localip;
|
||||
const char *subject=linphone_call_params_get_session_name(call->params);
|
||||
CodecConstraints codec_hints={0};
|
||||
|
||||
linphone_core_adapt_to_network(lc,call->ping_time,call->params);
|
||||
|
||||
|
|
@ -445,9 +572,11 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
md->streams[0].ptime=call->params->down_ptime;
|
||||
else
|
||||
md->streams[0].ptime=linphone_core_get_download_ptime(lc);
|
||||
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params->audio_bw,&md->streams[0].max_rate,-1);
|
||||
pt=payload_type_clone(rtp_profile_get_payload_from_mime(lc->default_profile,"telephone-event"));
|
||||
l=ms_list_append(l,pt);
|
||||
codec_hints.bandwidth_limit=call->params->audio_bw;
|
||||
codec_hints.max_codecs=-1;
|
||||
codec_hints.previously_used=old_md ? old_md->streams[0].already_assigned_payloads : NULL;
|
||||
l=make_codec_list(lc, &codec_hints, lc->codecs_conf.audio_codecs);
|
||||
md->streams[0].max_rate=get_max_codec_sample_rate(l);
|
||||
md->streams[0].payloads=l;
|
||||
if (call->audiostream && call->audiostream->ms.sessions.rtp_session) {
|
||||
char* me = linphone_address_as_string_uri_only(call->me);
|
||||
|
|
@ -467,7 +596,10 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
md->streams[1].rtcp_port=call->media_ports[1].rtcp_port;
|
||||
md->streams[1].proto=md->streams[0].proto;
|
||||
md->streams[1].type=SalVideo;
|
||||
l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL,-1);
|
||||
codec_hints.bandwidth_limit=0;
|
||||
codec_hints.max_codecs=-1;
|
||||
codec_hints.previously_used=old_md ? old_md->streams[1].already_assigned_payloads : NULL;
|
||||
l=make_codec_list(lc, &codec_hints, lc->codecs_conf.video_codecs);
|
||||
md->streams[1].payloads=l;
|
||||
if (call->videostream && call->videostream->ms.sessions.rtp_session) {
|
||||
char* me = linphone_address_as_string_uri_only(call->me);
|
||||
|
|
@ -490,7 +622,10 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
md->streams[i].proto = call->biggestdesc->streams[i].proto;
|
||||
md->streams[i].type = call->biggestdesc->streams[i].type;
|
||||
md->streams[i].dir = SalStreamInactive;
|
||||
l = make_codec_list(lc, lc->codecs_conf.video_codecs, 0, NULL, 1);
|
||||
codec_hints.bandwidth_limit=0;
|
||||
codec_hints.max_codecs=1;
|
||||
codec_hints.previously_used=NULL;
|
||||
l = make_codec_list(lc, &codec_hints, lc->codecs_conf.video_codecs);
|
||||
md->streams[i].payloads = l;
|
||||
}
|
||||
|
||||
|
|
@ -511,6 +646,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
linphone_call_update_local_media_description_from_ice_or_upnp(call);
|
||||
linphone_address_destroy(addr);
|
||||
if (old_md){
|
||||
transfer_already_assigned_payload_types(old_md,md);
|
||||
call->localdesc_changed=sal_media_description_equals(md,old_md);
|
||||
sal_media_description_unref(old_md);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -983,12 +983,13 @@ static void rtp_config_read(LinphoneCore *lc)
|
|||
linphone_core_set_avpf_mode(lc,lp_config_get_int(lc->config,"rtp","avpf",0));
|
||||
}
|
||||
|
||||
static PayloadType * find_payload(RtpProfile *prof, const char *mime_type, int clock_rate, int channels, const char *recv_fmtp){
|
||||
static PayloadType * find_payload(const MSList *default_list, const char *mime_type, int clock_rate, int channels, const char *recv_fmtp){
|
||||
PayloadType *candidate=NULL;
|
||||
int i;
|
||||
PayloadType *it;
|
||||
for(i=0;i<RTP_PROFILE_MAX_PAYLOADS;++i){
|
||||
it=rtp_profile_get_payload(prof,i);
|
||||
const MSList *elem;
|
||||
|
||||
for(elem=default_list;elem!=NULL;elem=elem->next){
|
||||
it=(PayloadType*)elem->data;
|
||||
if (it!=NULL && strcasecmp(mime_type,it->mime_type)==0
|
||||
&& (clock_rate==it->clock_rate || clock_rate<=0)
|
||||
&& (channels==it->channels || channels<=0) ){
|
||||
|
|
@ -1010,7 +1011,20 @@ static PayloadType * find_payload(RtpProfile *prof, const char *mime_type, int c
|
|||
return candidate;
|
||||
}
|
||||
|
||||
static bool_t get_codec(LinphoneCore *lc, const char* type, int index, PayloadType **ret){
|
||||
static PayloadType* find_payload_type_from_list(const char* type, int rate, int channels, const MSList* from) {
|
||||
const MSList *elem;
|
||||
for(elem=from;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if ((strcasecmp(type, payload_type_get_mime(pt)) == 0)
|
||||
&& (rate == LINPHONE_FIND_PAYLOAD_IGNORE_RATE || rate==pt->clock_rate)
|
||||
&& (channels == LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS || channels==pt->channels)) {
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, PayloadType **ret){
|
||||
char codeckey[50];
|
||||
const char *mime,*fmtp;
|
||||
int rate,channels,enabled;
|
||||
|
|
@ -1018,7 +1032,7 @@ static bool_t get_codec(LinphoneCore *lc, const char* type, int index, PayloadTy
|
|||
LpConfig *config=lc->config;
|
||||
|
||||
*ret=NULL;
|
||||
snprintf(codeckey,50,"%s_%i",type,index);
|
||||
snprintf(codeckey,50,"%s_codec_%i",type==SalAudio ? "audio" : "video", index);
|
||||
mime=lp_config_get_string(config,codeckey,"mime",NULL);
|
||||
if (mime==NULL || strlen(mime)==0 ) return FALSE;
|
||||
|
||||
|
|
@ -1026,85 +1040,52 @@ static bool_t get_codec(LinphoneCore *lc, const char* type, int index, PayloadTy
|
|||
fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL);
|
||||
channels=lp_config_get_int(config,codeckey,"channels",0);
|
||||
enabled=lp_config_get_int(config,codeckey,"enabled",1);
|
||||
pt=find_payload(lc->default_profile,mime,rate,channels,fmtp);
|
||||
if (pt && enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED;
|
||||
//ms_message("Found codec %s/%i",pt->mime_type,pt->clock_rate);
|
||||
if (pt==NULL) ms_warning("Ignoring codec config %s/%i with fmtp=%s because unsupported",
|
||||
mime,rate,fmtp ? fmtp : "");
|
||||
if (!ms_filter_codec_supported(mime)){
|
||||
ms_warning("Codec %s/%i read from conf is not supported by mediastreamer2, ignored.",mime,rate);
|
||||
return TRUE;
|
||||
}
|
||||
pt=find_payload(type==SalAudio ? lc->default_audio_codecs : lc->default_video_codecs,mime,rate,channels,fmtp);
|
||||
if (!pt){
|
||||
MSList **default_list=(type==SalAudio) ? &lc->default_audio_codecs : &lc->default_video_codecs;
|
||||
ms_warning("Codec %s/%i read from conf is not in the default list.",mime,rate);
|
||||
pt=payload_type_new();
|
||||
pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : PAYLOAD_VIDEO;
|
||||
pt->mime_type=ortp_strdup(mime);
|
||||
pt->clock_rate=rate;
|
||||
pt->channels=channels;
|
||||
payload_type_set_recv_fmtp(pt,fmtp);
|
||||
*default_list=ms_list_append(*default_list, pt);
|
||||
}
|
||||
if (enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED;
|
||||
*ret=pt;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define RANK_END 10000
|
||||
|
||||
typedef struct codec_desc{
|
||||
const char *name;
|
||||
int rate;
|
||||
}codec_desc_t;
|
||||
|
||||
static codec_desc_t codec_pref_order[]={
|
||||
{"opus", 48000},
|
||||
{"SILK", 16000},
|
||||
{"speex", 16000},
|
||||
{"speex", 8000},
|
||||
{"pcmu",8000},
|
||||
{"pcma",8000},
|
||||
{"VP8",90000},
|
||||
{"H264",90000},
|
||||
{"MP4V-ES",90000},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
static int find_codec_rank(const char *mime, int clock_rate){
|
||||
int i;
|
||||
|
||||
#ifdef __arm__
|
||||
/*hack for opus, that needs to be disabed by default on ARM single processor, otherwise there is no cpu left for video processing*/
|
||||
if (strcasecmp(mime,"opus")==0){
|
||||
if (ms_get_cpu_count()==1) return RANK_END;
|
||||
}
|
||||
#endif
|
||||
for(i=0;codec_pref_order[i].name!=NULL;++i){
|
||||
if (strcasecmp(codec_pref_order[i].name,mime)==0 && clock_rate==codec_pref_order[i].rate)
|
||||
return i;
|
||||
}
|
||||
return RANK_END;
|
||||
}
|
||||
|
||||
static int codec_compare(const PayloadType *a, const PayloadType *b){
|
||||
int ra,rb;
|
||||
ra=find_codec_rank(a->mime_type,a->clock_rate);
|
||||
rb=find_codec_rank(b->mime_type,b->clock_rate);
|
||||
if (ra>rb) return 1;
|
||||
if (ra<rb) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static MSList *add_missing_codecs(LinphoneCore *lc, SalStreamType mtype, MSList *l){
|
||||
int i;
|
||||
for(i=0;i<RTP_PROFILE_MAX_PAYLOADS;++i){
|
||||
PayloadType *pt=rtp_profile_get_payload(lc->default_profile,i);
|
||||
if (pt){
|
||||
if (mtype==SalVideo && pt->type!=PAYLOAD_VIDEO)
|
||||
pt=NULL;
|
||||
else if (mtype==SalAudio && (pt->type!=PAYLOAD_AUDIO_PACKETIZED
|
||||
&& pt->type!=PAYLOAD_AUDIO_CONTINUOUS)){
|
||||
pt=NULL;
|
||||
}
|
||||
if (pt && ms_filter_codec_supported(pt->mime_type)){
|
||||
if (ms_list_find(l,pt)==NULL){
|
||||
/*unranked codecs are disabled by default*/
|
||||
if (find_codec_rank(pt->mime_type, pt->clock_rate)!=RANK_END){
|
||||
payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED);
|
||||
}
|
||||
ms_message("Adding new codec %s/%i with fmtp %s",
|
||||
pt->mime_type,pt->clock_rate,pt->recv_fmtp ? pt->recv_fmtp : "");
|
||||
l=ms_list_insert_sorted(l,pt,(int (*)(const void *, const void *))codec_compare);
|
||||
}
|
||||
/*this function merges the payload types from the codec default list with the list read from configuration file.
|
||||
* If a new codec becomes supported in Liblinphone or if the list from configuration file is empty or incomplete, all the supported codecs are added
|
||||
* automatically. This 'l' list is entirely destroyed and rewritten.*/
|
||||
static MSList *add_missing_codecs(const MSList *default_list, MSList *l){
|
||||
const MSList *elem;
|
||||
MSList *newlist;
|
||||
|
||||
for(elem=default_list; elem!=NULL; elem=elem->next){
|
||||
MSList *elem2=ms_list_find(l,elem->data);
|
||||
if (!elem2){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
/*this codec from default list should be inserted in the list*/
|
||||
if (!elem->prev){
|
||||
l=ms_list_prepend(l,pt);
|
||||
}else{
|
||||
const MSList *after=ms_list_find(l,elem->prev->data);
|
||||
l=ms_list_insert(l, after->next, pt);
|
||||
}
|
||||
ms_message("Supported codec %s/%i fmtp=%s automatically added to codec list.", pt->mime_type,
|
||||
pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : "");
|
||||
}
|
||||
}
|
||||
return l;
|
||||
newlist=ms_list_copy_with_data(l,(void *(*)(void*))payload_type_clone);
|
||||
ms_list_free(l);
|
||||
return newlist;
|
||||
}
|
||||
|
||||
static MSList *codec_append_if_new(MSList *l, PayloadType *pt){
|
||||
|
|
@ -1124,23 +1105,23 @@ static void codecs_config_read(LinphoneCore *lc)
|
|||
PayloadType *pt;
|
||||
MSList *audio_codecs=NULL;
|
||||
MSList *video_codecs=NULL;
|
||||
for (i=0;get_codec(lc,"audio_codec",i,&pt);i++){
|
||||
|
||||
lc->codecs_conf.dyn_pt=96;
|
||||
lc->codecs_conf.telephone_event_pt=lp_config_get_int(lc->config,"misc","telephone_event_pt",101);
|
||||
|
||||
for (i=0;get_codec(lc,SalAudio,i,&pt);i++){
|
||||
if (pt){
|
||||
if (!ms_filter_codec_supported(pt->mime_type)){
|
||||
ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
|
||||
}else audio_codecs=codec_append_if_new(audio_codecs,pt);
|
||||
audio_codecs=codec_append_if_new(audio_codecs, pt);
|
||||
}
|
||||
}
|
||||
audio_codecs=add_missing_codecs(lc,SalAudio,audio_codecs);
|
||||
audio_codecs=add_missing_codecs(lc->default_audio_codecs,audio_codecs);
|
||||
|
||||
for (i=0;get_codec(lc,"video_codec",i,&pt);i++){
|
||||
for (i=0;get_codec(lc,SalVideo,i,&pt);i++){
|
||||
if (pt){
|
||||
if (!ms_filter_codec_supported(pt->mime_type)){
|
||||
ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
|
||||
}else video_codecs=codec_append_if_new(video_codecs,(void *)pt);
|
||||
video_codecs=codec_append_if_new(video_codecs, pt);
|
||||
}
|
||||
}
|
||||
video_codecs=add_missing_codecs(lc,SalVideo,video_codecs);
|
||||
video_codecs=add_missing_codecs(lc->default_video_codecs,video_codecs);
|
||||
linphone_core_set_audio_codecs(lc,audio_codecs);
|
||||
linphone_core_set_video_codecs(lc,video_codecs);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
|
|
@ -1413,60 +1394,45 @@ const char * linphone_core_get_version(void){
|
|||
return liblinphone_version;
|
||||
}
|
||||
|
||||
static void linphone_core_assign_payload_type(LinphoneCore *lc, PayloadType *const_pt, int number, const char *recv_fmtp){
|
||||
PayloadType *pt;
|
||||
|
||||
pt=payload_type_clone(const_pt);
|
||||
if (number==-1){
|
||||
/*look for a free number */
|
||||
MSList *elem;
|
||||
int i;
|
||||
for(i=lc->dyn_pt;i<RTP_PROFILE_MAX_PAYLOADS;++i){
|
||||
bool_t already_assigned=FALSE;
|
||||
for(elem=lc->payload_types;elem!=NULL;elem=elem->next){
|
||||
PayloadType *it=(PayloadType*)elem->data;
|
||||
if (payload_type_get_number(it)==i){
|
||||
already_assigned=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!already_assigned){
|
||||
number=i;
|
||||
lc->dyn_pt=i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (number==-1){
|
||||
ms_fatal("FIXME: too many codecs, no more free numbers.");
|
||||
}
|
||||
static void linphone_core_register_payload_type(LinphoneCore *lc, const PayloadType *const_pt, const char *recv_fmtp, bool_t enabled){
|
||||
MSList **codec_list=const_pt->type==PAYLOAD_VIDEO ? &lc->default_video_codecs : &lc->default_audio_codecs;
|
||||
if (ms_filter_codec_supported(const_pt->mime_type)){
|
||||
PayloadType *pt=payload_type_clone(const_pt);
|
||||
int number=-1;
|
||||
payload_type_set_enable(pt,enabled);
|
||||
if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp);
|
||||
/*Set a number to the payload type from the statically defined (RFC3551) profile, if not static, -1 is returned
|
||||
and the payload type number will be determined dynamically later, at call time.*/
|
||||
payload_type_set_number(pt,
|
||||
(number=rtp_profile_find_payload_number(&av_profile, pt->mime_type, pt->clock_rate, pt->channels))
|
||||
);
|
||||
ms_message("Codec %s/%i fmtp=[%s] number=%i, enabled=%i) added to default capabilities.", pt->mime_type, pt->clock_rate,
|
||||
pt->recv_fmtp ? pt->recv_fmtp : "", number, (int)payload_type_enabled(pt));
|
||||
*codec_list=ms_list_append(*codec_list,pt);
|
||||
}
|
||||
ms_message("assigning %s/%i payload type number %i",pt->mime_type,pt->clock_rate,number);
|
||||
payload_type_set_number(pt,number);
|
||||
if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp);
|
||||
rtp_profile_set_payload(lc->default_profile,number,pt);
|
||||
lc->payload_types=ms_list_append(lc->payload_types,pt);
|
||||
}
|
||||
|
||||
static void linphone_core_handle_static_payloads(LinphoneCore *lc){
|
||||
static void linphone_core_register_static_payloads(LinphoneCore *lc){
|
||||
RtpProfile *prof=&av_profile;
|
||||
int i;
|
||||
for(i=0;i<RTP_PROFILE_MAX_PAYLOADS;++i){
|
||||
PayloadType *pt=rtp_profile_get_payload(prof,i);
|
||||
if (pt){
|
||||
// insert static payload only if no profile exists
|
||||
if (rtp_profile_get_payload(lc->default_profile,i) == NULL){
|
||||
linphone_core_assign_payload_type(lc,pt,i,NULL);
|
||||
#ifndef VIDEO_ENABLED
|
||||
if (pt->type==PAYLOAD_VIDEO) continue;
|
||||
#endif
|
||||
if (find_payload_type_from_list(
|
||||
pt->mime_type, pt->clock_rate, pt->type!=PAYLOAD_VIDEO ? pt->channels : LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS,
|
||||
pt->type==PAYLOAD_VIDEO ? lc->default_video_codecs : lc->default_audio_codecs)==NULL){
|
||||
linphone_core_register_payload_type(lc,pt,NULL,FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_core_free_payload_types(LinphoneCore *lc){
|
||||
rtp_profile_clear_all(lc->default_profile);
|
||||
rtp_profile_destroy(lc->default_profile);
|
||||
ms_list_for_each(lc->payload_types,(void (*)(void*))payload_type_destroy);
|
||||
ms_list_free(lc->payload_types);
|
||||
lc->payload_types=NULL;
|
||||
ms_list_free_with_data(lc->default_audio_codecs, (void (*)(void*))payload_type_destroy);
|
||||
ms_list_free_with_data(lc->default_video_codecs, (void (*)(void*))payload_type_destroy);
|
||||
}
|
||||
|
||||
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message){
|
||||
|
|
@ -1548,10 +1514,73 @@ static void linphone_core_deactivate_log_serialization_if_needed(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata)
|
||||
{
|
||||
const char *remote_provisioning_uri = NULL;
|
||||
static void linphone_core_register_default_codecs(LinphoneCore *lc){
|
||||
const char *aac_fmtp162248, *aac_fmtp3244;
|
||||
bool_t opus_enabled=TRUE;
|
||||
/*default enabled audio codecs, in order of preference*/
|
||||
#ifdef __arm__
|
||||
/*hack for opus, that needs to be disabed by default on ARM single processor, otherwise there is no cpu left for video processing*/
|
||||
if (ms_get_cpu_count()==1) opus_enabled=FALSE;
|
||||
#endif
|
||||
linphone_core_register_payload_type(lc,&payload_type_opus,"useinbandfec=1; stereo=0; sprop-stereo=0",opus_enabled);
|
||||
linphone_core_register_payload_type(lc,&payload_type_silk_wb,NULL,TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_speex_wb,"vbr=on",TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_speex_nb,"vbr=on",TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_pcmu8000,NULL,TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_pcma8000,NULL,TRUE);
|
||||
|
||||
/*other audio codecs, not enabled by default, in order of preference*/
|
||||
linphone_core_register_payload_type(lc,&payload_type_gsm,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g722,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_ilbc,"mode=30",FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_amr,"octet-align=1",FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_amrwb,"octet-align=1",FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g729,"annexb=no",FALSE);
|
||||
/* For AAC, we use a config value to determine if we ought to support SBR. Since it is not offically supported
|
||||
* for the mpeg4-generic mime type, setting this flag to 1 will break compatibility with other clients. */
|
||||
if( lp_config_get_int(lc->config, "misc", "aac_use_sbr", FALSE) ) {
|
||||
ms_message("Using SBR for AAC");
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
} else {
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
}
|
||||
linphone_core_register_payload_type(lc,&payload_type_aaceld_16k,aac_fmtp162248,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aaceld_22k,aac_fmtp162248,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aaceld_32k,aac_fmtp3244,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aaceld_44k,aac_fmtp3244,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aaceld_48k,aac_fmtp162248,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_isac,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_speex_uwb,"vbr=on",FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_silk_nb,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_silk_mb,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_silk_swb,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g726_16,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g726_24,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g726_32,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_g726_40,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_16,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_24,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_32,NULL,FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_40,NULL,FALSE);
|
||||
|
||||
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
/*default enabled video codecs, in order of preference*/
|
||||
linphone_core_register_payload_type(lc,&payload_type_vp8,NULL,TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_h264,"profile-level-id=42801F",TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_mp4v,"profile-level-id=3",TRUE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_h263_1998,"CIF=1;QCIF=1",FALSE);
|
||||
linphone_core_register_payload_type(lc,&payload_type_h263,NULL,FALSE);
|
||||
#endif
|
||||
/*register all static payload types declared in av_profile of oRTP, if not already declared above*/
|
||||
linphone_core_register_static_payloads(lc);
|
||||
}
|
||||
|
||||
static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata){
|
||||
const char *remote_provisioning_uri = NULL;
|
||||
LinphoneCoreVTable* local_vtable= linphone_core_v_table_new();
|
||||
ms_message("Initializing LinphoneCore %s", linphone_core_get_version());
|
||||
|
||||
|
|
@ -1565,83 +1594,10 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
|
||||
ortp_init();
|
||||
linphone_core_activate_log_serialization_if_needed();
|
||||
lc->dyn_pt=96;
|
||||
lc->default_profile=rtp_profile_new("default profile");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_pcmu8000,0,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_gsm,3,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_pcma8000,8,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_speex_nb,110,"vbr=on");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_speex_wb,111,"vbr=on");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_speex_uwb,112,"vbr=on");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_telephone_event,101,"0-15");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g722,9,NULL);
|
||||
|
||||
#ifdef ENABLE_NONSTANDARD_GSM
|
||||
{
|
||||
PayloadType *pt;
|
||||
pt=payload_type_clone(&payload_type_gsm);
|
||||
pt->clock_rate=11025;
|
||||
linphone_core_assign_payload_type(lc,pt,-1,NULL);
|
||||
pt->clock_rate=22050;
|
||||
linphone_core_assign_payload_type(lc,pt,-1,NULL);
|
||||
payload_type_destroy(pt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
||||
linphone_core_assign_payload_type(lc,&payload_type_h263,34,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_h263_1998,98,"CIF=1;QCIF=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_mp4v,99,"profile-level-id=3");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_h264,102,"profile-level-id=42801F");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_vp8,103,NULL);
|
||||
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL); commented out to free 1 slot */
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL); commented out to free 1 slot */
|
||||
/* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */
|
||||
/* linphone_core_assign_payload_type(&payload_type_h264,-1,"packetization-mode=1;profile-level-id=428014");*/
|
||||
#endif
|
||||
|
||||
/* For AAC, we use a config value to determine if we ought to support SBR. Since it is not offically supported
|
||||
* for the mpeg4-generic mime type, setting this flag to 1 will break compatibility with other clients. */
|
||||
if( lp_config_get_int(lc->config, "misc", "aac_use_sbr", FALSE) ) {
|
||||
ms_message("Using SBR for AAC");
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
} else {
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
}
|
||||
|
||||
|
||||
/*add all payload type for which we don't care about the number */
|
||||
linphone_core_assign_payload_type(lc,&payload_type_ilbc,-1,"mode=30");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_amr,-1,"octet-align=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_amrwb,-1,"octet-align=1");
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_lpc1015,-1,NULL); commented out to free 1 slot */
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_16,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_24,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_32,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_40,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_16,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_24,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_32,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_40,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_silk_nb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_silk_mb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_silk_wb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_silk_swb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g729,18,"annexb=no");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_16k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_22k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_32k,-1,aac_fmtp3244);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_44k,-1,aac_fmtp3244);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_48k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; stereo=0; sprop-stereo=0");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_isac,-1,NULL);
|
||||
linphone_core_handle_static_payloads(lc);
|
||||
|
||||
|
||||
ms_init();
|
||||
|
||||
linphone_core_register_default_codecs(lc);
|
||||
/* create a mediastreamer2 event queue and set it as global */
|
||||
/* This allows to run event's callback in linphone_core_iterate() */
|
||||
lc->msevq=ms_event_queue_new();
|
||||
|
|
@ -1848,8 +1804,7 @@ LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc){
|
|||
* 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.
|
||||
**/
|
||||
int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs)
|
||||
{
|
||||
int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs){
|
||||
if (lc->codecs_conf.audio_codecs!=NULL) ms_list_free(lc->codecs_conf.audio_codecs);
|
||||
lc->codecs_conf.audio_codecs=codecs;
|
||||
_linphone_core_codec_config_write(lc);
|
||||
|
|
@ -1867,8 +1822,7 @@ int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs)
|
|||
* 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.
|
||||
**/
|
||||
int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs)
|
||||
{
|
||||
int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs){
|
||||
if (lc->codecs_conf.video_codecs!=NULL) ms_list_free(lc->codecs_conf.video_codecs);
|
||||
lc->codecs_conf.video_codecs=codecs;
|
||||
_linphone_core_codec_config_write(lc);
|
||||
|
|
@ -2632,6 +2586,15 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
|
||||
static LinphoneAddress* _linphone_core_destroy_addr_if_not_sip( LinphoneAddress* addr ){
|
||||
if( linphone_address_is_sip(addr) ) {
|
||||
return addr;
|
||||
} else {
|
||||
linphone_address_destroy(addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a call destination as supplied by the user, and returns a fully qualified
|
||||
* LinphoneAddress.
|
||||
|
|
@ -2668,7 +2631,7 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url)
|
|||
tmpurl=enumres->sip_address[0];
|
||||
uri=linphone_address_new(tmpurl);
|
||||
enum_lookup_res_free(enumres);
|
||||
return uri;
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
/* check if we have a "sip:" or a "sips:" */
|
||||
if ( (strstr(url,"sip:")==NULL) && (strstr(url,"sips:")==NULL) ){
|
||||
|
|
@ -2679,7 +2642,7 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url)
|
|||
uri=linphone_address_new(tmpurl);
|
||||
ms_free(tmpurl);
|
||||
if (uri){
|
||||
return uri;
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2695,12 +2658,12 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url)
|
|||
linphone_proxy_config_normalize_number(proxy,url,normalized_username,
|
||||
sizeof(normalized_username));
|
||||
linphone_address_set_username(uri,normalized_username);
|
||||
return uri;
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}else return NULL;
|
||||
}
|
||||
uri=linphone_address_new(url);
|
||||
if (uri!=NULL){
|
||||
return uri;
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -4021,7 +3984,11 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
|
||||
}
|
||||
#endif //BUILD_UPNP
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
if (!lc->sip_conf.sdp_200_ack){
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
} else {
|
||||
sal_call_set_local_media_description(call->op,NULL);
|
||||
}
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
|
||||
if (call->params->in_conference && !call->current_params->in_conference) subject="Conference";
|
||||
if ( sal_call_update(call->op,subject,FALSE) != 0){
|
||||
|
|
@ -4032,6 +3999,12 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
lc->current_call=call;
|
||||
snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",linphone_call_get_remote_address_as_string(call));
|
||||
linphone_core_notify_display_status(lc,temp);
|
||||
|
||||
if (lc->sip_conf.sdp_200_ack){
|
||||
/*we are NOT offering, set local media description after sending the call so that we are ready to
|
||||
process the remote offer when it will arrive*/
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6195,8 +6168,8 @@ void _linphone_core_codec_config_write(LinphoneCore *lc){
|
|||
static void codecs_config_uninit(LinphoneCore *lc)
|
||||
{
|
||||
_linphone_core_codec_config_write(lc);
|
||||
ms_list_free(lc->codecs_conf.audio_codecs);
|
||||
ms_list_free(lc->codecs_conf.video_codecs);
|
||||
ms_list_free_with_data(lc->codecs_conf.audio_codecs, (void (*)(void*))payload_type_destroy);
|
||||
ms_list_free_with_data(lc->codecs_conf.video_codecs, (void (*)(void*))payload_type_destroy);
|
||||
}
|
||||
|
||||
void ui_config_uninit(LinphoneCore* lc)
|
||||
|
|
@ -6505,20 +6478,6 @@ const char *linphone_core_get_remote_ringback_tone(const LinphoneCore *lc){
|
|||
return lc->sound_conf.ringback_tone;
|
||||
}
|
||||
|
||||
static PayloadType* find_payload_type_from_list(const char* type, int rate, int channels, const MSList* from) {
|
||||
const MSList *elem;
|
||||
for(elem=from;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if ((strcasecmp((char*)type, payload_type_get_mime(pt)) == 0)
|
||||
&& (rate == LINPHONE_FIND_PAYLOAD_IGNORE_RATE || rate==pt->clock_rate)
|
||||
&& (channels == LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS || channels==pt->channels)) {
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
if (result) {
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ LINPHONE_PUBLIC void linphone_address_set_port(LinphoneAddress *uri, int port);
|
|||
/*remove tags, params etc... so that it is displayable to the user*/
|
||||
LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_is_sip(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,LinphoneTransportType type);
|
||||
LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u);
|
||||
|
|
@ -2345,8 +2346,19 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, Linphone
|
|||
*/
|
||||
LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ;
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Returns the payload type number assigned for this codec.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* 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.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number);
|
||||
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
|
|
|||
|
|
@ -59,15 +59,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define RTP_HDR_SZ 12
|
||||
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
|
||||
|
||||
static void payload_type_set_enable(PayloadType *pt,int value)
|
||||
{
|
||||
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
|
||||
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
|
||||
}
|
||||
|
||||
static bool_t payload_type_enabled(const PayloadType *pt) {
|
||||
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
|
||||
}
|
||||
|
||||
bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){
|
||||
|
|
@ -97,6 +88,10 @@ int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *p
|
|||
return payload_type_get_number(pt);
|
||||
}
|
||||
|
||||
void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *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)){
|
||||
MSFilterDesc *desc=ms_filter_get_encoder(pt->mime_type);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,49 @@ static bool_t only_telephone_event(const MSList *l){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
typedef struct _PayloadTypeMatcher{
|
||||
const char *mime_type;
|
||||
PayloadType *(*match_func)(const MSList *l, const PayloadType *refpt);
|
||||
}PayloadTypeMatcher;
|
||||
|
||||
static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
/*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/
|
||||
if (strcasecmp(pt->mime_type,"opus")==0 ){
|
||||
if (refpt->channels==1){
|
||||
pt->channels=1; /*so that we respond with same number of channels */
|
||||
candidate=pt;
|
||||
}else if (refpt->channels==2){
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
/* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/
|
||||
static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
if (strcasecmp(pt->mime_type,"G729")==0 && refpt->channels==pt->channels){
|
||||
candidate=pt;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static PayloadType * amr_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
char value[10];
|
||||
const MSList *elem;
|
||||
|
|
@ -40,39 +82,63 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
|
|||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
/*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/
|
||||
if (refpt->mime_type && strcasecmp(refpt->mime_type,"opus")==0 && refpt->channels==1
|
||||
&& strcasecmp(pt->mime_type,refpt->mime_type)==0){
|
||||
pt->channels=1; /*so that we respond with same number of channels */
|
||||
candidate=pt;
|
||||
break;
|
||||
}
|
||||
|
||||
/* the compare between G729 and G729A is for some stupid uncompliant phone*/
|
||||
if ( pt->mime_type && refpt->mime_type &&
|
||||
(strcasecmp(pt->mime_type,refpt->mime_type)==0 ||
|
||||
(strcasecmp(pt->mime_type, "G729") == 0 && strcasecmp(refpt->mime_type, "G729A") == 0 ))
|
||||
&& pt->clock_rate==refpt->clock_rate && pt->channels==refpt->channels){
|
||||
candidate=pt;
|
||||
/*good candidate, check fmtp for H264 */
|
||||
if (strcasecmp(pt->mime_type,"H264")==0){
|
||||
if (pt->recv_fmtp!=NULL && refpt->recv_fmtp!=NULL){
|
||||
int mode1=0,mode2=0;
|
||||
if (fmtp_get_value(pt->recv_fmtp,"packetization-mode",value,sizeof(value))){
|
||||
mode1=atoi(value);
|
||||
}
|
||||
if (fmtp_get_value(refpt->recv_fmtp,"packetization-mode",value,sizeof(value))){
|
||||
mode2=atoi(value);
|
||||
}
|
||||
if (mode1==mode2)
|
||||
break; /*exact match */
|
||||
}
|
||||
}else break;
|
||||
if ( pt->mime_type && refpt->mime_type
|
||||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels) {
|
||||
int octedalign1=0,octedalign2=0;
|
||||
if (pt->recv_fmtp!=NULL && fmtp_get_value(pt->recv_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign1=atoi(value);
|
||||
}
|
||||
if (refpt->send_fmtp!=NULL && fmtp_get_value(refpt->send_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign2=atoi(value);
|
||||
}
|
||||
if (octedalign1==octedalign2) {
|
||||
candidate=pt;
|
||||
break; /*exact match */
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static PayloadType * generic_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
if ( pt->mime_type && refpt->mime_type
|
||||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels)
|
||||
return pt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PayloadTypeMatcher matchers[]={
|
||||
{"opus", opus_match},
|
||||
{"G729A", g729A_match},
|
||||
{"AMR", amr_match},
|
||||
{"AMR-WB", amr_match},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadTypeMatcher *m;
|
||||
for(m=matchers;m->mime_type!=NULL;++m){
|
||||
if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){
|
||||
return m->match_func(l,refpt);
|
||||
}
|
||||
}
|
||||
return generic_match(l,refpt);
|
||||
}
|
||||
|
||||
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
|
||||
const MSList *e2,*e1;
|
||||
MSList *res=NULL;
|
||||
|
|
@ -110,6 +176,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
res=ms_list_append(res,newp);
|
||||
/* we should use the remote numbering even when parsing a response */
|
||||
payload_type_set_number(newp,remote_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
if (reading_response && remote_number!=local_number){
|
||||
ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i",
|
||||
newp->mime_type, local_number, remote_number);
|
||||
|
|
@ -120,6 +187,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
*/
|
||||
newp=payload_type_clone(newp);
|
||||
payload_type_set_number(newp,local_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,newp);
|
||||
}
|
||||
}else{
|
||||
|
|
@ -143,7 +211,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
if (!found){
|
||||
ms_message("Adding %s/%i for compatibility, just in case.",p1->mime_type,p1->clock_rate);
|
||||
p1=payload_type_clone(p1);
|
||||
p1->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV;
|
||||
payload_type_set_flag(p1, PAYLOAD_TYPE_FLAG_CAN_RECV);
|
||||
payload_type_set_flag(p1, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,p1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ static MS2_INLINE void set_string(char **dest, const char *src){
|
|||
|
||||
#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0
|
||||
#define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3
|
||||
#define PAYLOAD_TYPE_FROZEN_NUMBER PAYLOAD_TYPE_USER_FLAG_4
|
||||
|
||||
void linphone_process_authentication(LinphoneCore* lc, SalOp *op);
|
||||
void linphone_authentication_ok(LinphoneCore *lc, SalOp *op);
|
||||
|
|
@ -631,7 +632,9 @@ typedef struct sound_config
|
|||
typedef struct codecs_config
|
||||
{
|
||||
MSList *audio_codecs; /* list of audio codecs in order of preference*/
|
||||
MSList *video_codecs; /* for later use*/
|
||||
MSList *video_codecs;
|
||||
int dyn_pt;
|
||||
int telephone_event_pt;
|
||||
}codecs_config_t;
|
||||
|
||||
typedef struct video_config{
|
||||
|
|
@ -698,7 +701,8 @@ struct _LinphoneCore
|
|||
Sal *sal;
|
||||
LinphoneGlobalState state;
|
||||
struct _LpConfig *config;
|
||||
RtpProfile *default_profile;
|
||||
MSList *default_audio_codecs;
|
||||
MSList *default_video_codecs;
|
||||
net_config_t net_conf;
|
||||
sip_config_t sip_conf;
|
||||
rtp_config_t rtp_conf;
|
||||
|
|
@ -707,8 +711,6 @@ struct _LinphoneCore
|
|||
codecs_config_t codecs_conf;
|
||||
ui_config_t ui_conf;
|
||||
autoreplier_config_t autoreplier_conf;
|
||||
MSList *payload_types;
|
||||
int dyn_pt;
|
||||
LinphoneProxyConfig *default_proxy;
|
||||
MSList *friends;
|
||||
MSList *auth_info;
|
||||
|
|
@ -1003,6 +1005,18 @@ static MS2_INLINE const LinphoneErrorInfo *linphone_error_info_from_sal_op(const
|
|||
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
|
||||
}
|
||||
|
||||
static MS2_INLINE void payload_type_set_enable(PayloadType *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) {
|
||||
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
|
||||
}
|
||||
|
||||
bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore);
|
||||
|
||||
const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
}
|
||||
|
||||
linphone_content_set_buffer(content, buffer, strlen(buffer));
|
||||
ms_free(buffer);
|
||||
|
||||
if (call->log->reporting.on_report_sent != NULL){
|
||||
call->log->reporting.on_report_sent(
|
||||
|
|
|
|||
|
|
@ -62,9 +62,10 @@ SalMediaDescription *sal_media_description_new(){
|
|||
static void sal_media_description_destroy(SalMediaDescription *md){
|
||||
int i;
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
|
||||
ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
|
||||
ms_list_free(md->streams[i].payloads);
|
||||
ms_list_free_with_data(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
|
||||
ms_list_free_with_data(md->streams[i].already_assigned_payloads,(void (*)(void *))payload_type_destroy);
|
||||
md->streams[i].payloads=NULL;
|
||||
md->streams[i].already_assigned_payloads=NULL;
|
||||
}
|
||||
ms_free(md);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ void sal_address_set_transport(SalAddress* addr,SalTransport transport);
|
|||
void sal_address_set_transport_name(SalAddress* addr,const char* transport);
|
||||
void sal_address_set_params(SalAddress *addr, const char *params);
|
||||
void sal_address_set_uri_params(SalAddress *addr, const char *params);
|
||||
bool_t sal_address_is_ipv6(SalAddress *addr);
|
||||
bool_t sal_address_is_ipv6(const SalAddress *addr);
|
||||
bool_t sal_address_is_sip(const SalAddress *addr);
|
||||
void sal_address_set_password(SalAddress *addr, const char *passwd);
|
||||
const char *sal_address_get_password(const SalAddress *addr);
|
||||
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value);
|
||||
|
|
@ -206,7 +207,8 @@ typedef struct SalStreamDescription{
|
|||
char rtcp_cname[255];
|
||||
int rtp_port;
|
||||
int rtcp_port;
|
||||
MSList *payloads; //<list of PayloadType
|
||||
MSList *payloads; /*<list of PayloadType */
|
||||
MSList *already_assigned_payloads; /*<list of PayloadType offered in the past, used for correct allocation of payload type numbers*/
|
||||
int bandwidth;
|
||||
int ptime;
|
||||
SalStreamDir dir;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit d5389594e93c3499d70d9ddd556f9aac62aabc0a
|
||||
Subproject commit 30e90d0f8a1a17fcd5b718a3eb8758f005f2052b
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 723deb7e9e016f5134a6f708f28ee95694e97068
|
||||
Subproject commit 4ef1702f7f8f21d65e6e9da68d4f8f2c2376f614
|
||||
2
po/ar.po
2
po/ar.po
|
|
@ -10,7 +10,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-06 14:11+0000\n"
|
||||
"PO-Revision-Date: 2015-01-13 16:34+0000\n"
|
||||
"Last-Translator: محيي الدين <tx99h4@hotmail.com>\n"
|
||||
"Language-Team: Arabic (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/ar/)\n"
|
||||
|
|
|
|||
2
po/de.po
2
po/de.po
|
|
@ -12,7 +12,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-06 11:29+0000\n"
|
||||
"PO-Revision-Date: 2015-01-13 16:34+0000\n"
|
||||
"Last-Translator: Gautier Pelloux-Prayer <gautier.pelloux@gmail.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/de/)\n"
|
||||
|
|
|
|||
2
po/fr.po
2
po/fr.po
|
|
@ -12,7 +12,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-06 11:41+0000\n"
|
||||
"PO-Revision-Date: 2015-01-13 16:34+0000\n"
|
||||
"Last-Translator: Gautier Pelloux-Prayer <gautier.pelloux@gmail.com>\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/fr/)\n"
|
||||
|
|
|
|||
2
po/ja.po
2
po/ja.po
|
|
@ -10,7 +10,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-09 16:31+0000\n"
|
||||
"PO-Revision-Date: 2015-01-13 16:34+0000\n"
|
||||
"Last-Translator: Alexander\n"
|
||||
"Language-Team: Japanese (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/ja/)\n"
|
||||
|
|
|
|||
2
po/ru.po
2
po/ru.po
|
|
@ -13,7 +13,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-07 08:31+0000\n"
|
||||
"PO-Revision-Date: 2015-01-14 09:11+0000\n"
|
||||
"Last-Translator: AlexL <loginov.alex.valer@gmail.com>\n"
|
||||
"Language-Team: Russian (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/ru/)\n"
|
||||
|
|
|
|||
2
po/sr.po
2
po/sr.po
|
|
@ -9,7 +9,7 @@ msgstr ""
|
|||
"Project-Id-Version: linphone-gtk\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-13 16:18+0100\n"
|
||||
"PO-Revision-Date: 2015-01-07 17:21+0000\n"
|
||||
"PO-Revision-Date: 2015-01-13 16:34+0000\n"
|
||||
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
|
||||
"Language-Team: Serbian (http://www.transifex.com/projects/p/linphone-gtk/"
|
||||
"language/sr/)\n"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ liblinphonetester_la_SOURCES = tester.c \
|
|||
transport_tester.c \
|
||||
player_tester.c \
|
||||
dtmf_tester.c \
|
||||
accountmanager.c
|
||||
accountmanager.c \
|
||||
offeranswer_tester.c
|
||||
|
||||
liblinphonetester_la_LDFLAGS= -no-undefined
|
||||
liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ void account_manager_destroy(void){
|
|||
ms_free(the_am);
|
||||
}
|
||||
the_am=NULL;
|
||||
ms_message("Test account manager destroyed.");
|
||||
}
|
||||
|
||||
Account *account_manager_get_account(AccountManager *m, const LinphoneAddress *identity){
|
||||
|
|
@ -211,10 +212,6 @@ void linphone_core_manager_check_accounts(LinphoneCoreManager *m){
|
|||
|
||||
for(it=linphone_core_get_proxy_config_list(m->lc);it!=NULL;it=it->next){
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)it->data;
|
||||
LinphoneAddress *modified_identity=account_manager_check_account(am,cfg);
|
||||
if (m->identity){
|
||||
linphone_address_unref(m->identity);
|
||||
}
|
||||
m->identity=linphone_address_ref(modified_identity);
|
||||
account_manager_check_account(am,cfg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
#endif
|
||||
|
||||
static void srtp_call(void);
|
||||
|
||||
static void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate);
|
||||
static char *create_filepath(const char *dir, const char *filename, const char *ext);
|
||||
|
||||
// prototype definition for call_recording()
|
||||
|
|
@ -728,7 +726,7 @@ static void cancelled_call(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate){
|
||||
void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate){
|
||||
const MSList *elem=linphone_core_get_audio_codecs(lc);
|
||||
PayloadType *pt;
|
||||
|
||||
|
|
@ -755,40 +753,6 @@ static void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mi
|
|||
}
|
||||
#endif
|
||||
|
||||
static void call_failed_because_of_codecs(void) {
|
||||
int begin,leaked_objects;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
{
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* out_call;
|
||||
|
||||
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
|
||||
disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1);
|
||||
out_call = linphone_core_invite_address(pauline->lc,marie->identity);
|
||||
linphone_call_ref(out_call);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
|
||||
|
||||
/*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/
|
||||
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000));
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0);
|
||||
|
||||
linphone_call_unref(out_call);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
static void call_with_dns_time_out(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
LCSipTransports transport = {9773,0,0,0};
|
||||
|
|
@ -2017,15 +1981,13 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
|
|||
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure);
|
||||
linphone_core_add_to_conference(marie->lc,marie_call_laure);
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,laure->lc,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000));
|
||||
|
||||
linphone_core_add_to_conference(marie->lc,marie_call_pauline);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000));
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000));
|
||||
|
||||
|
|
@ -2160,12 +2122,16 @@ static void call_with_file_player(void) {
|
|||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
#ifndef __arm__
|
||||
CU_ASSERT_TRUE(ms_audio_diff(hellopath,recordpath,&similar,NULL,NULL)==0);
|
||||
CU_ASSERT_TRUE(similar>threshold);
|
||||
CU_ASSERT_TRUE(similar<=1.0);
|
||||
if(similar > threshold && similar <=1.0) {
|
||||
remove(recordpath);
|
||||
}
|
||||
#else
|
||||
remove(recordpath);
|
||||
#endif
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
ms_free(recordpath);
|
||||
|
|
@ -2228,16 +2194,16 @@ static void call_with_mkv_file_player(void) {
|
|||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
#ifdef ANDROID
|
||||
/*inter-correlation process is too much CPU consuming ending in a 20 minutes test on Android...*/
|
||||
remove(recordpath);
|
||||
#else
|
||||
#ifndef __arm__
|
||||
CU_ASSERT_TRUE(ms_audio_diff(hellowav,recordpath,&similar,NULL,NULL)==0);
|
||||
CU_ASSERT_TRUE(similar>threshold);
|
||||
CU_ASSERT_TRUE(similar<=1.0);
|
||||
if(similar>threshold && similar<=1.0) {
|
||||
remove(recordpath);
|
||||
}
|
||||
#else
|
||||
/*inter-correlation process is too much CPU consuming ending in a 20 minutes test on arm...*/
|
||||
remove(recordpath);
|
||||
#endif
|
||||
ms_free(recordpath);
|
||||
|
||||
|
|
@ -3061,115 +3027,6 @@ static void multiple_early_media(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, const char *expected_profile) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
|
||||
LinphoneProxyConfig *lpc;
|
||||
const LinphoneCallParams *params;
|
||||
|
||||
if (avpf1) {
|
||||
linphone_core_get_default_proxy(marie->lc, &lpc);
|
||||
linphone_proxy_config_enable_avpf(lpc, TRUE);
|
||||
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
|
||||
}
|
||||
if (avpf2) {
|
||||
linphone_core_get_default_proxy(pauline->lc, &lpc);
|
||||
linphone_proxy_config_enable_avpf(lpc, TRUE);
|
||||
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
|
||||
}
|
||||
if (srtp1) {
|
||||
if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) {
|
||||
linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP);
|
||||
}
|
||||
}
|
||||
if (srtp2) {
|
||||
if (linphone_core_media_encryption_supported(pauline->lc, LinphoneMediaEncryptionSRTP)) {
|
||||
linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP);
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(call(marie, pauline));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
|
||||
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
|
||||
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
|
||||
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
|
||||
|
||||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1);
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1);
|
||||
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void avp_to_avp_call(void) {
|
||||
profile_call(FALSE, FALSE, FALSE, FALSE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_avpf_call(void) {
|
||||
profile_call(FALSE, FALSE, TRUE, FALSE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_savp_call(void) {
|
||||
profile_call(FALSE, FALSE, FALSE, TRUE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_savpf_call(void) {
|
||||
profile_call(FALSE, FALSE, TRUE, TRUE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avpf_to_avp_call(void) {
|
||||
profile_call(TRUE, FALSE, FALSE, FALSE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_avpf_call(void) {
|
||||
profile_call(TRUE, FALSE, TRUE, FALSE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_savp_call(void) {
|
||||
profile_call(TRUE, FALSE, FALSE, TRUE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_savpf_call(void) {
|
||||
profile_call(TRUE, FALSE, TRUE, TRUE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void savp_to_avp_call(void) {
|
||||
profile_call(FALSE, TRUE, FALSE, FALSE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_avpf_call(void) {
|
||||
profile_call(FALSE, TRUE, TRUE, FALSE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_savp_call(void) {
|
||||
profile_call(FALSE, TRUE, FALSE, TRUE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_savpf_call(void) {
|
||||
profile_call(FALSE, TRUE, TRUE, TRUE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savpf_to_avp_call(void) {
|
||||
profile_call(TRUE, TRUE, FALSE, FALSE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_avpf_call(void) {
|
||||
profile_call(TRUE, TRUE, TRUE, FALSE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_savp_call(void) {
|
||||
profile_call(TRUE, TRUE, FALSE, TRUE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_savpf_call(void) {
|
||||
profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static char *create_filepath(const char *dir, const char *filename, const char *ext) {
|
||||
return ms_strdup_printf("%s/%s.%s",dir,filename,ext);
|
||||
}
|
||||
|
|
@ -3548,6 +3405,65 @@ static void outgoing_reinvite_without_ack_sdp() {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void call_with_paused_no_sdp_on_resume() {
|
||||
int begin;
|
||||
int leaked_objects;
|
||||
int dummy=0;
|
||||
LinphoneCoreManager* marie;
|
||||
LinphoneCoreManager* pauline;
|
||||
LinphoneCall* call_marie = NULL;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(marie,pauline);
|
||||
|
||||
call_marie = linphone_core_get_current_call(marie->lc);
|
||||
CU_ASSERT_PTR_NOT_NULL(call_marie);
|
||||
|
||||
ms_message("== Call is OK ==");
|
||||
|
||||
/* the called party pause the call */
|
||||
wait_for_until(pauline->lc, marie->lc, NULL, 5, 3000);
|
||||
|
||||
linphone_core_pause_call(marie->lc,call_marie);
|
||||
ms_message("== Call pausing ==");
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausing,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPaused,1));
|
||||
|
||||
/*stay in pause a little while in order to generate traffic*/
|
||||
wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000);
|
||||
|
||||
ms_message("== Call paused, marie call: %p ==", call_marie);
|
||||
|
||||
linphone_core_enable_sdp_200_ack(marie->lc,TRUE);
|
||||
|
||||
linphone_core_resume_call(marie->lc,call_marie);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
|
||||
wait_for_until(marie->lc, pauline->lc, &dummy, 1, 3000);
|
||||
CU_ASSERT_TRUE(linphone_call_get_audio_stats(call_marie)->download_bandwidth>70);
|
||||
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70);
|
||||
|
||||
end_call(marie,pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
test_t call_tests[] = {
|
||||
{ "Early declined call", early_declined_call },
|
||||
{ "Call declined", call_declined },
|
||||
|
|
@ -3555,7 +3471,6 @@ test_t call_tests[] = {
|
|||
{ "Early cancelled call", early_cancelled_call},
|
||||
{ "Call with DNS timeout", call_with_dns_time_out },
|
||||
{ "Cancelled ringing call", cancelled_ringing_call },
|
||||
{ "Call failed because of codecs", call_failed_because_of_codecs },
|
||||
{ "Simple call", simple_call },
|
||||
{ "Call with timeouted bye", call_with_timeouted_bye },
|
||||
{ "Direct call over IPv6", direct_call_over_ipv6},
|
||||
|
|
@ -3633,25 +3548,10 @@ test_t call_tests[] = {
|
|||
{ "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error},
|
||||
{ "Call redirected by callee", call_redirect},
|
||||
{ "Call with specified codec bitrate", call_with_specified_codec_bitrate},
|
||||
{ "AVP to AVP call", avp_to_avp_call },
|
||||
{ "AVP to AVPF call", avp_to_avpf_call },
|
||||
{ "AVP to SAVP call", avp_to_savp_call },
|
||||
{ "AVP to SAVPF call", avp_to_savpf_call },
|
||||
{ "AVPF to AVP call", avpf_to_avp_call },
|
||||
{ "AVPF to AVPF call", avpf_to_avpf_call },
|
||||
{ "AVPF to SAVP call", avpf_to_savp_call },
|
||||
{ "AVPF to SAVPF call", avpf_to_savpf_call },
|
||||
{ "SAVP to AVP call", savp_to_avp_call },
|
||||
{ "SAVP to AVPF call", savp_to_avpf_call },
|
||||
{ "SAVP to SAVP call", savp_to_savp_call },
|
||||
{ "SAVP to SAVPF call", savp_to_savpf_call },
|
||||
{ "SAVPF to AVP call", savpf_to_avp_call },
|
||||
{ "SAVPF to AVPF call", savpf_to_avpf_call },
|
||||
{ "SAVPF to SAVP call", savpf_to_savp_call },
|
||||
{ "SAVPF to SAVPF call", savpf_to_savpf_call },
|
||||
{ "Call with in-dialog UPDATE request", call_with_in_dialog_update },
|
||||
{ "Call with in-dialog codec change", call_with_in_dialog_codec_change },
|
||||
{ "Call with in-dialog codec change no sdp", call_with_in_dialog_codec_change_no_sdp },
|
||||
{ "Call with pause no SDP on resume", call_with_paused_no_sdp_on_resume },
|
||||
{ "Call with custom supported tags", call_with_custom_supported_tags },
|
||||
{ "Call log from taken from asserted id",call_log_from_taken_from_p_asserted_id},
|
||||
{ "Incoming INVITE without SDP",incoming_invite_without_sdp},
|
||||
|
|
|
|||
|
|
@ -109,6 +109,14 @@ JNIEXPORT jint JNICALL Java_org_linphone_tester_Tester_run(JNIEnv *env, jobject
|
|||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_keepAccounts(JNIEnv *env, jclass c, jboolean keep) {
|
||||
liblinphone_tester_keep_accounts((int)keep);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_clearAccounts(JNIEnv *env, jclass c) {
|
||||
liblinphone_tester_clear_accounts();
|
||||
}
|
||||
|
||||
#endif /* ANDROID */
|
||||
|
||||
#ifdef __QNX__
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ extern test_suite_t log_collection_test_suite;
|
|||
extern test_suite_t transport_test_suite;
|
||||
extern test_suite_t player_test_suite;
|
||||
extern test_suite_t dtmf_test_suite;
|
||||
extern test_suite_t offeranswer_test_suite;
|
||||
|
||||
|
||||
extern int liblinphone_tester_nb_test_suites(void);
|
||||
|
|
@ -293,6 +294,7 @@ bool_t call_with_test_params(LinphoneCoreManager* caller_mgr
|
|||
|
||||
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr);
|
||||
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2);
|
||||
void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate);
|
||||
stats * get_stats(LinphoneCore *lc);
|
||||
LinphoneCoreManager *get_manager(LinphoneCore *lc);
|
||||
const char *liblinphone_tester_get_subscribe_content(void);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#endif
|
||||
|
||||
|
||||
/*getline is not available on android...*/
|
||||
#ifdef ANDROID
|
||||
/*getline is POSIX 2008, not available on many systems.*/
|
||||
#if defined(ANDROID) || defined(WIN32)
|
||||
/* This code is public domain -- Will Hartung 4/9/09 */
|
||||
size_t getline(char **lineptr, size_t *n, FILE *stream) {
|
||||
char *bufptr = NULL;
|
||||
|
|
@ -153,8 +153,10 @@ time_t check_file(LinphoneCoreManager* mgr) {
|
|||
int line_count = 0;
|
||||
char *line = NULL;
|
||||
size_t line_size = 256;
|
||||
#ifndef WIN32
|
||||
struct tm tm_curr;
|
||||
time_t time_prev = -1;
|
||||
#endif
|
||||
|
||||
#if HAVE_ZLIB
|
||||
// 0) if zlib is enabled, we must decompress the file first
|
||||
|
|
@ -170,6 +172,7 @@ time_t check_file(LinphoneCoreManager* mgr) {
|
|||
while (getline(&line, &line_size, file) != -1) {
|
||||
// a) there should be at least 25 lines
|
||||
++line_count;
|
||||
#ifndef WIN32
|
||||
// b) logs should be ordered by date (format: 2014-11-04 15:22:12:606)
|
||||
if (strlen(line) > 24) {
|
||||
char date[24] = {'\0'};
|
||||
|
|
@ -180,6 +183,9 @@ time_t check_file(LinphoneCoreManager* mgr) {
|
|||
time_prev = time_curr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ms_warning("strptime() not available for this platform, test is incomplete.");
|
||||
#endif
|
||||
}
|
||||
CU_ASSERT_TRUE(line_count > 25);
|
||||
free(line);
|
||||
|
|
|
|||
297
tester/offeranswer_tester.c
Normal file
297
tester/offeranswer_tester.c
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
liblinphone_tester - liblinphone test suite
|
||||
Copyright (C) 2013 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "CUnit/Basic.h"
|
||||
#include "linphonecore.h"
|
||||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
#include "liblinphone_tester.h"
|
||||
|
||||
static int get_codec_position(const MSList *l, const char *mime_type, int rate){
|
||||
const MSList *elem;
|
||||
int i;
|
||||
for (elem=l, i=0; elem!=NULL; elem=elem->next,i++){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if (strcasecmp(pt->mime_type, mime_type)==0 && pt->clock_rate==rate) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*check basic things about codecs at startup: order and enablement*/
|
||||
static void start_with_no_config(void){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc=linphone_core_new(&vtable, NULL, NULL, NULL);
|
||||
const MSList *codecs=linphone_core_get_audio_codecs(lc);
|
||||
int opus_codec_pos;
|
||||
int speex_codec_pos=get_codec_position(codecs, "speex", 8000);
|
||||
int speex16_codec_pos=get_codec_position(codecs, "speex", 16000);
|
||||
PayloadType *pt;
|
||||
opus_codec_pos=get_codec_position(codecs, "opus", 48000);
|
||||
if (opus_codec_pos!=-1) CU_ASSERT_TRUE(opus_codec_pos==0);
|
||||
CU_ASSERT_TRUE(speex16_codec_pos<speex_codec_pos);
|
||||
|
||||
pt=linphone_core_find_payload_type(lc, "speex", 16000, 1);
|
||||
CU_ASSERT_PTR_NOT_NULL(pt);
|
||||
if (pt) {
|
||||
CU_ASSERT_TRUE(linphone_core_payload_type_enabled(lc, pt)==TRUE);
|
||||
}
|
||||
linphone_core_destroy(lc);
|
||||
}
|
||||
|
||||
static void check_payload_type_numbers(LinphoneCall *call1, LinphoneCall *call2, int expected_number){
|
||||
const LinphoneCallParams *params=linphone_call_get_current_params(call1);
|
||||
const PayloadType *pt=linphone_call_params_get_used_audio_codec(params);
|
||||
CU_ASSERT_PTR_NOT_NULL(pt);
|
||||
if (pt){
|
||||
CU_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
|
||||
}
|
||||
params=linphone_call_get_current_params(call2);
|
||||
pt=linphone_call_params_get_used_audio_codec(params);
|
||||
CU_ASSERT_PTR_NOT_NULL(pt);
|
||||
if (pt){
|
||||
CU_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
|
||||
}
|
||||
}
|
||||
|
||||
static void simple_call_with_different_codec_mappings(void) {
|
||||
int begin;
|
||||
int leaked_objects;
|
||||
LinphoneCoreManager* marie;
|
||||
LinphoneCoreManager* pauline;
|
||||
LinphoneCall *pauline_call;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
|
||||
disable_all_audio_codecs_except_one(pauline->lc,"pcmu",-1);
|
||||
|
||||
/*marie set a fantasy number to PCMU*/
|
||||
linphone_core_set_payload_type_number(marie->lc,
|
||||
linphone_core_find_payload_type(marie->lc, "PCMU", 8000, -1),
|
||||
104);
|
||||
|
||||
CU_ASSERT_TRUE(call(marie,pauline));
|
||||
pauline_call=linphone_core_get_current_call(pauline->lc);
|
||||
CU_ASSERT_PTR_NOT_NULL(pauline_call);
|
||||
if (pauline_call){
|
||||
LinphoneCallParams *params;
|
||||
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
|
||||
/*make a reinvite in the other direction*/
|
||||
linphone_core_update_call(pauline->lc, pauline_call,
|
||||
params=linphone_core_create_call_params(pauline->lc, pauline_call));
|
||||
linphone_call_params_unref(params);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallUpdatedByRemote,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
/*payload type numbers shall remain the same*/
|
||||
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
|
||||
}
|
||||
|
||||
end_call(marie,pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
static void call_failed_because_of_codecs(void) {
|
||||
int begin,leaked_objects;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
{
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* out_call;
|
||||
|
||||
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
|
||||
disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1);
|
||||
out_call = linphone_core_invite_address(pauline->lc,marie->identity);
|
||||
linphone_call_ref(out_call);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
|
||||
|
||||
/*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/
|
||||
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000));
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0);
|
||||
|
||||
linphone_call_unref(out_call);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, const char *expected_profile) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
|
||||
LinphoneProxyConfig *lpc;
|
||||
const LinphoneCallParams *params;
|
||||
|
||||
if (avpf1) {
|
||||
linphone_core_get_default_proxy(marie->lc, &lpc);
|
||||
linphone_proxy_config_enable_avpf(lpc, TRUE);
|
||||
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
|
||||
}
|
||||
if (avpf2) {
|
||||
linphone_core_get_default_proxy(pauline->lc, &lpc);
|
||||
linphone_proxy_config_enable_avpf(lpc, TRUE);
|
||||
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
|
||||
}
|
||||
if (srtp1) {
|
||||
if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) {
|
||||
linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP);
|
||||
}
|
||||
}
|
||||
if (srtp2) {
|
||||
if (linphone_core_media_encryption_supported(pauline->lc, LinphoneMediaEncryptionSRTP)) {
|
||||
linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP);
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(call(marie, pauline));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
|
||||
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
|
||||
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
|
||||
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
|
||||
|
||||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1);
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1);
|
||||
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void avp_to_avp_call(void) {
|
||||
profile_call(FALSE, FALSE, FALSE, FALSE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_avpf_call(void) {
|
||||
profile_call(FALSE, FALSE, TRUE, FALSE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_savp_call(void) {
|
||||
profile_call(FALSE, FALSE, FALSE, TRUE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avp_to_savpf_call(void) {
|
||||
profile_call(FALSE, FALSE, TRUE, TRUE, "RTP/AVP");
|
||||
}
|
||||
|
||||
static void avpf_to_avp_call(void) {
|
||||
profile_call(TRUE, FALSE, FALSE, FALSE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_avpf_call(void) {
|
||||
profile_call(TRUE, FALSE, TRUE, FALSE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_savp_call(void) {
|
||||
profile_call(TRUE, FALSE, FALSE, TRUE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void avpf_to_savpf_call(void) {
|
||||
profile_call(TRUE, FALSE, TRUE, TRUE, "RTP/AVPF");
|
||||
}
|
||||
|
||||
static void savp_to_avp_call(void) {
|
||||
profile_call(FALSE, TRUE, FALSE, FALSE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_avpf_call(void) {
|
||||
profile_call(FALSE, TRUE, TRUE, FALSE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_savp_call(void) {
|
||||
profile_call(FALSE, TRUE, FALSE, TRUE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savp_to_savpf_call(void) {
|
||||
profile_call(FALSE, TRUE, TRUE, TRUE, "RTP/SAVP");
|
||||
}
|
||||
|
||||
static void savpf_to_avp_call(void) {
|
||||
profile_call(TRUE, TRUE, FALSE, FALSE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_avpf_call(void) {
|
||||
profile_call(TRUE, TRUE, TRUE, FALSE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_savp_call(void) {
|
||||
profile_call(TRUE, TRUE, FALSE, TRUE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static void savpf_to_savpf_call(void) {
|
||||
profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF");
|
||||
}
|
||||
|
||||
static test_t offeranswer_tests[] = {
|
||||
{ "Start with no config", start_with_no_config },
|
||||
{ "Call failed because of codecs", call_failed_because_of_codecs },
|
||||
{ "Simple call with different codec mappings", simple_call_with_different_codec_mappings},
|
||||
{ "AVP to AVP call", avp_to_avp_call },
|
||||
{ "AVP to AVPF call", avp_to_avpf_call },
|
||||
{ "AVP to SAVP call", avp_to_savp_call },
|
||||
{ "AVP to SAVPF call", avp_to_savpf_call },
|
||||
{ "AVPF to AVP call", avpf_to_avp_call },
|
||||
{ "AVPF to AVPF call", avpf_to_avpf_call },
|
||||
{ "AVPF to SAVP call", avpf_to_savp_call },
|
||||
{ "AVPF to SAVPF call", avpf_to_savpf_call },
|
||||
{ "SAVP to AVP call", savp_to_avp_call },
|
||||
{ "SAVP to AVPF call", savp_to_avpf_call },
|
||||
{ "SAVP to SAVP call", savp_to_savp_call },
|
||||
{ "SAVP to SAVPF call", savp_to_savpf_call },
|
||||
{ "SAVPF to AVP call", savpf_to_avp_call },
|
||||
{ "SAVPF to AVPF call", savpf_to_avpf_call },
|
||||
{ "SAVPF to SAVP call", savpf_to_savp_call },
|
||||
{ "SAVPF to SAVPF call", savpf_to_savpf_call },
|
||||
};
|
||||
|
||||
test_suite_t offeranswer_test_suite = {
|
||||
"Offer-answer",
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(offeranswer_tests) / sizeof(offeranswer_tests[0]),
|
||||
offeranswer_tests
|
||||
};
|
||||
|
|
@ -420,6 +420,7 @@ void liblinphone_tester_set_writable_dir_prefix(const char* writable_dir_prefix)
|
|||
void liblinphone_tester_init(void) {
|
||||
add_test_suite(&setup_test_suite);
|
||||
add_test_suite(®ister_test_suite);
|
||||
add_test_suite(&offeranswer_test_suite);
|
||||
add_test_suite(&call_test_suite);
|
||||
add_test_suite(&message_test_suite);
|
||||
add_test_suite(&presence_test_suite);
|
||||
|
|
|
|||
|
|
@ -181,11 +181,11 @@ class TestRegister:
|
|||
cm = CoreManager('multi_account_rc', False)
|
||||
number_of_udp_proxies = reduce(lambda x, y: x + int(y.transport == "udp"), cm.lc.proxy_config_list, 0)
|
||||
total_number_of_proxies = len(cm.lc.proxy_config_list)
|
||||
assert_equals(CoreManager.wait_for(cm, cm, lambda cm1, cm2: cm1.stats.number_of_LinphoneRegistrationOk == total_number_of_proxies), True)
|
||||
register_ok = cm.stats.number_of_LinphoneRegistrationOk
|
||||
# Keep only UDP
|
||||
tr = cm.lc.sip_transports
|
||||
tr.tcp_port = 0
|
||||
tr.tls_port = 0
|
||||
tr.dtls_port = 0
|
||||
tr = linphone.SipTransports(0, 0, 0, 0)
|
||||
tr.udp_port = cm.lc.sip_transports.udp_port
|
||||
cm.lc.sip_transports = tr
|
||||
assert_equals(CoreManager.wait_for(cm, cm, lambda cm1, cm2: cm1.stats.number_of_LinphoneRegistrationOk == number_of_udp_proxies), True)
|
||||
assert_equals(CoreManager.wait_for(cm, cm, lambda cm1, cm2: cm1.stats.number_of_LinphoneRegistrationOk == (register_ok + number_of_udp_proxies)), True)
|
||||
assert_equals(CoreManager.wait_for(cm, cm, lambda cm1, cm2: cm1.stats.number_of_LinphoneRegistrationFailed == (total_number_of_proxies - number_of_udp_proxies)), True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue