Merge branch 'master' of git.linphone.org:linphone

This commit is contained in:
Simon Morlat 2012-11-06 18:20:34 +01:00
commit 754315b9e3
18 changed files with 332 additions and 80 deletions

View file

@ -63,7 +63,8 @@ LOCAL_CFLAGS += \
-DENABLE_TRACE \
-DLINPHONE_VERSION=\"$(LINPHONE_VERSION)\" \
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
-DLOG_DOMAIN=$(MY_LOG_DOMAIN)
-DLOG_DOMAIN=$(MY_LOG_DOMAIN) \
-DHAVE_EXOSIP_TRYLOCK=1
LOCAL_CFLAGS += -DIN_LINPHONE
@ -74,13 +75,18 @@ LOCAL_CFLAGS += -DHAVE_X264
endif
endif
ifeq ($(USE_JAVAH),1)
LOCAL_CFLAGS += -DUSE_JAVAH
endif
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/../oRTP/include \
$(LOCAL_PATH)/../mediastreamer2/include \
$(LOCAL_PATH)/../../externals/exosip/include \
$(LOCAL_PATH)/../../externals/osip/include
$(LOCAL_PATH)/../../externals/osip/include \
$(LOCAL_PATH)/../../../gen
LOCAL_LDLIBS += -llog -ldl

1
coreapi/.gitignore vendored
View file

@ -5,3 +5,4 @@ Makefile.in
*.lo
*.la
*.loT
liblinphone_gitversion.h

View file

@ -1,7 +1,17 @@
GITVERSION_FILE=liblinphone_gitversion.h
GITVERSION_FILE_TMP=liblinphone_gitversion.h.tmp
GITDESCRIBE=$(shell git describe)
GITREVISION=$(shell git rev-parse HEAD)
ECHO=/bin/echo
SUBDIRS=. help
EXTRA_DIST=linphonecore_jni.cc
EXTRA_DIST=linphonecore_jni.cc $(GITVERSION_FILE)
BUILT_SOURCES=$(GITVERSION_FILE)
CLEANFILES=$(GITVERSION_FILE)
## Process this file with automake to produce Makefile.in
linphone_includedir=$(includedir)/linphone
@ -41,7 +51,8 @@ liblinphone_la_SOURCES=\
lsd.c linphonecore_utils.h \
ec-calibrator.c \
conference.c \
linphone_tunnel.cc
linphone_tunnel.cc \
$(GITVERSION_FILE)
if BUILD_WIZARD
liblinphone_la_SOURCES+=sipwizard.c
@ -97,3 +108,18 @@ AM_CFLAGS+= -DBUILD_WIZARD
endif
AM_CXXFLAGS=$(AM_CFLAGS)
make_gitversion_h:
if test "$(GITDESCRIBE)" != "" ; then \
$(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(GITDESCRIBE)\"" > $(GITVERSION_FILE_TMP) ; \
elif test "$(GITREVISION)" != "" ; then \
$(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(LINPHONE_VERSION)_$(GITREVISION)\"" > $(GITVERSION_FILE_TMP) ; \
else \
$(ECHO) -n "" > $(GITVERSION_FILE_TMP) ; \
fi
if test "`cat $(GITVERSION_FILE_TMP)`" != "`cat $(srcdir)/$(GITVERSION_FILE)`" ; then \
cp -f $(GITVERSION_FILE_TMP) $(srcdir)/$(GITVERSION_FILE) ; \
fi
rm -f $(GITVERSION_FILE_TMP) ;
$(GITVERSION_FILE): make_gitversion_h

View file

@ -27,9 +27,63 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details);
static bool_t media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd){
if (call->params.in_conference!=call->current_params.in_conference) return TRUE;
return !sal_media_description_equals(oldmd,newmd) || call->up_bw!=linphone_core_get_upload_bandwidth(call->core);
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;
if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_CHANGED;
return sal_media_description_equals(oldmd, newmd);
}
void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) {
SalStreamDescription *old_audiodesc = NULL;
SalStreamDescription *old_videodesc = NULL;
SalStreamDescription *new_audiodesc = NULL;
SalStreamDescription *new_videodesc = NULL;
char *rtp_addr, *rtcp_addr;
int i;
for (i = 0; i < old_md->nstreams; i++) {
if (old_md->streams[i].type == SalAudio) {
old_audiodesc = &old_md->streams[i];
} else if (old_md->streams[i].type == SalVideo) {
old_videodesc = &old_md->streams[i];
}
}
for (i = 0; i < new_md->nstreams; i++) {
if (new_md->streams[i].type == SalAudio) {
new_audiodesc = &new_md->streams[i];
} else if (new_md->streams[i].type == SalVideo) {
new_videodesc = &new_md->streams[i];
}
}
if (call->audiostream && new_audiodesc) {
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->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->session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
}
#endif
/* Copy address and port values from new_md to old_md since we will keep old_md as resultdesc */
strcpy(old_md->addr, new_md->addr);
if (old_audiodesc && new_audiodesc) {
strcpy(old_audiodesc->rtp_addr, new_audiodesc->rtp_addr);
strcpy(old_audiodesc->rtcp_addr, new_audiodesc->rtcp_addr);
old_audiodesc->rtp_port = new_audiodesc->rtp_port;
old_audiodesc->rtcp_port = new_audiodesc->rtcp_port;
}
if (old_videodesc && new_videodesc) {
strcpy(old_videodesc->rtp_addr, new_videodesc->rtp_addr);
strcpy(old_videodesc->rtcp_addr, new_videodesc->rtcp_addr);
old_videodesc->rtp_port = new_videodesc->rtp_port;
old_videodesc->rtcp_port = new_videodesc->rtcp_port;
}
}
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
@ -49,7 +103,8 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
if ((call->audiostream && call->audiostream->ticker) || (call->videostream && call->videostream->ticker)){
/* we already started media: check if we really need to restart it*/
if (oldmd){
if (!media_parameters_changed(call,oldmd,new_md) && !call->playing_ringbacktone){
int md_changed = media_parameters_changed(call, oldmd, new_md);
if ((md_changed == SAL_MEDIA_DESCRIPTION_UNCHANGED) && !call->playing_ringbacktone) {
/*as nothing has changed, keep the oldmd */
call->resultdesc=oldmd;
sal_media_description_unref(new_md);
@ -66,6 +121,12 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
}
ms_message("No need to restart streams, SDP is unchanged.");
return;
} else if ((md_changed == SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED) && !call->playing_ringbacktone) {
call->resultdesc = oldmd;
ms_message("Network parameters have changed, update them.");
linphone_core_update_streams_destinations(lc, call, oldmd, new_md);
sal_media_description_unref(new_md);
return;
}else{
ms_message("Media descriptions are different, need to restart the streams.");
}
@ -718,14 +779,33 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){
}
}
static void text_received(Sal *sal, const char *from, const char *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
linphone_core_message_received(lc,from,msg,NULL);
static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){
MSList *elem=lc->last_recv_msg_ids;
int i;
bool_t is_duplicate=FALSE;
for(i=0;elem!=NULL;elem=elem->next,i++){
if (strcmp((const char*)elem->data,msg_id)==0){
is_duplicate=TRUE;
}
}
if (!is_duplicate){
lc->last_recv_msg_ids=ms_list_prepend(lc->last_recv_msg_ids,ms_strdup(msg_id));
}
if (i>=10){
ms_free(elem->data);
ms_list_remove_link(lc->last_recv_msg_ids,elem);
}
return is_duplicate;
}
void message_external_body_received(Sal *sal, const char *from, const char *url) {
static void text_received(Sal *sal, const SalMessage *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
linphone_core_message_received(lc,from,NULL,url);
if (is_duplicate_msg(lc,msg->message_id)==FALSE){
linphone_core_message_received(lc,msg->from,msg->text,msg->url);
}
}
static void notify(SalOp *op, const char *from, const char *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer (op);
@ -841,7 +921,6 @@ SalCallbacks linphone_sal_callbacks={
dtmf_received,
refer_received,
text_received,
message_external_body_received,
text_delivery_update,
notify,
notify_presence,

View file

@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "private.h"
#include <ortp/event.h>
#include <ortp/b64.h>
#include <math.h>
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msvolume.h"
@ -1189,7 +1189,7 @@ static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){
}
void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted){
float mic_gain=lp_config_get_float(lc->config,"sound","mic_gain",1);
float mic_gain=lc->sound_conf.soft_mic_lev;
float thres = 0;
float recv_gain;
float ng_thres=lp_config_get_float(lc->config,"sound","ng_thres",0.05);
@ -1197,7 +1197,7 @@ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t mute
int dc_removal=lp_config_get_int(lc->config,"sound","dc_removal",0);
if (!muted)
audio_stream_set_mic_gain(st,mic_gain);
linphone_core_set_mic_gain_db (lc, mic_gain);
else
audio_stream_set_mic_gain(st,0);
@ -1231,7 +1231,7 @@ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t mute
}
if (st->volrecv){
/* parameters for a limited noise-gate effect, using echo limiter threshold */
float floorgain = 1/mic_gain;
float floorgain = 1/pow(10,(mic_gain)/10);
int spk_agc=lp_config_get_int(lc->config,"sound","speaker_agc_enabled",0);
ms_filter_call_method(st->volrecv, MS_VOLUME_ENABLE_AGC, &spk_agc);
ms_filter_call_method(st->volrecv,MS_VOLUME_SET_NOISE_GATE_THRESHOLD,&ng_thres);

View file

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "lpconfig.h"
#include "private.h"
#include <math.h>
#include <ortp/telephonyevents.h>
#include <ortp/zrtp.h>
#include "mediastreamer2/mediastream.h"
@ -40,13 +41,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "liblinphone_gitversion.h"
#else
#ifndef LIBLINPHONE_GIT_VERSION
#define LIBLINPHONE_GIT_VERSION "unknown"
#endif
#endif
/*#define UNSTANDART_GSM_11K 1*/
#define ROOT_CA_FILE PACKAGE_DATA_DIR "/linphone/rootca.pem"
static const char *liblinphone_version=LIBLINPHONE_VERSION;
static const char *liblinphone_version=
#ifdef LIBLINPHONE_GIT_VERSION
LIBLINPHONE_GIT_VERSION
#else
LIBLINPHONE_VERSION
#endif
;
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
static void linphone_core_run_hooks(LinphoneCore *lc);
static void linphone_core_free_hooks(LinphoneCore *lc);
@ -413,7 +426,6 @@ static void sound_config_read(LinphoneCore *lc)
int tmp;
const char *tmpbuf;
const char *devid;
float gain=0;
#ifdef __linux
/*alsadev let the user use custom alsa device within linphone*/
devid=lp_config_get_string(lc->config,"sound","alsadev",NULL);
@ -485,8 +497,8 @@ static void sound_config_read(LinphoneCore *lc)
linphone_core_enable_agc(lc,
lp_config_get_int(lc->config,"sound","agc",0));
gain=lp_config_get_float(lc->config,"sound","playback_gain_db",0);
linphone_core_set_playback_gain_db (lc,gain);
linphone_core_set_playback_gain_db (lc,lp_config_get_float(lc->config,"sound","playback_gain_db",0));
linphone_core_set_mic_gain_db (lc,lp_config_get_float(lc->config,"sound","mic_gain_db",0));
linphone_core_set_remote_ringback_tone (lc,lp_config_get_string(lc->config,"sound","ringback_tone",NULL));
@ -583,6 +595,9 @@ static void sip_config_read(LinphoneCore *lc)
tmp=lp_config_get_int(lc->config,"sip","inc_timeout",30);
linphone_core_set_inc_timeout(lc,tmp);
tmp=lp_config_get_int(lc->config,"sip","in_call_timeout",0);
linphone_core_set_in_call_timeout(lc,tmp);
/* get proxies config */
for(i=0;; i++){
LinphoneProxyConfig *cfg=linphone_proxy_config_new_from_config_file(lc->config,i);
@ -1099,6 +1114,7 @@ static void misc_config_read (LinphoneCore *lc) {
static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path,
const char *factory_config_path, void * userdata)
{
ms_message("Initializing LinphoneCore %s", linphone_core_get_version());
memset (lc, 0, sizeof (LinphoneCore));
lc->data=userdata;
lc->ringstream_autorelease=TRUE;
@ -1183,6 +1199,9 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
sal_set_user_pointer(lc->sal,lc);
sal_set_callbacks(lc->sal,&linphone_sal_callbacks);
lc->network_last_check = 0;
lc->network_last_status = FALSE;
sip_setup_register_all();
sound_config_read(lc);
net_config_read(lc);
@ -1794,24 +1813,22 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
static void monitor_network_state(LinphoneCore *lc, time_t curtime){
static time_t last_check=0;
static bool_t last_status=FALSE;
char result[LINPHONE_IPADDR_SIZE];
bool_t new_status=last_status;
bool_t new_status=lc->network_last_status;
/* only do the network up checking every five seconds */
if (last_check==0 || (curtime-last_check)>=5){
if (lc->network_last_check==0 || (curtime-lc->network_last_check)>=5){
linphone_core_get_local_ip_for(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,NULL,result);
if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
new_status=TRUE;
}else new_status=FALSE;
last_check=curtime;
if (new_status!=last_status) {
lc->network_last_check=curtime;
if (new_status!=lc->network_last_status) {
if (new_status){
ms_message("New local ip address is %s",result);
}
set_network_reachable(lc,new_status, curtime);
last_status=new_status;
lc->network_last_status=new_status;
}
}
}
@ -1969,6 +1986,7 @@ void linphone_core_iterate(LinphoneCore *lc){
calls= lc->calls;
while(calls!= NULL){
call = (LinphoneCall *)calls->data;
elapsed = curtime-call->start_time;
/* get immediately a reference to next one in case the one
we are going to examine is destroy and removed during
linphone_core_start_invite() */
@ -1985,7 +2003,6 @@ void linphone_core_iterate(LinphoneCore *lc){
linphone_core_start_invite(lc,call);
}
if (call->state==LinphoneCallIncomingReceived){
elapsed=curtime-call->start_time;
ms_message("incoming call ringing for %i seconds",elapsed);
if (elapsed>lc->sip_conf.inc_timeout){
ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout);
@ -1994,6 +2011,10 @@ void linphone_core_iterate(LinphoneCore *lc){
linphone_core_terminate_call(lc,call);
}
}
if (lc->sip_conf.in_call_timeout > 0 && elapsed>lc->sip_conf.in_call_timeout) {
ms_message("in call timeout (%i)",lc->sip_conf.in_call_timeout);
linphone_core_terminate_call(lc,call);
}
}
if (linphone_core_video_preview_enabled(lc)){
@ -3201,6 +3222,26 @@ int linphone_core_get_inc_timeout(LinphoneCore *lc){
return lc->sip_conf.inc_timeout;
}
/**
* Set the in call timeout in seconds.
*
* @ingroup call_control
* After this timeout period, the call is automatically hangup.
**/
void linphone_core_set_in_call_timeout(LinphoneCore *lc, int seconds){
lc->sip_conf.in_call_timeout=seconds;
}
/**
* Returns the in call timeout
*
* @ingroup call_control
* See linphone_core_set_in_call_timeout() for details.
**/
int linphone_core_get_in_call_timeout(LinphoneCore *lc){
return lc->sip_conf.in_call_timeout;
}
void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away,
const char *contact,
LinphoneOnlineStatus presence_mode)
@ -3269,6 +3310,40 @@ void linphone_core_set_ring_level(LinphoneCore *lc, int level){
if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_PLAYBACK,level);
}
/**
* Allow to control microphone level: gain in db
*
* @ingroup media_parameters
**/
void linphone_core_set_mic_gain_db (LinphoneCore *lc, float gaindb){
float gain=gaindb;
LinphoneCall *call=linphone_core_get_current_call (lc);
AudioStream *st;
lc->sound_conf.soft_mic_lev=gaindb;
if (linphone_core_ready(lc)){
lp_config_set_float(lc->config,"sound","mic_gain_db",lc->sound_conf.soft_mic_lev);
}
if (call==NULL || (st=call->audiostream)==NULL){
ms_message("linphone_core_set_mic_gain_db(): no active call.");
return;
}
if (st->volrecv){
ms_filter_call_method(st->volsend,MS_VOLUME_SET_DB_GAIN,&gain);
}else ms_warning("Could not apply gain: gain control wasn't activated.");
}
/**
* Get microphone gain in db.
*
* @ingroup media_parameters
**/
float linphone_core_get_mic_gain_db(LinphoneCore *lc) {
return lc->sound_conf.soft_mic_lev;
}
/**
* Allow to control play level before entering sound card: gain in db
*
@ -3280,6 +3355,9 @@ void linphone_core_set_playback_gain_db (LinphoneCore *lc, float gaindb){
AudioStream *st;
lc->sound_conf.soft_play_lev=gaindb;
if (linphone_core_ready(lc)){
lp_config_set_float(lc->config,"sound","playback_gain_db",lc->sound_conf.soft_play_lev);
}
if (call==NULL || (st=call->audiostream)==NULL){
ms_message("linphone_core_set_playback_gain_db(): no active call.");
@ -3680,7 +3758,7 @@ void linphone_core_mute_mic(LinphoneCore *lc, bool_t val){
}
if (st!=NULL){
audio_stream_set_mic_gain(st,
(val==TRUE) ? 0 : lp_config_get_float(lc->config,"sound","mic_gain",1));
(val==TRUE) ? 0 : pow(10,lc->sound_conf.soft_mic_lev/10));
if ( linphone_core_get_rtp_no_xmit_on_audio_mute(lc) ){
audio_stream_mute_rtp(st,val);
}
@ -4044,7 +4122,7 @@ int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
if (id!=NULL){
lc->video_conf.device=ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),id);
if (lc->video_conf.device==NULL){
ms_warning("Could not found video device %s",id);
ms_warning("Could not find video device %s",id);
}
}
if (lc->video_conf.device==NULL)
@ -4597,6 +4675,7 @@ void sip_config_uninit(LinphoneCore *lc)
lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
lp_config_set_string(lc->config,"sip","contact",config->contact);
lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout);
lp_config_set_int(lc->config,"sip","in_call_timeout",config->in_call_timeout);
lp_config_set_int(lc->config,"sip","use_info",config->use_info);
lp_config_set_int(lc->config,"sip","use_rfc2833",config->use_rfc2833);
lp_config_set_int(lc->config,"sip","use_ipv6",config->ipv6_enabled);
@ -4665,6 +4744,8 @@ static void sound_config_uninit(LinphoneCore *lc)
ms_free(config->cards);
lp_config_set_string(lc->config,"sound","remote_ring",config->remote_ring);
lp_config_set_float(lc->config,"sound","playback_gain_db",config->soft_play_lev);
lp_config_set_float(lc->config,"sound","mic_gain_db",config->soft_mic_lev);
if (config->local_ring) ms_free(config->local_ring);
if (config->remote_ring) ms_free(config->remote_ring);
@ -4784,6 +4865,9 @@ static void linphone_core_uninit(LinphoneCore *lc)
ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_destroy);
lc->call_logs=ms_list_free(lc->call_logs);
ms_list_for_each(lc->last_recv_msg_ids,ms_free);
lc->last_recv_msg_ids=ms_list_free(lc->last_recv_msg_ids);
linphone_core_free_payload_types(lc);
ortp_exit();

View file

@ -1164,6 +1164,10 @@ void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds);
int linphone_core_get_inc_timeout(LinphoneCore *lc);
void linphone_core_set_in_call_timeout(LinphoneCore *lc, int seconds);
int linphone_core_get_in_call_timeout(LinphoneCore *lc);
void linphone_core_set_stun_server(LinphoneCore *lc, const char *server);
const char * linphone_core_get_stun_server(const LinphoneCore *lc);
@ -1192,9 +1196,11 @@ int linphone_core_get_rec_level(LinphoneCore *lc);
void linphone_core_set_ring_level(LinphoneCore *lc, int level);
void linphone_core_set_play_level(LinphoneCore *lc, int level);
void linphone_core_set_mic_gain_db(LinphoneCore *lc, float level);
float linphone_core_get_mic_gain_db(LinphoneCore *lc);
void linphone_core_set_playback_gain_db(LinphoneCore *lc, float level);
float linphone_core_get_playback_gain_db(LinphoneCore *lc);
void linphone_core_set_rec_level(LinphoneCore *lc, int level);
const char * linphone_core_get_ringer_device(LinphoneCore *lc);
const char * linphone_core_get_playback_device(LinphoneCore *lc);

View file

@ -17,6 +17,9 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <jni.h>
#ifdef USE_JAVAH
#include "linphonecore_jni.h"
#endif
#include "linphonecore_utils.h"
#include <ortp/zrtp.h>
@ -2134,6 +2137,10 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setIncomingTimeout(JNIEn
linphone_core_set_inc_timeout((LinphoneCore *)lc, timeout);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setInCallTimeout(JNIEnv *env, jobject thiz, jlong lc, jint timeout) {
linphone_core_set_in_call_timeout((LinphoneCore *)lc, timeout);
}
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getVersion(JNIEnv* env,jobject thiz,jlong ptr) {
jstring jvalue =env->NewStringUTF(linphone_core_get_version());
return jvalue;

View file

@ -382,6 +382,7 @@ typedef struct sip_config
MSList *proxies;
MSList *deleted_proxies;
int inc_timeout; /*timeout after an un-answered incoming call is rejected*/
int in_call_timeout; /*timeout after a call is hangup */
unsigned int keepalive_period; /* interval in ms between keep alive messages sent to the proxy server*/
LCSipTransports transports;
bool_t use_info;
@ -436,6 +437,7 @@ typedef struct sound_config
const char **cards;
int latency; /* latency in samples of the current used sound device */
float soft_play_lev; /*playback gain in db.*/
float soft_mic_lev; /*mic gain in db.*/
char rec_lev;
char play_lev;
char ring_lev;
@ -556,12 +558,16 @@ struct _LinphoneCore
bool_t network_reachable;
bool_t use_preview_window;
time_t network_last_check;
bool_t network_last_status;
bool_t ringstream_autorelease;
bool_t pad[3];
int device_rotation;
int max_calls;
LinphoneTunnel *tunnel;
char* device_id;
MSList *last_recv_msg_ids;
};
LinphoneTunnel *linphone_core_tunnel_new(LinphoneCore *lc);

View file

@ -177,32 +177,40 @@ static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
return TRUE;
}
bool_t sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2){
if (sd1->proto!=sd2->proto) return FALSE;
if (sd1->type!=sd2->type) return FALSE;
if (strcmp(sd1->rtp_addr,sd2->rtp_addr)!=0) return FALSE;
if (sd1->rtp_port!=sd2->rtp_port) return FALSE;
if (strcmp(sd1->rtcp_addr,sd2->rtcp_addr)!=0) return FALSE;
if (sd1->rtcp_port!=sd2->rtcp_port) return FALSE;
if (!payload_list_equals(sd1->payloads,sd2->payloads)) return FALSE;
if (sd1->bandwidth!=sd2->bandwidth) return FALSE;
if (sd1->ptime!=sd2->ptime) return FALSE;
/* compare candidates: TODO */
if (sd1->dir!=sd2->dir) return FALSE;
return TRUE;
int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2) {
int result = SAL_MEDIA_DESCRIPTION_UNCHANGED;
/* A different proto should result in SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED but the encryption change
needs a stream restart for now, so use SAL_MEDIA_DESCRIPTION_CODEC_CHANGED */
if (sd1->proto != sd2->proto) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (sd1->type != sd2->type) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (strcmp(sd1->rtp_addr, sd2->rtp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (sd1->rtp_port != sd2->rtp_port) {
if ((sd1->rtp_port == 0) || (sd2->rtp_port == 0)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
else result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
}
if (strcmp(sd1->rtcp_addr, sd2->rtcp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (sd1->rtcp_port != sd2->rtcp_port) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (!payload_list_equals(sd1->payloads, sd2->payloads)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (sd1->bandwidth != sd2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (sd1->ptime != sd2->ptime) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (sd1->dir != sd2->dir) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
return result;
}
bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2){
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2) {
int result = SAL_MEDIA_DESCRIPTION_UNCHANGED;
int i;
if (strcmp(md1->addr,md2->addr)!=0) return FALSE;
if (md1->nstreams!=md2->nstreams) return FALSE;
if (md1->bandwidth!=md2->bandwidth) return FALSE;
for(i=0;i<md1->nstreams;++i){
if (!sal_stream_description_equals(&md1->streams[i],&md2->streams[i]))
return FALSE;
if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (md1->nstreams != md2->nstreams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
for(i = 0; i < md1->nstreams; ++i){
result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
}
return TRUE;
return result;
}
static void assign_string(char **str, const char *arg){

View file

@ -53,6 +53,11 @@ typedef enum {
SalTransportDTLS /*DTLS*/
}SalTransport;
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED 0x01
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED 0x02
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED)
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
/* Address manipulation API*/
@ -183,13 +188,20 @@ typedef struct SalMediaDescription{
bool_t ice_completed;
} SalMediaDescription;
typedef struct SalMessage{
const char *from;
const char *text;
const char *url;
const char *message_id;
}SalMessage;
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5
SalMediaDescription *sal_media_description_new();
void sal_media_description_ref(SalMediaDescription *md);
void sal_media_description_unref(SalMediaDescription *md);
bool_t sal_media_description_empty(const SalMediaDescription *md);
bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
SalMediaProto proto, SalStreamType type);
@ -275,8 +287,7 @@ typedef void (*SalOnRegisterFailure)(SalOp *op, SalError error, SalReason reason
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)(Sal *sal, const char *from, const char *msg);
typedef void (*SalOnMessageExternalBodyReceived)(Sal *sal, const char *from, const char *url);
typedef void (*SalOnTextReceived)(Sal *sal, const SalMessage *msg);
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus status);
typedef void (*SalOnNotify)(SalOp *op, const char *from, const char *event);
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
@ -302,7 +313,6 @@ typedef struct SalCallbacks{
SalOnDtmfReceived dtmf_received;
SalOnRefer refer_received;
SalOnTextReceived text_received;
SalOnMessageExternalBodyReceived message_external_body;
SalOnTextDeliveryUpdate text_delivery_update;
SalOnNotify notify;
SalOnNotifyPresence notify_presence;

View file

@ -343,8 +343,6 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
if (ctx->callbacks.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
if (ctx->callbacks.message_external_body==NULL)
ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
}
int sal_unlisten_ports(Sal *ctx){
@ -415,6 +413,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
sal_set_dscp(ctx,ctx->dscp);
sal_use_dates(ctx,ctx->add_dates);
ipv6=strchr(addr,':')!=NULL;
eXosip_enable_ipv6(ipv6);
@ -1727,11 +1726,13 @@ static bool_t comes_from_local_if(osip_message_t *msg){
static void text_received(Sal *sal, eXosip_event_t *ev){
osip_body_t *body=NULL;
char *from=NULL,*msg;
char *from=NULL,*msg=NULL;
osip_content_type_t* content_type;
osip_uri_param_t* external_body_url;
char unquoted_external_body_url [256];
int external_body_size=0;
SalMessage salmsg;
char message_id[256]={0};
content_type= osip_message_get_content_type(ev->request);
if (!content_type) {
@ -1743,13 +1744,12 @@ static void text_received(Sal *sal, eXosip_event_t *ev){
&& strcmp(content_type->type, "text")==0
&& content_type->subtype
&& strcmp(content_type->subtype, "plain")==0 ) {
osip_message_get_body(ev->request,0,&body);
if (body==NULL){
ms_error("Could not get text message from SIP body");
return;
}
msg=body->body;
sal->callbacks.text_received(sal,from,msg);
osip_message_get_body(ev->request,0,&body);
if (body==NULL){
ms_error("Could not get text message from SIP body");
return;
}
msg=body->body;
} if (content_type->type
&& strcmp(content_type->type, "message")==0
&& content_type->subtype
@ -1761,11 +1761,18 @@ static void text_received(Sal *sal, eXosip_event_t *ev){
,&external_body_url->gvalue[1]
,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
unquoted_external_body_url[external_body_size-1]='\0';
sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
} else {
ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
osip_free(from);
return;
}
snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
salmsg.from=from;
salmsg.text=msg;
salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
salmsg.message_id=message_id;
sal->callbacks.text_received(sal,&salmsg);
osip_free(from);
}

View file

@ -38,7 +38,7 @@ public interface LinphoneCallLog {
/**
* Call success.
*/
public final static CallStatus Sucess = new CallStatus(0,"Sucess");
public final static CallStatus Success = new CallStatus(0,"Sucess");
/**
* Call aborted.
*/

View file

@ -7,8 +7,7 @@ public interface LinphoneChatMessage {
interface StateListener{
void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state);
}
static class State {
@SuppressWarnings("rawtypes")
public static class State {
static private Vector values = new Vector();
private final int mValue;
public final int value() {return mValue;}
@ -31,7 +30,6 @@ public interface LinphoneChatMessage {
*/
public final static State NotDelivered = new State(3,"NotDelivered");
@SuppressWarnings("unchecked")
private State(int value,String stringValue) {
mValue = value;
values.addElement(this);

View file

@ -189,21 +189,21 @@ public interface LinphoneCore {
* Media (RTP) encryption enum-like.
*
*/
static public class MediaEncryption {
static public final class MediaEncryption {
static private Vector values = new Vector();
/**
* None
*/
static public MediaEncryption None = new MediaEncryption(0,"None");
static public final MediaEncryption None = new MediaEncryption(0,"None");
/**
* SRTP
*/
static public MediaEncryption SRTP = new MediaEncryption(1,"SRTP");
static public final MediaEncryption SRTP = new MediaEncryption(1,"SRTP");
/**
* ZRTP
*/
static public MediaEncryption ZRTP = new MediaEncryption(2,"ZRTP");
static public final MediaEncryption ZRTP = new MediaEncryption(2,"ZRTP");
protected final int mValue;
private final String mStringValue;
@ -843,4 +843,10 @@ public interface LinphoneCore {
* automatically declined.
**/
void setIncomingTimeout(int timeout);
/**
* Set the call timeout in seconds.
* Once this time is elapsed (ringing included), the call is automatically hung up.
**/
void setInCallTimeout(int timeout);
}

View file

@ -21,4 +21,6 @@ package org.linphone.core;
public interface PayloadType {
String getMime();
int getRate();
}

View file

@ -115,6 +115,7 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void setAudioPortRange(long nativePtr, int minPort, int maxPort);
private native void setVideoPortRange(long nativePtr, int minPort, int maxPort);
private native void setIncomingTimeout(long nativePtr, int timeout);
private native void setInCallTimeout(long nativePtr, int timeout);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
mListener=listener;
@ -782,4 +783,9 @@ class LinphoneCoreImpl implements LinphoneCore {
public void setIncomingTimeout(int timeout) {
setIncomingTimeout(nativePtr, timeout);
}
public void setInCallTimeout(int timeout)
{
setInCallTimeout(nativePtr, timeout);
}
}

@ -1 +1 @@
Subproject commit 49f616a4b8d32b1ab2adeaa68c8f614ef77276da
Subproject commit f743c8b4ab7ec010a96aa53f2e179cea69bfb4e6