From 2a9ad45d2723266beb3dceb416697178fabae592 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Wed, 14 Jan 2015 11:26:53 +0100 Subject: [PATCH 01/34] Update localization --- po/ar.po | 2 +- po/de.po | 2 +- po/fr.po | 2 +- po/ja.po | 2 +- po/ru.po | 2 +- po/sr.po | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/po/ar.po b/po/ar.po index c5eaa0244..c93c03c58 100644 --- a/po/ar.po +++ b/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: محيي الدين \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/linphone-gtk/" "language/ar/)\n" diff --git a/po/de.po b/po/de.po index 2446bd02c..229f60c71 100644 --- a/po/de.po +++ b/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 \n" "Language-Team: German (http://www.transifex.com/projects/p/linphone-gtk/" "language/de/)\n" diff --git a/po/fr.po b/po/fr.po index 23a2060fa..aff7882d6 100644 --- a/po/fr.po +++ b/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 \n" "Language-Team: French (http://www.transifex.com/projects/p/linphone-gtk/" "language/fr/)\n" diff --git a/po/ja.po b/po/ja.po index 0ebeaa016..e998ee25c 100644 --- a/po/ja.po +++ b/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" diff --git a/po/ru.po b/po/ru.po index fd7b8f5b9..b3e312070 100644 --- a/po/ru.po +++ b/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 \n" "Language-Team: Russian (http://www.transifex.com/projects/p/linphone-gtk/" "language/ru/)\n" diff --git a/po/sr.po b/po/sr.po index ae6f5da59..56f9e5f19 100644 --- a/po/sr.po +++ b/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: Мирослав Николић \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/linphone-gtk/" "language/sr/)\n" From f2a4cb60d2928f96b5300011aa8398d14c8e22a2 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 11:37:20 +0100 Subject: [PATCH 04/34] Fix a crash when an absolute address is passed to linphone_core_invite. See bug #2009. --- coreapi/bellesip_sal/sal_op_call.c | 5 +++++ coreapi/bellesip_sal/sal_op_events.c | 3 +++ coreapi/bellesip_sal/sal_op_impl.c | 23 ++++++++++++++++++++--- coreapi/bellesip_sal/sal_op_message.c | 3 +++ coreapi/bellesip_sal/sal_op_presence.c | 6 ++++-- coreapi/bellesip_sal/sal_op_publish.c | 9 +++++++++ 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 921184cf6..da9871cec 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -687,6 +687,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); diff --git a/coreapi/bellesip_sal/sal_op_events.c b/coreapi/bellesip_sal/sal_op_events.c index 4409c73a3..d4a24bd9b 100644 --- a/coreapi/bellesip_sal/sal_op_events.c +++ b/coreapi/bellesip_sal/sal_op_events.c @@ -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); diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 2e68146a0..451ac0f56 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -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)) + from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(to_address) ,belle_sip_random_token(token,sizeof(token))); } else { from_header=belle_sip_header_from_create2("Anonymous ",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, diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c index 3324cefb7..017845833 100644 --- a/coreapi/bellesip_sal/sal_op_message.c +++ b/coreapi/bellesip_sal/sal_op_message.c @@ -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))); } diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 23db49e6f..6de0a0fbf 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -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); } diff --git a/coreapi/bellesip_sal/sal_op_publish.c b/coreapi/bellesip_sal/sal_op_publish.c index 2655c58d2..17ef8e8db 100644 --- a/coreapi/bellesip_sal/sal_op_publish.c +++ b/coreapi/bellesip_sal/sal_op_publish.c @@ -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))); } From 0c4e7456d913b3dfb947937c73ce896dcaa27850 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 17:19:45 +0100 Subject: [PATCH 05/34] Prevent creating sip addresses which are not valid when using them --- coreapi/address.c | 7 +++++++ coreapi/bellesip_sal/sal_address_impl.c | 5 +++++ coreapi/linphonecore.c | 17 +++++++++++++---- coreapi/linphonecore.h | 1 + include/sal/sal.h | 1 + 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/coreapi/address.c b/coreapi/address.c index 764a8fb24..d9d772337 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -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; diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index c4ff234d7..18e7dc84b 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -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); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 8205d5f09..ef4133d87 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2625,6 +2625,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. @@ -2661,7 +2670,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) ){ @@ -2672,7 +2681,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); } } @@ -2688,12 +2697,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; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 8ff6cb69d..c8a259f25 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -397,6 +397,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); diff --git a/include/sal/sal.h b/include/sal/sal.h index 040ab9951..39085074f 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -110,6 +110,7 @@ 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_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); From 838520350c0a96d5730d745db06e5cc886a61c25 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 17:19:58 +0100 Subject: [PATCH 06/34] Use const for sal_address_is_ipv6() --- coreapi/bellesip_sal/sal_address_impl.c | 2 +- include/sal/sal.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index 18e7dc84b..034135f72 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -215,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){ diff --git a/include/sal/sal.h b/include/sal/sal.h index 39085074f..c44317c88 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -109,7 +109,7 @@ 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); From 546b953c5dc7bf9635998fa3c2ad71ce06325b83 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 15 Jan 2015 21:34:14 +0100 Subject: [PATCH 07/34] fix severe bug (everything broken) --- coreapi/bellesip_sal/sal_op_impl.c | 4 ++-- oRTP | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 451ac0f56..f9647f7ad 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -170,8 +170,8 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { } if (strcmp("REGISTER",method)==0 || op->privacy==SalPrivacyNone) { - from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(to_address) - ,belle_sip_random_token(token,sizeof(token))); + from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)) + ,belle_sip_random_token(token,sizeof(token))); } else { from_header=belle_sip_header_from_create2("Anonymous ",belle_sip_random_token(token,sizeof(token))); } diff --git a/oRTP b/oRTP index d806b0e0a..0ad89f5e1 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit d806b0e0ae878e70c4c1acb20b7f7116a6e6400b +Subproject commit 0ad89f5e106d9f9a4a1d0608101d26b9a10be8b7 From 23f950a73fe9bacd00e934fddfe40cd7acf970a9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 15 Jan 2015 22:18:56 +0100 Subject: [PATCH 08/34] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 0450c04a3..85c710a5b 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0450c04a38ce2c78430208d90e41dbe23163b950 +Subproject commit 85c710a5b69def49bb53c88a367e957d19ec5105 From a5d51cb821b1dd34cdfa251665c15b1a26b37cc3 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 16 Jan 2015 09:16:40 +0100 Subject: [PATCH 09/34] Update Mac README a bit for bundle --- README.macos.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.macos.md b/README.macos.md index 381efcf2f..b3768eea9 100644 --- a/README.macos.md +++ b/README.macos.md @@ -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,10 @@ If you don't need plugins, remove or comment out this line from the bundler file ${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so +If using HomeBrew, this is not working yet. However you will at least need to install `glib-networking` and modify also: + + /usr/local + Then run, inside Linphone source tree configure as told before but with `--enable-relativeprefix` appended. make && make bundle From 67dbf48b2596f58abac13037ad4a57f420a68337 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 16 Jan 2015 09:19:00 +0100 Subject: [PATCH 10/34] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 85c710a5b..25e08954e 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 85c710a5b69def49bb53c88a367e957d19ec5105 +Subproject commit 25e08954ef94a6e5dc17f783681945174273b455 From 47c92f50fa441b3f958e133c45abb9d2cd57e0d8 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 16 Jan 2015 09:30:16 +0100 Subject: [PATCH 11/34] Update Mac README a bit for bundle for global icons --- README.macos.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.macos.md b/README.macos.md index b3768eea9..4028bb40a 100644 --- a/README.macos.md +++ b/README.macos.md @@ -148,7 +148,12 @@ If you don't need plugins, remove or comment out this line from the bundler file ${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so -If using HomeBrew, this is not working yet. However you will at least need to install `glib-networking` and modify also: +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: /usr/local From 07376579418c12518e0efbb4f57075d4b655355f Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 17:08:51 +0100 Subject: [PATCH 12/34] Possible fix for App Nap problem --- build/macos/Info-linphone.plist.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/macos/Info-linphone.plist.in b/build/macos/Info-linphone.plist.in index b9cde78a9..7d20d4ac6 100644 --- a/build/macos/Info-linphone.plist.in +++ b/build/macos/Info-linphone.plist.in @@ -26,6 +26,8 @@ Copyright 2011 Belledonne Communications LSMinimumSystemVersion 10.4 + NSAppSleepDisabled + YES From d282ec6ad9c05e1e18c2cb9a917cb6b4f417e56d Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 17:31:30 +0100 Subject: [PATCH 13/34] Update ms2 for ios crash when camera access is denied --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 25e08954e..453c56062 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 25e08954ef94a6e5dc17f783681945174273b455 +Subproject commit 453c5606251d79bd0ac32dd6daec0ca8336de41d From 55973deb0e8fcf3776e6791115c90e08c1fecef4 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 17 Jan 2015 11:58:46 +0100 Subject: [PATCH 14/34] modularize payload type matching exceptions in offer/answer --- coreapi/offeranswer.c | 125 ++++++++++++++++++++++++++++++++---------- mediastreamer2 | 2 +- 2 files changed, 97 insertions(+), 30 deletions(-) diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index d7d2e6e84..a77774457 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -31,7 +31,50 @@ 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; + + /*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,"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 +83,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; diff --git a/mediastreamer2 b/mediastreamer2 index 0450c04a3..81e6bd551 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0450c04a38ce2c78430208d90e41dbe23163b950 +Subproject commit 81e6bd5511c16133df340e732807d64faac1f7b2 From de83e6795f3fa0f6e5356d70a8d022f9c1f3626f Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 17 Jan 2015 11:59:53 +0100 Subject: [PATCH 15/34] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 453c56062..81e6bd551 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 453c5606251d79bd0ac32dd6daec0ca8336de41d +Subproject commit 81e6bd5511c16133df340e732807d64faac1f7b2 From c1443751eca8d1ae5da981d286ef551869c5ba69 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 19 Jan 2015 10:35:37 +0100 Subject: [PATCH 16/34] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 81e6bd551..3312ddff4 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 81e6bd5511c16133df340e732807d64faac1f7b2 +Subproject commit 3312ddff4bded88adbf41d61bf0b7cf95615473d From 25b40de1ba6b8ba434ac9d5589784b40a46b4c3d Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Mon, 19 Jan 2015 14:07:37 +0100 Subject: [PATCH 17/34] Update ms2 for arm64 downscaling routine --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3312ddff4..a58ecee4b 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3312ddff4bded88adbf41d61bf0b7cf95615473d +Subproject commit a58ecee4bc3dfbdfcb6ce4c90324308242b57041 From af79c042080109f7ed73fd4db90d34f4c3f83652 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 20 Jan 2015 08:54:26 +0100 Subject: [PATCH 18/34] always create lib/mediastreamer/plugins at install time --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index a58ecee4b..0547e9ff4 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a58ecee4bc3dfbdfcb6ce4c90324308242b57041 +Subproject commit 0547e9ff4adc89c91f972ab6aba86f7410626a8e From b4dc7b3868a6fe6f5aa9ece5c08d28393ba0e8dd Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 20 Jan 2015 10:46:12 +0100 Subject: [PATCH 19/34] Fix typo for ZLIB --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b774fc448..db0356adb 100644 --- a/configure.ac +++ b/configure.ac @@ -298,7 +298,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 From 7f7671cfa26deffcb125018086189ccb39b4de47 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 20 Jan 2015 12:33:32 +0100 Subject: [PATCH 20/34] Include the git revision in the Windows setup.exe and Mac bundle file names. --- Makefile.am | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2fd425a0d..030964b09 100644 --- a/Makefile.am +++ b/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)-$(GITVERSION)-win32.zip ZIP_EXCLUDED=include lib \ $(OPTIONAL_SOUNDS) -SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-$(VERSION).zip +SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-$(GITVERSION)-win32.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)-$(GITVERSION)-setup.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. From 23530d3d27ed8fed42ea3c754ff2c4322d5c6243 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 20 Jan 2015 12:34:05 +0100 Subject: [PATCH 21/34] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 0547e9ff4..ebbef5c0c 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0547e9ff4adc89c91f972ab6aba86f7410626a8e +Subproject commit ebbef5c0cb97e181fb6055ff3e16f52c119147dc From 0d32bfbd3b336a55d13790b9d56b82d363e020a2 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 20 Jan 2015 16:22:38 +0100 Subject: [PATCH 22/34] Improve transport change test in Python. --- tools/python/unittests/test_register.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/python/unittests/test_register.py b/tools/python/unittests/test_register.py index f62da77e0..abfa6fa17 100644 --- a/tools/python/unittests/test_register.py +++ b/tools/python/unittests/test_register.py @@ -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) From 5824199483fbd4ff62d92722cd2c5175e41e7888 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Wed, 21 Jan 2015 12:29:13 +0100 Subject: [PATCH 23/34] Add keepAccounts(bool) and clearAccounts() to JNI --- tester/liblinphone_tester.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index aa4f78f29..27b9672b0 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -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__ From 317504a30655635d3c8bcfea3741de18f374674c Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Wed, 21 Jan 2015 13:59:01 +0100 Subject: [PATCH 24/34] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index ebbef5c0c..5662b24bc 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ebbef5c0cb97e181fb6055ff3e16f52c119147dc +Subproject commit 5662b24bc9ddd186daae74555b05b42bfedd763d From 16180e24301bad46d60570689b8d11e3a07561de Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 21 Jan 2015 22:36:23 +0100 Subject: [PATCH 25/34] change the way payload type numbers are assigned, so that an application can support more payload type than the RTP profile table allows to contain. Compliance with RFC3264 (offer answer model) is improved, by reusing numbers in case of reINVITEs. Fix memory leaks Move offer/answer related tests into a new test suite. --- build/android/liblinphone_tester.mk | 3 +- coreapi/bellesip_sal/sal_op_impl.c | 5 +- coreapi/callbacks.c | 17 ++ coreapi/linphonecall.c | 192 ++++++++++++-- coreapi/linphonecore.c | 394 ++++++++++++---------------- coreapi/linphonecore.h | 11 + coreapi/misc.c | 13 +- coreapi/offeranswer.c | 5 +- coreapi/private.h | 22 +- coreapi/quality_reporting.c | 1 + coreapi/sal.c | 5 +- include/sal/sal.h | 3 +- mediastreamer2 | 2 +- oRTP | 2 +- tester/Makefile.am | 3 +- tester/accountmanager.c | 7 +- tester/call_tester.c | 163 +----------- tester/liblinphone_tester.h | 2 + tester/offeranswer_tester.c | 297 +++++++++++++++++++++ tester/tester.c | 1 + 20 files changed, 704 insertions(+), 444 deletions(-) create mode 100644 tester/offeranswer_tester.c diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index ee2018621..d92bb60b5 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -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) \ diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index f9647f7ad..5c953ffc5 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -235,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); } } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index c43c84479..2d9ff58ae 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -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;inb_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); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 498c0accf..3c9dfaf90 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -228,35 +228,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; } @@ -395,9 +514,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;inb_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; @@ -406,6 +532,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); @@ -439,9 +566,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; nb_active_streams++; @@ -453,7 +582,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; nb_active_streams++; } @@ -468,7 +600,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; } @@ -481,6 +616,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); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ef4133d87..2543cb007 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -982,12 +982,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;inext){ + 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) ){ @@ -1009,7 +1010,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; @@ -1017,7 +1031,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; @@ -1025,85 +1039,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 (radefault_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){ @@ -1123,23 +1104,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); @@ -1412,60 +1393,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;ipayload_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;idefault_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){ @@ -1541,10 +1507,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()); @@ -1558,83 +1587,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(); @@ -1841,8 +1797,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); @@ -1860,8 +1815,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); @@ -6212,8 +6166,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) @@ -6519,20 +6473,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) { diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index c8a259f25..1e72fcd0a 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2345,8 +2345,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); diff --git a/coreapi/misc.c b/coreapi/misc.c index 59244d3de..d88c80cd5 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -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); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index d7d2e6e84..b9ece30d8 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -110,6 +110,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 +121,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 +145,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); } } diff --git a/coreapi/private.h b/coreapi/private.h index 55f1f1034..68a0e6354 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -365,6 +365,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); @@ -643,7 +644,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{ @@ -710,7 +713,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; @@ -719,8 +723,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; @@ -1014,6 +1016,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 diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index bb1d443bf..e22f7229c 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -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( diff --git a/coreapi/sal.c b/coreapi/sal.c index b8395c897..1577f95f6 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -62,9 +62,10 @@ SalMediaDescription *sal_media_description_new(){ static void sal_media_description_destroy(SalMediaDescription *md){ int i; for(i=0;istreams[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); } diff --git a/include/sal/sal.h b/include/sal/sal.h index c44317c88..42f2d6da8 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -196,7 +196,8 @@ typedef struct SalStreamDescription{ char rtcp_addr[64]; int rtp_port; int rtcp_port; - MSList *payloads; //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); } } diff --git a/tester/call_tester.c b/tester/call_tester.c index d608e9723..51cd2d550 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -34,7 +34,6 @@ static void srtp_call(void); static void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy); -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() @@ -727,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; @@ -754,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}; @@ -3036,115 +3001,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); } @@ -3530,7 +3386,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}, @@ -3607,22 +3462,6 @@ 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 }, diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 0ae708b70..5f257bb08 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -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); diff --git a/tester/offeranswer_tester.c b/tester/offeranswer_tester.c new file mode 100644 index 000000000..b9de6a879 --- /dev/null +++ b/tester/offeranswer_tester.c @@ -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 . +*/ + + +#include +#include +#include +#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_poslc,"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 +}; diff --git a/tester/tester.c b/tester/tester.c index 8c09b90f1..d3a34a375 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -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); From a75e8496116a2f1d4bfa10805e4cc37be02159d9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 22 Jan 2015 10:21:11 +0100 Subject: [PATCH 26/34] disable cross correlation tests, on arm, too long. --- tester/call_tester.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index 51cd2d550..dc8512f61 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2120,12 +2120,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); @@ -2188,16 +2192,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); From 9d3e0e736ee630c0b72ad06ec09c534b6f64c039 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 22 Jan 2015 10:22:58 +0100 Subject: [PATCH 27/34] fix conference with ice on android --- tester/call_tester.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index dc8512f61..ad703753e 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1981,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)); From 14451691c2c15c2849d0072b1eac0c5b2753bf98 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 22 Jan 2015 11:37:40 +0100 Subject: [PATCH 28/34] More coherent naming of SDK and setup package on Windows. --- Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 030964b09..4f3f46860 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,11 +22,11 @@ OPTIONAL_SOUNDS=\ INSTALLDIR=$(abs_top_builddir)/linphone-install INSTALLDIR_WITH_PREFIX=$(INSTALLDIR)/$(prefix) -ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-$(GITVERSION)-win32.zip +ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(GITVERSION).zip ZIP_EXCLUDED=include lib \ $(OPTIONAL_SOUNDS) -SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-$(GITVERSION)-win32.zip +SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-sdk-$(GITVERSION).zip SDK_EXCLUDED= \ bin/linphone.exe \ lib/*.la \ @@ -175,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)-$(GITVERSION)-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) From f48e34c4ee6306a3c482dc7326410efecf568ca1 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 23 Jan 2015 12:47:14 +0100 Subject: [PATCH 29/34] fix bad comment --- coreapi/offeranswer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index e24e4a215..f71734798 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -66,7 +66,6 @@ static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){ 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,"G729")==0 && refpt->channels==pt->channels){ candidate=pt; } From 7acf4df8831ac2b7f46c40033c307556afc34413 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 23 Jan 2015 09:38:34 +0100 Subject: [PATCH 30/34] Add a unit test for a no-sdp reinvite after a pause, and implement a correction to handle this case. --- coreapi/callbacks.c | 17 ++++++++++-- coreapi/linphonecore.c | 12 ++++++++- tester/call_tester.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 2d9ff58ae..2592f46a5 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -614,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; @@ -622,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)); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2543cb007..9a7a4af6b 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3977,7 +3977,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){ @@ -3988,6 +3992,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; } diff --git a/tester/call_tester.c b/tester/call_tester.c index ad703753e..b7146d5f8 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -3381,6 +3381,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 }, @@ -3467,6 +3526,7 @@ test_t call_tests[] = { { "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}, From f65ec2e2e92d8f408173a27d36db1058e63de01b Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 23 Jan 2015 16:26:57 +0100 Subject: [PATCH 31/34] Fix lengthy SDP buffer allocation --- coreapi/bellesip_sal/sal_op_call.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index da9871cec..4aca82a81 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -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); } } From 82419bbeea1d4f76f7688af05028babd17a003c0 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 23 Jan 2015 19:25:54 +0100 Subject: [PATCH 32/34] fix mingw compilation --- autogen.sh | 5 +++++ mediastreamer2 | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 9cedbf164..d5ec9ea80 100755 --- a/autogen.sh +++ b/autogen.sh @@ -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 diff --git a/mediastreamer2 b/mediastreamer2 index 7d2a30214..7ddb43caf 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 7d2a30214b8010224eed26bc1f239907618b9674 +Subproject commit 7ddb43caf21b79a3f45c93ff7532c4a4ab81031d From dd7524264209e6a4bebd01b119b1eed029b159ed Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 23 Jan 2015 22:38:31 +0100 Subject: [PATCH 33/34] fix multiple compilation problems with mingw --- mediastreamer2 | 2 +- tester/log_collection_tester.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 7ddb43caf..ae0c6d4b4 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 7ddb43caf21b79a3f45c93ff7532c4a4ab81031d +Subproject commit ae0c6d4b4088ea803b99b1339bcfa8fc2eb47aba diff --git a/tester/log_collection_tester.c b/tester/log_collection_tester.c index 35cf8d1f2..3260e3078 100644 --- a/tester/log_collection_tester.c +++ b/tester/log_collection_tester.c @@ -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); From acab82a28bb24df182833b173133f35fc559ca2a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 26 Jan 2015 17:29:33 +0100 Subject: [PATCH 34/34] Add /usr/include to the include path for MinGW. --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index db0356adb..64458d5ac 100644 --- a/configure.ac +++ b/configure.ac @@ -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