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

This commit is contained in:
Ghislain MARY 2012-10-02 10:31:59 +02:00
commit 73321771a8
21 changed files with 615 additions and 144 deletions

View file

@ -219,7 +219,9 @@ bundle: $(LIBICONV_HACK)
MS2_PLUGINS_INSTALL_PREFIX=$(prefix) \
gtk-mac-bundler $(PACKAGE_BUNDLE_FILE)
printf "[Pango]\nModuleFiles=./etc/pango/pango.modules\n" \
> $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc
> $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc
cp -f $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig
sed -e 's:@executable_path/../Resources:../..:g' $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig > $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules
cp -f $(LIBICONV_HACK) $(BUNDLEDIR)/Contents/Resources/lib/.
cd $(BUNDLEDIR)/.. && rm -f $(MACAPPZIP) && zip -r $(MACAPPZIP) $(MACAPPNAME) && cd -

View file

@ -184,7 +184,6 @@ static void call_received(SalOp *h){
}
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
sal_call_set_local_media_description(h,call->localdesc);
/* the call is acceptable so we can now add it to our list */
linphone_core_add_call(lc,call);
@ -535,7 +534,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
call->localdesc->streams[i].proto = SalProtoRtpAvp;
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
}
linphone_core_start_invite(lc, call, NULL);
linphone_core_start_invite(lc, call);
}
return;
}

View file

@ -29,7 +29,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void ecc_init_filters(EcCalibrator *ecc){
unsigned int rate;
ecc->ticker=ms_ticker_new();
MSTickerParams params={0};
params.name="Echo calibrator";
params.prio=MS_TICKER_PRIO_HIGH;
ecc->ticker=ms_ticker_new_with_params(&params);
ecc->sndread=ms_snd_card_create_reader(ecc->play_card);
ms_filter_call_method(ecc->sndread,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate);

View file

@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCallStats;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
@ -97,6 +98,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}

View file

@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCallStats;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
@ -75,6 +76,7 @@ public class TutorialChatRoom implements LinphoneCoreListener {
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){}
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}

View file

@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCallStats;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
@ -69,6 +70,7 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}

View file

@ -20,6 +20,7 @@ package org.linphone.core.tutorials;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCallStats;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
@ -80,6 +81,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {}
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {}
public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){}

View file

@ -193,6 +193,22 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw
return l;
}
static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){
if (ac->port!=0){
strcpy(md->streams[0].rtp_addr,ac->addr);
md->streams[0].rtp_port=ac->port;
if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->nstreams==1){
strcpy(md->addr,ac->addr);
}
}
if (vc->port!=0){
strcpy(md->streams[1].rtp_addr,vc->addr);
md->streams[1].rtp_port=vc->port;
}
}
static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){
MSList *l;
PayloadType *pt;
@ -201,6 +217,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
LinphoneAddress *addr=linphone_address_new(me);
const char *username=linphone_address_get_username (addr);
SalMediaDescription *md=sal_media_description_new();
if (call->ping_time>0) {
linphone_core_adapt_to_network(lc,call->ping_time,&call->params);
}
md->session_id=session_id;
md->session_ver=session_ver;
@ -253,11 +273,11 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
md->streams[i].crypto[1].algo = 0;
md->streams[i].crypto[2].algo = 0;
}
if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, i) == NULL)) {
ice_session_add_check_list(call->ice_session, ice_check_list_new());
}
}
update_media_description_from_stun(md,&call->ac,&call->vc);
if (call->ice_session != NULL) {
linphone_core_update_local_media_description_from_ice(md, call->ice_session);
}
linphone_address_destroy(addr);
return md;
}
@ -327,20 +347,6 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
stats->ice_state = LinphoneIceStateNotActivated;
}
static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){
if (ac->port!=0){
strcpy(md->streams[0].rtp_addr,ac->addr);
md->streams[0].rtp_port=ac->port;
if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->nstreams==1){
strcpy(md->addr,ac->addr);
}
}
if (vc->port!=0){
strcpy(md->streams[1].rtp_addr,vc->addr);
md->streams[1].rtp_port=vc->port;
}
}
static void discover_mtu(LinphoneCore *lc, const char *remote){
int mtu;
@ -355,13 +361,9 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){
}
}
#define STUN_CANDIDATE_INIT {{0},0}
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params)
{
LinphoneCall *call=ms_new0(LinphoneCall,1);
StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT;
int ping_time=-1;
call->dir=LinphoneCallOutgoing;
call->op=sal_op_new(lc->sal);
sal_op_set_user_pointer(call->op,call);
@ -374,13 +376,8 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
ice_session_set_role(call->ice_session, IR_Controlling);
}
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) {
ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc);
call->ping_time=linphone_core_run_stun_tests(call->core,call);
}
if (ping_time>=0) {
linphone_core_adapt_to_network(lc,ping_time,&call->params);
}
call->localdesc=create_local_media_description(lc,call);
update_media_description_from_stun(call->localdesc,&ac,&vc);
call->camera_active=params->has_video;
discover_mtu(lc,linphone_address_get_domain (to));
@ -394,8 +391,6 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
LinphoneCall *call=ms_new0(LinphoneCall,1);
char *from_str;
int ping_time=-1;
StunCandidate ac=STUN_CANDIDATE_INIT,vc=STUN_CANDIDATE_INIT;
call->dir=LinphoneCallIncoming;
sal_op_set_user_pointer(op,call);
@ -418,6 +413,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
linphone_call_init_common(call, from, to);
linphone_core_init_default_params(lc, &call->params);
call->params.has_video &= !!lc->video_policy.automatically_accept;
call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(op));
switch (linphone_core_get_firewall_policy(call->core)) {
case LinphonePolicyUseIce:
call->ice_session = ice_session_new();
@ -429,21 +425,16 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
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(call);
linphone_call_stop_media_streams_for_ice_gathering(call);
}
}
break;
case LinphonePolicyUseStun:
ping_time=linphone_core_run_stun_tests(call->core,call,&ac, &vc);
call->ping_time=linphone_core_run_stun_tests(call->core,call);
/* No break to also destroy ice session in this case. */
default:
break;
}
if (ping_time>=0) {
linphone_core_adapt_to_network(lc,ping_time,&call->params);
};
call->localdesc=create_local_media_description(lc,call);
update_media_description_from_stun(call->localdesc,&ac,&vc);
call->camera_active=call->params.has_video;
discover_mtu(lc,linphone_address_get_domain(from));
@ -975,9 +966,11 @@ void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, Lin
void linphone_call_init_audio_stream(LinphoneCall *call){
LinphoneCore *lc=call->core;
AudioStream *audiostream;
int dscp=linphone_core_get_audio_dscp(lc);
int dscp;
if (call->audiostream != NULL) return;
call->audiostream=audiostream=audio_stream_new(call->audio_port,call->audio_port+1,linphone_core_ipv6_enabled(lc));
dscp=linphone_core_get_audio_dscp(lc);
if (dscp!=-1)
audio_stream_set_dscp(audiostream,dscp);
if (linphone_core_echo_limiter_enabled(lc)){
@ -1015,6 +1008,9 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
rtp_session_set_pktinfo(audiostream->session, TRUE);
rtp_session_set_symmetric_rtp(audiostream->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->ice_check_list = ice_session_check_list(call->ice_session, 0);
ice_check_list_set_rtp_session(audiostream->ice_check_list, audiostream->session);
}
@ -1027,6 +1023,11 @@ 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){
int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0);
int dscp=linphone_core_get_video_dscp(lc);
@ -1045,9 +1046,12 @@ void linphone_call_init_video_stream(LinphoneCall *call){
RtpTransport *vrtcp=lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->video_port+1);
rtp_session_set_transports(call->videostream->session,vrtp,vrtcp);
}
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, 1))){
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
rtp_session_set_pktinfo(call->videostream->session, TRUE);
rtp_session_set_symmetric_rtp(call->videostream->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->ice_check_list = ice_session_check_list(call->ice_session, 1);
ice_check_list_set_rtp_session(call->videostream->ice_check_list, call->videostream->session);
}
@ -1235,8 +1239,6 @@ static void setup_ring_player(LinphoneCore *lc, LinphoneCall *call){
ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
}
#define LINPHONE_RTCP_SDES_TOOL "Linphone-" LINPHONE_VERSION
static bool_t linphone_call_sound_resources_available(LinphoneCall *call){
LinphoneCore *lc=call->core;
LinphoneCall *current=linphone_core_get_current_call(lc);
@ -1255,6 +1257,8 @@ static int find_crypto_index_from_tag(const SalSrtpCryptoAlgo crypto[],unsigned
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;
char rtcp_tool[128]={0};
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
/* look for savp stream first */
const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
SalProtoRtpSavp,SalAudio);
@ -1340,7 +1344,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
if (send_ringbacktone){
setup_ring_player(lc,call);
}
audio_stream_set_rtcp_information(call->audiostream, cname, LINPHONE_RTCP_SDES_TOOL);
audio_stream_set_rtcp_information(call->audiostream, cname, rtcp_tool);
/* valid local tags are > 0 */
if (stream->proto == SalProtoRtpSavp) {
@ -1377,6 +1381,9 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
/* look for savp stream first */
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
SalProtoRtpSavp,SalVideo);
char rtcp_tool[128]={0};
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
/* no savp audio stream, use avp */
if (!vstream)
vstream=sal_media_description_find_stream(call->resultdesc,
@ -1432,7 +1439,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
cam=get_nowebcam_device();
}
if (!is_inactive){
call->log->video_enabled = TRUE;
call->log->video_enabled = TRUE;
video_stream_set_direction (call->videostream, dir);
ms_message("%s lc rotation:%d\n", __FUNCTION__, lc->device_rotation);
video_stream_set_device_rotation(call->videostream, lc->device_rotation);
@ -1440,7 +1447,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
call->video_profile, rtp_addr, vstream->rtp_port,
rtcp_addr, linphone_core_rtcp_enabled(lc) ? (vstream->rtcp_port) : 0,
used_pt, linphone_core_get_video_jittcomp(lc), cam);
video_stream_set_rtcp_information(call->videostream, cname,LINPHONE_RTCP_SDES_TOOL);
video_stream_set_rtcp_information(call->videostream, cname,rtcp_tool);
}
if (vstream->proto == SalProtoRtpSavp) {
@ -1536,6 +1543,15 @@ void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call){
#endif
}
void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call){
audio_stream_unprepare_sound(call->audiostream);
#ifdef VIDEO_ENABLED
if (call->videostream) {
video_stream_unprepare_video(call->videostream);
}
#endif
}
void linphone_call_delete_ice_session(LinphoneCall *call){
if (call->ice_session != NULL) {
ice_session_destroy(call->ice_session);
@ -1552,7 +1568,7 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
log->quality=audio_stream_get_average_quality_rating(st);
}
void linphone_call_stop_media_streams(LinphoneCall *call){
void linphone_call_stop_audio_stream(LinphoneCall *call) {
if (call->audiostream!=NULL) {
call->audiostream->ice_check_list = NULL;
rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq);
@ -1575,8 +1591,9 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
audio_stream_stop(call->audiostream);
call->audiostream=NULL;
}
}
void linphone_call_stop_video_stream(LinphoneCall *call) {
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL){
call->videostream->ice_check_list = NULL;
@ -1588,6 +1605,11 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
call->videostream=NULL;
}
#endif
}
void linphone_call_stop_media_streams(LinphoneCall *call){
linphone_call_stop_audio_stream(call);
linphone_call_stop_video_stream(call);
ms_event_queue_skip(call->core->msevq);
if (call->audio_profile){
@ -1767,20 +1789,21 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
OrtpEventType evt=ortp_event_get_type(ev);
OrtpEventData *evd=ortp_event_get_data(ev);
int ping_time;
if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
switch (ice_session_state(call->ice_session)) {
case IS_Completed:
ice_session_select_candidates(call->ice_session);
if (ice_session_role(call->ice_session) == IR_Controlling) {
ice_session_select_candidates(call->ice_session);
linphone_core_update_call(call->core, call, &call->current_params);
}
break;
case IS_Failed:
if (ice_session_has_completed_check_list(call->ice_session) == TRUE) {
ice_session_select_candidates(call->ice_session);
if (ice_session_role(call->ice_session) == IR_Controlling) {
/* At least one ICE session has succeeded, so perform a call update. */
ice_session_select_candidates(call->ice_session);
linphone_core_update_call(call->core, call, &call->current_params);
}
}
@ -1790,7 +1813,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
}
linphone_core_update_ice_state_in_call_stats(call);
} else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
int ping_time = -1;
if (evd->info.ice_processing_successful==TRUE) {
ice_session_compute_candidates_foundations(call->ice_session);
ice_session_eliminate_redundant_candidates(call->ice_session);
@ -1798,6 +1821,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
ping_time = ice_session_gathering_duration(call->ice_session);
if (ping_time >=0) {
ping_time /= ice_session_nb_check_lists(call->ice_session);
call->ping_time=ping_time;
}
} else {
ms_warning("No STUN answer from [%s], disabling ICE",linphone_core_get_stun_server(call->core));
@ -1811,17 +1835,11 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
linphone_core_start_accept_call_update(call->core, call);
break;
case LinphoneCallOutgoingInit:
if (ping_time >= 0) {
linphone_core_adapt_to_network(call->core, ping_time, &call->params);
}
linphone_call_stop_media_streams(call);
linphone_call_stop_media_streams_for_ice_gathering(call);
linphone_core_proceed_with_invite_if_ready(call->core, call, NULL);
break;
default:
if (ping_time >= 0) {
linphone_core_adapt_to_network(call->core, ping_time, &call->params);
}
linphone_call_stop_media_streams(call);
linphone_call_stop_media_streams_for_ice_gathering(call);
linphone_core_notify_incoming_call(call->core, call);
break;
}

View file

@ -1596,6 +1596,14 @@ void linphone_core_set_user_agent(const char *name, const char *ver){
strncpy(_ua_version,ver,sizeof(_ua_version));
}
const char *linphone_core_get_user_agent_name(void){
return _ua_name;
}
const char *linphone_core_get_user_agent_version(void){
return _ua_version;
}
static void transport_error(LinphoneCore *lc, const char* transport, int port){
char *msg=ortp_strdup_printf("Could not start %s transport on port %i, maybe this port is already used.",transport,port);
ms_warning("%s",msg);
@ -1908,9 +1916,9 @@ void linphone_core_iterate(LinphoneCore *lc){
ms_warning("ICE candidates gathering from [%s] has not finished yet, proceed with the call without ICE anyway."
,linphone_core_get_stun_server(lc));
linphone_call_delete_ice_session(call);
linphone_call_stop_media_streams(call);
linphone_call_stop_media_streams_for_ice_gathering(call);
}
linphone_core_start_invite(lc,call,NULL);
linphone_core_start_invite(lc,call);
}
if (call->state==LinphoneCallIncomingReceived){
elapsed=curtime-call->start_time;
@ -2174,16 +2182,17 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
}
if ((ice_ready == TRUE) && (ping_ready == TRUE)) {
return linphone_core_start_invite(lc, call, dest_proxy);
return linphone_core_start_invite(lc, call);
}
return 0;
}
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy){
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call){
int err;
char *contact;
char *real_url,*barmsg;
char *from;
LinphoneProxyConfig *dest_proxy=call->dest_proxy;
/*try to be best-effort in giving real local or routable contact address */
contact=get_fixed_contact(lc,call,dest_proxy);
@ -2195,10 +2204,9 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
linphone_call_init_media_streams(call);
if (lc->ringstream==NULL)
audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
call->localdesc=create_local_media_description(lc,call);
if (!lc->sip_conf.sdp_200_ack){
call->media_pending=TRUE;
if (call->ice_session != NULL)
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
sal_call_set_local_media_description(call->op,call->localdesc);
}
real_url=linphone_address_as_string(call->log->to);
@ -2316,10 +2324,9 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
{
const char *route=NULL;
const char *from=NULL;
LinphoneProxyConfig *proxy=NULL;
LinphoneProxyConfig *proxy=NULL,*dest_proxy=NULL;
LinphoneAddress *parsed_url2=NULL;
char *real_url=NULL;
LinphoneProxyConfig *dest_proxy=NULL;
LinphoneCall *call;
bool_t use_ice = FALSE;
@ -2352,6 +2359,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
parsed_url2=linphone_address_new(from);
call=linphone_call_new_outgoing(lc,parsed_url2,linphone_address_clone(addr),params);
call->dest_proxy=dest_proxy;
sal_op_set_route(call->op,route);
if(linphone_core_add_call(lc,call)!= 0)
@ -2371,13 +2379,13 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
if (linphone_core_gather_ice_candidates(lc,call)<0) {
/* Ice candidates gathering failed, proceed with the call anyway. */
linphone_call_delete_ice_session(call);
linphone_call_stop_media_streams(call);
linphone_call_stop_media_streams_for_ice_gathering(call);
} else {
use_ice = TRUE;
}
}
if (dest_proxy==NULL && lc->sip_conf.ping_with_options==TRUE){
if (call->dest_proxy==NULL && lc->sip_conf.ping_with_options==TRUE){
/*defer the start of the call after the OPTIONS ping*/
call->ping_replied=FALSE;
call->ping_op=sal_op_new(lc->sal);
@ -2385,7 +2393,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
sal_op_set_user_pointer(call->ping_op,call);
call->start_time=time(NULL);
}else{
if (use_ice==FALSE) linphone_core_start_invite(lc,call,dest_proxy);
if (use_ice==FALSE) linphone_core_start_invite(lc,call);
}
if (real_url!=NULL) ms_free(real_url);
@ -2457,8 +2465,8 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
if (call->ice_session != NULL)
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
call->localdesc=create_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
md=sal_call_get_final_media_description(call->op);
if (md && sal_media_description_empty(md)){
sal_call_decline(call->op,SalReasonMedia,NULL);
@ -2651,7 +2659,9 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
* @return 0 if sucessful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state).
**/
int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
#ifdef VIDEO_ENABLED
bool_t old_has_video = call->params.has_video;
#endif
if (call->state!=LinphoneCallUpdatedByRemote){
ms_error("linphone_core_accept_update(): invalid state %s to call this function.",
linphone_call_state_to_string(call->state));
@ -2662,10 +2672,15 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
}else
call->params=*params;
if (call->params.has_video && !linphone_core_video_enabled(lc)){
ms_warning("linphone_core_accept_call_update(): requested video but video support is globally disabled. Refusing video.");
call->params.has_video=FALSE;
}
if (call->current_params.in_conference) {
ms_warning("Video isn't supported in conference");
call->params.has_video = FALSE;
}
call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op));
call->camera_active=call->params.has_video;
update_local_media_description(lc,call);
if (call->ice_session != NULL) {
@ -2719,7 +2734,7 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call){
**/
int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params)
{
LinphoneProxyConfig *cfg=NULL,*dest_proxy=NULL;
LinphoneProxyConfig *cfg=NULL;
const char *contact=NULL;
SalOp *replaced;
SalMediaDescription *new_md;
@ -2767,31 +2782,32 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
}
linphone_core_get_default_proxy(lc,&cfg);
dest_proxy=cfg;
dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to);
call->dest_proxy=cfg;
call->dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to);
if (cfg!=dest_proxy && dest_proxy!=NULL) {
if (cfg!=call->dest_proxy && call->dest_proxy!=NULL) {
ms_message("Overriding default proxy setting for this call:");
ms_message("The used identity will be %s",linphone_proxy_config_get_identity(dest_proxy));
ms_message("The used identity will be %s",linphone_proxy_config_get_identity(call->dest_proxy));
}
/*try to be best-effort in giving real local or routable contact address*/
contact=get_fixed_contact(lc,call,dest_proxy);
contact=get_fixed_contact(lc,call,call->dest_proxy);
if (contact)
sal_op_set_contact(call->op,contact);
if (params){
call->params=*params;
call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op));
call->camera_active=call->params.has_video;
update_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
}
if (call->audiostream==NULL)
linphone_call_init_media_streams(call);
if (!was_ringing && call->audiostream->ticker==NULL){
audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
}
if (params){
call->params=*params;
call->camera_active=call->params.has_video;
update_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
}
sal_call_accept(call->op);
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Connected."));
@ -5085,7 +5101,7 @@ void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m) {
void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *params) {
params->has_video=linphone_core_video_enabled(lc) && lc->video_policy.automatically_initiate;
params->media_encryption=linphone_core_get_media_encryption(lc);
params->media_encryption=linphone_core_get_media_encryption(lc);
params->in_conference=FALSE;
}

View file

@ -899,11 +899,14 @@ void linphone_core_disable_logs(void);
/*sets the user-agent string in sip messages, must be set before linphone_core_new() or linphone_core_init() */
void linphone_core_set_user_agent(const char *ua_name, const char *version);
const char *linphone_core_get_version(void);
const char *linphone_core_get_user_agent_name(void);
const char *linphone_core_get_user_agent_version(void);
LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
const char *config_path, const char *factory_config, void* userdata);
/* function to be periodically called in a main loop */
/* For ICE to work properly it should be called every 20ms */
void linphone_core_iterate(LinphoneCore *lc);
#if 0 /*not implemented yet*/
/**
@ -1420,6 +1423,8 @@ int linphone_core_get_audio_dscp(const LinphoneCore *lc);
void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp);
int linphone_core_get_video_dscp(const LinphoneCore *lc);
#ifdef __cplusplus
}
#endif

View file

@ -112,6 +112,7 @@ public:
vTable.message_received = message_received;
vTable.new_subscription_request = new_subscription_request;
vTable.notify_presence_recv = notify_presence_recv;
vTable.call_stats_updated = callStatsUpdated;
listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener));
@ -133,6 +134,9 @@ public:
callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
/*callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);*/
callStatsUpdatedId = env->GetMethodID(listenerClass, "callStatsUpdated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCallStats;)V");
chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State"));
chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;");
@ -172,6 +176,10 @@ public:
addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl"));
addressCtrId =env->GetMethodID(addressClass,"<init>", "(J)V");
callStatsClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallStatsImpl"));
callStatsId = env->GetMethodID(callStatsClass, "<init>", "(JJ)V");
callSetAudioStatsId = env->GetMethodID(callClass, "setAudioStats", "(Lorg/linphone/core/LinphoneCallStats;)V");
callSetVideoStatsId = env->GetMethodID(callClass, "setVideoStats", "(Lorg/linphone/core/LinphoneCallStats;)V");
}
~LinphoneCoreData() {
@ -184,6 +192,7 @@ public:
env->DeleteGlobalRef(globalStateClass);
env->DeleteGlobalRef(registrationStateClass);
env->DeleteGlobalRef(callStateClass);
env->DeleteGlobalRef(callStatsClass);
env->DeleteGlobalRef(chatMessageStateClass);
env->DeleteGlobalRef(proxyClass);
env->DeleteGlobalRef(callClass);
@ -202,6 +211,7 @@ public:
jmethodID notifyPresenceReceivedId;
jmethodID textReceivedId;
jmethodID messageReceivedId;
jmethodID callStatsUpdatedId;
jclass globalStateClass;
jmethodID globalStateId;
@ -215,6 +225,11 @@ public:
jmethodID callStateId;
jmethodID callStateFromIntId;
jclass callStatsClass;
jmethodID callStatsId;
jmethodID callSetAudioStatsId;
jmethodID callSetVideoStatsId;
jclass chatMessageStateClass;
jmethodID chatMessageStateFromIntId;
@ -424,6 +439,24 @@ public:
}
}
static void callStatsUpdated(LinphoneCore *lc, LinphoneCall* call, const LinphoneCallStats *stats) {
JNIEnv *env = 0;
jobject statsobj;
jobject callobj;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM\n");
return;
}
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
statsobj = env->NewObject(lcData->callStatsClass, lcData->callStatsId, (jlong)call, (jlong)stats);
callobj = lcData->getCall(env, call);
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
env->CallVoidMethod(callobj, lcData->callSetAudioStatsId, statsobj);
else
env->CallVoidMethod(callobj, lcData->callSetVideoStatsId, statsobj);
env->CallVoidMethod(lcData->listener, lcData->callStatsUpdatedId, lcData->core, callobj, statsobj);
}
};
@ -913,6 +946,14 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMediaEncryption(JNIEn
linphone_core_set_media_encryption((LinphoneCore*)lc,(LinphoneMediaEncryption)menc);
}
extern "C" long Java_org_linphone_core_LinphoneCallParamsImpl_getUsedAudioCodec(JNIEnv *env, jobject thiz, jlong cp) {
return (long)linphone_call_params_get_used_audio_codec((LinphoneCallParams *)cp);
}
extern "C" long Java_org_linphone_core_LinphoneCallParamsImpl_getUsedVideoCodec(JNIEnv *env, jobject thiz, jlong cp) {
return (long)linphone_call_params_get_used_video_codec((LinphoneCallParams *)cp);
}
extern "C" int Java_org_linphone_core_LinphoneCallParamsImpl_getMediaEncryption(JNIEnv* env
,jobject thiz
,jlong cp
@ -1041,6 +1082,12 @@ extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_normalizePhone
env->ReleaseStringUTFChars(jnumber, number);
return normalizedNumber;
}
extern "C" jint Java_org_linphone_core_LinphoneProxyConfigImpl_lookupCCCFromIso(JNIEnv* env, jobject thiz, jlong proxyCfg, jstring jiso) {
const char* iso = env->GetStringUTFChars(jiso, NULL);
int prefix = linphone_dial_plan_lookup_ccc_from_iso(iso);
env->ReleaseStringUTFChars(jiso, iso);
return (jint) prefix;
}
extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_getDomain(JNIEnv* env
,jobject thiz
,jlong proxyCfg) {
@ -1211,6 +1258,122 @@ extern "C" jint Java_org_linphone_core_LinphoneCallLogImpl_getCallDuration(JNIEn
return ((LinphoneCallLog*)ptr)->duration;
}
/* CallStats */
extern "C" int Java_org_linphone_core_LinphoneCallStatsImpl_getMediaType(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (int)((LinphoneCallStats *)stats_ptr)->type;
}
extern "C" int Java_org_linphone_core_LinphoneCallStatsImpl_getIceState(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (int)((LinphoneCallStats *)stats_ptr)->ice_state;
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getDownloadBandwidth(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (jfloat)((LinphoneCallStats *)stats_ptr)->download_bandwidth;
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getUploadBandwidth(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (jfloat)((LinphoneCallStats *)stats_ptr)->upload_bandwidth;
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) {
const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
const report_block_t *srb = NULL;
if (!stats->sent_rtcp)
return (jfloat)0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->sent_rtcp->b_cont != NULL)
msgpullup(stats->sent_rtcp, -1);
if (rtcp_is_SR(stats->sent_rtcp))
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
else if (rtcp_is_RR(stats->sent_rtcp))
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
if (!srb)
return (jfloat)0.0;
return (jfloat)(100.0 * report_block_get_fraction_lost(srb) / 256.0);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) {
const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
const report_block_t *rrb = NULL;
if (!stats->received_rtcp)
return (jfloat)0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->received_rtcp->b_cont != NULL)
msgpullup(stats->received_rtcp, -1);
if (rtcp_is_RR(stats->received_rtcp))
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
else if (rtcp_is_SR(stats->received_rtcp))
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
if (!rrb)
return (jfloat)0.0;
return (jfloat)(100.0 * report_block_get_fraction_lost(rrb) / 256.0);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderInterarrivalJitter(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
const LinphoneCall *call = (LinphoneCall *)call_ptr;
const LinphoneCallParams *params = linphone_call_get_current_params(call);
const PayloadType *pt;
const report_block_t *srb = NULL;
if (!stats->sent_rtcp)
return (jfloat)0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->sent_rtcp->b_cont != NULL)
msgpullup(stats->sent_rtcp, -1);
if (rtcp_is_SR(stats->sent_rtcp))
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
else if (rtcp_is_RR(stats->sent_rtcp))
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
if (!srb)
return (jfloat)0.0;
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
pt = linphone_call_params_get_used_audio_codec(params);
else
pt = linphone_call_params_get_used_video_codec(params);
return (jfloat)((float)report_block_get_interarrival_jitter(srb) / (float)pt->clock_rate);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverInterarrivalJitter(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
const LinphoneCall *call = (LinphoneCall *)call_ptr;
const LinphoneCallParams *params = linphone_call_get_current_params(call);
const PayloadType *pt;
const report_block_t *rrb = NULL;
if (!stats->received_rtcp)
return (jfloat)0.0;
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
if (stats->received_rtcp->b_cont != NULL)
msgpullup(stats->received_rtcp, -1);
if (rtcp_is_SR(stats->received_rtcp))
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
else if (rtcp_is_RR(stats->received_rtcp))
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
if (!rrb)
return (jfloat)0.0;
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
pt = linphone_call_params_get_used_audio_codec(params);
else
pt = linphone_call_params_get_used_video_codec(params);
return (jfloat)((float)report_block_get_interarrival_jitter(rrb) / (float)pt->clock_rate);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getRoundTripDelay(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (jfloat)((LinphoneCallStats *)stats_ptr)->round_trip_delay;
}
extern "C" jlong Java_org_linphone_core_LinphoneCallStatsImpl_getLatePacketsCumulativeNumber(JNIEnv *env, jobject thiz, jlong stats_ptr, jlong call_ptr) {
LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr;
LinphoneCall *call = (LinphoneCall *)call_ptr;
rtp_stats_t rtp_stats;
memset(&rtp_stats, 0, sizeof(rtp_stats));
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
audio_stream_get_local_rtp_stats(call->audiostream, &rtp_stats);
#ifdef VIDEO_ENABLED
else
video_stream_get_local_rtp_stats(call->videostream, &rtp_stats);
#endif
return (jlong)rtp_stats.outoftime;
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getJitterBufferSize(JNIEnv *env, jobject thiz, jlong stats_ptr) {
return (jfloat)((LinphoneCallStats *)stats_ptr)->jitter_stats.jitter_buffer_size_ms;
}
/*payloadType*/
extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) {
PayloadType* pt = (PayloadType*)ptr;
@ -1558,6 +1721,9 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createDefaultCallParams
}
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteParams(JNIEnv *env, jobject thiz, jlong lc){
if (linphone_call_get_remote_params((LinphoneCall*)lc) == NULL) {
return (jlong) 0;
}
return (jlong) linphone_call_params_copy(linphone_call_get_remote_params((LinphoneCall*)lc));
}

View file

@ -467,8 +467,10 @@ static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id
}
/* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc){
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
const char *server=linphone_core_get_stun_server(lc);
StunCandidate *ac=&call->ac;
StunCandidate *vc=&call->vc;
if (lc->sip_conf.ipv6_enabled){
ms_warning("stun support is not implemented for ipv6");
@ -618,14 +620,17 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
lc->vtable.display_status(lc, _("ICE local candidates gathering in progress..."));
/* Gather local host candidates. */
if (linphone_core_get_local_ip_for(AF_INET, NULL, local_addr) < 0) {
if (linphone_core_get_local_ip_for(AF_INET, server, local_addr) < 0) {
ms_error("Fail to get local ip");
return -1;
}
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);
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
if (call->params.has_video && (video_check_list != NULL)) {
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);
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
}
if (call->params.has_video && (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);
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
@ -650,31 +655,39 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
session_state = ice_session_state(call->ice_session);
if ((session_state == IS_Completed) || ((session_state == IS_Failed) && (ice_session_has_completed_check_list(call->ice_session) == TRUE))) {
switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) {
case ICT_HostCandidate:
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection;
break;
case ICT_ServerReflexiveCandidate:
case ICT_PeerReflexiveCandidate:
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection;
break;
case ICT_RelayedCandidate:
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection;
break;
}
if (call->params.has_video && (video_check_list != NULL)) {
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
if (ice_check_list_state(audio_check_list) == ICL_Completed) {
switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) {
case ICT_HostCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection;
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection;
break;
case ICT_ServerReflexiveCandidate:
case ICT_PeerReflexiveCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection;
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection;
break;
case ICT_RelayedCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection;
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection;
break;
}
} else {
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed;
}
if (call->params.has_video && (video_check_list != NULL)) {
if (ice_check_list_state(video_check_list) == ICL_Completed) {
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
case ICT_HostCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection;
break;
case ICT_ServerReflexiveCandidate:
case ICT_PeerReflexiveCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection;
break;
case ICT_RelayedCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection;
break;
}
} else {
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
}
}
} else {
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed;
@ -770,10 +783,14 @@ void linphone_core_update_local_media_description_from_ice(SalMediaDescription *
int rtp_port, rtcp_port;
memset(stream->ice_remote_candidates, 0, sizeof(stream->ice_remote_candidates));
ice_check_list_selected_valid_remote_candidate(cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port);
strncpy(stream->ice_remote_candidates[0].addr, rtp_addr, sizeof(stream->ice_remote_candidates[0].addr));
stream->ice_remote_candidates[0].port = rtp_port;
strncpy(stream->ice_remote_candidates[1].addr, rtcp_addr, sizeof(stream->ice_remote_candidates[1].addr));
stream->ice_remote_candidates[1].port = rtcp_port;
if ((rtp_addr != NULL) && (rtcp_addr != NULL)) {
strncpy(stream->ice_remote_candidates[0].addr, rtp_addr, sizeof(stream->ice_remote_candidates[0].addr));
stream->ice_remote_candidates[0].port = rtp_port;
strncpy(stream->ice_remote_candidates[1].addr, rtcp_addr, sizeof(stream->ice_remote_candidates[1].addr));
stream->ice_remote_candidates[1].port = rtcp_port;
} else {
ms_error("ice: Selected valid remote candidates should be present if the check list is in the Completed state");
}
}
}
}
@ -902,6 +919,17 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
}
}
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md)
{
int i;
for (i = 0; i < md->nstreams; i++) {
if ((md->streams[i].type == SalVideo) && (md->streams[i].rtp_port != 0))
return TRUE;
}
return FALSE;
}
void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md)
{
int i;
@ -969,10 +997,15 @@ static int get_local_ip_with_getifaddrs(int type, char *address, int size)
if (getifaddrs(&ifpstart) < 0) {
return -1;
}
#ifndef __linux
#define UP_FLAG IFF_UP /* interface is up */
#else
#define UP_FLAG IFF_RUNNING /* resources allocated */
#endif
for (ifp = ifpstart; ifp != NULL; ifp = ifp->ifa_next) {
if (ifp->ifa_addr && ifp->ifa_addr->sa_family == type
&& (ifp->ifa_flags & IFF_RUNNING) && !(ifp->ifa_flags & IFF_LOOPBACK))
&& (ifp->ifa_flags & UP_FLAG) && !(ifp->ifa_flags & IFF_LOOPBACK))
{
getnameinfo(ifp->ifa_addr,
(type == AF_INET6) ?

View file

@ -99,7 +99,13 @@ struct _LinphoneChatMessage {
char* external_body_url;
LinphoneAddress* from;
};
typedef struct StunCandidate{
char addr[64];
int port;
}StunCandidate;
struct _LinphoneCall
{
int magic; /*used to distinguish from proxy config*/
@ -119,10 +125,12 @@ struct _LinphoneCall
LinphoneCallState state;
LinphoneCallState transfer_state; /*idle if no transfer*/
LinphoneReason reason;
LinphoneProxyConfig *dest_proxy;
int refcnt;
void * user_pointer;
int audio_port;
int video_port;
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
struct _AudioStream *audiostream; /**/
struct _VideoStream *videostream;
MSAudioEndpoint *endpoint; /*used for conferencing*/
@ -132,27 +140,31 @@ struct _LinphoneCall
LinphoneCallParams remote_params;
int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
int audio_bw; /*upload bandwidth used by audio */
bool_t refer_pending;
bool_t media_pending;
bool_t audio_muted;
bool_t camera_active;
bool_t all_muted; /*this flag is set during early medias*/
bool_t playing_ringbacktone;
bool_t owns_call_log;
bool_t ringing_beep; /* whether this call is ringing through an already existent current call*/
OrtpEvQueue *audiostream_app_evq;
char *auth_token;
OrtpEvQueue *videostream_app_evq;
bool_t videostream_encrypted;
bool_t audiostream_encrypted;
bool_t auth_token_verified;
bool_t defer_update;
bool_t was_automatically_paused;
bool_t ping_replied;
CallCallbackObj nextVideoFrameDecoded;
LinphoneCallStats stats[2];
IceSession *ice_session;
LinphoneChatMessage* pending_message;
int ping_time;
bool_t refer_pending;
bool_t media_pending;
bool_t audio_muted;
bool_t camera_active;
bool_t all_muted; /*this flag is set during early medias*/
bool_t playing_ringbacktone;
bool_t owns_call_log;
bool_t ringing_beep; /* whether this call is ringing through an already existent current call*/
bool_t videostream_encrypted;
bool_t audiostream_encrypted;
bool_t auth_token_verified;
bool_t defer_update;
bool_t was_automatically_paused;
bool_t ping_replied;
};
@ -233,17 +245,13 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFri
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt);
typedef struct StunCandidate{
char addr[64];
int port;
}StunCandidate;
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc);
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params);
int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call);
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md);
void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md);
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
@ -273,8 +281,11 @@ void linphone_call_init_video_stream(LinphoneCall *call);
void linphone_call_init_media_streams(LinphoneCall *call);
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call);
void linphone_call_stop_audio_stream(LinphoneCall *call);
void linphone_call_stop_video_stream(LinphoneCall *call);
void linphone_call_stop_media_streams(LinphoneCall *call);
void linphone_call_delete_ice_session(LinphoneCall *call);
void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call);
const char * linphone_core_get_identity(LinphoneCore *lc);
const char * linphone_core_get_route(LinphoneCore *lc);
@ -283,7 +294,7 @@ void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float
void linphone_core_stop_waiting(LinphoneCore *lc);
int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy);
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy);
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call);

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<requires lib="gtk+" version="2.18"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="dscp_settings">
<property name="can_focus">False</property>

View file

@ -159,6 +159,30 @@ public interface LinphoneCall {
* @Return LinphoneCallLog
**/
LinphoneCallLog getCallLog();
/**
* Set the audio statistics associated with this call.
* @return LinphoneCallStats
*/
void setAudioStats(LinphoneCallStats stats);
/**
* Set the video statistics associated with this call.
* @return LinphoneCallStats
*/
void setVideoStats(LinphoneCallStats stats);
/**
* Get the audio statistics associated with this call.
* @return LinphoneCallStats
*/
LinphoneCallStats getAudioStats();
/**
* Get the video statistics associated with this call.
* @return LinphoneCallStats
*/
LinphoneCallStats getVideoStats();
LinphoneCallParams getRemoteParams();

View file

@ -34,7 +34,7 @@ public interface LinphoneCallParams {
* @param value 0 to disable limitation
*/
void setAudioBandwidth(int value);
/**
* return selected media encryption
* @return MediaEncryption.None MediaEncryption.SRTP or MediaEncryption.ZRTP
@ -45,5 +45,16 @@ public interface LinphoneCallParams {
* @params menc: MediaEncryption.None, MediaEncryption.SRTP or MediaEncryption.ZRTP
*/
void setMediaEnctyption(MediaEncryption menc);
/**
* Get the currently used audio codec
* @return PayloadType or null
*/
PayloadType getUsedAudioCodec();
/**
* Get the currently used video codec
* @return PayloadType or null
*/
PayloadType getUsedVideoCodec();
}

View file

@ -0,0 +1,164 @@
/*
LinPhoneCallStats.java
Copyright (C) 2010 Belledonne Communications, Grenoble, France
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.
*/
package org.linphone.core;
import java.util.Vector;
public interface LinphoneCallStats {
static public class MediaType {
static private Vector values = new Vector();
/**
* Audio
*/
static public MediaType Audio = new MediaType(0, "Audio");
/**
* Video
*/
static public MediaType Video = new MediaType(1, "Video");
protected final int mValue;
private final String mStringValue;
private MediaType(int value, String stringValue) {
mValue = value;
values.addElement(this);
mStringValue = stringValue;
}
public static MediaType fromInt(int value) {
for (int i = 0; i < values.size(); i++) {
MediaType mtype = (MediaType) values.elementAt(i);
if (mtype.mValue == value) return mtype;
}
throw new RuntimeException("MediaType not found [" + value + "]");
}
public String toString() {
return mStringValue;
}
}
static public class IceState {
static private Vector values = new Vector();
/**
* Not activated
*/
static public IceState NotActivated = new IceState(0, "Not activated");
/**
* Failed
*/
static public IceState Failed = new IceState(1, "Failed");
/**
* In progress
*/
static public IceState InProgress = new IceState(2, "In progress");
/**
* Host connection
*/
static public IceState HostConnection = new IceState(3, "Host connection");
/**
* Reflexive connection
*/
static public IceState ReflexiveConnection = new IceState(4, "Reflexive connection");
/**
* Relay connection
*/
static public IceState RelayConnection = new IceState(5, "Relay connection");
protected final int mValue;
private final String mStringValue;
private IceState(int value, String stringValue) {
mValue = value;
values.addElement(this);
mStringValue = stringValue;
}
public static IceState fromInt(int value) {
for (int i = 0; i < values.size(); i++) {
IceState mstate = (IceState) values.elementAt(i);
if (mstate.mValue == value) return mstate;
}
throw new RuntimeException("IceState not found [" + value + "]");
}
public String toString() {
return mStringValue;
}
}
/**
* Get the stats media type
* @return MediaType
*/
public MediaType getMediaType();
/**
* Get the ICE state
*/
public IceState getIceState();
/**
* Get the download bandwidth in kbit/s
* @return The download bandwidth
*/
public float getDownloadBandwidth();
/**
* Get the upload bandwidth in kbit/s
* @return The upload bandwidth
*/
public float getUploadBandwidth();
/**
* Get the sender loss rate since last report
* @return The sender loss rate
*/
public float getSenderLossRate();
/**
* Get the receiver loss rate since last report
* @return The receiver loss rate
*/
public float getReceiverLossRate();
/**
* Get the sender interarrival jitter
* @return The interarrival jitter at last emitted sender report
*/
public float getSenderInterarrivalJitter();
/**
* Get the receiver interarrival jitter
* @return The interarrival jitter at last received receiver report
*/
public float getReceiverInterarrivalJitter();
/**
* Get the round trip delay
* @return The round trip delay in seconds, -1 if the information is not available
*/
public float getRoundTripDelay();
/**
* Get the cumulative number of late packets
* @return The cumulative number of late packets
*/
public long getLatePacketsCumulativeNumber();
/**
* Get the jitter buffer size
* @return The jitter buffer size in milliseconds
*/
public float getJitterBufferSize();
}

View file

@ -40,6 +40,11 @@ public interface LinphoneCoreListener {
* */
void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);
/**
* Call stats notification
*/
void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);
/**
* Callback to display change in encryption state.
* @param encrypted true if all streams of the call are encrypted

View file

@ -139,4 +139,10 @@ public interface LinphoneProxyConfig {
* @param parameters to add
*/
public void setContactParameters(String params);
/**
* Return the international prefix for the given country
* @param country iso code
*/
public int lookupCCCFromIso(String iso);
}

@ -1 +1 @@
Subproject commit f225ee612009009075ab6caf7ef91bb3a21fa25f
Subproject commit c3d6a095338c7d98647517b949e06e0b85f6443e

2
oRTP

@ -1 +1 @@
Subproject commit b7c5f78d83f8a310ba3700e93174c7eb1234d2d3
Subproject commit 8a8843b1f3a56888492b298d5262a61369e15bb7