mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 04:58:14 +00:00
Merge branch 'master' into dev_bzrtp
This commit is contained in:
commit
bfba263da2
69 changed files with 2346 additions and 856 deletions
16
.cproject
16
.cproject
|
|
@ -22,7 +22,7 @@
|
|||
<folderInfo id="0.2079208171." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071.81924294" name=""/>
|
||||
<builder arguments="-j4 CFLAGS="-g -Wall -Qunused-arguments" CXXFLAGS="-g"" autoBuildTarget="all" cleanBuildTarget="clean" command="make" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.731584538" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<builder arguments="-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"" autoBuildTarget="all" cleanBuildTarget="clean" command="make" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.731584538" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1252970003" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1371414073" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.306286573" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
|
|
@ -39,20 +39,6 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<fileInfo id="0.2079208171.2090246372" name="ringback.wav" rcbsApplicability="disable" resourcePath="tester/sounds/ringback.wav" toolsToInvoke=""/>
|
||||
<folderInfo id="0.2079208171.1778481546" name="/" resourcePath="include">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1238844827" name="No ToolChain" superClass="org.eclipse.cdt.build.core.prefbase.toolchain" unusedChildren="">
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.58439860" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs.1252970003"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.899998629" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder.1371414073">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1829150855" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.252709365" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder.391709798">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.551083583" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1236597953" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder.754828354">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.714781911" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="coreapi"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gtk"/>
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -41,6 +41,7 @@ Specfile
|
|||
.anjuta_sym_db.db
|
||||
gtk-glade/version_date.h
|
||||
share/linphone.desktop
|
||||
share/audio-assistant.desktop
|
||||
Debug/
|
||||
build/macos/Info-linphone.plist
|
||||
coreapi/help/Doxyfile
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ LOCAL_CFLAGS += -DVIDEO_ENABLED
|
|||
ifeq ($(BUILD_X264),1)
|
||||
LOCAL_CFLAGS += -DHAVE_X264
|
||||
endif
|
||||
ifeq ($(BUILD_OPENH264),1)
|
||||
LOCAL_CFLAGS += -DHAVE_OPENH264
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_CONTACT_HEADER),1)
|
||||
|
|
@ -175,6 +178,11 @@ LOCAL_STATIC_LIBRARIES += \
|
|||
libmsx264 \
|
||||
libx264
|
||||
endif
|
||||
ifeq ($(BUILD_OPENH264),1)
|
||||
LOCAL_STATIC_LIBRARIES += \
|
||||
libmsopenh264 \
|
||||
libwels
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_UPNP),1)
|
||||
|
|
@ -199,13 +207,12 @@ LOCAL_SRC_FILES += $(LIBLINPHONE_EXTENDED_SRC_FILES)
|
|||
LOCAL_CFLAGS += $(LIBLINPHONE_EXTENDED_CFLAGS)
|
||||
|
||||
|
||||
ifeq ($(BUILD_GPLV3_ZRTP),1)
|
||||
LOCAL_SHARED_LIBRARIES += libssl-linphone libcrypto-linphone
|
||||
LOCAL_SHARED_LIBRARIES += libbzrtp
|
||||
ifeq ($(BUILD_ZRTP),1)
|
||||
LOCAL_STATIC_LIBRARIES += libbzrtp
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_SRTP),1)
|
||||
LOCAL_SHARED_LIBRARIES += libsrtp
|
||||
LOCAL_STATIC_LIBRARIES += libsrtp
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_SQLITE),1)
|
||||
|
|
|
|||
|
|
@ -16,13 +16,16 @@ Download and install the repo rpmforge :
|
|||
$ sudo yum install ffmpeg-devel
|
||||
$ sudo yum install openldap-devel
|
||||
|
||||
- Install antlr3
|
||||
$ git clone git://git.linphone.org/antlr3.git
|
||||
$ cd antlr3
|
||||
$ sudo cp antlr-3.4-complete.jar /usr/share/java/antlr3.jar
|
||||
|
||||
- Download and install packages
|
||||
$ sudo rpm -Uhv ftp://ftp.icm.edu.pl/vol/rzm2/linux-fedora/linux/epel/6/x86_64/polarssl-1.3.2-1.el6.x86_64.rpm
|
||||
$ sudo rpm -Uvh ftp://ftp.icm.edu.pl/vol/rzm2/linux-fedora/linux/epel/6/x86_64/polarssl-devel-1.3.2-1.el6.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-C-3.2-14.fc15.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-C-devel-3.2-14.fc15.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-tool-3.2-14.fc15.noarch.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Fedora/i386/os/Packages/antlr3-java-3.2-14.fc15.noarch.rpm
|
||||
|
||||
- Git repository
|
||||
|
||||
|
|
@ -41,6 +44,9 @@ Download and install the repo rpmforge :
|
|||
$ ./configure
|
||||
$ make && make rpm
|
||||
|
||||
- Compile msx264
|
||||
$ ./autogen.sh && ./configure && make
|
||||
$ make rpm
|
||||
|
||||
-Create yum repo :
|
||||
$ cd rpmbuild/RPMS/*arch*/
|
||||
|
|
|
|||
|
|
@ -767,7 +767,7 @@ AM_CONDITIONAL(ENABLE_MANUAL, test x$have_sgmltools$build_manual = xyesyes )
|
|||
|
||||
dnl for external use of linphone libs
|
||||
LINPHONE_CFLAGS="-I${includedir} -I${includedir}/linphone"
|
||||
LINPHONE_LIBS="-L${libdir} -llinphone -llpc2xml -lxml2lpc"
|
||||
LINPHONE_LIBS="-L${libdir} -llinphone"
|
||||
|
||||
AC_SUBST(LINPHONE_CFLAGS)
|
||||
AC_SUBST(LINPHONE_LIBS)
|
||||
|
|
@ -900,6 +900,7 @@ AC_CONFIG_FILES([
|
|||
share/xml/Makefile
|
||||
share/linphone.pc
|
||||
share/linphone.desktop
|
||||
share/audio-assistant.desktop
|
||||
scripts/Makefile
|
||||
tools/Makefile
|
||||
linphone.spec
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ static char last_in_history[256];
|
|||
#endif
|
||||
//auto answer (-a) option
|
||||
static bool_t auto_answer=FALSE;
|
||||
static bool_t real_early_media_sending=FALSE;
|
||||
static bool_t answer_call=FALSE;
|
||||
static bool_t vcap_enabled=FALSE;
|
||||
static bool_t display_enabled=FALSE;
|
||||
|
|
@ -362,10 +363,17 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L
|
|||
linphone_call_enable_camera (call,linphonec_camera_enabled);
|
||||
id=(long)linphone_call_get_user_pointer (call);
|
||||
linphonec_set_caller(from);
|
||||
linphonec_out("Receiving new incoming call from %s, assigned id %i\n", from,id);
|
||||
if ( auto_answer) {
|
||||
answer_call=TRUE;
|
||||
} else if (real_early_media_sending) {
|
||||
linphonec_out("Sending early media using real hardware\n");
|
||||
LinphoneCallParams* callparams = linphone_core_create_default_call_parameters(lc);
|
||||
linphone_call_params_enable_early_media_sending(callparams, TRUE);
|
||||
if (vcap_enabled) linphone_call_params_enable_video(callparams, TRUE);
|
||||
linphone_core_accept_early_media_with_params(lc, call, callparams);
|
||||
linphone_call_params_destroy(callparams);
|
||||
}
|
||||
linphonec_out("Receiving new incoming call from %s, assigned id %i\n", from,id);
|
||||
break;
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphonec_call_identify(call);
|
||||
|
|
@ -906,6 +914,7 @@ print_usage (int exit_status)
|
|||
" -l logfile specify the log file for your SIP phone\n"
|
||||
" -s sipaddress specify the sip call to do at startup\n"
|
||||
" -a enable auto answering for incoming calls\n"
|
||||
" --real-early-media enable sending early media using real audio/video (beware of privacy issue)\n"
|
||||
" -V enable video features globally (disabled by default)\n"
|
||||
" -C enable video capture only (disabled by default)\n"
|
||||
" -D enable video display only (disabled by default)\n"
|
||||
|
|
@ -1229,6 +1238,10 @@ linphonec_parse_cmdline(int argc, char **argv)
|
|||
{
|
||||
auto_answer = TRUE;
|
||||
}
|
||||
else if (strncmp ("--real-early-media", argv[arg_num], 2) == 0)
|
||||
{
|
||||
real_early_media_sending = TRUE;
|
||||
}
|
||||
else if (strncmp ("-C", argv[arg_num], 2) == 0)
|
||||
{
|
||||
vcap_enabled = TRUE;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,13 @@ void sal_process_authentication(SalOp *op) {
|
|||
belle_sip_list_t* auth_list=NULL;
|
||||
belle_sip_auth_event_t* auth_event;
|
||||
belle_sip_response_t *response=belle_sip_transaction_get_response((belle_sip_transaction_t*)op->pending_auth_transaction);
|
||||
belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(initial_request,belle_sip_header_from_t);
|
||||
belle_sip_uri_t *from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from);
|
||||
|
||||
if (strcasecmp(belle_sip_uri_get_host(from_uri),"anonymous.invalid")==0){
|
||||
/*prefer using the from from the SalOp*/
|
||||
from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)sal_op_get_from_address(op));
|
||||
}
|
||||
|
||||
if (op->dialog && belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_CONFIRMED) {
|
||||
new_request = belle_sip_dialog_create_request_from(op->dialog,initial_request);
|
||||
|
|
@ -132,7 +138,7 @@ void sal_process_authentication(SalOp *op) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,&auth_list)) {
|
||||
if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list)) {
|
||||
if (is_within_dialog) {
|
||||
sal_op_send_request(op,new_request);
|
||||
} else {
|
||||
|
|
@ -162,8 +168,8 @@ void sal_process_authentication(SalOp *op) {
|
|||
static void process_dialog_terminated(void *sal, const belle_sip_dialog_terminated_event_t *event){
|
||||
belle_sip_dialog_t* dialog = belle_sip_dialog_terminated_event_get_dialog(event);
|
||||
SalOp* op = belle_sip_dialog_get_application_data(dialog);
|
||||
if (op && op->callbacks.process_dialog_terminated) {
|
||||
op->callbacks.process_dialog_terminated(op,event);
|
||||
if (op && op->callbacks && op->callbacks->process_dialog_terminated) {
|
||||
op->callbacks->process_dialog_terminated(op,event);
|
||||
} else {
|
||||
ms_error("sal process_dialog_terminated no op found for this dialog [%p], ignoring",dialog);
|
||||
}
|
||||
|
|
@ -177,8 +183,8 @@ static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *e
|
|||
op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
/*also reset auth count on IO error*/
|
||||
op->auth_requests=0;
|
||||
if (op->callbacks.process_io_error) {
|
||||
op->callbacks.process_io_error(op,event);
|
||||
if (op->callbacks && op->callbacks->process_io_error) {
|
||||
op->callbacks->process_io_error(op,event);
|
||||
}
|
||||
} else {
|
||||
/*ms_error("sal process_io_error not implemented yet for non transaction");*/
|
||||
|
|
@ -290,8 +296,8 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
|
|||
sal_op_set_privacy_from_message(op,(belle_sip_message_t*)req);
|
||||
|
||||
sal_op_assign_recv_headers(op,(belle_sip_message_t*)req);
|
||||
if (op->callbacks.process_request_event) {
|
||||
op->callbacks.process_request_event(op,event);
|
||||
if (op->callbacks && op->callbacks->process_request_event) {
|
||||
op->callbacks->process_request_event(op,event);
|
||||
} else {
|
||||
ms_error("sal process_request_event not implemented yet");
|
||||
}
|
||||
|
|
@ -329,7 +335,7 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
|
|||
|
||||
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
|
||||
|
||||
if (op->callbacks.process_response_event) {
|
||||
if (op->callbacks && op->callbacks->process_response_event) {
|
||||
/*handle authorization*/
|
||||
switch (response_code) {
|
||||
case 200:
|
||||
|
|
@ -365,7 +371,7 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
|
|||
/*not an auth request*/
|
||||
op->auth_requests=0;
|
||||
}
|
||||
op->callbacks.process_response_event(op,event);
|
||||
op->callbacks->process_response_event(op,event);
|
||||
} else {
|
||||
ms_error("Unhandled event response [%p]",event);
|
||||
}
|
||||
|
|
@ -375,8 +381,8 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
|
|||
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
||||
belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event);
|
||||
SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
if (op && op->callbacks.process_timeout) {
|
||||
op->callbacks.process_timeout(op,event);
|
||||
if (op && op->callbacks && op->callbacks->process_timeout) {
|
||||
op->callbacks->process_timeout(op,event);
|
||||
} else {
|
||||
ms_error("Unhandled event timeout [%p]",event);
|
||||
}
|
||||
|
|
@ -393,8 +399,8 @@ static void process_transaction_terminated(void *user_ctx, const belle_sip_trans
|
|||
trans=BELLE_SIP_TRANSACTION(server_transaction);
|
||||
|
||||
op = (SalOp*)belle_sip_transaction_get_application_data(trans);
|
||||
if (op && op->callbacks.process_transaction_terminated) {
|
||||
op->callbacks.process_transaction_terminated(op,event);
|
||||
if (op && op->callbacks && op->callbacks->process_transaction_terminated) {
|
||||
op->callbacks->process_transaction_terminated(op,event);
|
||||
} else {
|
||||
ms_message("Unhandled transaction terminated [%p]",trans);
|
||||
}
|
||||
|
|
@ -443,6 +449,7 @@ Sal * sal_init(){
|
|||
sal->refresher_retry_after=60000; /*default value in ms*/
|
||||
return sal;
|
||||
}
|
||||
|
||||
void sal_set_user_pointer(Sal *sal, void *user_data){
|
||||
sal->up=user_data;
|
||||
}
|
||||
|
|
@ -536,14 +543,22 @@ int sal_transport_available(Sal *sal, SalTransport t){
|
|||
|
||||
int sal_add_listen_port(Sal *ctx, SalAddress* addr){
|
||||
int result;
|
||||
belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack
|
||||
,sal_address_get_domain(addr)
|
||||
,sal_address_get_port(addr)
|
||||
,sal_transport_to_string(sal_address_get_transport(addr)));
|
||||
belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack,
|
||||
sal_address_get_domain(addr),
|
||||
sal_address_get_port(addr),
|
||||
sal_transport_to_string(sal_address_get_transport(addr)));
|
||||
if (sal_address_get_port(addr)==-1 && lp==NULL){
|
||||
int random_port=(0xDFFF&random())+1024;
|
||||
ms_warning("This version of belle-sip doesn't support random port, choosing one here.");
|
||||
lp = belle_sip_stack_create_listening_point(ctx->stack,
|
||||
sal_address_get_domain(addr),
|
||||
random_port,
|
||||
sal_transport_to_string(sal_address_get_transport(addr)));
|
||||
}
|
||||
if (lp) {
|
||||
belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive);
|
||||
result = belle_sip_provider_add_listening_point(ctx->prov,lp);
|
||||
set_tls_properties(ctx);
|
||||
if (sal_address_get_transport(addr)==SalTransportTLS) set_tls_properties(ctx);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -560,22 +575,34 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
|
|||
sal_address_destroy(sal_addr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void remove_listening_point(belle_sip_listening_point_t* lp,belle_sip_provider_t* prov) {
|
||||
belle_sip_provider_remove_listening_point(prov,lp);
|
||||
}
|
||||
|
||||
int sal_get_listening_port(Sal *ctx, SalTransport tr){
|
||||
const char *tpn=sal_transport_to_string(tr);
|
||||
belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(ctx->prov, tpn);
|
||||
if (lp){
|
||||
return belle_sip_listening_point_get_port(lp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sal_unlisten_ports(Sal *ctx){
|
||||
const belle_sip_list_t * lps = belle_sip_provider_get_listening_points(ctx->prov);
|
||||
belle_sip_list_t * tmp_list = belle_sip_list_copy(lps);
|
||||
belle_sip_list_for_each2 (tmp_list,(void (*)(void*,void*))remove_listening_point,ctx->prov);
|
||||
belle_sip_list_free(tmp_list);
|
||||
|
||||
ms_message("sal_unlisten_ports done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ortp_socket_t sal_get_socket(Sal *ctx){
|
||||
ms_warning("sal_get_socket is deprecated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void sal_set_user_agent(Sal *ctx, const char *user_agent){
|
||||
belle_sip_header_user_agent_set_products(ctx->user_agent,NULL);
|
||||
belle_sip_header_user_agent_add_product(ctx->user_agent,user_agent);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ const char* sal_op_type_to_string(SalOpType type);
|
|||
|
||||
struct SalOp{
|
||||
SalOpBase base;
|
||||
belle_sip_listener_callbacks_t callbacks;
|
||||
const belle_sip_listener_callbacks_t *callbacks;
|
||||
SalErrorInfo error_info;
|
||||
belle_sip_client_transaction_t *pending_auth_transaction;
|
||||
belle_sip_server_transaction_t* pending_server_trans;
|
||||
belle_sip_server_transaction_t* pending_update_server_trans;
|
||||
|
|
@ -132,8 +133,10 @@ bool_t sal_op_is_secure(const SalOp* op);
|
|||
void sal_process_authentication(SalOp *op);
|
||||
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op) ;
|
||||
|
||||
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size);
|
||||
void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal_reason) ;
|
||||
bool_t _sal_compute_sal_errors(belle_sip_response_t* response, SalReason* sal_reason, char* reason, size_t reason_size);
|
||||
SalReason _sal_reason_from_sip_code(int code);
|
||||
|
||||
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response);
|
||||
/*presence*/
|
||||
void sal_op_presence_fill_cbs(SalOp*op);
|
||||
/*messaging*/
|
||||
|
|
|
|||
|
|
@ -38,19 +38,8 @@ static void call_set_released_and_unref(SalOp* op) {
|
|||
|
||||
|
||||
static void call_set_error(SalOp* op,belle_sip_response_t* response){
|
||||
SalError error=SalErrorUnknown;
|
||||
SalReason sr=SalReasonUnknown;
|
||||
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
|
||||
char* reason=(char*)belle_sip_response_get_reason_phrase(response);
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
if (reason_header){
|
||||
reason = ms_strdup_printf("%s %s",reason,belle_sip_header_get_unparsed_value(reason_header));
|
||||
}
|
||||
sal_compute_sal_errors_from_code(code,&error,&sr);
|
||||
op->base.root->callbacks.call_failure(op,error,sr,reason,code);
|
||||
if (reason_header != NULL){
|
||||
ms_free(reason);
|
||||
}
|
||||
sal_op_set_error_info_from_response(op,response);
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
}
|
||||
|
||||
static void sdp_process(SalOp *h){
|
||||
|
|
@ -127,7 +116,8 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event
|
|||
|
||||
if (!op->dialog) {
|
||||
/*call terminated very early*/
|
||||
op->base.root->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,"Service Unavailable",503);
|
||||
sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO error",NULL);
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
call_set_released(op);
|
||||
} else {
|
||||
/*dialog will terminated shortly, nothing to do*/
|
||||
|
|
@ -178,7 +168,12 @@ static void cancelling_invite(SalOp* op ){
|
|||
sal_op_send_request(op,cancel);
|
||||
op->state=SalOpStateTerminating;
|
||||
}
|
||||
|
||||
static int vfu_retry (void *user_data, unsigned int events) {
|
||||
SalOp *op=(SalOp *)user_data;
|
||||
sal_call_send_vfu_request(op);
|
||||
sal_op_unref(op);
|
||||
return BELLE_SIP_STOP;
|
||||
}
|
||||
static void call_process_response(void *op_base, const belle_sip_response_event_t *event){
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
belle_sip_request_t* ack;
|
||||
|
|
@ -187,6 +182,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
belle_sip_request_t* req;
|
||||
belle_sip_response_t* response=belle_sip_response_event_get_response(event);
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
belle_sip_header_content_type_t *header_content_type=NULL;
|
||||
|
||||
|
||||
if (!client_transaction) {
|
||||
|
|
@ -257,7 +253,16 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
op->state=SalOpStateActive;
|
||||
} else if (code >= 300 && strcmp("INVITE",belle_sip_request_get_method(req))==0){
|
||||
call_set_error(op,response);
|
||||
} else {
|
||||
} else if (code == 491
|
||||
&& strcmp("INFO",belle_sip_request_get_method(req)) == 0
|
||||
&& (header_content_type = belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t))
|
||||
&& strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0
|
||||
&& strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) {
|
||||
unsigned int retry_in =1000*((float)rand()/RAND_MAX);
|
||||
belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry");
|
||||
ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in);
|
||||
belle_sip_object_unref(s);
|
||||
}else {
|
||||
/*ignoring*/
|
||||
}
|
||||
break;
|
||||
|
|
@ -290,7 +295,8 @@ static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t
|
|||
|
||||
if (!op->dialog) {
|
||||
/*call terminated very early*/
|
||||
op->base.root->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,"Request Timeout",408);
|
||||
sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
call_set_released(op);
|
||||
} else {
|
||||
/*dialog will terminated shortly, nothing to do*/
|
||||
|
|
@ -631,13 +637,18 @@ int sal_call(SalOp *op, const char *from, const char *to){
|
|||
return sal_op_send_request(op,invite);
|
||||
}
|
||||
|
||||
static belle_sip_listener_callbacks_t call_op_callbacks={0};
|
||||
|
||||
void sal_op_call_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_io_error=call_process_io_error;
|
||||
op->callbacks.process_response_event=call_process_response;
|
||||
op->callbacks.process_timeout=call_process_timeout;
|
||||
op->callbacks.process_transaction_terminated=call_process_transaction_terminated;
|
||||
op->callbacks.process_request_event=process_request_event;
|
||||
op->callbacks.process_dialog_terminated=process_dialog_terminated;
|
||||
if (call_op_callbacks.process_response_event==NULL){
|
||||
call_op_callbacks.process_io_error=call_process_io_error;
|
||||
call_op_callbacks.process_response_event=call_process_response;
|
||||
call_op_callbacks.process_timeout=call_process_timeout;
|
||||
call_op_callbacks.process_transaction_terminated=call_process_transaction_terminated;
|
||||
call_op_callbacks.process_request_event=process_request_event;
|
||||
call_op_callbacks.process_dialog_terminated=process_dialog_terminated;
|
||||
}
|
||||
op->callbacks=&call_op_callbacks;
|
||||
op->type=SalOpCall;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ static void subscribe_refresher_listener (belle_sip_refresher_t* refresher
|
|||
,unsigned int status_code
|
||||
,const char* reason_phrase) {
|
||||
SalOp* op = (SalOp*)user_pointer;
|
||||
SalError error=SalErrorUnknown;
|
||||
SalReason sr=SalReasonUnknown;
|
||||
belle_sip_transaction_t *tr=BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher));
|
||||
/*belle_sip_response_t* response=belle_sip_transaction_get_response(tr);*/
|
||||
SalSubscribeStatus sss=SalSubscribeTerminated;
|
||||
|
|
@ -50,8 +48,8 @@ static void subscribe_refresher_listener (belle_sip_refresher_t* refresher
|
|||
set_or_update_dialog(op,belle_sip_transaction_get_dialog(tr));
|
||||
}
|
||||
if (status_code>=200){
|
||||
sal_compute_sal_errors_from_code(status_code,&error,&sr);
|
||||
op->base.root->callbacks.subscribe_response(op,sss,error,sr);
|
||||
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
|
||||
op->base.root->callbacks.subscribe_response(op,sss);
|
||||
}else if (status_code==0){
|
||||
op->base.root->callbacks.on_expire(op);
|
||||
}
|
||||
|
|
@ -172,13 +170,18 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
|
|||
}
|
||||
}
|
||||
|
||||
static belle_sip_listener_callbacks_t op_subscribe_callbacks={ 0 };
|
||||
|
||||
void sal_op_subscribe_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_io_error=subscribe_process_io_error;
|
||||
op->callbacks.process_response_event=subscribe_response_event;
|
||||
op->callbacks.process_timeout=subscribe_process_timeout;
|
||||
op->callbacks.process_transaction_terminated=subscribe_process_transaction_terminated;
|
||||
op->callbacks.process_request_event=subscribe_process_request_event;
|
||||
op->callbacks.process_dialog_terminated=subscribe_process_dialog_terminated;
|
||||
if (op_subscribe_callbacks.process_io_error==NULL){
|
||||
op_subscribe_callbacks.process_io_error=subscribe_process_io_error;
|
||||
op_subscribe_callbacks.process_response_event=subscribe_response_event;
|
||||
op_subscribe_callbacks.process_timeout=subscribe_process_timeout;
|
||||
op_subscribe_callbacks.process_transaction_terminated=subscribe_process_transaction_terminated;
|
||||
op_subscribe_callbacks.process_request_event=subscribe_process_request_event;
|
||||
op_subscribe_callbacks.process_dialog_terminated=subscribe_process_dialog_terminated;
|
||||
}
|
||||
op->callbacks=&op_subscribe_callbacks;
|
||||
op->type=SalOpSubscribe;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ void sal_op_release_impl(SalOp *op){
|
|||
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
|
||||
if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans);
|
||||
if (op->event) belle_sip_object_unref(op->event);
|
||||
sal_error_info_reset(&op->error_info);
|
||||
__sal_op_free(op);
|
||||
return ;
|
||||
}
|
||||
|
|
@ -89,18 +90,23 @@ SalAuthInfo * sal_op_get_auth_requested(SalOp *op){
|
|||
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){
|
||||
belle_sip_header_contact_t* contact_header;
|
||||
belle_sip_uri_t* contact_uri;
|
||||
|
||||
if (sal_op_get_contact_address(op)) {
|
||||
contact_header = belle_sip_header_contact_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_contact_address(op)));
|
||||
} else {
|
||||
contact_header= belle_sip_header_contact_new();
|
||||
}
|
||||
|
||||
if (!(contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_header)))) {
|
||||
/*no uri, just creating a new one*/
|
||||
contact_uri=belle_sip_uri_new();
|
||||
belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact_header),contact_uri);
|
||||
}
|
||||
|
||||
belle_sip_uri_set_secure(contact_uri,sal_op_is_secure(op));
|
||||
|
||||
if (op->privacy!=SalPrivacyNone){
|
||||
belle_sip_uri_set_user(contact_uri,NULL);
|
||||
}
|
||||
belle_sip_header_contact_set_automatic(contact_header,op->base.root->auto_contacts);
|
||||
if (op->base.root->uuid){
|
||||
if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance")==0){
|
||||
|
|
@ -298,7 +304,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION)
|
||||
&& !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) {
|
||||
/*hmm just in case we already have authentication param in cache*/
|
||||
belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL);
|
||||
belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL);
|
||||
}
|
||||
result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/);
|
||||
|
||||
|
|
@ -334,6 +340,12 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
|
|||
SalReason sal_reason_to_sip_code(SalReason r){
|
||||
int ret=500;
|
||||
switch(r){
|
||||
case SalReasonNone:
|
||||
ret=200;
|
||||
break;
|
||||
case SalReasonIOError:
|
||||
ret=503;
|
||||
break;
|
||||
case SalReasonUnknown:
|
||||
ret=400;
|
||||
break;
|
||||
|
|
@ -401,110 +413,123 @@ SalReason sal_reason_to_sip_code(SalReason r){
|
|||
return ret;
|
||||
}
|
||||
|
||||
void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal_reason) {
|
||||
*sal_err=SalErrorFailure;
|
||||
SalReason _sal_reason_from_sip_code(int code) {
|
||||
if (code>=100 && code<300) return SalReasonNone;
|
||||
|
||||
switch(code) {
|
||||
case 0:
|
||||
return SalReasonIOError;
|
||||
case 301:
|
||||
*sal_reason=SalReasonMovedPermanently;
|
||||
break;
|
||||
return SalReasonMovedPermanently;
|
||||
case 302:
|
||||
*sal_reason=SalReasonRedirect;
|
||||
break;
|
||||
return SalReasonRedirect;
|
||||
case 401:
|
||||
case 407:
|
||||
*sal_reason=SalReasonUnauthorized;
|
||||
break;
|
||||
return SalReasonUnauthorized;
|
||||
case 403:
|
||||
*sal_reason=SalReasonForbidden;
|
||||
break;
|
||||
return SalReasonForbidden;
|
||||
case 404:
|
||||
*sal_reason=SalReasonNotFound;
|
||||
break;
|
||||
return SalReasonNotFound;
|
||||
case 408:
|
||||
*sal_reason=SalReasonRequestTimeout;
|
||||
break;
|
||||
return SalReasonRequestTimeout;
|
||||
case 410:
|
||||
*sal_reason=SalReasonGone;
|
||||
break;
|
||||
return SalReasonGone;
|
||||
case 415:
|
||||
*sal_reason=SalReasonUnsupportedContent;
|
||||
break;
|
||||
return SalReasonUnsupportedContent;
|
||||
case 422:
|
||||
ms_error ("422 not implemented yet");;
|
||||
break;
|
||||
case 480:
|
||||
*sal_reason=SalReasonTemporarilyUnavailable;
|
||||
break;
|
||||
return SalReasonTemporarilyUnavailable;
|
||||
case 481:
|
||||
*sal_reason=SalReasonNoMatch;
|
||||
break;
|
||||
return SalReasonNoMatch;
|
||||
case 484:
|
||||
*sal_reason=SalReasonAddressIncomplete;
|
||||
break;
|
||||
return SalReasonAddressIncomplete;
|
||||
case 486:
|
||||
*sal_reason=SalReasonBusy;
|
||||
break;
|
||||
return SalReasonBusy;
|
||||
case 487:
|
||||
break;
|
||||
return SalReasonNone;
|
||||
case 488:
|
||||
*sal_reason=SalReasonNotAcceptable;
|
||||
break;
|
||||
return SalReasonNotAcceptable;
|
||||
case 491:
|
||||
*sal_reason=SalReasonRequestPending;
|
||||
break;
|
||||
return SalReasonRequestPending;
|
||||
case 501:
|
||||
*sal_reason=SalReasonNotImplemented;
|
||||
break;
|
||||
return SalReasonNotImplemented;
|
||||
case 502:
|
||||
*sal_reason=SalReasonBadGateway;
|
||||
break;
|
||||
return SalReasonBadGateway;
|
||||
case 504:
|
||||
*sal_reason=SalReasonServerTimeout;
|
||||
break;
|
||||
return SalReasonServerTimeout;
|
||||
case 600:
|
||||
*sal_reason=SalReasonDoNotDisturb;
|
||||
break;
|
||||
return SalReasonDoNotDisturb;
|
||||
case 603:
|
||||
*sal_reason=SalReasonDeclined;
|
||||
break;
|
||||
return SalReasonDeclined;
|
||||
case 503:
|
||||
*sal_reason=SalReasonServiceUnavailable;
|
||||
break;
|
||||
return SalReasonServiceUnavailable;
|
||||
default:
|
||||
if (code>=300){
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonUnknown;
|
||||
}else if (code>=100){
|
||||
*sal_err=SalErrorNone;
|
||||
*sal_reason=SalReasonUnknown;
|
||||
}else if (code==0){
|
||||
*sal_err=SalErrorNoResponse;
|
||||
}
|
||||
/* no break */
|
||||
return SalReasonUnknown;
|
||||
}
|
||||
return SalReasonUnknown;
|
||||
}
|
||||
|
||||
const SalErrorInfo *sal_error_info_none(void){
|
||||
static SalErrorInfo none={
|
||||
SalReasonNone,
|
||||
"Ok",
|
||||
200,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &none;
|
||||
}
|
||||
|
||||
void sal_error_info_reset(SalErrorInfo *ei){
|
||||
if (ei->status_string){
|
||||
ms_free(ei->status_string);
|
||||
ei->status_string=NULL;
|
||||
}
|
||||
if (ei->warnings){
|
||||
ms_free(ei->warnings);
|
||||
ei->warnings=NULL;
|
||||
|
||||
}
|
||||
if (ei->full_string){
|
||||
ms_free(ei->full_string);
|
||||
ei->full_string=NULL;
|
||||
}
|
||||
ei->protocol_code=0;
|
||||
ei->reason=SalReasonNone;
|
||||
}
|
||||
|
||||
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning){
|
||||
sal_error_info_reset(ei);
|
||||
if (reason==SalReasonUnknown) ei->reason=_sal_reason_from_sip_code(code);
|
||||
else ei->reason=reason;
|
||||
ei->protocol_code=code;
|
||||
ei->status_string=status_string ? ms_strdup(status_string) : NULL;
|
||||
ei->warnings=warning ? ms_strdup(warning) : NULL;
|
||||
if (ei->status_string){
|
||||
if (ei->warnings)
|
||||
ei->full_string=ms_strdup_printf("%s %s",ei->status_string,ei->warnings);
|
||||
else ei->full_string=ms_strdup(ei->status_string);
|
||||
}
|
||||
}
|
||||
/*return TRUE if error code*/
|
||||
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size) {
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
|
||||
*sal_err=SalErrorUnknown;
|
||||
*sal_reason = SalReasonUnknown;
|
||||
|
||||
if (reason_header){
|
||||
snprintf(reason
|
||||
,reason_size
|
||||
,"%s %s"
|
||||
,belle_sip_response_get_reason_phrase(response)
|
||||
,belle_sip_header_get_unparsed_value(reason_header));
|
||||
} else {
|
||||
strncpy(reason,belle_sip_response_get_reason_phrase(response),reason_size);
|
||||
}
|
||||
if (code>=400) {
|
||||
sal_compute_sal_errors_from_code(code,sal_err,sal_reason);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response){
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
const char *reason_phrase=belle_sip_response_get_reason_phrase(response);
|
||||
/*Remark: the reason header is to be used mainly in SIP requests, thus the use and prototype of this function should be changed.*/
|
||||
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
|
||||
belle_sip_header_t *warning=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Warning");
|
||||
SalErrorInfo *ei=&op->error_info;
|
||||
const char *warnings;
|
||||
|
||||
warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL;
|
||||
if (warnings==NULL) warnings=reason_header ? belle_sip_header_get_unparsed_value(reason_header) : NULL;
|
||||
sal_error_info_set(ei,SalReasonUnknown,code,reason_phrase,warnings);
|
||||
}
|
||||
|
||||
const SalErrorInfo *sal_op_get_error_info(const SalOp *op){
|
||||
return &op->error_info;
|
||||
}
|
||||
|
||||
void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
static void process_error( SalOp* op) {
|
||||
if (op->dir == SalOpDirOutgoing) {
|
||||
op->base.root->callbacks.text_delivery_update(op, SalTextDeliveryFailed, SalReasonUnknown);
|
||||
op->base.root->callbacks.text_delivery_update(op, SalTextDeliveryFailed);
|
||||
} else {
|
||||
ms_warning("unexpected io error for incoming message on op [%p]",op);
|
||||
}
|
||||
|
|
@ -30,33 +30,20 @@ static void process_error( SalOp* op) {
|
|||
|
||||
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
|
||||
SalOp* op = (SalOp*)user_ctx;
|
||||
// belle_sip_object_t* source = belle_sip_io_error_event_get_source(event);
|
||||
// if (BELLE_SIP_IS_INSTANCE_OF(source,belle_sip_transaction_t)) {
|
||||
// /*reset op to make sure transaction terminated does not need op*/
|
||||
// belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(source),NULL);
|
||||
// }
|
||||
sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO Error",NULL);
|
||||
process_error(op);
|
||||
}
|
||||
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
||||
SalOp* op=(SalOp*)user_ctx;
|
||||
// belle_sip_client_transaction_t *client_transaction=belle_sip_timeout_event_get_client_transaction(event);
|
||||
// belle_sip_server_transaction_t *server_transaction=belle_sip_timeout_event_get_server_transaction(event);
|
||||
// /*reset op to make sure transaction terminated does not need op*/
|
||||
// if (client_transaction) {
|
||||
// belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),NULL);
|
||||
// } else {
|
||||
// belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),NULL);
|
||||
// }
|
||||
sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
|
||||
process_error(op);
|
||||
|
||||
}
|
||||
static void process_response_event(void *op_base, const belle_sip_response_event_t *event){
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
/*belle_sip_client_transaction_t *client_transaction=belle_sip_response_event_get_client_transaction(event);*/
|
||||
int code = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
|
||||
SalTextDeliveryStatus status;
|
||||
SalReason reason=SalReasonUnknown;
|
||||
SalError err=SalErrorNone;
|
||||
sal_op_set_error_info_from_response(op,belle_sip_response_event_get_response(event));
|
||||
|
||||
if (code>=100 && code <200)
|
||||
status=SalTextDeliveryInProgress;
|
||||
|
|
@ -64,13 +51,10 @@ static void process_response_event(void *op_base, const belle_sip_response_event
|
|||
status=SalTextDeliveryDone;
|
||||
else
|
||||
status=SalTextDeliveryFailed;
|
||||
if (status != SalTextDeliveryInProgress) {
|
||||
/*reset op to make sure transaction terminated does not need op
|
||||
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),NULL);*/
|
||||
}
|
||||
sal_compute_sal_errors_from_code(code,&err,&reason);
|
||||
op->base.root->callbacks.text_delivery_update(op,status, reason);
|
||||
|
||||
op->base.root->callbacks.text_delivery_update(op,status);
|
||||
}
|
||||
|
||||
static bool_t is_plain_text(belle_sip_header_content_type_t* content_type) {
|
||||
return strcmp("text",belle_sip_header_content_type_get_type(content_type))==0
|
||||
&& strcmp("plain",belle_sip_header_content_type_get_subtype(content_type))==0;
|
||||
|
|
@ -108,6 +92,11 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
|
|||
|| (external_body=is_external_body(content_type)))) {
|
||||
SalMessage salmsg;
|
||||
char message_id[256]={0};
|
||||
|
||||
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
|
||||
op->pending_server_trans=server_transaction;
|
||||
belle_sip_object_ref(op->pending_server_trans);
|
||||
|
||||
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
|
||||
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
|
||||
|
|
@ -136,6 +125,8 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
|
|||
saliscomposing.from=from;
|
||||
saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
|
||||
op->base.root->callbacks.is_composing_received(op,&saliscomposing);
|
||||
resp = belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
belle_sip_object_unref(address);
|
||||
belle_sip_free(from);
|
||||
} else {
|
||||
|
|
@ -146,14 +137,11 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
|
|||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
return;
|
||||
}
|
||||
resp = belle_sip_response_create_from_request(req,200);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
}
|
||||
|
||||
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
sal_process_incoming_message(op,event);
|
||||
sal_op_release(op);
|
||||
}
|
||||
|
||||
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){
|
||||
|
|
@ -187,14 +175,30 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
|
|||
|
||||
}
|
||||
|
||||
int sal_message_reply(SalOp *op, SalReason reason){
|
||||
if (op->pending_server_trans){
|
||||
int code=sal_reason_to_sip_code(reason);
|
||||
belle_sip_response_t *resp = belle_sip_response_create_from_request(
|
||||
belle_sip_transaction_get_request((belle_sip_transaction_t*)op->pending_server_trans),code);
|
||||
belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
|
||||
return 0;
|
||||
}else ms_error("sal_message_reply(): no server transaction");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) {
|
||||
return sal_message_send(op,from,to,"text/plain",msg);
|
||||
}
|
||||
|
||||
static belle_sip_listener_callbacks_t op_message_callbacks={0};
|
||||
|
||||
void sal_op_message_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_io_error=process_io_error;
|
||||
op->callbacks.process_response_event=process_response_event;
|
||||
op->callbacks.process_timeout=process_timeout;
|
||||
op->callbacks.process_request_event=process_request_event;
|
||||
if (op_message_callbacks.process_io_error==NULL){
|
||||
op_message_callbacks.process_io_error=process_io_error;
|
||||
op_message_callbacks.process_response_event=process_response_event;
|
||||
op_message_callbacks.process_timeout=process_timeout;
|
||||
op_message_callbacks.process_request_event=process_request_event;
|
||||
}
|
||||
op->callbacks=&op_message_callbacks;
|
||||
op->type=SalOpMessage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,13 +94,12 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
|
|||
belle_sip_response_t* response=belle_sip_response_event_get_response(event);
|
||||
belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
int code = belle_sip_response_get_status_code(response);
|
||||
char reason[256]={0};
|
||||
SalError error=SalErrorUnknown;
|
||||
SalReason sr=SalReasonUnknown;
|
||||
belle_sip_header_expires_t* expires;
|
||||
|
||||
sal_op_set_error_info_from_response(op,response);
|
||||
|
||||
if (sal_compute_sal_errors(response,&error,&sr,reason, sizeof(reason))) {
|
||||
ms_error("subscription to [%s] rejected reason [%s]",sal_op_get_to(op),reason[0]!=0?reason:sal_reason_to_string(sr));
|
||||
if (code>=300) {
|
||||
ms_message("subscription to [%s] rejected",sal_op_get_to(op));
|
||||
op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
|
||||
return;
|
||||
}
|
||||
|
|
@ -267,13 +266,18 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
|
|||
}
|
||||
}
|
||||
|
||||
static belle_sip_listener_callbacks_t op_presence_callbacks={0};
|
||||
|
||||
void sal_op_presence_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_io_error=presence_process_io_error;
|
||||
op->callbacks.process_response_event=presence_response_event;
|
||||
op->callbacks.process_timeout=presence_process_timeout;
|
||||
op->callbacks.process_transaction_terminated=presence_process_transaction_terminated;
|
||||
op->callbacks.process_request_event=presence_process_request_event;
|
||||
op->callbacks.process_dialog_terminated=presence_process_dialog_terminated;
|
||||
if (op_presence_callbacks.process_request_event==NULL){
|
||||
op_presence_callbacks.process_io_error=presence_process_io_error;
|
||||
op_presence_callbacks.process_response_event=presence_response_event;
|
||||
op_presence_callbacks.process_timeout=presence_process_timeout;
|
||||
op_presence_callbacks.process_transaction_terminated=presence_process_transaction_terminated;
|
||||
op_presence_callbacks.process_request_event=presence_process_request_event;
|
||||
op_presence_callbacks.process_dialog_terminated=presence_process_dialog_terminated;
|
||||
}
|
||||
op->callbacks=&op_presence_callbacks;
|
||||
op->type=SalOpPresence;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,24 +35,26 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher
|
|||
}else if (status_code==0){
|
||||
op->base.root->callbacks.on_expire(op);
|
||||
}else if (status_code>=200){
|
||||
SalError err;
|
||||
SalReason reason;
|
||||
sal_compute_sal_errors_from_code(status_code,&err,&reason);
|
||||
op->base.root->callbacks.on_publish_response(op,err,reason);
|
||||
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
|
||||
op->base.root->callbacks.on_publish_response(op);
|
||||
}
|
||||
}
|
||||
|
||||
static void publish_response_event(void *userctx, const belle_sip_response_event_t *event){
|
||||
SalOp *op=(SalOp*)userctx;
|
||||
int code=belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
|
||||
SalError err;
|
||||
SalReason reason;
|
||||
sal_compute_sal_errors_from_code(code,&err,&reason);
|
||||
op->base.root->callbacks.on_publish_response(op,err,reason);
|
||||
sal_op_set_error_info_from_response(op,belle_sip_response_event_get_response(event));
|
||||
if (op->error_info.protocol_code>=200){
|
||||
op->base.root->callbacks.on_publish_response(op);
|
||||
}
|
||||
}
|
||||
|
||||
void sal_op_publish_fill_cbs(SalOp*op) {
|
||||
op->callbacks.process_response_event=publish_response_event;
|
||||
static belle_sip_listener_callbacks_t op_publish_callbacks={0};
|
||||
|
||||
void sal_op_publish_fill_cbs(SalOp *op) {
|
||||
if (op_publish_callbacks.process_response_event==NULL){
|
||||
op_publish_callbacks.process_response_event=publish_response_event;
|
||||
}
|
||||
op->callbacks=&op_publish_callbacks;
|
||||
op->type=SalOpPublish;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
|
|||
,unsigned int status_code
|
||||
,const char* reason_phrase) {
|
||||
SalOp* op = (SalOp*)user_pointer;
|
||||
SalError sal_err;
|
||||
SalReason sal_reason;
|
||||
belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
|
||||
ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));
|
||||
|
||||
|
|
@ -57,9 +55,8 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
|
|||
chooses not to re-register, the UA SHOULD discard any stored service
|
||||
route for that address-of-record. */
|
||||
sal_op_set_service_route(op,NULL);
|
||||
|
||||
sal_compute_sal_errors_from_code(status_code,&sal_err,&sal_reason);
|
||||
op->base.root->callbacks.register_failure(op,sal_err,sal_reason,reason_phrase);
|
||||
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
|
||||
op->base.root->callbacks.register_failure(op);
|
||||
if (op->auth_info) {
|
||||
/*add pending auth*/
|
||||
sal_add_pending_auth(op->base.root,op);
|
||||
|
|
|
|||
|
|
@ -68,26 +68,26 @@ static void add_ice_remote_candidates(belle_sdp_media_description_t *md, const S
|
|||
if (buffer[0] != '\0') belle_sdp_media_description_add_attribute(md,belle_sdp_attribute_create("remote-candidates",buffer));
|
||||
}
|
||||
|
||||
static belle_sdp_attribute_t * create_rtcp_xr_attribute(const SalRtcpXrDescription *desc) {
|
||||
static belle_sdp_attribute_t * create_rtcp_xr_attribute(const OrtpRtcpXrConfiguration *config) {
|
||||
belle_sdp_rtcp_xr_attribute_t *attribute = belle_sdp_rtcp_xr_attribute_new();
|
||||
if (desc->rcvr_rtt_mode != SalRtcpXrRcvrRttNone) {
|
||||
if (desc->rcvr_rtt_mode == SalRtcpXrRcvrRttAll) belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode(attribute, "all");
|
||||
else if (desc->rcvr_rtt_mode == SalRtcpXrRcvrRttSender) belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode(attribute, "sender");
|
||||
belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_max_size(attribute, desc->rcvr_rtt_max_size);
|
||||
if (config->rcvr_rtt_mode != OrtpRtcpXrRcvrRttNone) {
|
||||
if (config->rcvr_rtt_mode == OrtpRtcpXrRcvrRttAll) belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode(attribute, "all");
|
||||
else if (config->rcvr_rtt_mode == OrtpRtcpXrRcvrRttSender) belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode(attribute, "sender");
|
||||
belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_max_size(attribute, config->rcvr_rtt_max_size);
|
||||
}
|
||||
belle_sdp_rtcp_xr_attribute_set_stat_summary(attribute, (desc->stat_summary_enabled == TRUE));
|
||||
if (desc->stat_summary_enabled == TRUE) {
|
||||
if (desc->stat_summary_flags & SalRtcpXrStatSummaryLoss) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "loss");
|
||||
if (desc->stat_summary_flags & SalRtcpXrStatSummaryDup) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "dup");
|
||||
if (desc->stat_summary_flags & SalRtcpXrStatSummaryJitt) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "jitt");
|
||||
if (desc->stat_summary_flags & SalRtcpXrStatSummaryTTL) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "TTL");
|
||||
if (desc->stat_summary_flags & SalRtcpXrStatSummaryHL) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "HL");
|
||||
belle_sdp_rtcp_xr_attribute_set_stat_summary(attribute, (config->stat_summary_enabled == TRUE));
|
||||
if (config->stat_summary_enabled == TRUE) {
|
||||
if (config->stat_summary_flags & OrtpRtcpXrStatSummaryLoss) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "loss");
|
||||
if (config->stat_summary_flags & OrtpRtcpXrStatSummaryDup) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "dup");
|
||||
if (config->stat_summary_flags & OrtpRtcpXrStatSummaryJitt) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "jitt");
|
||||
if (config->stat_summary_flags & OrtpRtcpXrStatSummaryTTL) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "TTL");
|
||||
if (config->stat_summary_flags & OrtpRtcpXrStatSummaryHL) belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(attribute, "HL");
|
||||
}
|
||||
belle_sdp_rtcp_xr_attribute_set_voip_metrics(attribute, (desc->voip_metrics_enabled == TRUE));
|
||||
belle_sdp_rtcp_xr_attribute_set_voip_metrics(attribute, (config->voip_metrics_enabled == TRUE));
|
||||
return BELLE_SDP_ATTRIBUTE(attribute);
|
||||
}
|
||||
|
||||
static belle_sdp_media_description_t *stream_description_to_sdp ( const SalMediaDescription *md, const SalStreamDescription *stream ) {
|
||||
static void stream_description_to_sdp ( belle_sdp_session_description_t *session_desc, const SalMediaDescription *md, const SalStreamDescription *stream ) {
|
||||
belle_sdp_mime_parameter_t* mime_param;
|
||||
belle_sdp_media_description_t* media_desc;
|
||||
int j;
|
||||
|
|
@ -215,10 +215,27 @@ static belle_sdp_media_description_t *stream_description_to_sdp ( const SalMedia
|
|||
}
|
||||
|
||||
if (stream->rtcp_xr.enabled == TRUE) {
|
||||
belle_sdp_media_description_add_attribute(media_desc, create_rtcp_xr_attribute(&stream->rtcp_xr));
|
||||
char sastr[1024] = {0};
|
||||
char mastr[1024] = {0};
|
||||
size_t saoff = 0;
|
||||
size_t maoff = 0;
|
||||
const belle_sdp_attribute_t *session_attribute = belle_sdp_session_description_get_attribute(session_desc, "rtcp-xr");
|
||||
belle_sdp_attribute_t *media_attribute;
|
||||
if (session_attribute != NULL) {
|
||||
belle_sip_object_marshal((belle_sip_object_t*)session_attribute, sastr, sizeof(sastr), &saoff);
|
||||
}
|
||||
media_attribute = create_rtcp_xr_attribute(&stream->rtcp_xr);
|
||||
if (media_attribute != NULL) {
|
||||
belle_sip_object_marshal((belle_sip_object_t*)media_attribute, mastr, sizeof(mastr), &maoff);
|
||||
}
|
||||
if (strcmp(sastr, mastr) != 0) {
|
||||
belle_sdp_media_description_add_attribute(media_desc, media_attribute);
|
||||
} else {
|
||||
belle_sip_object_unref((belle_sip_object_t*)media_attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return media_desc;
|
||||
belle_sdp_session_description_add_media_description(session_desc, media_desc);
|
||||
}
|
||||
|
||||
belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescription *desc ) {
|
||||
|
|
@ -272,7 +289,7 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr
|
|||
}
|
||||
|
||||
for ( i=0; i<desc->n_total_streams; i++ ) {
|
||||
belle_sdp_session_description_add_media_description ( session_desc,stream_description_to_sdp(desc,&desc->streams[i]));
|
||||
stream_description_to_sdp(session_desc, desc, &desc->streams[i]);
|
||||
}
|
||||
return session_desc;
|
||||
}
|
||||
|
|
@ -304,8 +321,7 @@ static void sdp_parse_payload_types(belle_sdp_media_description_t *media_desc, S
|
|||
|
||||
static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
belle_sip_list_t *attribute_it;
|
||||
const belle_sdp_attribute_t *attribute;
|
||||
const belle_sdp_raw_attribute_t *raw_attribute;
|
||||
belle_sdp_attribute_t *attribute;
|
||||
char tmp[256], tmp2[256];
|
||||
int valid_count = 0;
|
||||
int nb;
|
||||
|
|
@ -315,10 +331,9 @@ static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *med
|
|||
; valid_count < SAL_CRYPTO_ALGO_MAX && attribute_it!=NULL;
|
||||
attribute_it=attribute_it->next ) {
|
||||
attribute=BELLE_SDP_ATTRIBUTE ( attribute_it->data );
|
||||
raw_attribute=BELLE_SDP_RAW_ATTRIBUTE(attribute);
|
||||
|
||||
if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_raw_attribute_get_value ( raw_attribute ) !=NULL ) {
|
||||
nb = sscanf ( belle_sdp_raw_attribute_get_value ( raw_attribute ), "%d %256s inline:%256s",
|
||||
if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_attribute_get_value ( attribute ) !=NULL ) {
|
||||
nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s",
|
||||
&stream->crypto[valid_count].tag,
|
||||
tmp,
|
||||
tmp2 );
|
||||
|
|
@ -345,7 +360,7 @@ static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *med
|
|||
valid_count++;
|
||||
}
|
||||
} else {
|
||||
ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_raw_attribute_get_value ( raw_attribute ),nb );
|
||||
ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value ( attribute ),nb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -354,17 +369,15 @@ static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *med
|
|||
|
||||
static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
belle_sip_list_t *attribute_it;
|
||||
const belle_sdp_attribute_t *attribute;
|
||||
const belle_sdp_raw_attribute_t *raw_attribute;
|
||||
belle_sdp_attribute_t *attribute;
|
||||
const char *att_name;
|
||||
const char *value;
|
||||
int nb_ice_candidates = 0;
|
||||
|
||||
for (attribute_it = belle_sdp_media_description_get_attributes(media_desc); attribute_it != NULL; attribute_it=attribute_it->next) {
|
||||
attribute=BELLE_SDP_ATTRIBUTE(attribute_it->data);
|
||||
raw_attribute=BELLE_SDP_RAW_ATTRIBUTE(attribute);
|
||||
att_name = belle_sdp_attribute_get_name(attribute);
|
||||
value = belle_sdp_raw_attribute_get_value(raw_attribute);
|
||||
value = belle_sdp_attribute_get_value(attribute);
|
||||
|
||||
if ((keywordcmp("candidate", att_name) == 0) && (value != NULL)) {
|
||||
SalIceCandidate *candidate = &stream->ice_candidates[nb_ice_candidates];
|
||||
|
|
@ -400,63 +413,63 @@ static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_
|
|||
}
|
||||
}
|
||||
|
||||
static void sal_init_rtcp_xr_description(SalRtcpXrDescription *desc) {
|
||||
desc->enabled = FALSE;
|
||||
desc->rcvr_rtt_mode = SalRtcpXrRcvrRttNone;
|
||||
desc->rcvr_rtt_max_size = -1;
|
||||
desc->stat_summary_flags = 0;
|
||||
desc->voip_metrics_enabled = FALSE;
|
||||
static void sal_init_rtcp_xr_description(OrtpRtcpXrConfiguration *config) {
|
||||
config->enabled = FALSE;
|
||||
config->rcvr_rtt_mode = OrtpRtcpXrRcvrRttNone;
|
||||
config->rcvr_rtt_max_size = -1;
|
||||
config->stat_summary_flags = 0;
|
||||
config->voip_metrics_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void sdp_parse_rtcp_xr_parameters(const belle_sdp_attribute_t *attribute, SalRtcpXrDescription *desc) {
|
||||
sal_init_rtcp_xr_description(desc);
|
||||
|
||||
static void sdp_parse_rtcp_xr_parameters(const belle_sdp_attribute_t *attribute, OrtpRtcpXrConfiguration *config) {
|
||||
if (attribute != NULL) {
|
||||
const belle_sdp_rtcp_xr_attribute_t *xr_attr = BELLE_SDP_RTCP_XR_ATTRIBUTE(attribute);
|
||||
const char *rcvr_rtt_mode = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_mode(xr_attr);
|
||||
const belle_sdp_rtcp_xr_attribute_t *xr_attr;
|
||||
const char *rcvr_rtt_mode;
|
||||
sal_init_rtcp_xr_description(config);
|
||||
xr_attr = BELLE_SDP_RTCP_XR_ATTRIBUTE(attribute);
|
||||
rcvr_rtt_mode = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_mode(xr_attr);
|
||||
if (rcvr_rtt_mode != NULL) {
|
||||
if (strcasecmp(rcvr_rtt_mode, "all") == 0) {
|
||||
desc->rcvr_rtt_mode = SalRtcpXrRcvrRttAll;
|
||||
config->rcvr_rtt_mode = OrtpRtcpXrRcvrRttAll;
|
||||
} else if (strcasecmp(rcvr_rtt_mode, "sender") == 0) {
|
||||
desc->rcvr_rtt_mode = SalRtcpXrRcvrRttSender;
|
||||
config->rcvr_rtt_mode = OrtpRtcpXrRcvrRttSender;
|
||||
}
|
||||
desc->rcvr_rtt_max_size = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_max_size(xr_attr);
|
||||
config->rcvr_rtt_max_size = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_max_size(xr_attr);
|
||||
}
|
||||
desc->stat_summary_enabled = (belle_sdp_rtcp_xr_attribute_has_stat_summary(xr_attr) != 0);
|
||||
if (desc->stat_summary_enabled) {
|
||||
config->stat_summary_enabled = (belle_sdp_rtcp_xr_attribute_has_stat_summary(xr_attr) != 0);
|
||||
if (config->stat_summary_enabled) {
|
||||
belle_sip_list_t *stat_summary_flag_it;
|
||||
for (stat_summary_flag_it = belle_sdp_rtcp_xr_attribute_get_stat_summary_flags(xr_attr); stat_summary_flag_it != NULL; stat_summary_flag_it = stat_summary_flag_it->next ) {
|
||||
const char *flag = (const char *)stat_summary_flag_it->data;
|
||||
if (flag != NULL) {
|
||||
if (strcasecmp(flag, "loss") == 0) desc->stat_summary_flags |= SalRtcpXrStatSummaryLoss;
|
||||
else if (strcasecmp(flag, "dup") == 0) desc->stat_summary_flags |= SalRtcpXrStatSummaryDup;
|
||||
else if (strcasecmp(flag, "jitt") == 0) desc->stat_summary_flags |= SalRtcpXrStatSummaryJitt;
|
||||
else if (strcasecmp(flag, "TTL") == 0) desc->stat_summary_flags |= SalRtcpXrStatSummaryTTL;
|
||||
else if (strcasecmp(flag, "HL") == 0) desc->stat_summary_flags |= SalRtcpXrStatSummaryHL;
|
||||
if (strcasecmp(flag, "loss") == 0) config->stat_summary_flags |= OrtpRtcpXrStatSummaryLoss;
|
||||
else if (strcasecmp(flag, "dup") == 0) config->stat_summary_flags |= OrtpRtcpXrStatSummaryDup;
|
||||
else if (strcasecmp(flag, "jitt") == 0) config->stat_summary_flags |= OrtpRtcpXrStatSummaryJitt;
|
||||
else if (strcasecmp(flag, "TTL") == 0) config->stat_summary_flags |= OrtpRtcpXrStatSummaryTTL;
|
||||
else if (strcasecmp(flag, "HL") == 0) config->stat_summary_flags |= OrtpRtcpXrStatSummaryHL;
|
||||
}
|
||||
}
|
||||
}
|
||||
desc->voip_metrics_enabled = (belle_sdp_rtcp_xr_attribute_has_voip_metrics(xr_attr) != 0);
|
||||
desc->enabled = TRUE;
|
||||
config->voip_metrics_enabled = (belle_sdp_rtcp_xr_attribute_has_voip_metrics(xr_attr) != 0);
|
||||
config->enabled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void sdp_parse_session_rtcp_xr_parameters(belle_sdp_session_description_t *session_desc, SalRtcpXrDescription *desc) {
|
||||
static void sdp_parse_session_rtcp_xr_parameters(belle_sdp_session_description_t *session_desc, OrtpRtcpXrConfiguration *config) {
|
||||
const belle_sdp_attribute_t *attribute = belle_sdp_session_description_get_attribute(session_desc, "rtcp-xr");
|
||||
sdp_parse_rtcp_xr_parameters(attribute, desc);
|
||||
sdp_parse_rtcp_xr_parameters(attribute, config);
|
||||
}
|
||||
|
||||
static void sdp_parse_media_rtcp_xr_parameters(belle_sdp_media_description_t *media_desc, SalRtcpXrDescription *desc) {
|
||||
static void sdp_parse_media_rtcp_xr_parameters(belle_sdp_media_description_t *media_desc, OrtpRtcpXrConfiguration *config) {
|
||||
const belle_sdp_attribute_t *attribute = belle_sdp_media_description_get_attribute(media_desc, "rtcp-xr");
|
||||
sdp_parse_rtcp_xr_parameters(attribute, desc);
|
||||
sdp_parse_rtcp_xr_parameters(attribute, config);
|
||||
}
|
||||
|
||||
static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, belle_sdp_media_description_t *media_desc) {
|
||||
SalStreamDescription *stream;
|
||||
belle_sdp_connection_t* cnx;
|
||||
belle_sdp_media_t* media;
|
||||
const belle_sdp_attribute_t* attribute;
|
||||
const belle_sdp_raw_attribute_t* raw_attribute;
|
||||
belle_sdp_attribute_t* attribute;
|
||||
const char* value;
|
||||
const char *mtype,*proto;
|
||||
|
||||
|
|
@ -518,8 +531,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
stream->rtcp_port = stream->rtp_port + 1;
|
||||
snprintf(stream->rtcp_addr, sizeof(stream->rtcp_addr), "%s", stream->rtp_addr);
|
||||
attribute=belle_sdp_media_description_get_attribute(media_desc,"rtcp");
|
||||
raw_attribute=BELLE_SDP_RAW_ATTRIBUTE(attribute);
|
||||
if (attribute && (value=belle_sdp_raw_attribute_get_value(raw_attribute))!=NULL){
|
||||
if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
|
||||
char tmp[256];
|
||||
int nb = sscanf(value, "%d IN IP4 %s", &stream->rtcp_port, tmp);
|
||||
if (nb == 1) {
|
||||
|
|
@ -540,6 +552,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
sdp_parse_media_ice_parameters(media_desc, stream);
|
||||
|
||||
/* Get RTCP-XR attributes if any */
|
||||
stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined
|
||||
sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr);
|
||||
|
||||
md->n_total_streams++;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details);
|
||||
static void register_failure(SalOp *op);
|
||||
|
||||
static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) {
|
||||
if (call->params.in_conference != call->current_params.in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED;
|
||||
|
|
@ -58,14 +58,14 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c
|
|||
rtp_addr = (new_audiodesc->rtp_addr[0] != '\0') ? new_audiodesc->rtp_addr : new_md->addr;
|
||||
rtcp_addr = (new_audiodesc->rtcp_addr[0] != '\0') ? new_audiodesc->rtcp_addr : new_md->addr;
|
||||
ms_message("Change audio stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_audiodesc->rtp_port, rtcp_addr, new_audiodesc->rtcp_port);
|
||||
rtp_session_set_remote_addr_full(call->audiostream->ms.session, rtp_addr, new_audiodesc->rtp_port, rtcp_addr, new_audiodesc->rtcp_port);
|
||||
rtp_session_set_remote_addr_full(call->audiostream->ms.sessions.rtp_session, rtp_addr, new_audiodesc->rtp_port, rtcp_addr, new_audiodesc->rtcp_port);
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream && new_videodesc) {
|
||||
rtp_addr = (new_videodesc->rtp_addr[0] != '\0') ? new_videodesc->rtp_addr : new_md->addr;
|
||||
rtcp_addr = (new_videodesc->rtcp_addr[0] != '\0') ? new_videodesc->rtcp_addr : new_md->addr;
|
||||
ms_message("Change video stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
|
||||
rtp_session_set_remote_addr_full(call->videostream->ms.session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
|
||||
rtp_session_set_remote_addr_full(call->videostream->ms.sessions.rtp_session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
|
||||
}
|
||||
#else
|
||||
(void)new_videodesc;
|
||||
|
|
@ -97,7 +97,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
sal_media_description_ref(new_md);
|
||||
call->expect_media_in_ack=FALSE;
|
||||
call->resultdesc=new_md;
|
||||
if ((call->audiostream && call->audiostream->ms.ticker) || (call->videostream && call->videostream->ms.ticker)){
|
||||
if ((call->audiostream && call->audiostream->ms.state==MSStreamStarted) || (call->videostream && call->videostream->ms.state==MSStreamStarted)){
|
||||
/* we already started media: check if we really need to restart it*/
|
||||
if (oldmd){
|
||||
int md_changed = media_parameters_changed(call, oldmd, new_md);
|
||||
|
|
@ -143,8 +143,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
|
||||
send_ringbacktone=TRUE;
|
||||
}
|
||||
if (call->state==LinphoneCallIncomingEarlyMedia ||
|
||||
(call->state==LinphoneCallOutgoingEarlyMedia && !call->params.real_early_media)){
|
||||
if ((call->state==LinphoneCallIncomingEarlyMedia || call->state==LinphoneCallOutgoingEarlyMedia) && !call->params.real_early_media){
|
||||
all_muted=TRUE;
|
||||
}
|
||||
linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
|
||||
|
|
@ -206,7 +205,8 @@ static void call_received(SalOp *h){
|
|||
const char *from,*to;
|
||||
char *alt_contact;
|
||||
LinphoneAddress *from_addr, *to_addr;
|
||||
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE);
|
||||
/*this mode is deprcated because probably useless*/
|
||||
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",FALSE);
|
||||
|
||||
/* first check if we can answer successfully to this invite */
|
||||
if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) {
|
||||
|
|
@ -549,7 +549,7 @@ static void call_terminated(SalOp *op, const char *from){
|
|||
break;
|
||||
case LinphoneCallIncomingReceived:
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
call->reason=LinphoneReasonNotAnswered;
|
||||
sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,0,"Incoming call cancelled",NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -592,14 +592,15 @@ static int resume_call_after_failed_transfer(LinphoneCall *call){
|
|||
return BELLE_SIP_STOP;
|
||||
}
|
||||
|
||||
static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){
|
||||
static void call_failure(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(op);
|
||||
char *msg486=_("User is busy.");
|
||||
char *msg480=_("User is temporarily unavailable.");
|
||||
/*char *retrymsg=_("%s. Retry after %i minute(s).");*/
|
||||
char *msg600=_("User does not want to be disturbed.");
|
||||
char *msg603=_("Call declined.");
|
||||
const char *msg=details;
|
||||
const char *msg=ei->full_string;
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
LinphoneCall *referer=call->referer;
|
||||
|
||||
|
|
@ -609,102 +610,94 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
}
|
||||
|
||||
if (lc->vtable.show) lc->vtable.show(lc);
|
||||
|
||||
if (error==SalErrorNoResponse){
|
||||
msg=_("No response.");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
}else if (error==SalErrorProtocol){
|
||||
msg=details ? details : _("Protocol error.");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc, msg);
|
||||
}else if (error==SalErrorFailure){
|
||||
switch(sr){
|
||||
case SalReasonDeclined:
|
||||
msg=msg603;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg603);
|
||||
break;
|
||||
case SalReasonBusy:
|
||||
msg=msg486;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg486);
|
||||
break;
|
||||
case SalReasonRedirect:
|
||||
{
|
||||
ms_error("case SalReasonRedirect");
|
||||
linphone_call_stop_media_streams(call);
|
||||
if ( call->state==LinphoneCallOutgoingInit
|
||||
switch(ei->reason){
|
||||
case SalReasonNone:
|
||||
break;
|
||||
case SalReasonRequestTimeout:
|
||||
msg=_("Request timeout.");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
break;
|
||||
case SalReasonDeclined:
|
||||
msg=msg603;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg603);
|
||||
break;
|
||||
case SalReasonBusy:
|
||||
msg=msg486;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg486);
|
||||
break;
|
||||
case SalReasonRedirect:
|
||||
{
|
||||
linphone_call_stop_media_streams(call);
|
||||
if ( call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingRinging /*push case*/
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
LinphoneAddress* redirection_to = (LinphoneAddress*)sal_op_get_remote_contact_address(call->op);
|
||||
if( redirection_to ){
|
||||
char* url = linphone_address_as_string(redirection_to);
|
||||
ms_warning("Redirecting call [%p] to %s",call, url);
|
||||
ms_free(url);
|
||||
linphone_call_create_op(call);
|
||||
linphone_core_start_invite(lc, call, redirection_to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
msg=_("Redirected");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
}
|
||||
break;
|
||||
case SalReasonTemporarilyUnavailable:
|
||||
msg=msg480;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg480);
|
||||
break;
|
||||
case SalReasonNotFound:
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
break;
|
||||
case SalReasonDoNotDisturb:
|
||||
msg=msg600;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg600);
|
||||
break;
|
||||
case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/
|
||||
case SalReasonNotAcceptable:
|
||||
//media_encryption_mandatory
|
||||
if (call->params.media_encryption == LinphoneMediaEncryptionSRTP &&
|
||||
!linphone_core_is_media_encryption_mandatory(lc)) {
|
||||
int i;
|
||||
ms_message("Outgoing call [%p] failed with SRTP (SAVP) enabled",call);
|
||||
if (call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingRinging /*push case*/
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
LinphoneAddress* redirection_to = (LinphoneAddress*)sal_op_get_remote_contact_address(call->op);
|
||||
if( redirection_to ){
|
||||
char* url = linphone_address_as_string(redirection_to);
|
||||
ms_error("Redirecting call [%p] to %s",call, url);
|
||||
ms_free(url);
|
||||
linphone_call_create_op(call);
|
||||
linphone_core_start_invite(lc, call, redirection_to);
|
||||
return;
|
||||
ms_message("Retrying call [%p] with AVP",call);
|
||||
/* clear SRTP local params */
|
||||
call->params.media_encryption = LinphoneMediaEncryptionNone;
|
||||
for(i=0; i<call->localdesc->n_active_streams; i++) {
|
||||
call->localdesc->streams[i].proto = SalProtoRtpAvp;
|
||||
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
|
||||
}
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
msg=_("Redirected");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
}
|
||||
break;
|
||||
case SalReasonTemporarilyUnavailable:
|
||||
msg=msg480;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg480);
|
||||
break;
|
||||
case SalReasonNotFound:
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
break;
|
||||
case SalReasonDoNotDisturb:
|
||||
msg=msg600;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg600);
|
||||
break;
|
||||
case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/
|
||||
case SalReasonNotAcceptable:
|
||||
//media_encryption_mandatory
|
||||
if (call->params.media_encryption == LinphoneMediaEncryptionSRTP &&
|
||||
!linphone_core_is_media_encryption_mandatory(lc)) {
|
||||
int i;
|
||||
ms_message("Outgoing call [%p] failed with SRTP (SAVP) enabled",call);
|
||||
linphone_call_stop_media_streams(call);
|
||||
if ( call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingRinging /*push case*/
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
ms_message("Retrying call [%p] with AVP",call);
|
||||
/* clear SRTP local params */
|
||||
call->params.media_encryption = LinphoneMediaEncryptionNone;
|
||||
for(i=0; i<call->localdesc->n_active_streams; i++) {
|
||||
call->localdesc->streams[i].proto = SalProtoRtpAvp;
|
||||
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
|
||||
}
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
msg=_("Incompatible media parameters.");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
break;
|
||||
case SalReasonRequestPending:
|
||||
/*restore previous state, the application will decide to resubmit the action if relevant*/
|
||||
call->reason=linphone_reason_from_sal(sr);
|
||||
linphone_call_set_state(call,call->prevstate,msg);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Call failed."));
|
||||
}
|
||||
msg=_("Incompatible media parameters.");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg);
|
||||
break;
|
||||
case SalReasonRequestPending:
|
||||
/*restore previous state, the application will decide to resubmit the action if relevant*/
|
||||
linphone_call_set_state(call,call->prevstate,msg);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Call failed."));
|
||||
}
|
||||
|
||||
/*some call error are not fatal*/
|
||||
|
|
@ -713,8 +706,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
case LinphoneCallPausing:
|
||||
case LinphoneCallResuming:
|
||||
ms_message("Call error on state [%s], restoring previous state",linphone_call_state_to_string(call->prevstate));
|
||||
call->reason=linphone_reason_from_sal(sr);
|
||||
linphone_call_set_state(call, call->prevstate,details);
|
||||
linphone_call_set_state(call, call->prevstate,ei->full_string);
|
||||
return;
|
||||
default:
|
||||
break; /*nothing to do*/
|
||||
|
|
@ -727,13 +719,14 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
linphone_call_delete_upnp_session(call);
|
||||
#endif //BUILD_UPNP
|
||||
|
||||
call->reason=linphone_reason_from_sal(sr);
|
||||
if (sr==SalReasonDeclined){
|
||||
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
|
||||
}else{
|
||||
linphone_call_set_state(call,LinphoneCallError,details);
|
||||
if (call->state!=LinphoneCallEnd && call->state!=LinphoneCallError){
|
||||
if (ei->reason==SalReasonDeclined){
|
||||
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
|
||||
}else{
|
||||
linphone_call_set_state(call,LinphoneCallError,ei->full_string);
|
||||
}
|
||||
if (ei->reason!=SalReasonNone) linphone_core_play_call_error_tone(lc,linphone_reason_from_sal(ei->reason));
|
||||
}
|
||||
linphone_core_play_call_error_tone(lc,call->reason);
|
||||
|
||||
if (referer){
|
||||
/*notify referer of the failure*/
|
||||
|
|
@ -772,7 +765,6 @@ static void register_success(SalOp *op, bool_t registered){
|
|||
ms_message("Registration success for removed proxy config, ignored");
|
||||
return;
|
||||
}
|
||||
linphone_proxy_config_set_error(cfg,LinphoneReasonNone);
|
||||
linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared ,
|
||||
registered ? "Registration successful" : "Unregistration done");
|
||||
if (lc->vtable.display_status){
|
||||
|
|
@ -784,9 +776,11 @@ static void register_success(SalOp *op, bool_t registered){
|
|||
|
||||
}
|
||||
|
||||
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details){
|
||||
static void register_failure(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(op);
|
||||
const char *details=ei->full_string;
|
||||
|
||||
if (cfg==NULL){
|
||||
ms_warning("Registration failed for unknown proxy config.");
|
||||
|
|
@ -800,15 +794,12 @@ static void register_failure(SalOp *op, SalError error, SalReason reason, const
|
|||
details=_("no response timeout");
|
||||
|
||||
if (lc->vtable.display_status) {
|
||||
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op),details );
|
||||
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op), details);
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(msg);
|
||||
}
|
||||
|
||||
linphone_proxy_config_set_error(cfg,linphone_reason_from_sal(reason));
|
||||
|
||||
if (error== SalErrorFailure
|
||||
&& reason == SalReasonServiceUnavailable
|
||||
if ((ei->reason == SalReasonServiceUnavailable || ei->reason == SalReasonIOError)
|
||||
&& linphone_proxy_config_get_state(cfg) == LinphoneRegistrationOk) {
|
||||
linphone_proxy_config_set_state(cfg,LinphoneRegistrationProgress,_("Service unavailable, retrying"));
|
||||
} else {
|
||||
|
|
@ -886,9 +877,12 @@ static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){
|
|||
|
||||
static void text_received(SalOp *op, const SalMessage *msg){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
if (is_duplicate_msg(lc,msg->message_id)==FALSE){
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (lc->chat_deny_code==LinphoneReasonNone && is_duplicate_msg(lc,msg->message_id)==FALSE){
|
||||
linphone_core_message_received(lc,op,msg);
|
||||
}
|
||||
sal_message_reply(op,linphone_reason_to_sal(lc->chat_deny_code));
|
||||
if (!call) sal_op_release(op);
|
||||
}
|
||||
|
||||
static void is_composing_received(SalOp *op, const SalIsComposing *is_composing) {
|
||||
|
|
@ -1030,22 +1024,15 @@ static LinphoneChatMessageState chatStatusSal2Linphone(SalTextDeliveryStatus sta
|
|||
return LinphoneChatMessageStateIdle;
|
||||
}
|
||||
|
||||
static int op_equals(LinphoneCall *a, SalOp *b) {
|
||||
return a->op !=b; /*return 0 if equals*/
|
||||
}
|
||||
|
||||
static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status, SalReason reason){
|
||||
static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
|
||||
LinphoneChatMessage *chat_msg=(LinphoneChatMessage* )sal_op_get_user_pointer(op);
|
||||
const MSList* calls;
|
||||
|
||||
if (chat_msg == NULL) {
|
||||
// Do not handle delivery status for isComposing messages.
|
||||
return;
|
||||
}
|
||||
calls = linphone_core_get_calls(chat_msg->chat_room->lc);
|
||||
|
||||
chat_msg->state=chatStatusSal2Linphone(status);
|
||||
chat_msg->reason=linphone_reason_from_sal(reason);
|
||||
linphone_chat_message_store_state(chat_msg);
|
||||
if (chat_msg && chat_msg->cb) {
|
||||
ms_message("Notifying text delivery with status %i",chat_msg->state);
|
||||
|
|
@ -1055,11 +1042,6 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status, SalRea
|
|||
}
|
||||
if (status != SalTextDeliveryInProgress) { /*don't release op if progress*/
|
||||
linphone_chat_message_destroy(chat_msg);
|
||||
|
||||
if (!ms_list_find_custom((MSList*)calls, (MSCompareFunc) op_equals, op)) {
|
||||
/*op was only create for messaging purpose, destroying*/
|
||||
sal_op_release(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1068,7 +1050,7 @@ static void info_received(SalOp *op, const SalBody *body){
|
|||
linphone_core_notify_info_message(lc,op,body);
|
||||
}
|
||||
|
||||
static void subscribe_response(SalOp *op, SalSubscribeStatus status, SalError error, SalReason reason){
|
||||
static void subscribe_response(SalOp *op, SalSubscribeStatus status){
|
||||
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
|
||||
|
||||
if (lev==NULL) return;
|
||||
|
|
@ -1078,7 +1060,6 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status, SalError er
|
|||
}else if (status==SalSubscribePending){
|
||||
linphone_event_set_state(lev,LinphoneSubscriptionPending);
|
||||
}else{
|
||||
linphone_event_set_reason(lev, linphone_reason_from_sal(reason));
|
||||
linphone_event_set_state(lev,LinphoneSubscriptionError);
|
||||
}
|
||||
}
|
||||
|
|
@ -1120,18 +1101,18 @@ static void subscribe_closed(SalOp *op){
|
|||
linphone_event_set_state(lev,LinphoneSubscriptionTerminated);
|
||||
}
|
||||
|
||||
static void on_publish_response(SalOp* op, SalError err, SalReason reason){
|
||||
static void on_publish_response(SalOp* op){
|
||||
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(op);
|
||||
|
||||
if (lev==NULL) return;
|
||||
if (err==SalErrorNone){
|
||||
if (ei->reason==SalReasonNone){
|
||||
if (!lev->terminating)
|
||||
linphone_event_set_publish_state(lev,LinphonePublishOk);
|
||||
else
|
||||
linphone_event_set_publish_state(lev,LinphonePublishCleared);
|
||||
|
||||
}else{
|
||||
linphone_event_set_reason(lev,linphone_reason_from_sal(reason));
|
||||
linphone_event_set_publish_state(lev,LinphonePublishError);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,31 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Inconditionnaly disable incoming chat messages.
|
||||
* @param lc the core
|
||||
* @param deny_reason the deny reason (#LinphoneReasonNone has no effect).
|
||||
**/
|
||||
void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason){
|
||||
lc->chat_deny_code=deny_reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable reception of incoming chat messages.
|
||||
* By default it is enabled but it can be disabled with linphone_core_disable_chat().
|
||||
* @param lc the core
|
||||
**/
|
||||
void linphone_core_enable_chat(LinphoneCore *lc){
|
||||
lc->chat_deny_code=LinphoneReasonNone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether chat is enabled.
|
||||
**/
|
||||
bool_t linphone_core_chat_enabled(const LinphoneCore *lc){
|
||||
return lc->chat_deny_code!=LinphoneReasonNone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of chat rooms
|
||||
* @param lc #LinphoneCore object
|
||||
|
|
@ -160,7 +185,7 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
|
|||
identity=linphone_proxy_config_get_identity(proxy);
|
||||
}else identity=linphone_core_get_primary_contact(cr->lc);
|
||||
/*sending out of calls*/
|
||||
op = sal_op_new(cr->lc->sal);
|
||||
msg->op = op = sal_op_new(cr->lc->sal);
|
||||
linphone_configure_op(cr->lc,op,cr->peer_url,msg->custom_headers,lp_config_get_int(cr->lc->config,"sip","chat_msg_with_contact",0));
|
||||
sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/
|
||||
}
|
||||
|
|
@ -779,6 +804,7 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg)
|
|||
* Destroys a LinphoneChatMessage.
|
||||
**/
|
||||
void linphone_chat_message_destroy(LinphoneChatMessage* msg) {
|
||||
if (msg->op) sal_op_release(msg->op);
|
||||
if (msg->message) ms_free(msg->message);
|
||||
if (msg->external_body_url) ms_free(msg->external_body_url);
|
||||
if (msg->from) linphone_address_destroy(msg->from);
|
||||
|
|
@ -787,9 +813,17 @@ void linphone_chat_message_destroy(LinphoneChatMessage* msg) {
|
|||
ms_free(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full details about delivery error of a chat message.
|
||||
* @param msg a LinphoneChatMessage
|
||||
* @return a LinphoneErrorInfo describing the details.
|
||||
**/
|
||||
const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg){
|
||||
return linphone_error_info_from_sal_op(msg->op);
|
||||
}
|
||||
|
||||
LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg) {
|
||||
return msg->reason;
|
||||
return linphone_error_info_get_reason(linphone_chat_message_get_error_info(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -107,6 +107,9 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s
|
|||
if (lc->vtable.publish_state_changed){
|
||||
lc->vtable.publish_state_changed(lev->lc,lev,state);
|
||||
}
|
||||
if (state==LinphonePublishCleared){
|
||||
linphone_event_unref(lev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,12 +117,12 @@ LinphonePublishState linphone_event_get_publish_state(const LinphoneEvent *lev){
|
|||
return lev->publish_state;
|
||||
}
|
||||
|
||||
void linphone_event_set_reason(LinphoneEvent *lev, LinphoneReason reason){
|
||||
lev->reason=reason;
|
||||
const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev){
|
||||
return linphone_error_info_from_sal_op(lev->op);
|
||||
}
|
||||
|
||||
LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev){
|
||||
return lev->reason;
|
||||
return linphone_error_info_get_reason(linphone_event_get_error_info(lev));
|
||||
}
|
||||
|
||||
LinphoneEvent *linphone_core_create_subscribe(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){
|
||||
|
|
@ -291,7 +294,8 @@ void linphone_event_terminate(LinphoneEvent *lev){
|
|||
if (lev->publish_state!=LinphonePublishNone){
|
||||
if (lev->publish_state==LinphonePublishOk){
|
||||
sal_publish(lev->op,NULL,NULL,NULL,0,NULL);
|
||||
}
|
||||
}else sal_op_stop_refreshing(lev->op);
|
||||
linphone_event_set_publish_state(lev,LinphonePublishCleared);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ LINPHONE_PUBLIC int linphone_event_update_publish(LinphoneEvent *lev, const Linp
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev);
|
||||
|
||||
/**
|
||||
* Get full details about an error occured.
|
||||
**/
|
||||
const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev);
|
||||
|
||||
/**
|
||||
* Get subscription state. If the event object was not created by a subscription mechanism, #LinphoneSubscriptionNone is returned.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ const char* linphone_call_get_authentication_token(LinphoneCall *call){
|
|||
return call->auth_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether ZRTP authentication token is verified.
|
||||
* If not, it must be verified by users as described in ZRTP procedure.
|
||||
* Once done, the application must inform of the results with linphone_call_set_authentication_token_verified().
|
||||
* @param call the LinphoneCall
|
||||
* @return TRUE if authentication token is verifed, false otherwise.
|
||||
* @ingroup call_control
|
||||
**/
|
||||
bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){
|
||||
return call->auth_token_verified;
|
||||
}
|
||||
|
|
@ -172,17 +180,24 @@ static void linphone_call_audiostream_auth_token_ready(void *data, const char* a
|
|||
ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the result of ZRTP short code verification by user.
|
||||
* If remote party also does the same, it will update the ZRTP cache so that user's verification will not be required for the two users.
|
||||
* @param call the LinphoneCall
|
||||
* @param verified whether the ZRTP SAS is verified.
|
||||
* @ingroup call_control
|
||||
**/
|
||||
void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified){
|
||||
if (call->audiostream==NULL){
|
||||
ms_error("linphone_call_set_authentication_token_verified(): No audio stream");
|
||||
}
|
||||
if (call->audiostream->ms.zrtp_context==NULL){
|
||||
if (call->audiostream->ms.sessions.zrtp_context==NULL){
|
||||
ms_error("linphone_call_set_authentication_token_verified(): No zrtp context.");
|
||||
}
|
||||
if (!call->auth_token_verified && verified){
|
||||
ortp_zrtp_sas_verified(call->audiostream->ms.zrtp_context);
|
||||
ortp_zrtp_sas_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
}else if (call->auth_token_verified && !verified){
|
||||
ortp_zrtp_sas_reset_verified(call->audiostream->ms.zrtp_context);
|
||||
ortp_zrtp_sas_reset_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
}
|
||||
call->auth_token_verified=verified;
|
||||
propagate_encryption_changed(call);
|
||||
|
|
@ -260,22 +275,26 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
|
|||
|
||||
static void setup_rtcp_xr(LinphoneCall *call, SalMediaDescription *md) {
|
||||
LinphoneCore *lc = call->core;
|
||||
int i;
|
||||
|
||||
md->rtcp_xr.enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_enabled", 0);
|
||||
if (md->rtcp_xr.enabled == TRUE) {
|
||||
const char *rcvr_rtt_mode = lp_config_get_string(lc->config, "rtp", "rtcp_xr_rcvr_rtt_mode", "none");
|
||||
if (strcasecmp(rcvr_rtt_mode, "all") == 0) md->rtcp_xr.rcvr_rtt_mode = SalRtcpXrRcvrRttAll;
|
||||
else if (strcasecmp(rcvr_rtt_mode, "sender") == 0) md->rtcp_xr.rcvr_rtt_mode = SalRtcpXrRcvrRttSender;
|
||||
else md->rtcp_xr.rcvr_rtt_mode = SalRtcpXrRcvrRttNone;
|
||||
if (md->rtcp_xr.rcvr_rtt_mode != SalRtcpXrRcvrRttNone) {
|
||||
if (strcasecmp(rcvr_rtt_mode, "all") == 0) md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttAll;
|
||||
else if (strcasecmp(rcvr_rtt_mode, "sender") == 0) md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttSender;
|
||||
else md->rtcp_xr.rcvr_rtt_mode = OrtpRtcpXrRcvrRttNone;
|
||||
if (md->rtcp_xr.rcvr_rtt_mode != OrtpRtcpXrRcvrRttNone) {
|
||||
md->rtcp_xr.rcvr_rtt_max_size = lp_config_get_int(lc->config, "rtp", "rtcp_xr_rcvr_rtt_max_size", 0);
|
||||
}
|
||||
md->rtcp_xr.stat_summary_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_stat_summary_enabled", 0);
|
||||
if (md->rtcp_xr.stat_summary_enabled == TRUE) {
|
||||
md->rtcp_xr.stat_summary_flags = SalRtcpXrStatSummaryLoss | SalRtcpXrStatSummaryDup | SalRtcpXrStatSummaryJitt | SalRtcpXrStatSummaryTTL;
|
||||
md->rtcp_xr.stat_summary_flags = OrtpRtcpXrStatSummaryLoss | OrtpRtcpXrStatSummaryDup | OrtpRtcpXrStatSummaryJitt | OrtpRtcpXrStatSummaryTTL;
|
||||
}
|
||||
md->rtcp_xr.voip_metrics_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_enabled", 0);
|
||||
}
|
||||
for (i = 0; i < md->n_active_streams; i++) {
|
||||
memcpy(&md->streams[i].rtcp_xr, &md->rtcp_xr, sizeof(md->streams[i].rtcp_xr));
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
|
|
@ -314,8 +333,8 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
strncpy(md->streams[0].rtp_addr,local_ip,sizeof(md->streams[0].rtp_addr));
|
||||
strncpy(md->streams[0].rtcp_addr,local_ip,sizeof(md->streams[0].rtcp_addr));
|
||||
strncpy(md->streams[0].name,"Audio",sizeof(md->streams[0].name)-1);
|
||||
md->streams[0].rtp_port=call->audio_port;
|
||||
md->streams[0].rtcp_port=call->audio_port+1;
|
||||
md->streams[0].rtp_port=call->media_ports[0].rtp_port;
|
||||
md->streams[0].rtcp_port=call->media_ports[0].rtcp_port;
|
||||
md->streams[0].proto=(call->params.media_encryption == LinphoneMediaEncryptionSRTP) ?
|
||||
SalProtoRtpSavp : SalProtoRtpAvp;
|
||||
md->streams[0].type=SalAudio;
|
||||
|
|
@ -331,8 +350,8 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
if (call->params.has_video){
|
||||
md->n_active_streams++;
|
||||
strncpy(md->streams[0].name,"Video",sizeof(md->streams[0].name)-1);
|
||||
md->streams[1].rtp_port=call->video_port;
|
||||
md->streams[1].rtcp_port=call->video_port+1;
|
||||
md->streams[1].rtp_port=call->media_ports[1].rtp_port;
|
||||
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);
|
||||
|
|
@ -374,34 +393,19 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
}
|
||||
}
|
||||
|
||||
static int find_port_offset(LinphoneCore *lc, SalStreamType type){
|
||||
static int find_port_offset(LinphoneCore *lc, int stream_index, int base_port){
|
||||
int offset;
|
||||
MSList *elem;
|
||||
int tried_port;
|
||||
int existing_port;
|
||||
bool_t already_used=FALSE;
|
||||
|
||||
for(offset=0;offset<100;offset+=2){
|
||||
switch (type) {
|
||||
default:
|
||||
case SalAudio:
|
||||
tried_port=linphone_core_get_audio_port (lc)+offset;
|
||||
break;
|
||||
case SalVideo:
|
||||
tried_port=linphone_core_get_video_port (lc)+offset;
|
||||
break;
|
||||
}
|
||||
tried_port=base_port+offset;
|
||||
already_used=FALSE;
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
switch (type) {
|
||||
default:
|
||||
case SalAudio:
|
||||
existing_port = call->audio_port;
|
||||
break;
|
||||
case SalVideo:
|
||||
existing_port = call->video_port;
|
||||
break;
|
||||
}
|
||||
existing_port=call->media_ports[stream_index].rtp_port;
|
||||
if (existing_port==tried_port) {
|
||||
already_used=TRUE;
|
||||
break;
|
||||
|
|
@ -416,37 +420,19 @@ static int find_port_offset(LinphoneCore *lc, SalStreamType type){
|
|||
return offset;
|
||||
}
|
||||
|
||||
static int select_random_port(LinphoneCore *lc, SalStreamType type) {
|
||||
static int select_random_port(LinphoneCore *lc, int stream_index, int min_port, int max_port) {
|
||||
MSList *elem;
|
||||
int nb_tries;
|
||||
int tried_port = 0;
|
||||
int existing_port = 0;
|
||||
int min_port = 0, max_port = 0;
|
||||
bool_t already_used = FALSE;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case SalAudio:
|
||||
linphone_core_get_audio_port_range(lc, &min_port, &max_port);
|
||||
break;
|
||||
case SalVideo:
|
||||
linphone_core_get_video_port_range(lc, &min_port, &max_port);
|
||||
break;
|
||||
}
|
||||
tried_port = (rand() % (max_port - min_port) + min_port) & ~0x1;
|
||||
if (tried_port < min_port) tried_port = min_port + 2;
|
||||
for (nb_tries = 0; nb_tries < 100; nb_tries++) {
|
||||
for (elem = lc->calls; elem != NULL; elem = elem->next) {
|
||||
LinphoneCall *call = (LinphoneCall *)elem->data;
|
||||
switch (type) {
|
||||
default:
|
||||
case SalAudio:
|
||||
existing_port = call->audio_port;
|
||||
break;
|
||||
case SalVideo:
|
||||
existing_port = call->video_port;
|
||||
break;
|
||||
}
|
||||
existing_port=call->media_ports[stream_index].rtp_port;
|
||||
if (existing_port == tried_port) {
|
||||
already_used = TRUE;
|
||||
break;
|
||||
|
|
@ -461,8 +447,31 @@ static int select_random_port(LinphoneCore *lc, SalStreamType type) {
|
|||
return tried_port;
|
||||
}
|
||||
|
||||
static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
|
||||
static void port_config_set_random(LinphoneCall *call, int stream_index){
|
||||
call->media_ports[stream_index].rtp_port=-1;
|
||||
call->media_ports[stream_index].rtcp_port=-1;
|
||||
}
|
||||
|
||||
static void port_config_set(LinphoneCall *call, int stream_index, int min_port, int max_port){
|
||||
int port_offset;
|
||||
if (min_port>0 && max_port>0){
|
||||
if (min_port == max_port) {
|
||||
/* Used fixed RTP audio port. */
|
||||
port_offset=find_port_offset(call->core, stream_index, min_port);
|
||||
if (port_offset==-1) {
|
||||
port_config_set_random(call, stream_index);
|
||||
return;
|
||||
}
|
||||
call->media_ports[stream_index].rtp_port=min_port+port_offset;
|
||||
} else {
|
||||
/* Select random RTP audio port in the specified range. */
|
||||
call->media_ports[stream_index].rtp_port = select_random_port(call->core, stream_index, min_port, max_port);
|
||||
}
|
||||
call->media_ports[stream_index].rtcp_port=call->media_ports[stream_index].rtp_port+1;
|
||||
}else port_config_set_random(call,stream_index);
|
||||
}
|
||||
|
||||
static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
|
||||
int min_port, max_port;
|
||||
|
||||
call->magic=linphone_call_magic;
|
||||
|
|
@ -475,25 +484,11 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
|
|||
call->camera_enabled=TRUE;
|
||||
|
||||
linphone_core_get_audio_port_range(call->core, &min_port, &max_port);
|
||||
if (min_port == max_port) {
|
||||
/* Used fixed RTP audio port. */
|
||||
port_offset=find_port_offset (call->core, SalAudio);
|
||||
if (port_offset==-1) return;
|
||||
call->audio_port=linphone_core_get_audio_port(call->core)+port_offset;
|
||||
} else {
|
||||
/* Select random RTP audio port in the specified range. */
|
||||
call->audio_port = select_random_port(call->core, SalAudio);
|
||||
}
|
||||
port_config_set(call,0,min_port,max_port);
|
||||
|
||||
linphone_core_get_video_port_range(call->core, &min_port, &max_port);
|
||||
if (min_port == max_port) {
|
||||
/* Used fixed RTP video port. */
|
||||
port_offset=find_port_offset (call->core, SalVideo);
|
||||
if (port_offset==-1) return;
|
||||
call->video_port=linphone_core_get_video_port(call->core)+port_offset;
|
||||
} else {
|
||||
/* Select random RTP video port in the specified range. */
|
||||
call->video_port = select_random_port(call->core, SalVideo);
|
||||
}
|
||||
port_config_set(call,1,min_port,max_port);
|
||||
|
||||
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO);
|
||||
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO);
|
||||
}
|
||||
|
|
@ -644,20 +639,22 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
// In this case WE chose the media parameters according to policy.
|
||||
call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
|
||||
}
|
||||
|
||||
/*create the ice session now if ICE is required*/
|
||||
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseIce){
|
||||
call->ice_session = ice_session_new();
|
||||
ice_session_set_role(call->ice_session, IR_Controlled);
|
||||
}
|
||||
/*reserve the sockets immediately*/
|
||||
linphone_call_init_media_streams(call);
|
||||
switch (linphone_core_get_firewall_policy(call->core)) {
|
||||
case LinphonePolicyUseIce:
|
||||
call->ice_session = ice_session_new();
|
||||
ice_session_set_role(call->ice_session, IR_Controlled);
|
||||
/*start ICE gathering*/
|
||||
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_call_init_media_streams(call);
|
||||
linphone_call_start_media_streams_for_ice_gathering(call);
|
||||
if (linphone_core_gather_ice_candidates(call->core,call)<0) {
|
||||
/* Ice candidates gathering failed, proceed with the call anyway. */
|
||||
linphone_call_delete_ice_session(call);
|
||||
linphone_call_stop_media_streams_for_ice_gathering(call);
|
||||
}
|
||||
linphone_call_start_media_streams_for_ice_gathering(call);
|
||||
if (linphone_core_gather_ice_candidates(call->core,call)<0) {
|
||||
/* Ice candidates gathering failed, proceed with the call anyway. */
|
||||
linphone_call_delete_ice_session(call);
|
||||
linphone_call_stop_media_streams_for_ice_gathering(call);
|
||||
}
|
||||
break;
|
||||
case LinphonePolicyUseStun:
|
||||
|
|
@ -669,7 +666,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
if(!lc->rtp_conf.disable_upnp) {
|
||||
call->upnp_session = linphone_upnp_session_new(call);
|
||||
if (call->upnp_session != NULL) {
|
||||
linphone_call_init_media_streams(call);
|
||||
if (linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op))<0) {
|
||||
/* uPnP port mappings failed, proceed with the call anyway. */
|
||||
linphone_call_delete_upnp_session(call);
|
||||
|
|
@ -695,6 +691,11 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
static void linphone_call_set_terminated(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
linphone_call_stop_media_streams(call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
linphone_call_delete_upnp_session(call);
|
||||
linphone_call_delete_ice_session(call);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
|
||||
call->owns_call_log=FALSE;
|
||||
|
|
@ -789,11 +790,11 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
call->state=cstate;
|
||||
}
|
||||
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
|
||||
switch(call->reason){
|
||||
case LinphoneReasonDeclined:
|
||||
switch(call->non_op_error.reason){
|
||||
case SalReasonDeclined:
|
||||
call->log->status=LinphoneCallDeclined;
|
||||
break;
|
||||
case LinphoneReasonNotAnswered:
|
||||
case SalReasonRequestTimeout:
|
||||
call->log->status=LinphoneCallMissed;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -810,6 +811,11 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
lc->vtable.call_state_changed(lc,call,cstate,message);
|
||||
if (cstate==LinphoneCallReleased){
|
||||
if (call->op!=NULL) {
|
||||
/*transfer the last error so that it can be obtained even in Released state*/
|
||||
if (call->non_op_error.reason==SalReasonNone){
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(call->op);
|
||||
sal_error_info_set(&call->non_op_error,ei->reason,ei->protocol_code,ei->status_string,ei->warnings);
|
||||
}
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
|
|
@ -832,11 +838,6 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
static void linphone_call_destroy(LinphoneCall *obj)
|
||||
{
|
||||
ms_message("Call [%p] freed.",obj);
|
||||
linphone_call_stop_media_streams(obj);
|
||||
#ifdef BUILD_UPNP
|
||||
linphone_call_delete_upnp_session(obj);
|
||||
#endif //BUILD_UPNP
|
||||
linphone_call_delete_ice_session(obj);
|
||||
if (obj->op!=NULL) {
|
||||
sal_op_release(obj->op);
|
||||
obj->op=NULL;
|
||||
|
|
@ -873,6 +874,7 @@ static void linphone_call_destroy(LinphoneCall *obj)
|
|||
}
|
||||
linphone_call_params_uninit(&obj->params);
|
||||
linphone_call_params_uninit(&obj->current_params);
|
||||
sal_error_info_reset(&obj->non_op_error);
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
|
|
@ -994,7 +996,16 @@ LinphoneCallState linphone_call_get_state(const LinphoneCall *call){
|
|||
* Returns the reason for a call termination (either error or normal termination)
|
||||
**/
|
||||
LinphoneReason linphone_call_get_reason(const LinphoneCall *call){
|
||||
return call->reason;
|
||||
return linphone_error_info_get_reason(linphone_call_get_error_info(call));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns full details about call errors or termination reasons.
|
||||
**/
|
||||
const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call){
|
||||
if (call->non_op_error.reason!=SalReasonNone){
|
||||
return (const LinphoneErrorInfo*)&call->non_op_error;
|
||||
}else return linphone_error_info_from_sal_op(call->op);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1410,17 +1421,31 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin
|
|||
call->nextVideoFrameDecoded._func = cb;
|
||||
call->nextVideoFrameDecoded._user_data = user_data;
|
||||
#ifdef VIDEO_ENABLED
|
||||
ms_filter_call_method_noarg(call->videostream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION);
|
||||
if (call->videostream && call->videostream->ms.decoder)
|
||||
ms_filter_call_method_noarg(call->videostream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void port_config_set_random_choosed(LinphoneCall *call, int stream_index, RtpSession *session){
|
||||
call->media_ports[stream_index].rtp_port=rtp_session_get_local_port(session);
|
||||
call->media_ports[stream_index].rtcp_port=rtp_session_get_local_rtcp_port(session);
|
||||
}
|
||||
|
||||
void linphone_call_init_audio_stream(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
AudioStream *audiostream;
|
||||
int dscp;
|
||||
|
||||
if (call->audiostream != NULL) return;
|
||||
call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,call->af==AF_INET6);
|
||||
if (call->sessions[0].rtp_session==NULL){
|
||||
call->audiostream=audiostream=audio_stream_new(call->media_ports[0].rtp_port,call->media_ports[0].rtcp_port,call->af==AF_INET6);
|
||||
}else{
|
||||
call->audiostream=audio_stream_new_with_sessions(&call->sessions[0]);
|
||||
}
|
||||
audiostream=call->audiostream;
|
||||
if (call->media_ports[0].rtp_port==-1){
|
||||
port_config_set_random_choosed(call,0,audiostream->ms.sessions.rtp_session);
|
||||
}
|
||||
dscp=linphone_core_get_audio_dscp(lc);
|
||||
if (dscp!=-1)
|
||||
audio_stream_set_dscp(audiostream,dscp);
|
||||
|
|
@ -1452,68 +1477,73 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
|
|||
audio_stream_set_features(audiostream,linphone_core_get_audio_features(lc));
|
||||
|
||||
if (lc->rtptf){
|
||||
RtpTransport *artp=lc->rtptf->audio_rtp_func(lc->rtptf->audio_rtp_func_data, call->audio_port);
|
||||
RtpTransport *artcp=lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->audio_port+1);
|
||||
rtp_session_set_transports(audiostream->ms.session,artp,artcp);
|
||||
RtpTransport *artp=lc->rtptf->audio_rtp_func(lc->rtptf->audio_rtp_func_data, call->media_ports[0].rtp_port);
|
||||
RtpTransport *artcp=lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->media_ports[0].rtcp_port);
|
||||
rtp_session_set_transports(audiostream->ms.sessions.rtp_session,artp,artcp);
|
||||
}
|
||||
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
|
||||
rtp_session_set_pktinfo(audiostream->ms.session, TRUE);
|
||||
rtp_session_set_symmetric_rtp(audiostream->ms.session, FALSE);
|
||||
rtp_session_set_pktinfo(audiostream->ms.sessions.rtp_session, TRUE);
|
||||
rtp_session_set_symmetric_rtp(audiostream->ms.sessions.rtp_session, FALSE);
|
||||
if (ice_session_check_list(call->ice_session, 0) == NULL) {
|
||||
ice_session_add_check_list(call->ice_session, ice_check_list_new());
|
||||
}
|
||||
audiostream->ms.ice_check_list = ice_session_check_list(call->ice_session, 0);
|
||||
ice_check_list_set_rtp_session(audiostream->ms.ice_check_list, audiostream->ms.session);
|
||||
ice_check_list_set_rtp_session(audiostream->ms.ice_check_list, audiostream->ms.sessions.rtp_session);
|
||||
}
|
||||
|
||||
call->audiostream_app_evq = ortp_ev_queue_new();
|
||||
rtp_session_register_event_queue(audiostream->ms.session,call->audiostream_app_evq);
|
||||
rtp_session_register_event_queue(audiostream->ms.sessions.rtp_session,call->audiostream_app_evq);
|
||||
}
|
||||
|
||||
void linphone_call_init_video_stream(LinphoneCall *call){
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
if (!call->params.has_video) {
|
||||
linphone_call_stop_video_stream(call);
|
||||
return;
|
||||
}
|
||||
if (call->videostream != NULL) return;
|
||||
if ((lc->video_conf.display || lc->video_conf.capture) && call->params.has_video){
|
||||
if (call->videostream == NULL){
|
||||
int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0);
|
||||
int dscp=linphone_core_get_video_dscp(lc);
|
||||
const char *display_filter=linphone_core_get_video_display_filter(lc);
|
||||
|
||||
call->videostream=video_stream_new(call->video_port,call->video_port+1,call->af==AF_INET6);
|
||||
|
||||
if (call->sessions[1].rtp_session==NULL){
|
||||
call->videostream=video_stream_new(call->media_ports[1].rtp_port,call->media_ports[1].rtcp_port, call->af==AF_INET6);
|
||||
}else{
|
||||
call->videostream=video_stream_new_with_sessions(&call->sessions[1]);
|
||||
}
|
||||
if (call->media_ports[1].rtp_port==-1){
|
||||
port_config_set_random_choosed(call,1,call->videostream->ms.sessions.rtp_session);
|
||||
}
|
||||
if (dscp!=-1)
|
||||
video_stream_set_dscp(call->videostream,dscp);
|
||||
video_stream_enable_display_filter_auto_rotate(call->videostream, lp_config_get_int(lc->config,"video","display_filter_auto_rotate",0));
|
||||
if (video_recv_buf_size>0) rtp_session_set_recv_buf_size(call->videostream->ms.session,video_recv_buf_size);
|
||||
if (video_recv_buf_size>0) rtp_session_set_recv_buf_size(call->videostream->ms.sessions.rtp_session,video_recv_buf_size);
|
||||
|
||||
if (display_filter != NULL)
|
||||
video_stream_set_display_filter_name(call->videostream,display_filter);
|
||||
video_stream_set_event_callback(call->videostream,video_stream_event_cb, call);
|
||||
if (lc->rtptf){
|
||||
RtpTransport *vrtp=lc->rtptf->video_rtp_func(lc->rtptf->video_rtp_func_data, call->video_port);
|
||||
RtpTransport *vrtcp=lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->video_port+1);
|
||||
rtp_session_set_transports(call->videostream->ms.session,vrtp,vrtcp);
|
||||
RtpTransport *vrtp=lc->rtptf->video_rtp_func(lc->rtptf->video_rtp_func_data, call->media_ports[1].rtp_port);
|
||||
RtpTransport *vrtcp=lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->media_ports[1].rtcp_port);
|
||||
rtp_session_set_transports(call->videostream->ms.sessions.rtp_session,vrtp,vrtcp);
|
||||
}
|
||||
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
|
||||
rtp_session_set_pktinfo(call->videostream->ms.session, TRUE);
|
||||
rtp_session_set_symmetric_rtp(call->videostream->ms.session, FALSE);
|
||||
if (ice_session_check_list(call->ice_session, 1) == NULL) {
|
||||
ice_session_add_check_list(call->ice_session, ice_check_list_new());
|
||||
}
|
||||
call->videostream->ms.ice_check_list = ice_session_check_list(call->ice_session, 1);
|
||||
ice_check_list_set_rtp_session(call->videostream->ms.ice_check_list, call->videostream->ms.session);
|
||||
ms_message ("creating new ice video check list [%p] for session [%p]",call->videostream->ms.ice_check_list,call->videostream->ms.session);
|
||||
}
|
||||
call->videostream_app_evq = ortp_ev_queue_new();
|
||||
rtp_session_register_event_queue(call->videostream->ms.session,call->videostream_app_evq);
|
||||
call->videostream_app_evq = ortp_ev_queue_new();
|
||||
rtp_session_register_event_queue(call->videostream->ms.sessions.rtp_session,call->videostream_app_evq);
|
||||
#ifdef TEST_EXT_RENDERER
|
||||
video_stream_set_render_callback(call->videostream,rendercb,NULL);
|
||||
#endif
|
||||
}
|
||||
/*eventually re-create the ICE check list that may have been destroyed if the stream wasn't used recently*/
|
||||
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
|
||||
rtp_session_set_pktinfo(call->videostream->ms.sessions.rtp_session, TRUE);
|
||||
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session, FALSE);
|
||||
if (ice_session_check_list(call->ice_session, 1) == NULL) {
|
||||
ice_session_add_check_list(call->ice_session, ice_check_list_new());
|
||||
}
|
||||
call->videostream->ms.ice_check_list = ice_session_check_list(call->ice_session, 1);
|
||||
ice_check_list_set_rtp_session(call->videostream->ms.ice_check_list, call->videostream->ms.sessions.rtp_session);
|
||||
ms_message ("creating new ice video check list [%p] for session [%p]",call->videostream->ms.ice_check_list,call->videostream->ms.sessions.rtp_session);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
call->videostream=NULL;
|
||||
#endif
|
||||
|
|
@ -1717,6 +1747,49 @@ static int find_crypto_index_from_tag(const SalSrtpCryptoAlgo crypto[],unsigned
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void configure_rtp_session_for_rtcp_xr(LinphoneCore *lc, LinphoneCall *call, SalStreamType type) {
|
||||
RtpSession *session;
|
||||
const OrtpRtcpXrConfiguration *localconfig;
|
||||
const OrtpRtcpXrConfiguration *remoteconfig;
|
||||
OrtpRtcpXrConfiguration currentconfig;
|
||||
const SalStreamDescription *localstream;
|
||||
const SalStreamDescription *remotestream;
|
||||
|
||||
localstream = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, type);
|
||||
if (!localstream) localstream = sal_media_description_find_stream(call->localdesc, SalProtoRtpAvp, type);
|
||||
if (!localstream) return;
|
||||
localconfig = &localstream->rtcp_xr;
|
||||
remotestream = sal_media_description_find_stream(sal_call_get_remote_media_description(call->op), SalProtoRtpSavp, type);
|
||||
if (!remotestream) remotestream = sal_media_description_find_stream(sal_call_get_remote_media_description(call->op), SalProtoRtpAvp, type);
|
||||
if (!remotestream) return;
|
||||
remoteconfig = &remotestream->rtcp_xr;
|
||||
|
||||
if (localstream->dir == SalStreamInactive) return;
|
||||
else if (localstream->dir == SalStreamRecvOnly) {
|
||||
/* Use local config for unilateral parameters and remote config for collaborative parameters. */
|
||||
memcpy(¤tconfig, localconfig, sizeof(currentconfig));
|
||||
currentconfig.rcvr_rtt_mode = remoteconfig->rcvr_rtt_mode;
|
||||
currentconfig.rcvr_rtt_max_size = remoteconfig->rcvr_rtt_max_size;
|
||||
} else {
|
||||
memcpy(¤tconfig, remoteconfig, sizeof(currentconfig));
|
||||
}
|
||||
if (type == SalAudio) {
|
||||
session = call->audiostream->ms.sessions.rtp_session;
|
||||
} else {
|
||||
session = call->videostream->ms.sessions.rtp_session;
|
||||
}
|
||||
rtp_session_configure_rtcp_xr(session, ¤tconfig);
|
||||
if (currentconfig.rcvr_rtt_mode != OrtpRtcpXrRcvrRttNone) {
|
||||
rtp_session_set_rtcp_xr_rcvr_rtt_interval(session, lp_config_get_int(lc->config, "rtp", "rtcp_xr_rcvr_rtt_interval_duration", 5000));
|
||||
}
|
||||
if (currentconfig.stat_summary_enabled == TRUE) {
|
||||
rtp_session_set_rtcp_xr_stat_summary_interval(session, lp_config_get_int(lc->config, "rtp", "rtcp_xr_stat_summary_interval_duration", 5000));
|
||||
}
|
||||
if (currentconfig.voip_metrics_enabled == TRUE) {
|
||||
rtp_session_set_rtcp_xr_voip_metrics_interval(session, lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_interval_duration", 5000));
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cname, bool_t muted, bool_t send_ringbacktone, bool_t use_arc){
|
||||
LinphoneCore *lc=call->core;
|
||||
int used_pt=-1;
|
||||
|
|
@ -1811,6 +1884,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
call->audiostream_encrypted=FALSE;
|
||||
}
|
||||
}else call->audiostream_encrypted=FALSE;
|
||||
configure_rtp_session_for_rtcp_xr(lc, call, SalAudio);
|
||||
audio_stream_start_full(
|
||||
call->audiostream,
|
||||
call->audio_profile,
|
||||
|
|
@ -1932,7 +2006,8 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
}else{
|
||||
call->videostream_encrypted=FALSE;
|
||||
}
|
||||
|
||||
configure_rtp_session_for_rtcp_xr(lc, call, SalVideo);
|
||||
|
||||
call->log->video_enabled = TRUE;
|
||||
video_stream_set_direction (call->videostream, dir);
|
||||
ms_message("%s lc rotation:%d\n", __FUNCTION__, lc->device_rotation);
|
||||
|
|
@ -2087,14 +2162,16 @@ void linphone_call_delete_ice_session(LinphoneCall *call){
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BUILD_UPNP
|
||||
|
||||
void linphone_call_delete_upnp_session(LinphoneCall *call){
|
||||
#ifdef BUILD_UPNP
|
||||
if(call->upnp_session!=NULL) {
|
||||
linphone_upnp_session_destroy(call->upnp_session);
|
||||
call->upnp_session=NULL;
|
||||
}
|
||||
}
|
||||
#endif //BUILD_UPNP
|
||||
}
|
||||
|
||||
|
||||
static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){
|
||||
float quality=media_stream_get_average_quality_rating(st);
|
||||
|
|
@ -2107,7 +2184,8 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){
|
|||
|
||||
void linphone_call_stop_audio_stream(LinphoneCall *call) {
|
||||
if (call->audiostream!=NULL) {
|
||||
rtp_session_unregister_event_queue(call->audiostream->ms.session,call->audiostream_app_evq);
|
||||
media_stream_reclaim_sessions(&call->audiostream->ms,&call->sessions[0]);
|
||||
rtp_session_unregister_event_queue(call->audiostream->ms.sessions.rtp_session,call->audiostream_app_evq);
|
||||
ortp_ev_queue_flush(call->audiostream_app_evq);
|
||||
ortp_ev_queue_destroy(call->audiostream_app_evq);
|
||||
call->audiostream_app_evq=NULL;
|
||||
|
|
@ -2134,7 +2212,8 @@ void linphone_call_stop_audio_stream(LinphoneCall *call) {
|
|||
void linphone_call_stop_video_stream(LinphoneCall *call) {
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL){
|
||||
rtp_session_unregister_event_queue(call->videostream->ms.session,call->videostream_app_evq);
|
||||
media_stream_reclaim_sessions(&call->videostream->ms,&call->sessions[1]);
|
||||
rtp_session_unregister_event_queue(call->videostream->ms.sessions.rtp_session,call->videostream_app_evq);
|
||||
ortp_ev_queue_flush(call->videostream_app_evq);
|
||||
ortp_ev_queue_destroy(call->videostream_app_evq);
|
||||
call->videostream_app_evq=NULL;
|
||||
|
|
@ -2605,12 +2684,12 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
if ((call->state==LinphoneCallStreamsRunning || call->state==LinphoneCallOutgoingEarlyMedia || call->state==LinphoneCallIncomingEarlyMedia) && one_second_elapsed){
|
||||
float audio_load=0, video_load=0;
|
||||
if (call->audiostream!=NULL){
|
||||
if (call->audiostream->ms.ticker)
|
||||
audio_load=ms_ticker_get_average_load(call->audiostream->ms.ticker);
|
||||
if (call->audiostream->ms.sessions.ticker)
|
||||
audio_load=ms_ticker_get_average_load(call->audiostream->ms.sessions.ticker);
|
||||
}
|
||||
if (call->videostream!=NULL){
|
||||
if (call->videostream->ms.ticker)
|
||||
video_load=ms_ticker_get_average_load(call->videostream->ms.ticker);
|
||||
if (call->videostream->ms.sessions.ticker)
|
||||
video_load=ms_ticker_get_average_load(call->videostream->ms.sessions.ticker);
|
||||
}
|
||||
report_bandwidth(call,(MediaStream*)call->audiostream,(MediaStream*)call->videostream);
|
||||
ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load);
|
||||
|
|
@ -2637,20 +2716,22 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
|
||||
linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->ms.session);
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->ms.sessions.rtp_session);
|
||||
if(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp != NULL)
|
||||
freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp);
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp = evd->packet;
|
||||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO],(MediaStream*)call->videostream);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
|
||||
memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->ms.session), sizeof(jitter_stats_t));
|
||||
memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->ms.sessions.rtp_session), sizeof(jitter_stats_t));
|
||||
if(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp != NULL)
|
||||
freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp);
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp = evd->packet;
|
||||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO],(MediaStream*)call->videostream);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
|
||||
|
|
@ -2680,20 +2761,22 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
} else if (evt == ORTP_EVENT_ZRTP_SAS_READY) {
|
||||
linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->ms.session);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->ms.sessions.rtp_session);
|
||||
if(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp != NULL)
|
||||
freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp = evd->packet;
|
||||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO],(MediaStream*)call->audiostream);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
|
||||
memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->ms.session), sizeof(jitter_stats_t));
|
||||
memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->ms.sessions.rtp_session), sizeof(jitter_stats_t));
|
||||
if(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp != NULL)
|
||||
freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp = evd->packet;
|
||||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO],(MediaStream*)call->audiostream);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
|
||||
|
|
|
|||
|
|
@ -536,8 +536,25 @@ static void sound_config_read(LinphoneCore *lc)
|
|||
/*alsadev let the user use custom alsa device within linphone*/
|
||||
devid=lp_config_get_string(lc->config,"sound","alsadev",NULL);
|
||||
if (devid){
|
||||
MSSndCard *card=ms_alsa_card_new_custom(devid,devid);
|
||||
ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
|
||||
MSSndCard* card;
|
||||
const char* delim=",";
|
||||
size_t l=strlen(devid);
|
||||
char* d=malloc(l+1);
|
||||
char* i;
|
||||
memcpy(d,devid,l+1);
|
||||
for (l=0,i=strpbrk(d+l,delim);i;i=strpbrk(d+l,delim)){
|
||||
char s=*i;
|
||||
*i='\0';
|
||||
card=ms_alsa_card_new_custom(d+l,d+l);
|
||||
ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
|
||||
*i=s;
|
||||
l=i-d+1;
|
||||
}
|
||||
if(d[l]!='\0') {
|
||||
card=ms_alsa_card_new_custom(d+l,d+l);
|
||||
ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
tmp=lp_config_get_int(lc->config,"sound","alsa_forced_rate",-1);
|
||||
if (tmp>0) ms_alsa_card_set_forced_sample_rate(tmp);
|
||||
|
|
@ -615,11 +632,13 @@ static void sound_config_read(LinphoneCore *lc)
|
|||
|
||||
static void certificates_config_read(LinphoneCore *lc)
|
||||
{
|
||||
const char *rootca;
|
||||
#ifdef __linux
|
||||
sal_set_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs"));
|
||||
rootca=lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs");
|
||||
#else
|
||||
sal_set_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE));
|
||||
rootca=lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE);
|
||||
#endif
|
||||
linphone_core_set_root_ca(lc,rootca);
|
||||
linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE));
|
||||
linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE));
|
||||
}
|
||||
|
|
@ -1350,7 +1369,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_assign_payload_type(lc,&payload_type_g729,18,"annexb=no");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_22k,-1,"config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_44k,-1,"config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; usedtx=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; usedtx=0; cbr=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_isac,-1,NULL);
|
||||
linphone_core_handle_static_payloads(lc);
|
||||
|
||||
|
|
@ -1369,6 +1388,8 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
lc->network_last_status = FALSE;
|
||||
|
||||
lc->http_provider = belle_sip_stack_create_http_provider(sal_get_belle_sip_stack(lc->sal), "0.0.0.0");
|
||||
lc->http_verify_policy = belle_tls_verify_policy_new();
|
||||
belle_http_provider_set_tls_verify_policy(lc->http_provider,lc->http_verify_policy);
|
||||
|
||||
certificates_config_read(lc);
|
||||
|
||||
|
|
@ -1521,7 +1542,7 @@ static void update_primary_contact(LinphoneCore *lc){
|
|||
lc->sip_conf.loopback_only=TRUE;
|
||||
}else lc->sip_conf.loopback_only=FALSE;
|
||||
linphone_address_set_domain(url,tmp);
|
||||
linphone_address_set_port(url,linphone_core_get_sip_port (lc));
|
||||
linphone_address_set_port(url,linphone_core_get_sip_port(lc));
|
||||
guessed=linphone_address_as_string(url);
|
||||
lc->sip_conf.guessed_contact=guessed;
|
||||
linphone_address_destroy(url);
|
||||
|
|
@ -1734,6 +1755,8 @@ void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc,bool_t rtp_no_
|
|||
|
||||
/**
|
||||
* Sets the UDP port used for audio streaming.
|
||||
* A value if -1 will request the system to allocate the local port randomly.
|
||||
* This is recommended in order to avoid firewall warnings.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
|
|
@ -1754,6 +1777,8 @@ void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_
|
|||
|
||||
/**
|
||||
* Sets the UDP port used for video streaming.
|
||||
* A value if -1 will request the system to allocate the local port randomly.
|
||||
* This is recommended in order to avoid firewall warnings.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
|
|
@ -1833,8 +1858,9 @@ void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,bool_t use_rfc2833)
|
|||
**/
|
||||
int linphone_core_get_sip_port(LinphoneCore *lc)
|
||||
{
|
||||
LCSipTransports *tr=&lc->sip_conf.transports;
|
||||
return tr->udp_port>0 ? tr->udp_port : (tr->tcp_port > 0 ? tr->tcp_port : tr->tls_port);
|
||||
LCSipTransports tr;
|
||||
linphone_core_get_sip_transports_used(lc,&tr);
|
||||
return tr.udp_port>0 ? tr.udp_port : (tr.tcp_port > 0 ? tr.tcp_port : tr.tls_port);
|
||||
}
|
||||
|
||||
#if !USE_BELLE_SIP
|
||||
|
|
@ -1918,25 +1944,23 @@ static int apply_transports(LinphoneCore *lc){
|
|||
anyaddr="0.0.0.0";
|
||||
|
||||
sal_unlisten_ports(sal);
|
||||
if (tr->udp_port>0){
|
||||
if (tr->udp_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
|
||||
transport_error(lc,"udp",tr->udp_port);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (tr->tcp_port>0){
|
||||
if (tr->tcp_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
|
||||
transport_error(lc,"tcp",tr->tcp_port);
|
||||
}
|
||||
}
|
||||
if (tr->tls_port>0){
|
||||
if (tr->tls_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,TRUE)!=0){
|
||||
transport_error(lc,"tls",tr->tls_port);
|
||||
}
|
||||
}
|
||||
|
||||
apply_user_agent(lc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1951,37 +1975,24 @@ bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTra
|
|||
* Sets the ports to be used for each of transport (UDP or TCP)
|
||||
*
|
||||
* A zero value port for a given transport means the transport
|
||||
* is not used.
|
||||
* is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be choosen randomly by the system.
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * tr_config /*config to be saved*/){
|
||||
LCSipTransports tr=*tr_config;
|
||||
int random_port=(0xDFFF&random())+1024;
|
||||
|
||||
if (lp_config_get_int(lc->config,"sip","sip_random_port",0)==1) {
|
||||
/*legacy random mode*/
|
||||
if (tr.udp_port>0){
|
||||
tr.udp_port=random_port;
|
||||
tr.tls_port=tr.tcp_port=0; /*make sure only one transport is active at a time*/
|
||||
}else if (tr.tcp_port>0){
|
||||
tr.tcp_port=random_port;
|
||||
tr.tls_port=tr.udp_port=0; /*make sure only one transport is active at a time*/
|
||||
}else if (tr.tls_port>0){
|
||||
tr.tls_port=random_port;
|
||||
tr.udp_port=tr.tcp_port=0; /*make sure only one transport is active at a time*/
|
||||
} else {
|
||||
tr.udp_port=random_port;
|
||||
tr.udp_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
}
|
||||
if (tr.tcp_port>0){
|
||||
tr.tcp_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
}
|
||||
if (tr.tls_port>0){
|
||||
tr.tls_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
}
|
||||
}
|
||||
if (tr.udp_port == LC_SIP_TRANSPORT_RANDOM) {
|
||||
tr.udp_port=random_port;
|
||||
}
|
||||
if (tr.tcp_port == LC_SIP_TRANSPORT_RANDOM) {
|
||||
tr.tcp_port=random_port;
|
||||
}
|
||||
if (tr.tls_port == LC_SIP_TRANSPORT_RANDOM) {
|
||||
tr.tls_port=random_port+1;
|
||||
}
|
||||
|
||||
if (tr.udp_port==0 && tr.tcp_port==0 && tr.tls_port==0){
|
||||
|
|
@ -2003,9 +2014,9 @@ int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * t
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ports used for each transport (udp, tcp).
|
||||
* Retrieves the port configuration used for each transport (udp, tcp, tls).
|
||||
* A zero value port for a given transport means the transport
|
||||
* is not used.
|
||||
* is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be choosen randomly by the system.
|
||||
* @ingroup network_parameters
|
||||
**/
|
||||
int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *tr){
|
||||
|
|
@ -2013,6 +2024,18 @@ int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *tr){
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the real port number assigned for each sip transport (udp, tcp, tls).
|
||||
* A zero value means that the transport is not activated.
|
||||
* If LC_SIP_TRANSPORT_RANDOM was passed to linphone_core_set_sip_transports(), the random port choosed by the system is returned.
|
||||
* @ingroup network_parameters
|
||||
* @param tr a LCSipTransports structure.
|
||||
**/
|
||||
void linphone_core_get_sip_transports_used(LinphoneCore *lc, LCSipTransports *tr){
|
||||
tr->udp_port=sal_get_listening_port(lc->sal,SalTransportUDP);
|
||||
tr->tcp_port=sal_get_listening_port(lc->sal,SalTransportTCP);
|
||||
tr->tls_port=sal_get_listening_port(lc->sal,SalTransportTLS);
|
||||
}
|
||||
/**
|
||||
* Sets the UDP port to be used by SIP.
|
||||
*
|
||||
|
|
@ -2281,7 +2304,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout);
|
||||
decline_reason=lc->current_call ? LinphoneReasonBusy : LinphoneReasonDeclined;
|
||||
call->log->status=LinphoneCallMissed;
|
||||
call->reason=LinphoneReasonNotAnswered;
|
||||
sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,408,"Not answered",NULL);
|
||||
linphone_core_decline_call(lc,call,decline_reason);
|
||||
}
|
||||
}
|
||||
|
|
@ -2526,7 +2549,6 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
|
|||
for (elem=linphone_core_get_proxy_config_list(lc);elem!=NULL;elem=elem->next){
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
|
||||
const char *domain=linphone_proxy_config_get_domain(cfg);
|
||||
/* ms_warning("Checking %s / %s %s", domain, linphone_address_get_domain(uri), linphone_proxy_config_get_route(cfg)); */
|
||||
if (domain!=NULL && strcmp(domain,linphone_address_get_domain(uri))==0){
|
||||
if (linphone_proxy_config_register_enabled(cfg)) {
|
||||
found_cfg=cfg;
|
||||
|
|
@ -2540,7 +2562,7 @@ end:
|
|||
if (!found_cfg && found_noreg_cfg) found_cfg = found_noreg_cfg;
|
||||
if (found_cfg && found_cfg!=default_cfg){
|
||||
ms_debug("Overriding default proxy setting for this call/message/subscribe operation.");
|
||||
}
|
||||
}else if (!found_cfg) found_cfg=default_cfg; /*when no matching proxy config is found, use the default proxy config*/
|
||||
return found_cfg;
|
||||
}
|
||||
|
||||
|
|
@ -2586,6 +2608,10 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
|
|||
|
||||
int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call){
|
||||
linphone_call_create_op(call);
|
||||
linphone_call_stop_media_streams(call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
linphone_call_init_media_streams(call);
|
||||
return linphone_core_start_invite(lc,call, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -2597,7 +2623,6 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const Linph
|
|||
linphone_call_set_contact_op(call);
|
||||
|
||||
linphone_core_stop_dtmf_stream(lc);
|
||||
linphone_call_init_media_streams(call);
|
||||
linphone_call_make_local_media_description(lc,call);
|
||||
|
||||
if (lc->ringstream==NULL) {
|
||||
|
|
@ -2784,7 +2809,6 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
lc->vtable.display_warning(lc,_("Sorry, we have reached the maximum number of simultaneous calls"));
|
||||
return NULL;
|
||||
}
|
||||
linphone_core_get_default_proxy(lc,&proxy);
|
||||
|
||||
real_url=linphone_address_as_string(addr);
|
||||
proxy=linphone_core_lookup_known_proxy(lc,addr);
|
||||
|
|
@ -2809,9 +2833,9 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
/* this call becomes now the current one*/
|
||||
lc->current_call=call;
|
||||
linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call");
|
||||
linphone_call_init_media_streams(call);
|
||||
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
|
||||
/* Defer the start of the call after the ICE gathering process. */
|
||||
linphone_call_init_media_streams(call);
|
||||
linphone_call_start_media_streams_for_ice_gathering(call);
|
||||
call->log->start_date_time=time(NULL);
|
||||
if (linphone_core_gather_ice_candidates(lc,call)<0) {
|
||||
|
|
@ -2824,7 +2848,6 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
}
|
||||
else if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseUpnp) {
|
||||
#ifdef BUILD_UPNP
|
||||
linphone_call_init_media_streams(call);
|
||||
call->log->start_date_time=time(NULL);
|
||||
if (linphone_core_update_upnp(lc,call)<0) {
|
||||
/* uPnP port mappings failed, proceed with the call anyway. */
|
||||
|
|
@ -3038,7 +3061,6 @@ int linphone_core_accept_early_media_with_params(LinphoneCore* lc, LinphoneCall*
|
|||
|
||||
// if parameters are passed, update the media description
|
||||
if ( params ) {
|
||||
md = sal_call_get_remote_media_description ( call->op );
|
||||
_linphone_call_params_copy ( &call->params,params );
|
||||
linphone_call_make_local_media_description ( lc,call );
|
||||
sal_call_set_local_media_description ( call->op,call->localdesc );
|
||||
|
|
@ -3264,6 +3286,7 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
|
|||
}
|
||||
return _linphone_core_accept_call_update(lc, call, params);
|
||||
}
|
||||
|
||||
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
SalMediaDescription *remote_desc;
|
||||
bool_t keep_sdp_version;
|
||||
|
|
@ -3294,13 +3317,13 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
|
|||
call->params.has_video = FALSE;
|
||||
}
|
||||
call->params.has_video &= linphone_core_media_description_contains_video_stream(remote_desc);
|
||||
linphone_call_init_media_streams(call); /*so that video stream is initialized if necessary*/
|
||||
linphone_call_make_local_media_description(lc,call);
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_core_update_ice_from_remote_media_description(call, remote_desc);
|
||||
#ifdef VIDEO_ENABLED
|
||||
if ((call->ice_session != NULL) &&!ice_session_candidates_gathered(call->ice_session)) {
|
||||
if ((call->ice_session != NULL) && !ice_session_candidates_gathered(call->ice_session)) {
|
||||
if ((call->params.has_video) && (call->params.has_video != old_has_video)) {
|
||||
linphone_call_init_video_stream(call);
|
||||
video_stream_prepare_video(call->videostream);
|
||||
if (linphone_core_gather_ice_candidates(lc,call)<0) {
|
||||
/* Ice candidates gathering failed, proceed with the call anyway. */
|
||||
|
|
@ -3316,7 +3339,6 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
|
|||
linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(call->op));
|
||||
#ifdef VIDEO_ENABLED
|
||||
if ((call->params.has_video) && (call->params.has_video != old_has_video)) {
|
||||
linphone_call_init_video_stream(call);
|
||||
video_stream_prepare_video(call->videostream);
|
||||
if (linphone_core_update_upnp(lc, call)<0) {
|
||||
/* uPnP update failed, proceed with the call anyway. */
|
||||
|
|
@ -3419,9 +3441,6 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
sal_op_set_sent_custom_header(call->op,params->custom_headers);
|
||||
}
|
||||
|
||||
if (call->audiostream==NULL)
|
||||
linphone_call_init_media_streams(call);
|
||||
|
||||
/*give a chance a set card prefered sampling frequency*/
|
||||
if (call->localdesc->streams[0].max_rate>0) {
|
||||
ms_message ("configuring prefered card sampling rate to [%i]",call->localdesc->streams[0].max_rate);
|
||||
|
|
@ -3431,7 +3450,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
ms_snd_card_set_preferred_sample_rate(lc->sound_conf.capt_sndcard, call->localdesc->streams[0].max_rate);
|
||||
}
|
||||
|
||||
if (!was_ringing && call->audiostream->ms.ticker==NULL){
|
||||
if (!was_ringing && call->audiostream->ms.state==MSStreamInitialized){
|
||||
audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
|
||||
}
|
||||
|
||||
|
|
@ -3471,8 +3490,8 @@ int linphone_core_abort_call(LinphoneCore *lc, LinphoneCall *call, const char *e
|
|||
|
||||
static void terminate_call(LinphoneCore *lc, LinphoneCall *call){
|
||||
if (call->state==LinphoneCallIncomingReceived){
|
||||
if (call->reason!=LinphoneReasonNotAnswered)
|
||||
call->reason=LinphoneReasonDeclined;
|
||||
if (call->non_op_error.reason!=SalReasonRequestTimeout)
|
||||
call->non_op_error.reason=SalReasonDeclined;
|
||||
}
|
||||
/*stop ringing*/
|
||||
linphone_core_stop_ringing(lc);
|
||||
|
|
@ -3491,7 +3510,7 @@ static void terminate_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
int linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri){
|
||||
if (call->state==LinphoneCallIncomingReceived){
|
||||
sal_call_decline(call->op,SalReasonRedirect,redirect_uri);
|
||||
call->reason=LinphoneReasonDeclined;
|
||||
sal_error_info_set(&call->non_op_error,SalReasonRedirect,603,"Call redirected",NULL);
|
||||
terminate_call(lc,call);
|
||||
}else{
|
||||
ms_error("Bad state for call redirection.");
|
||||
|
|
@ -4349,6 +4368,10 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){
|
|||
**/
|
||||
void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){
|
||||
sal_set_root_ca(lc->sal, path);
|
||||
if (lc->http_verify_policy){
|
||||
belle_tls_verify_policy_set_root_ca(lc->http_verify_policy,path);
|
||||
}
|
||||
lp_config_set_string(lc->config,"sip","root_ca",path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4359,7 +4382,7 @@ void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){
|
|||
* @ingroup initializing
|
||||
**/
|
||||
const char *linphone_core_get_root_ca(LinphoneCore *lc){
|
||||
return sal_get_root_ca(lc->sal);
|
||||
return lp_config_get_string(lc->config,"sip","root_ca",NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4369,6 +4392,10 @@ const char *linphone_core_get_root_ca(LinphoneCore *lc){
|
|||
**/
|
||||
void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){
|
||||
sal_verify_server_certificates(lc->sal,yesno);
|
||||
if (lc->http_verify_policy){
|
||||
belle_tls_verify_policy_set_exceptions(lc->http_verify_policy, yesno ? 0 : BELLE_TLS_VERIFY_ANY_REASON);
|
||||
}
|
||||
lp_config_set_int(lc->config,"sip","verify_server_certs",yesno);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4377,6 +4404,10 @@ void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){
|
|||
**/
|
||||
void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){
|
||||
sal_verify_server_cn(lc->sal,yesno);
|
||||
if (lc->http_verify_policy){
|
||||
belle_tls_verify_policy_set_exceptions(lc->http_verify_policy, yesno ? 0 : BELLE_TLS_VERIFY_CN_MISMATCH);
|
||||
}
|
||||
lp_config_set_int(lc->config,"sip","verify_server_cn",yesno);
|
||||
}
|
||||
|
||||
static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){
|
||||
|
|
@ -5338,7 +5369,7 @@ void linphone_core_set_play_file(LinphoneCore *lc, const char *file){
|
|||
}
|
||||
if (file!=NULL) {
|
||||
lc->play_file=ms_strdup(file);
|
||||
if (call && call->audiostream && call->audiostream->ms.ticker)
|
||||
if (call && call->audiostream && call->audiostream->ms.state==MSStreamStarted)
|
||||
audio_stream_play(call->audiostream,file);
|
||||
}
|
||||
}
|
||||
|
|
@ -5613,9 +5644,6 @@ void net_config_uninit(LinphoneCore *lc)
|
|||
{
|
||||
net_config_t *config=&lc->net_conf;
|
||||
|
||||
if (lc->http_provider) {
|
||||
belle_sip_object_unref(lc->http_provider);
|
||||
}
|
||||
if (config->stun_server!=NULL){
|
||||
ms_free(config->stun_server);
|
||||
}
|
||||
|
|
@ -5690,6 +5718,14 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
|
||||
sal_reset_transports(lc->sal);
|
||||
sal_unlisten_ports(lc->sal); /*to make sure no new messages are received*/
|
||||
if (lc->http_provider) {
|
||||
belle_sip_object_unref(lc->http_provider);
|
||||
lc->http_provider=NULL;
|
||||
}
|
||||
if (lc->http_verify_policy){
|
||||
belle_sip_object_unref(lc->http_verify_policy);
|
||||
lc->http_verify_policy=NULL;
|
||||
}
|
||||
sal_iterate(lc->sal); /*make sure event are purged*/
|
||||
sal_uninit(lc->sal);
|
||||
lc->sal=NULL;
|
||||
|
|
@ -6153,6 +6189,8 @@ const char *linphone_reason_to_string(LinphoneReason err){
|
|||
return "Bad gateway";
|
||||
case LinphoneReasonServerTimeout:
|
||||
return "Server timeout";
|
||||
case LinphoneReasonUnknown:
|
||||
return "Unknown error";
|
||||
}
|
||||
return "unknown error";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ typedef struct _LinphoneCall LinphoneCall;
|
|||
* Enum describing various failure reasons or contextual information for some events.
|
||||
* @see linphone_call_get_reason()
|
||||
* @see linphone_proxy_config_get_error()
|
||||
* @see linphone_error_info_get_reason()
|
||||
* @ingroup misc
|
||||
**/
|
||||
enum _LinphoneReason{
|
||||
|
|
@ -181,7 +182,8 @@ enum _LinphoneReason{
|
|||
LinphoneReasonAddressIncomplete, /**<Address incomplete*/
|
||||
LinphoneReasonNotImplemented, /**<Not implemented*/
|
||||
LinphoneReasonBadGateway, /**<Bad gateway*/
|
||||
LinphoneReasonServerTimeout /**<Server timeout*/
|
||||
LinphoneReasonServerTimeout, /**<Server timeout*/
|
||||
LinphoneReasonUnknown /**Unknown reason*/
|
||||
};
|
||||
|
||||
#define LinphoneReasonBadCredentials LinphoneReasonForbidden
|
||||
|
|
@ -201,6 +203,18 @@ typedef enum _LinphoneReason LinphoneReason;
|
|||
**/
|
||||
const char *linphone_reason_to_string(LinphoneReason err);
|
||||
|
||||
/**
|
||||
* Object representing full details about a signaling error or status.
|
||||
* All LinphoneErrorInfo object returned by the liblinphone API are readonly and transcients. For safety they must be used immediately
|
||||
* after obtaining them. Any other function call to the liblinphone may change their content or invalidate the pointer.
|
||||
* @ingroup misc
|
||||
**/
|
||||
typedef struct _LinphoneErrorInfo LinphoneErrorInfo;
|
||||
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei);
|
||||
LINPHONE_PUBLIC const char *linphone_error_info_get_phrase(const LinphoneErrorInfo *ei);
|
||||
LINPHONE_PUBLIC const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei);
|
||||
LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei);
|
||||
|
||||
/* linphone dictionary */
|
||||
LINPHONE_PUBLIC LinphoneDictionary* linphone_dictionary_new();
|
||||
|
|
@ -564,6 +578,10 @@ enum _LinphoneUpnpState{
|
|||
typedef enum _LinphoneUpnpState LinphoneUpnpState;
|
||||
|
||||
|
||||
#define LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE (1 << 0) /**< received_rtcp field of LinphoneCallStats object has been updated */
|
||||
#define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */
|
||||
|
||||
|
||||
/**
|
||||
* The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams.
|
||||
*
|
||||
|
|
@ -594,6 +612,7 @@ struct _LinphoneCallStats {
|
|||
float upload_bandwidth; /**<Download bandwidth measurement of sent stream, expressed in kbit/s, including IP/UDP/RTP headers*/
|
||||
float local_late_rate; /**<percentage of packet received too late over last second*/
|
||||
float local_loss_rate; /**<percentage of lost packet over last second*/
|
||||
int updated; /**< Tell which RTCP packet has been updated (received_rtcp or sent_rtcp). Can be either LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE or LINPHONE_CALL_STATS_SENT_RTCP_UPDATE */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -662,6 +681,7 @@ LINPHONE_PUBLIC void linphone_call_enable_camera(LinphoneCall *lc, bool_t enable
|
|||
LINPHONE_PUBLIC bool_t linphone_call_camera_enabled(const LinphoneCall *lc);
|
||||
LINPHONE_PUBLIC int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file);
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
|
||||
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call);
|
||||
LINPHONE_PUBLIC const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC const char *linphone_call_get_remote_contact(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC LinphoneAddress *linphone_call_get_remote_contact_address(LinphoneCall *call);
|
||||
|
|
@ -837,6 +857,13 @@ LINPHONE_PUBLIC const char * linphone_proxy_config_get_dial_prefix(const Linphon
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Get detailed information why registration failed when the proxy config state is LinphoneRegistrationFailed.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @returns The details why registration failed for this proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/*
|
||||
* return the transport from either : service route, route, or addr
|
||||
* @returns cfg object
|
||||
|
|
@ -1002,6 +1029,9 @@ LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, cons
|
|||
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to);
|
||||
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to);
|
||||
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr);
|
||||
LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason);
|
||||
LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_destroy(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message);
|
||||
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming);
|
||||
|
|
@ -1057,6 +1087,7 @@ LINPHONE_PUBLIC bool_t linphone_chat_message_is_read(LinphoneChatMessage* messag
|
|||
LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* message);
|
||||
LINPHONE_PUBLIC unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message);
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg);
|
||||
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
@ -1682,6 +1713,8 @@ LINPHONE_PUBLIC int linphone_core_set_sip_transports(LinphoneCore *lc, const LCS
|
|||
|
||||
LINPHONE_PUBLIC int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *transports);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_get_sip_transports_used(LinphoneCore *lc, LCSipTransports *tr);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp);
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
extern "C" {
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
}
|
||||
#include "mediastreamer2/msjava.h"
|
||||
#include "private.h"
|
||||
|
|
@ -39,6 +40,9 @@ extern "C" void libmsilbc_init();
|
|||
#ifdef HAVE_X264
|
||||
extern "C" void libmsx264_init();
|
||||
#endif
|
||||
#ifdef HAVE_OPENH264
|
||||
extern "C" void libmsopenh264_init();
|
||||
#endif
|
||||
#ifdef HAVE_AMR
|
||||
extern "C" void libmsamr_init();
|
||||
#endif
|
||||
|
|
@ -742,12 +746,17 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv*
|
|||
const char* factoryConfig = jfactoryConfig?env->GetStringUTFChars(jfactoryConfig, NULL):NULL;
|
||||
LinphoneCoreData* ldata = new LinphoneCoreData(env,thiz,jlistener,juserdata);
|
||||
|
||||
ms_init(); // Initialize mediastreamer2 before loading the plugins
|
||||
|
||||
#ifdef HAVE_ILBC
|
||||
libmsilbc_init(); // requires an fpu
|
||||
#endif
|
||||
#ifdef HAVE_X264
|
||||
libmsx264_init();
|
||||
#endif
|
||||
#ifdef HAVE_OPENH264
|
||||
libmsopenh264_init();
|
||||
#endif
|
||||
#ifdef HAVE_AMR
|
||||
libmsamr_init();
|
||||
#endif
|
||||
|
|
@ -776,6 +785,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env
|
|||
,jlong lc) {
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc);
|
||||
linphone_core_destroy((LinphoneCore*)lc);
|
||||
ms_exit();
|
||||
delete lcData;
|
||||
}
|
||||
|
||||
|
|
@ -798,6 +808,10 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCallImpl_sendInfoMessage(J
|
|||
return linphone_call_send_info_message((LinphoneCall*)callptr,(LinphoneInfoMessage*)infoptr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopRinging(JNIEnv* env, jobject thiz, jlong lc) {
|
||||
linphone_core_stop_ringing((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_core_set_chat_database_path((LinphoneCore*)lc, path);
|
||||
|
|
@ -805,8 +819,8 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIE
|
|||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact(JNIEnv* env, jobject thiz, jlong lc, jstring jdisplayname, jstring jusername) {
|
||||
const char* displayname = env->GetStringUTFChars(jdisplayname, NULL);
|
||||
const char* username = env->GetStringUTFChars(jusername, NULL);
|
||||
const char* displayname = jdisplayname ? env->GetStringUTFChars(jdisplayname, NULL) : NULL;
|
||||
const char* username = jusername ? env->GetStringUTFChars(jusername, NULL) : NULL;
|
||||
|
||||
LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed((LinphoneCore*)lc);
|
||||
if (parsed != NULL) {
|
||||
|
|
@ -816,8 +830,8 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact(JNIEnv
|
|||
linphone_core_set_primary_contact((LinphoneCore*)lc, contact);
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(jdisplayname, displayname);
|
||||
env->ReleaseStringUTFChars(jusername, username);
|
||||
if (jdisplayname) env->ReleaseStringUTFChars(jdisplayname, displayname);
|
||||
if (jusername) env->ReleaseStringUTFChars(jusername, username);
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getPrimaryContactUsername(JNIEnv* env, jobject thiz, jlong lc) {
|
||||
|
|
@ -1455,6 +1469,34 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createProxyConfig(JNIEn
|
|||
return (jlong) proxy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_LinphoneCoreImpl
|
||||
* Method: disableChat
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
extern "C" JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_disableChat(JNIEnv *env, jobject jobj, jlong ptr, jint reason){
|
||||
linphone_core_disable_chat((LinphoneCore*)ptr,(LinphoneReason)reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_LinphoneCoreImpl
|
||||
* Method: enableChat
|
||||
* Signature: (J)V
|
||||
*/
|
||||
extern "C" JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_enableChat(JNIEnv *env, jobject jobj, jlong ptr){
|
||||
linphone_core_enable_chat((LinphoneCore*)ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_LinphoneCoreImpl
|
||||
* Method: chatEnabled
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
extern "C" JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_chatEnabled(JNIEnv *env, jobject jobj, jlong ptr){
|
||||
return (jboolean) linphone_core_chat_enabled((LinphoneCore*)ptr);
|
||||
}
|
||||
|
||||
|
||||
//ProxyConfig
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_newLinphoneProxyConfig(JNIEnv* env,jobject thiz) {
|
||||
|
|
@ -1622,6 +1664,10 @@ extern "C" jint Java_org_linphone_core_LinphoneProxyConfigImpl_getError(JNIEnv*
|
|||
return linphone_proxy_config_get_error((LinphoneProxyConfig *) ptr);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_getErrorInfo(JNIEnv* env,jobject thiz,jlong ptr) {
|
||||
return (jlong)linphone_proxy_config_get_error_info((LinphoneProxyConfig *) ptr);
|
||||
}
|
||||
|
||||
//Auth Info
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneAuthInfoImpl_newLinphoneAuthInfo(JNIEnv* env
|
||||
|
|
@ -2074,6 +2120,18 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteAddress( JNIEn
|
|||
return (jlong)linphone_call_get_remote_address((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getErrorInfo( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong)linphone_call_get_error_info((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCallImpl_getReason( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jint)linphone_call_get_reason((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneCallImpl_getRemoteUserAgent(JNIEnv *env, jobject thiz, jlong ptr) {
|
||||
LinphoneCall *call = (LinphoneCall *)ptr;
|
||||
const char *value=linphone_call_get_remote_user_agent(call);
|
||||
|
|
@ -2400,6 +2458,12 @@ extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_getReason(JNIEnv*
|
|||
return linphone_chat_message_get_reason((LinphoneChatMessage*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneChatMessageImpl_getErrorInfo(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong)linphone_chat_message_get_error_info((LinphoneChatMessage*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getCustomHeader(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr, jstring jheader_name) {
|
||||
|
|
@ -3684,6 +3748,11 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_getReason(JNIEnv
|
|||
return linphone_event_get_reason(ev);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_linphone_core_LinphoneEventImpl_getErrorInfo(JNIEnv *env, jobject jobj, jlong evptr){
|
||||
LinphoneEvent *ev=(LinphoneEvent*)evptr;
|
||||
return (jlong)linphone_event_get_error_info(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_LinphoneEventImpl
|
||||
* Method: getSubscriptionDir
|
||||
|
|
@ -4616,4 +4685,49 @@ JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_isSdp200AckEn
|
|||
return (jboolean)linphone_core_sdp_200_ack_enabled((const LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
/* Header for class org_linphone_core_ErrorInfoImpl */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_linphone_core_ErrorInfoImpl
|
||||
* Method: getReason
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_linphone_core_ErrorInfoImpl_getReason(JNIEnv *env, jobject jobj, jlong ei){
|
||||
return linphone_error_info_get_reason((const LinphoneErrorInfo*)ei);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_ErrorInfoImpl
|
||||
* Method: getProtocolCode
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_linphone_core_ErrorInfoImpl_getProtocolCode(JNIEnv *env, jobject jobj, jlong ei){
|
||||
return linphone_error_info_get_protocol_code((const LinphoneErrorInfo*)ei);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_ErrorInfoImpl
|
||||
* Method: getPhrase
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getPhrase(JNIEnv *env, jobject jobj, jlong ei){
|
||||
const char *tmp=linphone_error_info_get_phrase((const LinphoneErrorInfo*)ei);
|
||||
return tmp ? env->NewStringUTF(tmp) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_linphone_core_ErrorInfoImpl
|
||||
* Method: getDetails
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getDetails(JNIEnv *env, jobject jobj, jlong ei){
|
||||
const char *tmp=linphone_error_info_get_details((const LinphoneErrorInfo*)ei);
|
||||
return tmp ? env->NewStringUTF(tmp) : NULL;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -324,8 +324,9 @@ int lp_config_read_file(LpConfig *lpconfig, const char *filename){
|
|||
}
|
||||
|
||||
void lp_item_set_value(LpItem *item, const char *value){
|
||||
ortp_free(item->value);
|
||||
char *prev_value=item->value;
|
||||
item->value=ortp_strdup(value);
|
||||
ortp_free(prev_value);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -375,6 +375,10 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
ms_warning("stun support is not implemented for ipv6");
|
||||
return -1;
|
||||
}
|
||||
if (call->media_ports[0].rtp_port==-1){
|
||||
ms_warning("Stun-only support not available for system random port");
|
||||
return -1;
|
||||
}
|
||||
if (server!=NULL){
|
||||
const struct addrinfo *ai=linphone_core_get_stun_server_addrinfo(lc);
|
||||
ortp_socket_t sock1=-1, sock2=-1;
|
||||
|
|
@ -394,10 +398,10 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
lc->vtable.display_status(lc,_("Stun lookup in progress..."));
|
||||
|
||||
/*create the two audio and video RTP sockets, and send STUN message to our stun server */
|
||||
sock1=create_socket(call->audio_port);
|
||||
sock1=create_socket(call->media_ports[0].rtp_port);
|
||||
if (sock1==-1) return -1;
|
||||
if (video_enabled){
|
||||
sock2=create_socket(call->video_port);
|
||||
sock2=create_socket(call->media_ports[1].rtp_port);
|
||||
if (sock2==-1) return -1;
|
||||
}
|
||||
got_audio=FALSE;
|
||||
|
|
@ -581,14 +585,14 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
|
|||
return -1;
|
||||
}
|
||||
if ((ice_check_list_state(audio_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(audio_check_list) == FALSE)) {
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port, 1, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port + 1, 2, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtcp_port, 2, NULL);
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
|
||||
}
|
||||
if (call->params.has_video && (video_check_list != NULL)
|
||||
if (linphone_core_video_enabled(lc) && (video_check_list != NULL)
|
||||
&& (ice_check_list_state(video_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(video_check_list) == FALSE)) {
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port, 1, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtp_port, 1, NULL);
|
||||
ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtcp_port, 2, NULL);
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
|
||||
}
|
||||
|
||||
|
|
@ -883,7 +887,12 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
}
|
||||
}
|
||||
for (i = ice_session_nb_check_lists(call->ice_session); i > md->n_active_streams; i--) {
|
||||
ice_session_remove_check_list(call->ice_session, ice_session_check_list(call->ice_session, i - 1));
|
||||
IceCheckList *removed=ice_session_check_list(call->ice_session, i - 1);
|
||||
ice_session_remove_check_list(call->ice_session, removed);
|
||||
if (call->audiostream && call->audiostream->ms.ice_check_list==removed)
|
||||
call->audiostream->ms.ice_check_list=NULL;
|
||||
if (call->videostream && call->videostream->ms.ice_check_list==removed)
|
||||
call->videostream->ms.ice_check_list=NULL;
|
||||
}
|
||||
ice_session_check_mismatch(call->ice_session);
|
||||
} else {
|
||||
|
|
@ -1100,9 +1109,9 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
|
|||
SalReason linphone_reason_to_sal(LinphoneReason reason){
|
||||
switch(reason){
|
||||
case LinphoneReasonNone:
|
||||
return SalReasonUnknown;
|
||||
return SalReasonNone;
|
||||
case LinphoneReasonNoResponse:
|
||||
return SalReasonUnknown;
|
||||
return SalReasonRequestTimeout;
|
||||
case LinphoneReasonForbidden:
|
||||
return SalReasonForbidden;
|
||||
case LinphoneReasonDeclined:
|
||||
|
|
@ -1139,6 +1148,8 @@ SalReason linphone_reason_to_sal(LinphoneReason reason){
|
|||
return SalReasonServerTimeout;
|
||||
case LinphoneReasonNotAnswered:
|
||||
return SalReasonRequestTimeout;
|
||||
case LinphoneReasonUnknown:
|
||||
return SalReasonUnknown;
|
||||
}
|
||||
return SalReasonUnknown;
|
||||
}
|
||||
|
|
@ -1146,9 +1157,15 @@ SalReason linphone_reason_to_sal(LinphoneReason reason){
|
|||
LinphoneReason linphone_reason_from_sal(SalReason r){
|
||||
LinphoneReason ret=LinphoneReasonNone;
|
||||
switch(r){
|
||||
case SalReasonUnknown:
|
||||
case SalReasonNone:
|
||||
ret=LinphoneReasonNone;
|
||||
break;
|
||||
case SalReasonIOError:
|
||||
ret=LinphoneReasonIOError;
|
||||
break;
|
||||
case SalReasonUnknown:
|
||||
ret=LinphoneReasonUnknown;
|
||||
break;
|
||||
case SalReasonBusy:
|
||||
ret=LinphoneReasonBusy;
|
||||
break;
|
||||
|
|
@ -1213,6 +1230,52 @@ LinphoneReason linphone_reason_from_sal(SalReason r){
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reason code from the error info.
|
||||
* @param ei the error info.
|
||||
* @return a #LinphoneReason
|
||||
* @ingroup misc
|
||||
**/
|
||||
LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei){
|
||||
const SalErrorInfo *sei=(const SalErrorInfo*)ei;
|
||||
return linphone_reason_from_sal(sei->reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get textual phrase from the error info.
|
||||
* This is the text that is provided by the peer in the protocol (SIP).
|
||||
* @param ei the error info.
|
||||
* @return the error phrase
|
||||
* @ingroup misc
|
||||
**/
|
||||
const char *linphone_error_info_get_phrase(const LinphoneErrorInfo *ei){
|
||||
const SalErrorInfo *sei=(const SalErrorInfo*)ei;
|
||||
return sei->status_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides additional information regarding the failure.
|
||||
* With SIP protocol, the "Reason" and "Warning" headers are returned.
|
||||
* @param ei the error info.
|
||||
* @return more details about the failure.
|
||||
* @ingroup misc
|
||||
**/
|
||||
const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei){
|
||||
const SalErrorInfo *sei=(const SalErrorInfo*)ei;
|
||||
return sei->warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status code from the low level protocol (ex a SIP status code).
|
||||
* @param ei the error info.
|
||||
* @return the status code.
|
||||
* @ingroup misc
|
||||
**/
|
||||
int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei){
|
||||
const SalErrorInfo *sei=(const SalErrorInfo*)ei;
|
||||
return sei->protocol_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the mediastreamer2 filter to be used for rendering video.
|
||||
* This is for advanced users of the library, mainly to workaround hardware/driver bugs.
|
||||
|
|
@ -1308,7 +1371,7 @@ int linphone_core_migrate_to_multi_transport(LinphoneCore *lc){
|
|||
newtp.udp_port=port;
|
||||
newtp.tcp_port=port;
|
||||
newtp.tls_port=LC_SIP_TRANSPORT_RANDOM;
|
||||
lp_config_set_string(lc->config, "sip","sip_random_port",NULL); //remove
|
||||
lp_config_set_string(lc->config, "sip","sip_random_port",NULL); /*remove*/
|
||||
linphone_core_set_sip_transports(lc,&newtp);
|
||||
}
|
||||
lp_config_set_int(lc->config,"sip","multi_transport_migration_done",1);
|
||||
|
|
|
|||
|
|
@ -273,16 +273,17 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
const SalMediaDescription *remote_answer,
|
||||
SalMediaDescription *result){
|
||||
int i,j;
|
||||
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
for(i=0,j=0;i<local_offer->n_total_streams;++i){
|
||||
ms_message("Processing for stream %i",i);
|
||||
ls=&local_offer->streams[i];
|
||||
rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type);
|
||||
if (rs) {
|
||||
initiate_outgoing(ls,rs,&result->streams[j]);
|
||||
memcpy(&result->streams[i].rtcp_xr, &ls->rtcp_xr, sizeof(result->streams[i].rtcp_xr));
|
||||
if ((ls->rtcp_xr.enabled == TRUE) && (rs->rtcp_xr.enabled == FALSE)) {
|
||||
memset(&result->streams[j].rtcp_xr, 0, sizeof(result->streams[j].rtcp_xr));
|
||||
result->streams[i].rtcp_xr.enabled = FALSE;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
|
@ -292,8 +293,9 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
result->n_total_streams=local_offer->n_total_streams;
|
||||
result->bandwidth=remote_answer->bandwidth;
|
||||
strcpy(result->addr,remote_answer->addr);
|
||||
memcpy(&result->rtcp_xr, &local_offer->rtcp_xr, sizeof(result->rtcp_xr));
|
||||
if ((local_offer->rtcp_xr.enabled == TRUE) && (remote_answer->rtcp_xr.enabled == FALSE)) {
|
||||
memset(&result->rtcp_xr, 0, sizeof(result->rtcp_xr));
|
||||
result->rtcp_xr.enabled = FALSE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -352,10 +354,11 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
// Handle media RTCP XR attribute
|
||||
memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr));
|
||||
if (rs->rtcp_xr.enabled == TRUE) {
|
||||
if (ls->rtcp_xr.enabled == TRUE) {
|
||||
memcpy(&result->streams[i].rtcp_xr, &ls->rtcp_xr, sizeof(result->streams[i].rtcp_xr));
|
||||
} else if (local_capabilities->rtcp_xr.enabled == TRUE) {
|
||||
memcpy(&result->streams[i].rtcp_xr, &local_capabilities->rtcp_xr, sizeof(result->streams[i].rtcp_xr));
|
||||
const OrtpRtcpXrConfiguration *rtcp_xr_conf = NULL;
|
||||
if (ls->rtcp_xr.enabled == TRUE) rtcp_xr_conf = &ls->rtcp_xr;
|
||||
else if (local_capabilities->rtcp_xr.enabled == TRUE) rtcp_xr_conf = &local_capabilities->rtcp_xr;
|
||||
if ((rtcp_xr_conf != NULL) && (ls->dir == SalStreamSendRecv)) {
|
||||
memcpy(&result->streams[i].rtcp_xr, rtcp_xr_conf, sizeof(result->streams[i].rtcp_xr));
|
||||
} else {
|
||||
result->streams[i].rtcp_xr.enabled = TRUE;
|
||||
}
|
||||
|
|
@ -385,11 +388,13 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
strcpy(result->ice_ufrag, local_capabilities->ice_ufrag);
|
||||
result->ice_lite = local_capabilities->ice_lite;
|
||||
result->ice_completed = local_capabilities->ice_completed;
|
||||
|
||||
strcpy(result->name,local_capabilities->name);
|
||||
|
||||
// Handle session RTCP XR attribute
|
||||
memset(&result->rtcp_xr, 0, sizeof(result->rtcp_xr));
|
||||
if (remote_offer->rtcp_xr.enabled == TRUE) {
|
||||
if (local_capabilities->rtcp_xr.enabled == TRUE) {
|
||||
if ((local_capabilities->rtcp_xr.enabled == TRUE) && (local_capabilities->dir == SalStreamSendRecv)) {
|
||||
memcpy(&result->rtcp_xr, &local_capabilities->rtcp_xr, sizeof(result->rtcp_xr));
|
||||
} else {
|
||||
result->rtcp_xr.enabled = TRUE;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ struct _LinphoneChatMessage {
|
|||
LinphoneChatMessageState state;
|
||||
bool_t is_read;
|
||||
unsigned int storage_id;
|
||||
LinphoneReason reason;
|
||||
SalOp *op;
|
||||
};
|
||||
|
||||
typedef struct StunCandidate{
|
||||
|
|
@ -155,10 +155,16 @@ typedef struct StunCandidate{
|
|||
}StunCandidate;
|
||||
|
||||
|
||||
typedef struct _PortConfig{
|
||||
int rtp_port;
|
||||
int rtcp_port;
|
||||
}PortConfig;
|
||||
|
||||
struct _LinphoneCall
|
||||
{
|
||||
int magic; /*used to distinguish from proxy config*/
|
||||
struct _LinphoneCore *core;
|
||||
SalErrorInfo non_op_error;
|
||||
int af; /*the address family to prefer for RTP path, guessed from signaling path*/
|
||||
LinphoneCallDir dir;
|
||||
SalMediaDescription *biggestdesc; /*media description with all already proposed streams, used to remember the mapping of streams*/
|
||||
|
|
@ -174,12 +180,11 @@ struct _LinphoneCall
|
|||
LinphoneCallState state;
|
||||
LinphoneCallState prevstate;
|
||||
LinphoneCallState transfer_state; /*idle if no transfer*/
|
||||
LinphoneReason reason;
|
||||
LinphoneProxyConfig *dest_proxy;
|
||||
int refcnt;
|
||||
void * user_pointer;
|
||||
int audio_port;
|
||||
int video_port;
|
||||
PortConfig media_ports[2];
|
||||
MSMediaStreamSessions sessions[2]; /*the rtp, srtp, zrtp contexts for each stream*/
|
||||
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
|
|
@ -204,7 +209,7 @@ struct _LinphoneCall
|
|||
unsigned int remote_session_ver;
|
||||
LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/
|
||||
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
|
||||
int localdesc_changed;
|
||||
int localdesc_changed;/*not a boolean, contains a mask representing changes*/
|
||||
|
||||
bool_t refer_pending;
|
||||
bool_t expect_media_in_ack;
|
||||
|
|
@ -373,7 +378,6 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
|
|||
void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md);
|
||||
extern SalCallbacks linphone_sal_callbacks;
|
||||
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg, LinphoneReason error);
|
||||
bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
|
||||
|
||||
LinphoneCall * is_a_linphone_call(void *user_pointer);
|
||||
|
|
@ -413,7 +417,6 @@ struct _LinphoneProxyConfig
|
|||
bool_t pad[3];
|
||||
void* user_data;
|
||||
time_t deletion_date;
|
||||
LinphoneReason error;
|
||||
LinphonePrivacyMask privacy;
|
||||
};
|
||||
|
||||
|
|
@ -682,7 +685,9 @@ struct _LinphoneCore
|
|||
UpnpContext *upnp;
|
||||
#endif //BUILD_UPNP
|
||||
belle_http_provider_t *http_provider;
|
||||
belle_tls_verify_policy_t *http_verify_policy;
|
||||
MSList *tones;
|
||||
LinphoneReason chat_deny_code;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -693,7 +698,6 @@ struct _LinphoneEvent{
|
|||
SalCustomHeader *send_custom_headers;
|
||||
LinphoneSubscriptionState subscription_state;
|
||||
LinphonePublishState publish_state;
|
||||
LinphoneReason reason;
|
||||
void *userdata;
|
||||
int refcnt;
|
||||
char *name;
|
||||
|
|
@ -806,7 +810,6 @@ LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir,
|
|||
LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name);
|
||||
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state);
|
||||
void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state);
|
||||
void linphone_event_set_reason(LinphoneEvent *lev, LinphoneReason reason);
|
||||
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
|
||||
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
|
|
@ -847,6 +850,10 @@ char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *
|
|||
void linphone_free_xml_text_content(const char *text);
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
|
||||
static inline const LinphoneErrorInfo *linphone_error_info_from_sal_op(const SalOp *op){
|
||||
if (op==NULL) return (LinphoneErrorInfo*)sal_error_info_none();
|
||||
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
|
||||
}
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1368,11 +1368,11 @@ LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyCon
|
|||
}
|
||||
|
||||
LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) {
|
||||
return cfg->error;
|
||||
return linphone_error_info_get_reason(linphone_proxy_config_get_error_info(cfg));
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg,LinphoneReason error) {
|
||||
cfg->error = error;
|
||||
const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg){
|
||||
return linphone_error_info_from_sal_op(cfg->op);
|
||||
}
|
||||
|
||||
const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg) {
|
||||
|
|
|
|||
|
|
@ -52,11 +52,32 @@ static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml
|
|||
}
|
||||
}
|
||||
|
||||
static int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){
|
||||
int status = -1;
|
||||
FILE* f = fopen(file_path, "r");
|
||||
|
||||
if( f ){
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char* provisioning = ms_malloc(fsize + 1);
|
||||
fread(provisioning, fsize, 1, f);
|
||||
fclose(f);
|
||||
linphone_remote_provisioning_apply(lc, provisioning);
|
||||
status = 0;
|
||||
} else {
|
||||
ms_error("Couldn't open file %s for provisioning", file_path);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void belle_request_process_response_event(void *ctx, const belle_http_response_event_t *event) {
|
||||
LinphoneCore *lc = (LinphoneCore *)ctx;
|
||||
belle_sip_message_t *body = BELLE_SIP_MESSAGE(event->response);
|
||||
const char *message = belle_sip_message_get_body(body);
|
||||
|
||||
|
||||
if (belle_http_response_get_status_code(event->response) == 200) {
|
||||
linphone_remote_provisioning_apply(lc, message);
|
||||
} else {
|
||||
|
|
@ -80,23 +101,31 @@ static void belle_request_process_auth_requested(void *ctx, belle_sip_auth_event
|
|||
}
|
||||
|
||||
int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri) {
|
||||
belle_generic_uri_t *uri=belle_generic_uri_parse(remote_provisioning_uri);
|
||||
belle_http_request_listener_callbacks_t belle_request_listener = {
|
||||
belle_request_process_response_event,
|
||||
belle_request_process_io_error,
|
||||
belle_request_process_timeout,
|
||||
belle_request_process_auth_requested
|
||||
};
|
||||
belle_http_request_listener_t *listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc);
|
||||
belle_http_request_t *request;
|
||||
|
||||
if (uri==NULL) {
|
||||
belle_sip_error("Invalid provisioning URI [%s]",remote_provisioning_uri);
|
||||
return -1;
|
||||
const char* file_path = strstr(remote_provisioning_uri, "file://");
|
||||
|
||||
if( file_path == remote_provisioning_uri ){
|
||||
// We allow for 'local remote-provisioning' in case the file is to be opened from the hard drive
|
||||
file_path += strlen("file://");
|
||||
return linphone_remote_provisioning_load_file(lc, file_path);
|
||||
} else {
|
||||
belle_generic_uri_t *uri=belle_generic_uri_parse(remote_provisioning_uri);
|
||||
belle_http_request_listener_callbacks_t belle_request_listener = {
|
||||
belle_request_process_response_event,
|
||||
belle_request_process_io_error,
|
||||
belle_request_process_timeout,
|
||||
belle_request_process_auth_requested
|
||||
};
|
||||
belle_http_request_listener_t *listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc);
|
||||
belle_http_request_t *request;
|
||||
|
||||
if (uri==NULL) {
|
||||
belle_sip_error("Invalid provisioning URI [%s]",remote_provisioning_uri);
|
||||
return -1;
|
||||
}
|
||||
request=belle_http_request_create("GET",uri, NULL);
|
||||
belle_http_provider_send_request(lc->http_provider, request, listener);
|
||||
return 0;
|
||||
}
|
||||
request=belle_http_request_create("GET",uri, NULL);
|
||||
belle_http_provider_send_request(lc->http_provider, request, listener);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_core_set_provisioning_uri(LinphoneCore *lc, const char *uri) {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ UI_FILES= about.ui \
|
|||
call_statistics.ui \
|
||||
ldap.ui \
|
||||
config-uri.ui \
|
||||
provisioning-fetch.ui
|
||||
provisioning-fetch.ui \
|
||||
audio_assistant.ui
|
||||
|
||||
PIXMAPS= \
|
||||
stock_people.png
|
||||
|
|
@ -52,6 +53,7 @@ linphone_SOURCES= \
|
|||
singleinstance.c \
|
||||
conference.c \
|
||||
config-fetching.c \
|
||||
audio_assistant.c \
|
||||
linphone.h
|
||||
if BUILD_WIZARD
|
||||
linphone_SOURCES+= \
|
||||
|
|
|
|||
469
gtk/audio_assistant.c
Normal file
469
gtk/audio_assistant.c
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
linphone, gtk-glade interface.
|
||||
Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "linphone.h"
|
||||
#include "linphonecore_utils.h"
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "mediastreamer2/msvolume.h"
|
||||
|
||||
static GtkWidget *audio_assistant=NULL;
|
||||
static void prepare(GtkAssistant *w);
|
||||
|
||||
GtkWidget *get_widget_from_assistant(const char *name){
|
||||
return (GtkWidget *)g_object_get_data(G_OBJECT(audio_assistant),name);
|
||||
}
|
||||
|
||||
static void set_widget_to_assistant(const char *name,GtkWidget *w){
|
||||
g_object_set_data(G_OBJECT(audio_assistant),name,w);
|
||||
}
|
||||
|
||||
static void update_record_button(gboolean is_visible){
|
||||
GtkWidget *rec_button = get_widget_from_assistant("rec_button");
|
||||
gtk_widget_set_sensitive(rec_button,is_visible);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void activate_record_button(gboolean is_active){
|
||||
GtkWidget *rec_button = get_widget_from_assistant("rec_button");
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rec_button),is_active);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void update_play_button(gboolean is_visible){
|
||||
GtkWidget *play_button = get_widget_from_assistant("play_button");
|
||||
gtk_widget_set_sensitive(play_button,is_visible);
|
||||
}
|
||||
|
||||
static void activate_play_button(gboolean is_active){
|
||||
GtkWidget *play_button = get_widget_from_assistant("play_button");
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button),is_active);
|
||||
}
|
||||
|
||||
static gchar *get_record_file(){
|
||||
char filename[256]={0};
|
||||
char date[64]={0};
|
||||
time_t curtime=time(NULL);
|
||||
struct tm loctime;
|
||||
|
||||
#ifdef WIN32
|
||||
loctime=*localtime(&curtime);
|
||||
#else
|
||||
localtime_r(&curtime,&loctime);
|
||||
#endif
|
||||
snprintf(date,sizeof(date)-1,"%i%02i%02i-%02i%02i%2i",loctime.tm_year+1900,loctime.tm_mon+1,loctime.tm_mday, loctime.tm_hour, loctime.tm_min, loctime.tm_sec);
|
||||
|
||||
snprintf(filename,sizeof(filename)-1,"record-%s.wav",date);
|
||||
return g_build_path(G_DIR_SEPARATOR_S,g_get_tmp_dir(),filename,NULL);;
|
||||
}
|
||||
|
||||
static float audio_stream_get_record_volume(AudioStream *st){
|
||||
if (st && st->volsend){
|
||||
float vol=0;
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_GET,&vol);
|
||||
return vol;
|
||||
}
|
||||
return LINPHONE_VOLUME_DB_LOWEST;
|
||||
}
|
||||
|
||||
static float audio_stream_get_max_volume(AudioStream *st){
|
||||
if (st && st->volsend){
|
||||
float vol=0;
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_GET_MAX,&vol);
|
||||
return vol;
|
||||
}
|
||||
return LINPHONE_VOLUME_DB_LOWEST;
|
||||
}
|
||||
|
||||
static gboolean update_audio_label(volume_ctx_t *ctx){
|
||||
float volume_db=ctx->get_volume(ctx->data);
|
||||
gchar *result;
|
||||
if (volume_db < -20) result = _("No voice detected");
|
||||
else if (volume_db <= -10) result = _("Too low");
|
||||
else if (volume_db < -6) result = _("Good");
|
||||
else result = _("Too loud");
|
||||
g_message("volume_max_db=%f, text=%s",volume_db,result);
|
||||
gtk_label_set_text(GTK_LABEL(ctx->widget),result);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_audio_label_destroy(guint task_id){
|
||||
g_source_remove(task_id);
|
||||
}
|
||||
|
||||
void linphone_gtk_init_audio_label(GtkWidget *w, get_volume_t get_volume, void *data){
|
||||
guint task_id=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"task_id_t"));
|
||||
if (task_id==0){
|
||||
volume_ctx_t *ctx=g_new(volume_ctx_t,1);
|
||||
ctx->widget=w;
|
||||
ctx->get_volume=get_volume;
|
||||
ctx->data=data;
|
||||
ctx->last_value=0;
|
||||
g_object_set_data_full(G_OBJECT(w),"ctx_t",ctx,g_free);
|
||||
task_id=g_timeout_add(200,(GSourceFunc)update_audio_label,ctx);
|
||||
g_object_set_data_full(G_OBJECT(w),"task_id_t",GINT_TO_POINTER(task_id),(GDestroyNotify)on_audio_label_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_uninit_audio_label(GtkWidget *w){
|
||||
guint task_id=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"task_id_t"));
|
||||
if (task_id!=0){
|
||||
g_object_set_data(G_OBJECT(w),"ctx_t",NULL);
|
||||
g_object_set_data(G_OBJECT(w),"task_id_t",NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void playback_device_changed(GtkWidget *w){
|
||||
gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));
|
||||
linphone_core_set_playback_device(linphone_gtk_get_core(),sel);
|
||||
g_free(sel);
|
||||
}
|
||||
|
||||
static void capture_device_changed(GtkWidget *capture_device){
|
||||
gchar *sel;
|
||||
GtkWidget *mic_audiolevel;
|
||||
GtkWidget *label_audiolevel;
|
||||
GtkWidget *assistant=gtk_widget_get_toplevel(capture_device);
|
||||
AudioStream *audio_stream;
|
||||
|
||||
mic_audiolevel = get_widget_from_assistant("mic_audiolevel");
|
||||
label_audiolevel = get_widget_from_assistant("label_audiolevel");
|
||||
audio_stream = (AudioStream *) g_object_get_data(G_OBJECT(assistant),"stream");
|
||||
sel = gtk_combo_box_get_active_text(GTK_COMBO_BOX(capture_device));
|
||||
linphone_core_set_capture_device(linphone_gtk_get_core(),sel);
|
||||
linphone_gtk_uninit_audio_meter(mic_audiolevel);
|
||||
linphone_gtk_uninit_audio_label(label_audiolevel);
|
||||
audio_stream_stop(audio_stream);
|
||||
g_free(sel);
|
||||
/*now restart the audio stream*/
|
||||
prepare(GTK_ASSISTANT(assistant));
|
||||
}
|
||||
|
||||
static void dialog_click(GtkWidget *dialog, guint response_id, GtkWidget *page){
|
||||
switch(response_id){
|
||||
case GTK_RESPONSE_YES:
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(audio_assistant),page,TRUE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data){
|
||||
ms_message("echo calibration finished %s.",status==LinphoneEcCalibratorDone ? "successfully" : "with faillure");
|
||||
if (status==LinphoneEcCalibratorDone) ms_message("Measured delay is %i",delay);
|
||||
|
||||
GtkWidget * dialog;
|
||||
GtkWidget *speaker_page = get_widget_from_assistant("speaker_page");
|
||||
|
||||
dialog = gtk_message_dialog_new (
|
||||
GTK_WINDOW(audio_assistant),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_YES_NO,
|
||||
"%s","Did you hear three beeps ?");
|
||||
|
||||
g_signal_connect(G_OBJECT (dialog), "response",
|
||||
G_CALLBACK (dialog_click),speaker_page);
|
||||
gtk_widget_show(dialog);
|
||||
}
|
||||
|
||||
void linphone_gtk_start_sound(GtkWidget *w){
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
linphone_core_start_echo_calibration(lc,calibration_finished,NULL,NULL,NULL);
|
||||
}
|
||||
|
||||
static gboolean linphone_gtk_stop_record(gpointer data){
|
||||
AudioStream *stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant),"record_stream");
|
||||
if(stream != NULL){
|
||||
audio_stream_stop(stream);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"record_stream",NULL);
|
||||
}
|
||||
update_record_button(FALSE);
|
||||
update_play_button(TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void linphone_gtk_start_record_sound(GtkWidget *w, gpointer data){
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
AudioStream *stream = NULL;
|
||||
MSSndCardManager *manager = ms_snd_card_manager_get();
|
||||
gboolean active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
|
||||
|
||||
if(active){
|
||||
gchar *path = get_record_file();
|
||||
stream=audio_stream_new(8888, 8889, FALSE);
|
||||
if(stream != NULL){
|
||||
audio_stream_start_full(stream,&av_profile,"127.0.0.1",8888,"127.0.0.1",8889,0,0,NULL,
|
||||
path,NULL,ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"record_stream",stream);
|
||||
}
|
||||
gint timeout_id = gtk_timeout_add(6000,(GtkFunction)linphone_gtk_stop_record,NULL);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"timeout_id",GINT_TO_POINTER(timeout_id));
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"path",path);
|
||||
} else {
|
||||
stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant),"record_stream");
|
||||
gint timeout_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(audio_assistant),"timeout_id"));
|
||||
gtk_timeout_remove(timeout_id);
|
||||
if(stream != NULL){
|
||||
audio_stream_stop(stream);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"record_stream",NULL);
|
||||
}
|
||||
update_record_button(FALSE);
|
||||
update_play_button(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void endoffile_cb(void *ud, MSFilter *f, unsigned int ev,void * arg){
|
||||
switch (ev) {
|
||||
case MS_PLAYER_EOF: {
|
||||
ms_message("EndOfFile received");
|
||||
activate_play_button(FALSE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_start_play_record_sound(GtkWidget *w,gpointer data){
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
gboolean active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
|
||||
AudioStream *stream = NULL;
|
||||
MSSndCardManager *manager = ms_snd_card_manager_get();
|
||||
|
||||
if(active){
|
||||
gchar *path = g_object_get_data(G_OBJECT(audio_assistant),"path");
|
||||
stream=audio_stream_new(8888, 8889, FALSE);
|
||||
if(path != NULL){
|
||||
audio_stream_start_full(stream,&av_profile,"127.0.0.1",8888,"127.0.0.1",8889,0,0,path,
|
||||
NULL,ms_snd_card_manager_get_card(manager,linphone_core_get_playback_device(lc)),NULL,FALSE);
|
||||
ms_filter_add_notify_callback(stream->soundread,endoffile_cb,stream,FALSE);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"play_stream",stream);
|
||||
}
|
||||
} else {
|
||||
stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant),"play_stream");
|
||||
if(stream != NULL){
|
||||
audio_stream_stop(stream);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"play_stream",NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *create_intro(){
|
||||
GtkWidget *vbox=gtk_vbox_new(FALSE,2);
|
||||
GtkWidget *label=gtk_label_new(_("Welcome !\nThis assistant will help you to configure audio settings for Linphone"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
|
||||
gtk_widget_show_all(vbox);
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static GtkWidget *create_mic_page(){
|
||||
GtkWidget *vbox=gtk_table_new(3,2,FALSE);
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
|
||||
GtkWidget *labelMicChoice=gtk_label_new(_("Capture device"));
|
||||
GtkWidget *labelMicLevel=gtk_label_new(_("Recorded volume"));
|
||||
GtkWidget *mic_audiolevel=gtk_progress_bar_new();
|
||||
GtkWidget *capture_device=gtk_combo_box_new();
|
||||
GtkWidget *box = gtk_vbox_new(FALSE,0);
|
||||
GtkWidget *label_audiolevel=gtk_label_new(_("No voice"));
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(box),mic_audiolevel,TRUE,TRUE,1);
|
||||
gtk_box_pack_start(GTK_BOX(box),label_audiolevel,FALSE,FALSE,1);
|
||||
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelMicChoice, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), capture_device, 1, 2, 0, 1);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelMicLevel, 0, 1, 1, 2);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), box, 1, 2, 1, 2);
|
||||
|
||||
gtk_table_set_row_spacings(GTK_TABLE(vbox),10);
|
||||
|
||||
set_widget_to_assistant("mic_audiolevel",mic_audiolevel);
|
||||
set_widget_to_assistant("label_audiolevel",label_audiolevel);
|
||||
|
||||
const char **sound_devices=linphone_core_get_sound_devices(lc);
|
||||
linphone_gtk_fill_combo_box(capture_device, sound_devices,
|
||||
linphone_core_get_capture_device(lc), CAP_CAPTURE);
|
||||
gtk_widget_show_all(vbox);
|
||||
|
||||
g_signal_connect(G_OBJECT(capture_device),"changed",(GCallback)capture_device_changed,capture_device);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static GtkWidget *create_speaker_page(){
|
||||
GtkWidget *vbox=gtk_table_new(2,2,FALSE);
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
|
||||
GtkWidget *labelSpeakerChoice=gtk_label_new(_("Playback device"));
|
||||
GtkWidget *labelSpeakerLevel=gtk_label_new(_("Play three beeps"));
|
||||
GtkWidget *spk_button=gtk_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
|
||||
GtkWidget *playback_device=gtk_combo_box_new();
|
||||
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelSpeakerChoice, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), playback_device, 1, 2, 0, 1);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelSpeakerLevel, 0, 1, 1, 2);
|
||||
gtk_table_attach(GTK_TABLE(vbox), spk_button, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0,0);
|
||||
|
||||
gtk_table_set_row_spacings(GTK_TABLE(vbox),10);
|
||||
|
||||
const char **sound_devices=linphone_core_get_sound_devices(lc);
|
||||
linphone_gtk_fill_combo_box(playback_device, sound_devices,
|
||||
linphone_core_get_playback_device(lc),CAP_PLAYBACK);
|
||||
gtk_widget_show_all(vbox);
|
||||
|
||||
set_widget_to_assistant("speaker_page",vbox);
|
||||
g_signal_connect(G_OBJECT(playback_device),"changed",(GCallback)playback_device_changed,playback_device);
|
||||
g_signal_connect(G_OBJECT(spk_button),"clicked",(GCallback)linphone_gtk_start_sound,vbox);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static GtkWidget *create_play_record_page(){
|
||||
GtkWidget *vbox=gtk_table_new(2,2,FALSE);
|
||||
GtkWidget *labelRecord=gtk_label_new(_("Press the record button and say some words"));
|
||||
GtkWidget *labelPlay=gtk_label_new(_("Listen to your record voice"));
|
||||
GtkWidget *rec_button=gtk_toggle_button_new_with_label("Record");
|
||||
GtkWidget *play_button=gtk_toggle_button_new_with_label("Play");
|
||||
GtkWidget *image;
|
||||
|
||||
image=gtk_image_new_from_stock(GTK_STOCK_MEDIA_RECORD,GTK_ICON_SIZE_MENU);
|
||||
gtk_button_set_image(GTK_BUTTON(rec_button),image);
|
||||
|
||||
image=gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY,GTK_ICON_SIZE_MENU);
|
||||
gtk_button_set_image(GTK_BUTTON(play_button),image);
|
||||
gtk_widget_set_sensitive(play_button,FALSE);
|
||||
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelRecord, 0, 1, 0, 1);
|
||||
gtk_table_attach(GTK_TABLE(vbox), rec_button, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0,0);
|
||||
gtk_table_attach_defaults(GTK_TABLE(vbox), labelPlay, 0, 1, 1, 2);
|
||||
gtk_table_attach(GTK_TABLE(vbox), play_button, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0,0);
|
||||
|
||||
gtk_widget_show_all(vbox);
|
||||
|
||||
set_widget_to_assistant("rec_button",rec_button);
|
||||
set_widget_to_assistant("play_button",play_button);
|
||||
g_signal_connect(G_OBJECT(rec_button),"toggled",(GCallback)linphone_gtk_start_record_sound,vbox);
|
||||
g_signal_connect(G_OBJECT(play_button),"toggled",(GCallback)linphone_gtk_start_play_record_sound,vbox);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static GtkWidget *create_end_page(){
|
||||
GtkWidget *vbox=gtk_vbox_new(FALSE,2);
|
||||
GtkWidget *label=gtk_label_new(_("Let's start Linphone now"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
|
||||
gtk_widget_show_all(vbox);
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static void prepare(GtkAssistant *w){
|
||||
AudioStream *audio_stream = NULL;
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
int page = gtk_assistant_get_current_page(w);
|
||||
GtkWidget *mic_audiolevel = get_widget_from_assistant("mic_audiolevel");
|
||||
GtkWidget *label_audiolevel = get_widget_from_assistant("label_audiolevel");
|
||||
|
||||
//Speaker page
|
||||
if(page == 1){
|
||||
MSSndCardManager *manager = ms_snd_card_manager_get();
|
||||
audio_stream = audio_stream_start_with_sndcards(&av_profile,9898,"127.0.0.1",19898,0,0,ms_snd_card_manager_get_card(manager,linphone_core_get_playback_device(lc)),ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
|
||||
if (mic_audiolevel != NULL && audio_stream != NULL){
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"stream",audio_stream);
|
||||
linphone_gtk_init_audio_meter(mic_audiolevel,(get_volume_t)audio_stream_get_record_volume,audio_stream);
|
||||
linphone_gtk_init_audio_label(label_audiolevel,(get_volume_t)audio_stream_get_max_volume,audio_stream);
|
||||
}
|
||||
} else if(page == 2 || page == 0){
|
||||
if(mic_audiolevel != NULL && label_audiolevel != NULL){
|
||||
audio_stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant),"stream");
|
||||
if(audio_stream != NULL){
|
||||
linphone_gtk_uninit_audio_meter(mic_audiolevel);
|
||||
linphone_gtk_uninit_audio_label(label_audiolevel);
|
||||
audio_stream_stop(audio_stream);
|
||||
g_object_set_data(G_OBJECT(audio_assistant),"stream",NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_close_audio_assistant(GtkWidget *w){
|
||||
gchar *path = g_object_get_data(G_OBJECT(audio_assistant),"path");
|
||||
if(path != NULL){
|
||||
g_unlink(path);
|
||||
}
|
||||
gtk_widget_destroy(w);
|
||||
if(linphone_gtk_get_audio_assistant_option()){
|
||||
gtk_main_quit();
|
||||
}
|
||||
audio_assistant = NULL;
|
||||
}
|
||||
|
||||
void linphone_gtk_audio_assistant_apply(GtkWidget *w){
|
||||
linphone_gtk_close_audio_assistant(w);
|
||||
}
|
||||
|
||||
void linphone_gtk_show_audio_assistant(void){
|
||||
GtkWidget *w;
|
||||
if(audio_assistant!=NULL)
|
||||
return;
|
||||
w=audio_assistant=linphone_gtk_create_window("audio_assistant");
|
||||
|
||||
gtk_window_set_resizable (GTK_WINDOW(w), FALSE);
|
||||
gtk_window_set_title(GTK_WINDOW(w),_("Audio Assistant"));
|
||||
|
||||
GtkWidget *welcome=create_intro();
|
||||
GtkWidget *mic_page=create_mic_page();
|
||||
GtkWidget *speaker_page=create_speaker_page();
|
||||
GtkWidget *play_record_page=create_play_record_page();
|
||||
GtkWidget *end_page=create_end_page();
|
||||
|
||||
gtk_assistant_append_page(GTK_ASSISTANT(w),welcome);
|
||||
gtk_assistant_set_page_type(GTK_ASSISTANT(w),welcome,GTK_ASSISTANT_PAGE_INTRO);
|
||||
gtk_assistant_set_page_title(GTK_ASSISTANT(w),welcome,_("Audio assistant"));
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(w),welcome,TRUE);
|
||||
|
||||
gtk_assistant_append_page(GTK_ASSISTANT(w),mic_page);
|
||||
gtk_assistant_set_page_type(GTK_ASSISTANT(w),mic_page,GTK_ASSISTANT_PAGE_CONTENT);
|
||||
gtk_assistant_set_page_title(GTK_ASSISTANT(w),mic_page,_("Mic Gain calibration"));
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(w),mic_page,TRUE);
|
||||
|
||||
gtk_assistant_append_page(GTK_ASSISTANT(w),speaker_page);
|
||||
gtk_assistant_set_page_type(GTK_ASSISTANT(w),speaker_page,GTK_ASSISTANT_PAGE_CONTENT);
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(w),speaker_page,FALSE);
|
||||
gtk_assistant_set_page_title(GTK_ASSISTANT(w),speaker_page,_("Speaker volume calibration"));
|
||||
|
||||
gtk_assistant_append_page(GTK_ASSISTANT(w),play_record_page);
|
||||
gtk_assistant_set_page_type(GTK_ASSISTANT(w),play_record_page,GTK_ASSISTANT_PAGE_CONTENT);
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(w),play_record_page,TRUE);
|
||||
gtk_assistant_set_page_title(GTK_ASSISTANT(w),play_record_page,_("Record and Play"));
|
||||
|
||||
gtk_assistant_append_page(GTK_ASSISTANT(w),end_page);
|
||||
gtk_assistant_set_page_type(GTK_ASSISTANT(w),end_page,GTK_ASSISTANT_PAGE_SUMMARY);
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(w),end_page,TRUE);
|
||||
gtk_assistant_set_page_title(GTK_ASSISTANT(w),end_page,_("Terminating"));
|
||||
|
||||
g_signal_connect(G_OBJECT(w),"close",(GCallback)linphone_gtk_close_audio_assistant,w);
|
||||
g_signal_connect(G_OBJECT(w),"cancel",(GCallback)linphone_gtk_close_audio_assistant,w);
|
||||
g_signal_connect(G_OBJECT(w),"prepare",(GCallback)prepare,NULL);
|
||||
|
||||
gtk_widget_show(w);
|
||||
}
|
||||
21
gtk/audio_assistant.ui
Normal file
21
gtk/audio_assistant.ui
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkAssistant" id="audio_assistant">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">12</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -567,19 +567,12 @@ static gboolean linphone_gtk_in_call_view_refresh(LinphoneCall *call){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _volume_ctx{
|
||||
GtkWidget *widget;
|
||||
get_volume_t get_volume;
|
||||
void *data;
|
||||
float last_value;
|
||||
}volume_ctx_t;
|
||||
|
||||
#define UNSIGNIFICANT_VOLUME (-26)
|
||||
#define UNSIGNIFICANT_VOLUME (-23)
|
||||
#define SMOOTH 0.15
|
||||
|
||||
static gboolean update_audio_meter(volume_ctx_t *ctx){
|
||||
float volume_db=ctx->get_volume(ctx->data);
|
||||
float frac=(volume_db-UNSIGNIFICANT_VOLUME)/(float)(-UNSIGNIFICANT_VOLUME+3.0);
|
||||
float frac=(volume_db-UNSIGNIFICANT_VOLUME)/(float)(-UNSIGNIFICANT_VOLUME-3.0);
|
||||
if (frac<0) frac=0;
|
||||
if (frac>1.0) frac=1.0;
|
||||
if (frac<ctx->last_value){
|
||||
|
|
|
|||
|
|
@ -53,6 +53,27 @@ enum {
|
|||
COMPLETION_LDAP
|
||||
};
|
||||
|
||||
typedef float (*get_volume_t)(void *data);
|
||||
|
||||
typedef struct _volume_ctx{
|
||||
GtkWidget *widget;
|
||||
get_volume_t get_volume;
|
||||
void *data;
|
||||
float last_value;
|
||||
}volume_ctx_t;
|
||||
|
||||
typedef enum {
|
||||
CAP_IGNORE,
|
||||
CAP_PLAYBACK,
|
||||
CAP_CAPTURE
|
||||
}DeviceCap;
|
||||
|
||||
enum {
|
||||
START_LINPHONE,
|
||||
START_AUDIO_ASSISTANT,
|
||||
START_LINPHONE_WITH_CALL
|
||||
};
|
||||
|
||||
GdkPixbuf * create_pixbuf(const gchar *filename);
|
||||
GdkPixbufAnimation *create_pixbuf_animation(const gchar *filename);
|
||||
void add_pixmap_directory(const gchar *directory);
|
||||
|
|
@ -96,7 +117,6 @@ LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void);
|
|||
void linphone_gtk_set_ldap(LinphoneLDAPContactProvider* ldap);
|
||||
int linphone_gtk_is_ldap_supported(void);
|
||||
|
||||
|
||||
void linphone_gtk_open_browser(const char *url);
|
||||
void linphone_gtk_check_for_new_version(void);
|
||||
const char *linphone_gtk_get_lang(const char *config_file);
|
||||
|
|
@ -150,8 +170,8 @@ void linphone_gtk_unset_from_conference(LinphoneCall *call);
|
|||
void linphone_gtk_terminate_conference_participant(LinphoneCall *call);
|
||||
void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call);
|
||||
void linphone_gtk_update_video_button(LinphoneCall *call);
|
||||
typedef float (*get_volume_t)(void *data);
|
||||
void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data);
|
||||
void linphone_gtk_uninit_audio_meter(GtkWidget *w);
|
||||
|
||||
void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login);
|
||||
void linphone_gtk_exit_login_frame(void);
|
||||
|
|
@ -159,14 +179,18 @@ void linphone_gtk_set_ui_config(const char *key, const char *value);
|
|||
|
||||
void linphone_gtk_log_uninit();
|
||||
|
||||
bool_t linphone_gtk_init_instance(const char *app_name, const char *addr_to_call);
|
||||
bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call);
|
||||
void linphone_gtk_uninit_instance(void);
|
||||
void linphone_gtk_monitor_usb(void);
|
||||
void linphone_gtk_unmonitor_usb(void);
|
||||
|
||||
void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap);
|
||||
gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_conference);
|
||||
void linphone_gtk_schedule_restart(void);
|
||||
|
||||
void linphone_gtk_show_audio_assistant(void);
|
||||
gboolean linphone_gtk_get_audio_assistant_option(void);
|
||||
|
||||
void linphone_gtk_set_configuration_uri(void);
|
||||
GtkWidget * linphone_gtk_show_config_fetching(void);
|
||||
void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState state);
|
||||
|
|
|
|||
24
gtk/main.c
24
gtk/main.c
|
|
@ -86,8 +86,10 @@ static gboolean verbose=0;
|
|||
static gboolean quit_done=FALSE;
|
||||
static gboolean auto_answer = 0;
|
||||
static gchar * addr_to_call = NULL;
|
||||
static int start_option = START_LINPHONE;
|
||||
static gboolean no_video=FALSE;
|
||||
static gboolean iconified=FALSE;
|
||||
static gboolean run_audio_assistant=FALSE;
|
||||
static gchar *workingdir=NULL;
|
||||
static char *progpath=NULL;
|
||||
gchar *linphone_logfile=NULL;
|
||||
|
|
@ -153,6 +155,13 @@ static GOptionEntry linphone_options[]={
|
|||
.arg_data = (gpointer) &custom_config_file,
|
||||
.description = N_("Configuration file")
|
||||
},
|
||||
{
|
||||
.long_name = "run-audio-assistant",
|
||||
.short_name = '\0',
|
||||
.arg = G_OPTION_ARG_NONE,
|
||||
.arg_data = (gpointer) &run_audio_assistant,
|
||||
.description = N_("Run the audio assistant")
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
@ -262,6 +271,10 @@ void linphone_gtk_schedule_restart(void){
|
|||
restart=TRUE;
|
||||
}
|
||||
|
||||
gboolean linphone_gtk_get_audio_assistant_option(void){
|
||||
return run_audio_assistant;
|
||||
}
|
||||
|
||||
static void linphone_gtk_init_liblinphone(const char *config_file,
|
||||
const char *factory_config_file, const char *db_file) {
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
|
@ -2136,6 +2149,11 @@ static void linphone_gtk_init_ui(void){
|
|||
}
|
||||
#endif
|
||||
|
||||
if(run_audio_assistant){
|
||||
linphone_gtk_show_audio_assistant();
|
||||
start_option=START_AUDIO_ASSISTANT;
|
||||
iconified = TRUE;
|
||||
}
|
||||
#ifndef HAVE_GTK_OSX
|
||||
linphone_gtk_init_status_icon();
|
||||
#endif
|
||||
|
|
@ -2168,7 +2186,6 @@ int main(int argc, char *argv[]){
|
|||
|
||||
config_file=linphone_gtk_get_config_file(NULL);
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
/*workaround for windows: sometimes LANG is defined to an integer value, not understood by gtk */
|
||||
if ((lang=getenv("LANG"))!=NULL){
|
||||
|
|
@ -2226,6 +2243,9 @@ int main(int argc, char *argv[]){
|
|||
}
|
||||
config_file=linphone_gtk_get_config_file(custom_config_file);
|
||||
|
||||
if(run_audio_assistant) start_option=START_AUDIO_ASSISTANT;
|
||||
if(addr_to_call != NULL) start_option=START_LINPHONE_WITH_CALL;
|
||||
|
||||
settings=gtk_settings_get_default();
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM));
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
|
||||
|
|
@ -2275,7 +2295,7 @@ int main(int argc, char *argv[]){
|
|||
#endif
|
||||
|
||||
core_start:
|
||||
if (linphone_gtk_init_instance(app_name, addr_to_call) == FALSE){
|
||||
if (linphone_gtk_init_instance(app_name, start_option, addr_to_call) == FALSE){
|
||||
g_warning("Another running instance of linphone has been detected. It has been woken-up.");
|
||||
g_warning("This instance is going to exit now.");
|
||||
gdk_threads_leave();
|
||||
|
|
|
|||
129
gtk/main.ui
129
gtk/main.ui
|
|
@ -786,6 +786,12 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image21">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="yalign">0.49000000953674316</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
|
|
@ -821,6 +827,59 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model1">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All users</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Online users</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model2">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">ADSL</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Fiber Channel</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model3">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Default</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model4">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">ADSL</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Fiber Channel</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkWindow" id="main">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
|
|
@ -991,6 +1050,17 @@
|
|||
<signal name="activate" handler="linphone_gtk_show_assistant" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="audio_assistant_item">
|
||||
<property name="label" translatable="yes">Audio assistant</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="image">image21</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="linphone_gtk_show_audio_assistant" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
@ -1733,9 +1803,6 @@
|
|||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="userid">
|
||||
<property name="can_focus">False</property>
|
||||
|
|
@ -1762,6 +1829,9 @@
|
|||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
@ -1881,59 +1951,6 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model1">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All users</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Online users</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model2">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">ADSL</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Fiber Channel</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model3">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Default</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model4">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">ADSL</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Fiber Channel</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkImage" id="remove_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
|
|
|
|||
|
|
@ -21,13 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "linphone_tunnel.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
typedef enum {
|
||||
CAP_IGNORE,
|
||||
CAP_PLAYBACK,
|
||||
CAP_CAPTURE
|
||||
}DeviceCap;
|
||||
|
||||
static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){
|
||||
void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){
|
||||
const char **p=devices;
|
||||
int i=0,active=-1;
|
||||
GtkTreeModel *model;
|
||||
|
|
@ -1286,6 +1280,7 @@ void linphone_gtk_fill_webcams(GtkWidget *pb){
|
|||
}
|
||||
|
||||
void linphone_gtk_fill_video_renderers(GtkWidget *pb){
|
||||
#ifdef VIDEO_ENABLED /* video_stream_get_default_video_renderer requires video enabled */
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *combo=linphone_gtk_get_widget(pb,"renderers");
|
||||
MSList *l=ms_filter_lookup_by_interface(MSFilterVideoDisplayInterface);
|
||||
|
|
@ -1296,7 +1291,7 @@ void linphone_gtk_fill_video_renderers(GtkWidget *pb){
|
|||
GtkListStore *store;
|
||||
GtkCellRenderer *renderer=gtk_cell_renderer_text_new();
|
||||
GtkTreeModel *model=GTK_TREE_MODEL(store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING));
|
||||
|
||||
|
||||
if (current_renderer==NULL) current_renderer=video_stream_get_default_video_renderer();
|
||||
|
||||
gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model);
|
||||
|
|
@ -1314,6 +1309,7 @@ void linphone_gtk_fill_video_renderers(GtkWidget *pb){
|
|||
}
|
||||
ms_list_free(l);
|
||||
if (active!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active);
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static void linphone_account_informations_changed(GtkEntry *entry, GtkWidget *w)
|
|||
GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username"));
|
||||
|
||||
gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w,
|
||||
gtk_entry_get_text_length(username) >= LOGIN_MIN_SIZE);
|
||||
gtk_entry_get_text_length(username) > 0);
|
||||
}
|
||||
|
||||
static GtkWidget *create_linphone_account_informations_page() {
|
||||
|
|
@ -453,6 +453,7 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page
|
|||
|
||||
static gint destroy_assistant(GtkWidget* w){
|
||||
gtk_widget_destroy(w);
|
||||
the_assistant = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,26 @@ gchar *make_name(const char *appname){
|
|||
return g_strdup(appname);
|
||||
}
|
||||
|
||||
static gboolean execute_wakeup(char *uri){
|
||||
linphone_gtk_show_main_window();
|
||||
if (strlen(uri)>0)
|
||||
linphone_gtk_refer_received(linphone_gtk_get_core(),uri);
|
||||
g_free(uri);
|
||||
static gboolean execute_wakeup(char *buf){
|
||||
char uri[255]={0};
|
||||
int option;
|
||||
|
||||
if (strlen(buf)>1) sscanf(buf,"%i%s",&option,uri);
|
||||
else sscanf(buf,"%i",&option);
|
||||
|
||||
switch(option){
|
||||
case START_LINPHONE:
|
||||
linphone_gtk_show_main_window();
|
||||
break;
|
||||
case START_AUDIO_ASSISTANT:
|
||||
linphone_gtk_show_audio_assistant();
|
||||
break;
|
||||
case START_LINPHONE_WITH_CALL:
|
||||
linphone_gtk_refer_received(linphone_gtk_get_core(),uri);
|
||||
break;
|
||||
};
|
||||
|
||||
g_free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -71,14 +86,16 @@ static void linphone_gtk_init_pipe(const char *name){
|
|||
ms_thread_create(&pipe_thread,NULL,server_pipe_thread,NULL);
|
||||
}
|
||||
|
||||
bool_t linphone_gtk_init_instance(const char *app_name, const char *addr_to_call){
|
||||
bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call){
|
||||
pipe_name=make_name(app_name);
|
||||
ortp_pipe_t p=ortp_client_pipe_connect(pipe_name);
|
||||
if (p!=(ortp_pipe_t)-1){
|
||||
uint8_t buf[256]={0};
|
||||
g_message("There is already a running instance.");
|
||||
if (addr_to_call!=NULL){
|
||||
strncpy((char*)buf,addr_to_call,sizeof(buf)-1);
|
||||
sprintf((char *)buf,"%i%s",option,addr_to_call);
|
||||
} else {
|
||||
sprintf((char *)buf,"%i",option);
|
||||
}
|
||||
if (ortp_pipe_write(p,buf,sizeof(buf))==-1){
|
||||
g_error("Fail to send wakeup command to running instance: %s",strerror(errno));
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
#include "ortp/rtpsession.h"
|
||||
#include "ortp/ortp_srtp.h"
|
||||
#include "belle-sip/belle-sip.h"
|
||||
|
||||
|
|
@ -135,20 +136,6 @@ typedef enum{
|
|||
}SalStreamDir;
|
||||
const char* sal_stream_dir_to_string(SalStreamDir type);
|
||||
|
||||
typedef enum {
|
||||
SalRtcpXrRcvrRttNone,
|
||||
SalRtcpXrRcvrRttAll,
|
||||
SalRtcpXrRcvrRttSender
|
||||
} SalRtcpXrRcvrRttMode;
|
||||
|
||||
typedef enum {
|
||||
SalRtcpXrStatSummaryLoss = (1 << 0),
|
||||
SalRtcpXrStatSummaryDup = (1 << 1),
|
||||
SalRtcpXrStatSummaryJitt = (1 << 2),
|
||||
SalRtcpXrStatSummaryTTL = (1 << 3),
|
||||
SalRtcpXrStatSummaryHL = (1 << 4)
|
||||
} SalRtcpXrStatSummaryFlag;
|
||||
|
||||
|
||||
#define SAL_ENDPOINT_CANDIDATE_MAX 2
|
||||
|
||||
|
|
@ -190,15 +177,6 @@ typedef struct SalSrtpCryptoAlgo {
|
|||
|
||||
#define SAL_CRYPTO_ALGO_MAX 4
|
||||
|
||||
typedef struct SalRtcpXrDescription {
|
||||
bool_t enabled;
|
||||
bool_t stat_summary_enabled;
|
||||
bool_t voip_metrics_enabled;
|
||||
SalRtcpXrRcvrRttMode rcvr_rtt_mode;
|
||||
int rcvr_rtt_max_size;
|
||||
SalRtcpXrStatSummaryFlag stat_summary_flags;
|
||||
} SalRtcpXrDescription;
|
||||
|
||||
typedef struct SalStreamDescription{
|
||||
char name[16]; /*unique name of stream, in order to ease offer/answer model algorithm*/
|
||||
SalMediaProto proto;
|
||||
|
|
@ -216,7 +194,7 @@ typedef struct SalStreamDescription{
|
|||
SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX];
|
||||
unsigned int crypto_local_tag;
|
||||
int max_rate;
|
||||
SalRtcpXrDescription rtcp_xr;
|
||||
OrtpRtcpXrConfiguration rtcp_xr;
|
||||
SalIceCandidate ice_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES];
|
||||
SalIceRemoteCandidate ice_remote_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES];
|
||||
char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN];
|
||||
|
|
@ -243,7 +221,7 @@ typedef struct SalMediaDescription{
|
|||
unsigned int session_id;
|
||||
SalStreamDir dir;
|
||||
SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
|
||||
SalRtcpXrDescription rtcp_xr;
|
||||
OrtpRtcpXrConfiguration rtcp_xr;
|
||||
char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN];
|
||||
char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN];
|
||||
bool_t ice_lite;
|
||||
|
|
@ -276,6 +254,7 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
|||
SalMediaProto proto, SalStreamType type);
|
||||
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
|
||||
|
||||
|
||||
/*this structure must be at the first byte of the SalOp structure defined by implementors*/
|
||||
typedef struct SalOpBase{
|
||||
Sal *root;
|
||||
|
|
@ -301,15 +280,8 @@ typedef struct SalOpBase{
|
|||
} SalOpBase;
|
||||
|
||||
|
||||
typedef enum SalError{
|
||||
SalErrorNone,
|
||||
SalErrorNoResponse,
|
||||
SalErrorProtocol,
|
||||
SalErrorFailure, /* see SalReason for more details */
|
||||
SalErrorUnknown
|
||||
} SalError;
|
||||
|
||||
typedef enum SalReason{
|
||||
SalReasonNone, /*no error, please leave first so that it takes 0 value*/
|
||||
SalReasonDeclined,
|
||||
SalReasonBusy,
|
||||
SalReasonRedirect,
|
||||
|
|
@ -330,11 +302,20 @@ typedef enum SalReason{
|
|||
SalReasonAddressIncomplete,
|
||||
SalReasonNotImplemented,
|
||||
SalReasonBadGateway,
|
||||
SalReasonServerTimeout
|
||||
SalReasonServerTimeout,
|
||||
SalReasonIOError
|
||||
}SalReason;
|
||||
|
||||
const char* sal_reason_to_string(const SalReason reason);
|
||||
|
||||
typedef struct SalErrorInfo{
|
||||
SalReason reason;
|
||||
char *status_string;
|
||||
int protocol_code;
|
||||
char *warnings;
|
||||
char *full_string; /*concatenation of status_string + warnings*/
|
||||
}SalErrorInfo;
|
||||
|
||||
typedef enum SalPresenceStatus{
|
||||
SalPresenceOffline,
|
||||
SalPresenceOnline,
|
||||
|
|
@ -422,21 +403,21 @@ typedef void (*SalOnCallAccepted)(SalOp *op);
|
|||
typedef void (*SalOnCallAck)(SalOp *op);
|
||||
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE/UPDATE is received*/
|
||||
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op);
|
||||
typedef void (*SalOnCallReleased)(SalOp *salop);
|
||||
typedef void (*SalOnAuthRequestedLegacy)(SalOp *op, const char *realm, const char *username);
|
||||
typedef bool_t (*SalOnAuthRequested)(Sal *sal,SalAuthInfo* info);
|
||||
typedef void (*SalOnAuthFailure)(SalOp *op, SalAuthInfo* info);
|
||||
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
|
||||
typedef void (*SalOnRegisterFailure)(SalOp *op, SalError error, SalReason reason, const char *details);
|
||||
typedef void (*SalOnRegisterFailure)(SalOp *op);
|
||||
typedef void (*SalOnVfuRequest)(SalOp *op);
|
||||
typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf);
|
||||
typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto);
|
||||
typedef void (*SalOnTextReceived)(SalOp *op, const SalMessage *msg);
|
||||
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus, SalReason);
|
||||
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus);
|
||||
typedef void (*SalOnIsComposingReceived)(SalOp *op, const SalIsComposing *is_composing);
|
||||
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
|
||||
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status, SalError error, SalReason reason);
|
||||
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status);
|
||||
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, const SalBody *body);
|
||||
typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *event, const SalBody *body);
|
||||
typedef void (*SalOnSubscribeClosed)(SalOp *salop);
|
||||
|
|
@ -447,7 +428,7 @@ typedef void (*SalOnSubscribePresenceReceived)(SalOp *salop, const char *from);
|
|||
typedef void (*SalOnSubscribePresenceClosed)(SalOp *salop, const char *from);
|
||||
typedef void (*SalOnPingReply)(SalOp *salop);
|
||||
typedef void (*SalOnInfoReceived)(SalOp *salop, const SalBody *body);
|
||||
typedef void (*SalOnPublishResponse)(SalOp *salop, SalError error, SalReason reason);
|
||||
typedef void (*SalOnPublishResponse)(SalOp *salop);
|
||||
typedef void (*SalOnExpire)(SalOp *salop);
|
||||
/*allows sal implementation to access auth info if available, return TRUE if found*/
|
||||
|
||||
|
|
@ -520,6 +501,7 @@ void sal_signing_key_delete(SalSigningKey *key);
|
|||
|
||||
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure);
|
||||
int sal_get_listening_port(Sal *ctx, SalTransport tr);
|
||||
int sal_unlisten_ports(Sal *ctx);
|
||||
int sal_transport_available(Sal *ctx, SalTransport t);
|
||||
void sal_set_dscp(Sal *ctx, int dscp);
|
||||
|
|
@ -599,6 +581,11 @@ bool_t sal_op_is_ipv6(SalOp *op);
|
|||
/*returns TRUE if there is no pending request that may block a future one */
|
||||
bool_t sal_op_is_idle(SalOp *op);
|
||||
|
||||
const SalErrorInfo *sal_error_info_none(void);
|
||||
const SalErrorInfo *sal_op_get_error_info(const SalOp *op);
|
||||
void sal_error_info_reset(SalErrorInfo *ei);
|
||||
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning);
|
||||
|
||||
/*Call API*/
|
||||
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
|
||||
int sal_call(SalOp *h, const char *from, const char *to);
|
||||
|
|
@ -632,6 +619,7 @@ int sal_unregister(SalOp *h);
|
|||
/*Messaging */
|
||||
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
|
||||
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg);
|
||||
int sal_message_reply(SalOp *op, SalReason reason);
|
||||
|
||||
/*presence Subscribe/notify*/
|
||||
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
|
||||
|
|
|
|||
24
java/common/org/linphone/core/ErrorInfo.java
Normal file
24
java/common/org/linphone/core/ErrorInfo.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package org.linphone.core;
|
||||
|
||||
public interface ErrorInfo {
|
||||
/**
|
||||
* Return the Reason enum corresponding to the error type.
|
||||
* @return the reason.
|
||||
*/
|
||||
Reason getReason();
|
||||
/**
|
||||
* Get the protocol code corresponding to the error (typically a SIP status code).
|
||||
* @return the code.
|
||||
*/
|
||||
int getProtocolCode();
|
||||
/**
|
||||
* Get the reason-phrase provided by the protocol (typically a SIP reason-phrase).
|
||||
* @return the reason phrase.
|
||||
*/
|
||||
String getPhrase();
|
||||
/**
|
||||
* Get details about the error, if provided by the protocol. For SIP it consists of the content of a Warning or Reason header.
|
||||
* @return details about the error.
|
||||
*/
|
||||
String getDetails();
|
||||
}
|
||||
|
|
@ -315,4 +315,12 @@ public interface LinphoneCall {
|
|||
**/
|
||||
LinphoneCall getTransferTargetCall();
|
||||
|
||||
Reason getReason();
|
||||
|
||||
/**
|
||||
* Returns last error reported for the call.
|
||||
* @return an ErrorInfo.
|
||||
*/
|
||||
ErrorInfo getErrorInfo();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,8 +142,14 @@ public interface LinphoneChatMessage {
|
|||
*/
|
||||
int getStorageId();
|
||||
|
||||
/**
|
||||
* @return the reason if response received
|
||||
*/
|
||||
Reason getReason();
|
||||
/**
|
||||
* @return the reason if response received
|
||||
*/
|
||||
Reason getReason();
|
||||
|
||||
/**
|
||||
* Returns full error in case of failure when sending message.
|
||||
* @return an ErrorInfo.
|
||||
*/
|
||||
ErrorInfo getErrorInfo();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1564,5 +1564,30 @@ public interface LinphoneCore {
|
|||
*/
|
||||
public boolean isSdp200AckEnabled();
|
||||
|
||||
/**
|
||||
* Inconditionnaly disable incoming chat messages.
|
||||
* @param lc the core
|
||||
* @param deny_reason the deny reason (using ReasonNone has no effect).
|
||||
**/
|
||||
public void disableChat(Reason denycode);
|
||||
|
||||
/**
|
||||
* Enable reception of incoming chat messages.
|
||||
* By default it is enabled but it can be disabled with linphone_core_disable_chat().
|
||||
* @param lc the core
|
||||
**/
|
||||
public void enableChat();
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether chat is enabled.
|
||||
* @return true if chat is enabled, false otherwise.
|
||||
**/
|
||||
public boolean chatEnabled();
|
||||
|
||||
/**
|
||||
* Whenever the liblinphone is playing a ring to advertise an incoming call or ringback of an outgoing call, this function stops the ringing.
|
||||
* Typical use is to stop ringing when the user requests to ignore the call.
|
||||
**/
|
||||
public void stopRinging();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ public interface LinphoneEvent {
|
|||
*/
|
||||
Reason getReason();
|
||||
|
||||
/**
|
||||
* In case of error notified, returns the full error details.
|
||||
* @return an ErrorInfo.
|
||||
*/
|
||||
ErrorInfo getErrorInfo();
|
||||
|
||||
/**
|
||||
* Assign an application context to the LinphoneEvent, for later use.
|
||||
* @param obj
|
||||
|
|
|
|||
|
|
@ -211,4 +211,10 @@ public interface LinphoneProxyConfig {
|
|||
* @return reason code.
|
||||
*/
|
||||
public Reason getError();
|
||||
|
||||
/**
|
||||
* Get full error information about last error occured on the proxy config.
|
||||
* @return an ErrorInfo.
|
||||
*/
|
||||
public ErrorInfo getErrorInfo();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ public class Reason {
|
|||
* Server timeout
|
||||
*/
|
||||
static public Reason ServerTimeout = new Reason(19,"ServerTimeout");
|
||||
/**
|
||||
* Unknown
|
||||
*/
|
||||
static public Reason Unknown = new Reason(20,"Unknown");
|
||||
|
||||
protected final int mValue;
|
||||
private final String mStringValue;
|
||||
|
|
|
|||
41
java/impl/org/linphone/core/ErrorInfoImpl.java
Normal file
41
java/impl/org/linphone/core/ErrorInfoImpl.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package org.linphone.core;
|
||||
|
||||
public class ErrorInfoImpl implements ErrorInfo {
|
||||
private Reason mReason;
|
||||
private int mCode;
|
||||
private String mPhrase;
|
||||
private String mDetails;
|
||||
|
||||
private native int getReason(long nativePtr);
|
||||
private native int getProtocolCode(long nativePtr);
|
||||
private native String getPhrase(long nativePtr);
|
||||
private native String getDetails(long nativePtr);
|
||||
|
||||
public ErrorInfoImpl(long nativePtr){
|
||||
mReason=Reason.fromInt(getReason(nativePtr));
|
||||
mCode=getProtocolCode(nativePtr);
|
||||
mPhrase=getPhrase(nativePtr);
|
||||
mDetails=getDetails(nativePtr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reason getReason() {
|
||||
return mReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolCode() {
|
||||
return mCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPhrase() {
|
||||
return mPhrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
return mDetails;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -226,4 +226,14 @@ class LinphoneCallImpl implements LinphoneCall {
|
|||
public LinphoneCall getTransferTargetCall() {
|
||||
return (LinphoneCall)getTransferTargetCall(nativePtr);
|
||||
}
|
||||
@Override
|
||||
public Reason getReason() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
private native long getErrorInfo(long nativePtr);
|
||||
@Override
|
||||
public ErrorInfo getErrorInfo() {
|
||||
return new ErrorInfoImpl(getErrorInfo(nativePtr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,4 +100,9 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
|
|||
public Reason getReason() {
|
||||
return Reason.fromInt(getReason(nativePtr));
|
||||
}
|
||||
private native long getErrorInfo(long nativePtr);
|
||||
@Override
|
||||
public ErrorInfo getErrorInfo() {
|
||||
return new ErrorInfoImpl(getErrorInfo(nativePtr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,10 +57,6 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
|
|||
loadOptionalLibrary("avcodec-linphone-arm");
|
||||
}
|
||||
|
||||
// Secure RTP and key negotiation
|
||||
loadOptionalLibrary("srtp-" + eabi);
|
||||
loadOptionalLibrary("zrtpcpp-" + eabi); // GPLv3+
|
||||
|
||||
//Main library
|
||||
System.loadLibrary("linphone-" + eabi);
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
private native void setCallErrorTone(long nativePtr, int reason, String path);
|
||||
private native void enableSdp200Ack(long nativePtr,boolean enable);
|
||||
private native boolean isSdp200AckEnabled(long nativePtr);
|
||||
private native void stopRinging(long nativePtr);
|
||||
|
||||
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata) throws IOException {
|
||||
mListener = listener;
|
||||
|
|
@ -966,79 +967,79 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
|
||||
private native boolean upnpAvailable(long ptr);
|
||||
public boolean upnpAvailable() {
|
||||
public synchronized boolean upnpAvailable() {
|
||||
return upnpAvailable(nativePtr);
|
||||
}
|
||||
|
||||
private native int getUpnpState(long ptr);
|
||||
public UpnpState getUpnpState() {
|
||||
public synchronized UpnpState getUpnpState() {
|
||||
return UpnpState.fromInt(getUpnpState(nativePtr));
|
||||
}
|
||||
|
||||
private native String getUpnpExternalIpaddress(long ptr);
|
||||
public String getUpnpExternalIpaddress() {
|
||||
public synchronized String getUpnpExternalIpaddress() {
|
||||
return getUpnpExternalIpaddress(nativePtr);
|
||||
}
|
||||
private native int startConferenceRecording(long nativePtr, String path);
|
||||
@Override
|
||||
public void startConferenceRecording(String path) {
|
||||
public synchronized void startConferenceRecording(String path) {
|
||||
startConferenceRecording(nativePtr,path);
|
||||
}
|
||||
|
||||
private native int stopConferenceRecording(long nativePtr);
|
||||
@Override
|
||||
public void stopConferenceRecording() {
|
||||
public synchronized void stopConferenceRecording() {
|
||||
stopConferenceRecording(nativePtr);
|
||||
}
|
||||
@Override
|
||||
public PayloadType findPayloadType(String mime) {
|
||||
public synchronized PayloadType findPayloadType(String mime) {
|
||||
return findPayloadType(mime, FIND_PAYLOAD_IGNORE_RATE);
|
||||
}
|
||||
|
||||
private native void setSipDscp(long nativePtr, int dscp);
|
||||
@Override
|
||||
public void setSipDscp(int dscp) {
|
||||
public synchronized void setSipDscp(int dscp) {
|
||||
setSipDscp(nativePtr,dscp);
|
||||
}
|
||||
|
||||
private native int getSipDscp(long nativePtr);
|
||||
@Override
|
||||
public int getSipDscp() {
|
||||
public synchronized int getSipDscp() {
|
||||
return getSipDscp(nativePtr);
|
||||
}
|
||||
private native void setAudioDscp(long nativePtr, int dscp);
|
||||
@Override
|
||||
public void setAudioDscp(int dscp) {
|
||||
public synchronized void setAudioDscp(int dscp) {
|
||||
setAudioDscp(nativePtr, dscp);
|
||||
}
|
||||
|
||||
private native int getAudioDscp(long nativePtr);
|
||||
@Override
|
||||
public int getAudioDscp() {
|
||||
public synchronized int getAudioDscp() {
|
||||
return getAudioDscp(nativePtr);
|
||||
}
|
||||
|
||||
private native void setVideoDscp(long nativePtr, int dscp);
|
||||
@Override
|
||||
public void setVideoDscp(int dscp) {
|
||||
public synchronized void setVideoDscp(int dscp) {
|
||||
setVideoDscp(nativePtr,dscp);
|
||||
}
|
||||
|
||||
private native int getVideoDscp(long nativePtr);
|
||||
@Override
|
||||
public int getVideoDscp() {
|
||||
public synchronized int getVideoDscp() {
|
||||
return getVideoDscp(nativePtr);
|
||||
}
|
||||
|
||||
private native long createInfoMessage(long nativeptr);
|
||||
@Override
|
||||
public LinphoneInfoMessage createInfoMessage() {
|
||||
public synchronized LinphoneInfoMessage createInfoMessage() {
|
||||
return new LinphoneInfoMessageImpl(createInfoMessage(nativePtr));
|
||||
}
|
||||
|
||||
private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding);
|
||||
@Override
|
||||
public LinphoneEvent subscribe(LinphoneAddress resource, String eventname,
|
||||
public synchronized LinphoneEvent subscribe(LinphoneAddress resource, String eventname,
|
||||
int expires, LinphoneContent content) {
|
||||
return (LinphoneEvent)subscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
|
||||
content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null,
|
||||
|
|
@ -1046,7 +1047,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
private native Object publish(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding);
|
||||
@Override
|
||||
public LinphoneEvent publish(LinphoneAddress resource, String eventname,
|
||||
public synchronized LinphoneEvent publish(LinphoneAddress resource, String eventname,
|
||||
int expires, LinphoneContent content) {
|
||||
return (LinphoneEvent)publish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
|
||||
content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null,
|
||||
|
|
@ -1055,18 +1056,18 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
|
||||
private native Object createSubscribe(long core, long addr, String event, int expires);
|
||||
@Override
|
||||
public LinphoneEvent createSubscribe(LinphoneAddress resource,
|
||||
public synchronized LinphoneEvent createSubscribe(LinphoneAddress resource,
|
||||
String event, int expires) {
|
||||
return (LinphoneEvent)createSubscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, event, expires);
|
||||
}
|
||||
private native Object createPublish(long core, long addr, String event, int expires);
|
||||
@Override
|
||||
public LinphoneEvent createPublish(LinphoneAddress resource,
|
||||
public synchronized LinphoneEvent createPublish(LinphoneAddress resource,
|
||||
String event, int expires) {
|
||||
return (LinphoneEvent)createPublish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, event, expires);
|
||||
}
|
||||
|
||||
public void setChatDatabasePath(String path) {
|
||||
public synchronized void setChatDatabasePath(String path) {
|
||||
setChatDatabasePath(nativePtr, path);
|
||||
}
|
||||
|
||||
|
|
@ -1082,7 +1083,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
|
||||
return proxies;
|
||||
}
|
||||
public LinphoneAuthInfo[] getAuthInfosList() {
|
||||
public synchronized LinphoneAuthInfo[] getAuthInfosList() {
|
||||
long[] typesPtr = getAuthInfosList(nativePtr);
|
||||
if (typesPtr == null) return null;
|
||||
|
||||
|
|
@ -1095,7 +1096,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
return authInfos;
|
||||
}
|
||||
|
||||
public LinphoneAuthInfo findAuthInfo(String username, String realm, String domain) {
|
||||
public synchronized LinphoneAuthInfo findAuthInfo(String username, String realm, String domain) {
|
||||
long ptr = findAuthInfos(nativePtr, username, realm, domain);
|
||||
if (ptr == 0)
|
||||
return null;
|
||||
|
|
@ -1104,7 +1105,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
private native LinphoneCall startReferedCall(long corePtr, long callptr, long paramsPtr);
|
||||
@Override
|
||||
public LinphoneCall startReferedCall(LinphoneCall call,
|
||||
public synchronized LinphoneCall startReferedCall(LinphoneCall call,
|
||||
LinphoneCallParams params) {
|
||||
long ptrParams =((LinphoneCallParamsImpl)params).nativePtr;
|
||||
return startReferedCall(nativePtr, getCallPtr(call), ptrParams);
|
||||
|
|
@ -1112,58 +1113,78 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
|
||||
private native String[] listSupportedVideoResolutions(long ptr);
|
||||
@Override
|
||||
public String[] getSupportedVideoSizes() {
|
||||
public synchronized String[] getSupportedVideoSizes() {
|
||||
return listSupportedVideoResolutions(nativePtr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int migrateToMultiTransport() {
|
||||
public synchronized int migrateToMultiTransport() {
|
||||
return migrateToMultiTransport(nativePtr);
|
||||
}
|
||||
|
||||
private native boolean acceptEarlyMedia(long lc, long call);
|
||||
@Override
|
||||
public boolean acceptEarlyMedia(LinphoneCall call) {
|
||||
public synchronized boolean acceptEarlyMedia(LinphoneCall call) {
|
||||
return acceptEarlyMedia(nativePtr, getCallPtr(call));
|
||||
}
|
||||
|
||||
private native boolean acceptEarlyMediaWithParams(long lc, long call, long params);
|
||||
@Override
|
||||
public boolean acceptEarlyMediaWithParams(LinphoneCall call,
|
||||
public synchronized boolean acceptEarlyMediaWithParams(LinphoneCall call,
|
||||
LinphoneCallParams params) {
|
||||
long ptrParams = params != null ? ((LinphoneCallParamsImpl) params).nativePtr : 0;
|
||||
return acceptEarlyMediaWithParams(nativePtr, getCallPtr(call), ptrParams);
|
||||
}
|
||||
@Override
|
||||
public LinphoneProxyConfig createProxyConfig() {
|
||||
public synchronized LinphoneProxyConfig createProxyConfig() {
|
||||
return new LinphoneProxyConfigImpl(createProxyConfig(nativePtr));
|
||||
}
|
||||
@Override
|
||||
public void setCallErrorTone(Reason reason, String path) {
|
||||
public synchronized void setCallErrorTone(Reason reason, String path) {
|
||||
setCallErrorTone(nativePtr, reason.mValue, path);
|
||||
}
|
||||
private native void setMtu(long nativePtr, int mtu);
|
||||
@Override
|
||||
public void setMtu(int mtu) {
|
||||
public synchronized void setMtu(int mtu) {
|
||||
setMtu(nativePtr,mtu);
|
||||
}
|
||||
private native int getMtu(long nativePtr);
|
||||
@Override
|
||||
public int getMtu() {
|
||||
public synchronized int getMtu() {
|
||||
return getMtu(nativePtr);
|
||||
}
|
||||
@Override
|
||||
public void enableSdp200Ack(boolean enable) {
|
||||
public synchronized void enableSdp200Ack(boolean enable) {
|
||||
enableSdp200Ack(nativePtr,enable);
|
||||
}
|
||||
@Override
|
||||
public boolean isSdp200AckEnabled() {
|
||||
public synchronized boolean isSdp200AckEnabled() {
|
||||
return isSdp200AckEnabled(nativePtr);
|
||||
}
|
||||
private native void setTone(long nativePtr, int id, String wavfile);
|
||||
@Override
|
||||
public void setTone(ToneID id, String wavfile) {
|
||||
public synchronized void setTone(ToneID id, String wavfile) {
|
||||
setTone(nativePtr, id.mValue, wavfile);
|
||||
}
|
||||
private native void disableChat(long ptr, int denycode);
|
||||
@Override
|
||||
public synchronized void disableChat(Reason denycode) {
|
||||
disableChat(nativePtr,denycode.mValue);
|
||||
}
|
||||
private native void enableChat(long ptr);
|
||||
@Override
|
||||
public synchronized void enableChat() {
|
||||
enableChat(nativePtr);
|
||||
}
|
||||
private native boolean chatEnabled(long ptr);
|
||||
@Override
|
||||
public synchronized boolean chatEnabled() {
|
||||
return chatEnabled(nativePtr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopRinging() {
|
||||
stopRinging(nativePtr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,5 +118,10 @@ public class LinphoneEventImpl implements LinphoneEvent {
|
|||
else
|
||||
sendPublish(mNativePtr, null, null, null, null);
|
||||
}
|
||||
private native long getErrorInfo(long nativePtr);
|
||||
@Override
|
||||
public ErrorInfo getErrorInfo() {
|
||||
return new ErrorInfoImpl(getErrorInfo(mNativePtr));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,4 +207,9 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
|
|||
public String getContactUriParameters() {
|
||||
return getContactUriParameters(nativePtr);
|
||||
}
|
||||
private native long getErrorInfo(long nativePtr);
|
||||
@Override
|
||||
public ErrorInfo getErrorInfo() {
|
||||
return new ErrorInfoImpl(getErrorInfo(nativePtr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%{_libdir}/*.so.*
|
||||
%{_mandir}/*
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_datadir}/applications/audio-assistant.desktop
|
||||
%{_datadir}/pixmaps/linphone
|
||||
%{_datadir}/linphone
|
||||
%{_datadir}/pixmaps/linphone.png
|
||||
|
|
|
|||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 5c3952c5b90b82fe2cff122c67959b88c358bce8
|
||||
Subproject commit a0bab264b915bcb5b67c061ed27bbb2b90a1b29a
|
||||
|
|
@ -13,6 +13,7 @@ gtk/setupwizard.c
|
|||
gtk/incall_view.c
|
||||
gtk/loginframe.c
|
||||
gtk/config-fetching.c
|
||||
gtk/audio_assistant.c
|
||||
[type: gettext/glade]gtk/main.ui
|
||||
[type: gettext/glade]gtk/about.ui
|
||||
[type: gettext/glade]gtk/contact.ui
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ ring_DATA=$(LINPHONE_RINGS)
|
|||
|
||||
#to be compliant with freedesktop.org:
|
||||
linphone_fddir= $(datadir)/applications
|
||||
linphone_fd_DATA= linphone.desktop
|
||||
linphone_fd_DATA= linphone.desktop audio-assistant.desktop
|
||||
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
|
|
@ -43,9 +43,10 @@ rootca.pem:
|
|||
cp -f $(srcdir)/archived-rootca.pem $(builddir)/rootca.pem ; \
|
||||
fi
|
||||
|
||||
EXTRA_DIST = $(LINPHONE_SOUNDS) \
|
||||
EXTRA_DIST = $(LINPHONE_SOUNDS) \
|
||||
$(LINPHONE_RINGS) \
|
||||
linphone.desktop.in \
|
||||
linphone.desktop.in \
|
||||
audio-assistant.desktop.in \
|
||||
linphone.pc.in \
|
||||
Makefile.inc \
|
||||
archived-rootca.pem
|
||||
|
|
|
|||
9
share/audio-assistant.desktop.in
Normal file
9
share/audio-assistant.desktop.in
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Name=Audio assistant
|
||||
Comment=Linphone audio assistant
|
||||
Comment[fr]=Assistant audio de Linphone.
|
||||
Type=Application
|
||||
Exec=linphone --run-audio-assistant
|
||||
Icon=/usr/local/share/pixmaps/linphone/linphone.png
|
||||
Terminal=false
|
||||
Categories=Network;Telephony;
|
||||
|
|
@ -519,7 +519,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee
|
|||
return success;
|
||||
}
|
||||
|
||||
static void call_with_ice(void) {
|
||||
static void _call_with_ice(bool_t random_ports) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -527,6 +527,13 @@ static void call_with_ice(void) {
|
|||
linphone_core_set_stun_server(marie->lc,"stun.linphone.org");
|
||||
linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce);
|
||||
linphone_core_set_stun_server(pauline->lc,"stun.linphone.org");
|
||||
|
||||
if (random_ports){
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
linphone_core_set_audio_port(pauline->lc,-1);
|
||||
linphone_core_set_video_port(pauline->lc,-1);
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
|
|
@ -536,8 +543,6 @@ static void call_with_ice(void) {
|
|||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
|
||||
liblinphone_tester_check_rtcp(marie,pauline);
|
||||
|
||||
|
||||
/*then close the call*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
|
|
@ -547,6 +552,14 @@ static void call_with_ice(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_with_ice(void){
|
||||
_call_with_ice(FALSE);
|
||||
}
|
||||
|
||||
static void call_with_ice_random_ports(void){
|
||||
_call_with_ice(TRUE);
|
||||
}
|
||||
|
||||
static void call_with_custom_headers(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
|
@ -718,6 +731,7 @@ static bool_t add_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee)
|
|||
return wait_for(caller->lc,callee->lc,&callee->stat.number_of_IframeDecoded,initial_callee_stat.number_of_IframeDecoded+1);
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
static void call_with_video_added(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
|
@ -733,7 +747,26 @@ static void call_with_video_added(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_with_video_added_random_ports(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
linphone_core_set_audio_port(pauline->lc,-1);
|
||||
linphone_core_set_video_port(pauline->lc,-1);
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
CU_ASSERT_TRUE(add_video(pauline,marie));
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->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));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_with_declined_video(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
|
|
@ -808,19 +841,26 @@ static void video_call(void) {
|
|||
}
|
||||
#endif /*VIDEO_ENABLED*/
|
||||
|
||||
static void call_with_media_relay(void) {
|
||||
static void _call_with_media_relay(bool_t random_ports) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
|
||||
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
|
||||
|
||||
if (random_ports){
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
linphone_core_set_audio_port(pauline->lc,-1);
|
||||
linphone_core_set_video_port(pauline->lc,-1);
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(pauline,marie);
|
||||
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
CU_ASSERT_TRUE(add_video(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(pauline,marie);
|
||||
#endif
|
||||
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
|
|
@ -828,7 +868,14 @@ static void call_with_media_relay(void) {
|
|||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_with_media_relay(void) {
|
||||
_call_with_media_relay(FALSE);
|
||||
}
|
||||
|
||||
static void call_with_media_relay_random_ports(void) {
|
||||
_call_with_media_relay(TRUE);
|
||||
}
|
||||
|
||||
static void call_with_privacy(void) {
|
||||
|
|
@ -886,8 +933,150 @@ static void call_with_privacy(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
/*this ones makes call with privacy without previous registration*/
|
||||
static void call_with_privacy2(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_rc",FALSE);
|
||||
LinphoneCall *c1,*c2;
|
||||
LinphoneCallParams *params;
|
||||
LinphoneProxyConfig* pauline_proxy;
|
||||
params=linphone_core_create_default_call_parameters(pauline->lc);
|
||||
linphone_call_params_set_privacy(params,LinphonePrivacyId);
|
||||
|
||||
linphone_core_get_default_proxy(pauline->lc,&pauline_proxy);
|
||||
linphone_proxy_config_edit(pauline_proxy);
|
||||
linphone_proxy_config_enable_register(pauline_proxy,FALSE);
|
||||
linphone_proxy_config_done(pauline_proxy);
|
||||
|
||||
CU_ASSERT_TRUE(call_with_caller_params(pauline,marie,params));
|
||||
linphone_call_params_destroy(params);
|
||||
|
||||
c1=linphone_core_get_current_call(pauline->lc);
|
||||
c2=linphone_core_get_current_call(marie->lc);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(c1);
|
||||
CU_ASSERT_PTR_NOT_NULL(c2);
|
||||
|
||||
/*make sure local identity is unchanged*/
|
||||
CU_ASSERT_TRUE(linphone_address_weak_equal(linphone_call_log_get_from(linphone_call_get_call_log(c1)),pauline->identity));
|
||||
|
||||
/*make sure remote identity is hidden*/
|
||||
CU_ASSERT_FALSE(linphone_address_weak_equal(linphone_call_get_remote_address(c2),pauline->identity));
|
||||
|
||||
CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId);
|
||||
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->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));
|
||||
|
||||
/*test proxy config privacy*/
|
||||
linphone_proxy_config_set_privacy(pauline_proxy,LinphonePrivacyId);
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
c1=linphone_core_get_current_call(pauline->lc);
|
||||
c2=linphone_core_get_current_call(marie->lc);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(c1);
|
||||
CU_ASSERT_PTR_NOT_NULL(c2);
|
||||
|
||||
/*make sure remote identity is hidden*/
|
||||
CU_ASSERT_FALSE(linphone_address_weak_equal(linphone_call_get_remote_address(c2),pauline->identity));
|
||||
|
||||
CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId);
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,2));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,2));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_waiting_indication_with_param(bool_t enable_caller_privacy) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc");
|
||||
char hellopath[256];
|
||||
MSList *iterator;
|
||||
LinphoneCall* pauline_called_by_marie;
|
||||
LinphoneCall* pauline_called_by_laure=NULL;
|
||||
LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc);
|
||||
LinphoneCallParams *marie_params=linphone_core_create_default_call_parameters(marie->lc);
|
||||
|
||||
if (enable_caller_privacy)
|
||||
linphone_call_params_set_privacy(marie_params,LinphonePrivacyId);
|
||||
|
||||
MSList* lcs=ms_list_append(NULL,marie->lc);
|
||||
lcs=ms_list_append(lcs,pauline->lc);
|
||||
lcs=ms_list_append(lcs,laure->lc);
|
||||
|
||||
CU_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params));
|
||||
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc);
|
||||
|
||||
|
||||
/*use playfile for callee to avoid locking on capture card*/
|
||||
linphone_core_use_files (laure->lc,TRUE);
|
||||
snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
|
||||
linphone_core_set_play_file(laure->lc,hellopath);
|
||||
if (enable_caller_privacy)
|
||||
linphone_call_params_set_privacy(laure_params,LinphonePrivacyId);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params));
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(laure->lc
|
||||
,pauline->lc
|
||||
,&pauline->stat.number_of_LinphoneCallIncomingReceived
|
||||
,2));
|
||||
|
||||
CU_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1);
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(laure->lc
|
||||
,pauline->lc
|
||||
,&laure->stat.number_of_LinphoneCallOutgoingRinging
|
||||
,1));
|
||||
|
||||
for (iterator=(MSList *)linphone_core_get_calls(pauline->lc);iterator!=NULL;iterator=iterator->next) {
|
||||
LinphoneCall *call=(LinphoneCall *)iterator->data;
|
||||
if (call != pauline_called_by_marie) {
|
||||
/*fine, this is the call waiting*/
|
||||
linphone_core_accept_call(pauline->lc,pauline_called_by_laure=call);
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(laure->lc
|
||||
,pauline->lc
|
||||
,&laure->stat.number_of_LinphoneCallConnected
|
||||
,1));
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc
|
||||
,marie->lc
|
||||
,&marie->stat.number_of_LinphoneCallPausedByRemote
|
||||
,1));
|
||||
|
||||
if (pauline_called_by_laure && enable_caller_privacy )
|
||||
CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId);
|
||||
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(laure);
|
||||
ms_list_free(lcs);
|
||||
}
|
||||
static void call_waiting_indication(void) {
|
||||
call_waiting_indication_with_param(FALSE);
|
||||
}
|
||||
|
||||
static void call_waiting_indication_with_privacy(void) {
|
||||
call_waiting_indication_with_param(TRUE);
|
||||
}
|
||||
|
||||
static void simple_conference(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
|
|
@ -1102,7 +1291,7 @@ static void early_media_call_with_ringing(void){
|
|||
|
||||
marie_call = linphone_core_invite_address(marie->lc, pauline->identity);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,1000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
|
||||
|
||||
|
||||
|
|
@ -1697,6 +1886,7 @@ test_t call_tests[] = {
|
|||
{ "Call failed because of codecs", call_failed_because_of_codecs },
|
||||
{ "Simple call", simple_call },
|
||||
{ "Call with media relay", call_with_media_relay},
|
||||
{ "Call with media relay (random ports)", call_with_media_relay_random_ports},
|
||||
{ "Simple call compatibility mode", simple_call_compatibility_mode },
|
||||
{ "Early-media call", early_media_call },
|
||||
{ "Early-media call with ringing", early_media_call_with_ringing },
|
||||
|
|
@ -1713,20 +1903,25 @@ test_t call_tests[] = {
|
|||
{ "Simple video call",video_call},
|
||||
{ "SRTP ice video call", srtp_video_ice_call },
|
||||
{ "Call with video added", call_with_video_added },
|
||||
{ "Call with video added (random ports)", call_with_video_added_random_ports },
|
||||
{ "Call with video declined",call_with_declined_video},
|
||||
#else
|
||||
{ "SRTP ice call", srtp_ice_call },
|
||||
#endif
|
||||
{ "Call with privacy", call_with_privacy },
|
||||
{ "Call with privacy 2", call_with_privacy2 },
|
||||
{ "Call rejected because of wrong credential", call_rejected_because_wrong_credentials},
|
||||
{ "Call rejected without 403 because of wrong credential", call_rejected_without_403_because_wrong_credentials},
|
||||
{ "Call rejected without 403 because of wrong credential and no auth req cb", call_rejected_without_403_because_wrong_credentials_no_auth_req_cb},
|
||||
{ "Call waiting indication", call_waiting_indication },
|
||||
{ "Call waiting indication with privacy", call_waiting_indication_with_privacy },
|
||||
{ "Simple conference", simple_conference },
|
||||
{ "Simple call transfer", simple_call_transfer },
|
||||
{ "Unattended call transfer", unattended_call_transfer },
|
||||
{ "Unattended call transfer with error", unattended_call_transfer_with_error },
|
||||
{ "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call },
|
||||
{ "Call with ICE", call_with_ice },
|
||||
{ "Call with ICE (random ports)", call_with_ice_random_ports },
|
||||
{ "Call with custom headers",call_with_custom_headers},
|
||||
{ "Call established with rejected INFO",call_established_with_rejected_info},
|
||||
{ "Call established with rejected RE-INVITE",call_established_with_rejected_reinvite},
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ static void subscribe_test_declined(void) {
|
|||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneContent content={0};
|
||||
LinphoneEvent *lev;
|
||||
const LinphoneErrorInfo *ei;
|
||||
MSList* lcs=ms_list_append(NULL,marie->lc);
|
||||
lcs=ms_list_append(lcs,pauline->lc);
|
||||
|
||||
|
|
@ -122,13 +124,21 @@ static void subscribe_test_declined(void) {
|
|||
|
||||
pauline->decline_subscribe=TRUE;
|
||||
|
||||
linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,&content);
|
||||
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,&content);
|
||||
linphone_event_ref(lev);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
|
||||
ei=linphone_event_get_error_info(lev);
|
||||
CU_ASSERT_PTR_NOT_NULL(ei);
|
||||
if (ei){
|
||||
CU_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603);
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
|
||||
}
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
|
||||
|
||||
linphone_event_unref(lev);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ no-403=user-agent contains 'tester-no-403'
|
|||
# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org')
|
||||
# && (user-agent == 'Linphone v2')
|
||||
# Default value:
|
||||
filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org'
|
||||
filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid'
|
||||
|
||||
# List of whitespace separated domain names to challenge. Others
|
||||
# are denied.
|
||||
|
|
|
|||
|
|
@ -263,6 +263,25 @@ static void text_message_with_send_error(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void text_message_denied(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to = linphone_address_as_string(pauline->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
|
||||
/*pauline doesn't want to be disturbed*/
|
||||
linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb);
|
||||
|
||||
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,marie->lc);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0);
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static const char *info_content="<somexml>blabla</somexml>";
|
||||
|
||||
void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneInfoMessage *msg){
|
||||
|
|
@ -360,6 +379,7 @@ test_t message_tests[] = {
|
|||
{ "Text message with ack", text_message_with_ack },
|
||||
{ "Text message with send error", text_message_with_send_error },
|
||||
{ "Text message with external body", text_message_with_external_body },
|
||||
{ "Text message denied", text_message_denied },
|
||||
{ "Info message", info_message },
|
||||
{ "Info message with body", info_message_with_body },
|
||||
{ "IsComposing notification", is_composing_notification }
|
||||
|
|
|
|||
11
tester/rcfiles/marie_remote_localfile2_rc
Normal file
11
tester/rcfiles/marie_remote_localfile2_rc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd">
|
||||
<section name="app">
|
||||
<entry name="show_login_view" overwrite="true">0</entry>
|
||||
<entry name="pushnotification_preference" overwrite="true">1</entry>
|
||||
</section>
|
||||
<section name="misc">
|
||||
<entry name="transient_provisioning" overwrite="true">1</entry>
|
||||
<entry name="tester_file_ok" overwrite="true">1</entry>
|
||||
</section>
|
||||
</config>
|
||||
3
tester/rcfiles/marie_remote_localfile_rc
Normal file
3
tester/rcfiles/marie_remote_localfile_rc
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[misc]
|
||||
config-uri=file://./rcfiles/marie_remote_localfile2_rc
|
||||
|
||||
|
|
@ -356,6 +356,22 @@ static void authenticated_register_with_wrong_credentials_with_params(const char
|
|||
/*wait for retry*/
|
||||
CU_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&counters->number_of_auth_info_requested,4));
|
||||
CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,1);
|
||||
|
||||
/*check the detailed error info */
|
||||
if (!user_agent || strcmp(user_agent,"tester-no-403")!=0){
|
||||
LinphoneProxyConfig *cfg=NULL;
|
||||
linphone_core_get_default_proxy(mgr->lc,&cfg);
|
||||
CU_ASSERT_PTR_NOT_NULL(cfg);
|
||||
if (cfg){
|
||||
const LinphoneErrorInfo *ei=linphone_proxy_config_get_error_info(cfg);
|
||||
const char *phrase=linphone_error_info_get_phrase(ei);
|
||||
CU_ASSERT_PTR_NOT_NULL(phrase);
|
||||
if (phrase) CU_ASSERT_TRUE(strcmp(phrase,"Forbidden")==0);
|
||||
CU_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),403);
|
||||
CU_ASSERT_PTR_NULL(linphone_error_info_get_details(ei));
|
||||
}
|
||||
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
static void authenticated_register_with_wrong_credentials() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
/*
|
||||
liblinphone_tester - liblinphone test suite
|
||||
Copyright (C) 2013 Belledonne Communications SARL
|
||||
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 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.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -29,9 +29,9 @@ void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState st
|
|||
if (status == LinphoneConfiguringSkipped) {
|
||||
counters->number_of_LinphoneConfiguringSkipped++;
|
||||
} else if (status == LinphoneConfiguringFailed) {
|
||||
counters->number_of_LinphoneConfiguringFailed++;
|
||||
counters->number_of_LinphoneConfiguringFailed++;
|
||||
} else if (status == LinphoneConfiguringSuccessful) {
|
||||
counters->number_of_LinphoneConfiguringSuccessful++;
|
||||
counters->number_of_LinphoneConfiguringSuccessful++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +89,18 @@ static void remote_provisioning_default_values(void) {
|
|||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void remote_provisioning_file(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new2("marie_remote_localfile_rc", FALSE);
|
||||
const LpConfig* conf;
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1));
|
||||
|
||||
conf = linphone_core_get_config( marie->lc );
|
||||
CU_ASSERT_EQUAL( lp_config_get_int(conf,"misc","tester_file_ok", 0), 1 );
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
|
||||
test_t remote_provisioning_tests[] = {
|
||||
{ "Remote provisioning skipped", remote_provisioning_skipped },
|
||||
{ "Remote provisioning successful behind http", remote_provisioning_http },
|
||||
|
|
@ -96,7 +108,8 @@ test_t remote_provisioning_tests[] = {
|
|||
{ "Remote provisioning 404 not found", remote_provisioning_not_found },
|
||||
{ "Remote provisioning invalid", remote_provisioning_invalid },
|
||||
{ "Remote provisioning transient successful", remote_provisioning_transient },
|
||||
{ "Remote provisioning default values", remote_provisioning_default_values }
|
||||
{ "Remote provisioning default values", remote_provisioning_default_values },
|
||||
{ "Remote provisioning from file", remote_provisioning_file }
|
||||
};
|
||||
|
||||
test_suite_t remote_provisioning_test_suite = {
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ static void linphone_stun_test_grab_ip()
|
|||
int tmp=0;
|
||||
|
||||
memset(&dummy_call, 0, sizeof(LinphoneCall));
|
||||
dummy_call.audio_port = 7078;
|
||||
dummy_call.audio_port = 9078;
|
||||
dummy_call.media_ports[0].rtp_port = 7078;
|
||||
dummy_call.media_ports[1].rtp_port = 9078;
|
||||
|
||||
linphone_core_set_stun_server(lc_stun->lc, stun_address);
|
||||
CU_ASSERT_STRING_EQUAL(stun_address, linphone_core_get_stun_server(lc_stun->lc));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue