Commit 59ae512c authored by jehan's avatar jehan

merge public branch

parent dc8e7fa8
......@@ -98,6 +98,7 @@ other-cherrypick:
/mingw/bin/libstdc++-6.dll \
/mingw/bin/libintl-8.dll \
/mingw/bin/libiconv-2.dll \
/mingw/bin/libpthread-2.dll \
$(INSTALLDIR_WITH_PREFIX)/bin/.
......
......@@ -320,7 +320,11 @@ if test "$video" = "true"; then
if test "$enable_x11" = "true"; then
AC_CHECK_HEADERS(X11/Xlib.h)
AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11")
if test "$build_macos" = "yes"; then
X11_LIBS="-L/usr/X11/lib -lX11"
else
AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11")
fi
AC_SUBST(X11_LIBS)
fi
AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available])
......
......@@ -328,7 +328,7 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L
long id=(long)linphone_call_get_user_pointer (call);
switch(st){
case LinphoneCallEnd:
linphonec_out("Call %i with %s ended.\n", id, from);
linphonec_out("Call %i with %s ended (%s).\n", id, from, linphone_reason_to_string(linphone_call_get_reason(call)));
break;
case LinphoneCallResuming:
linphonec_out("Resuming call %i with %s.\n", id, from);
......@@ -358,7 +358,6 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L
case LinphoneCallOutgoingInit:
linphonec_call_identify(call);
id=(long)linphone_call_get_user_pointer (call);
from=linphone_call_get_remote_address_as_string(call);
linphonec_out("Establishing call id to %s, assigned id %i\n", from,id);
break;
case LinphoneCallUpdatedByRemote:
......
......@@ -49,7 +49,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
/* 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){
sal_media_description_unref(oldmd);
/*as nothing has changed, keep the oldmd */
call->resultdesc=oldmd;
sal_media_description_unref(new_md);
if (call->all_muted){
ms_message("Early media finished, unmuting inputs...");
/*we were in early media, now we want to enable real media */
......@@ -145,6 +147,7 @@ static void call_received(SalOp *h){
if (is_duplicate_call(lc,from_addr,to_addr)){
ms_warning("Receiving duplicated call, refusing this one.");
sal_call_decline(h,SalReasonBusy,NULL);
sal_op_release(h);
linphone_address_destroy(from_addr);
linphone_address_destroy(to_addr);
return;
......
......@@ -43,6 +43,13 @@
*
**/
/**
* @defgroup call_misc Obtaining information about a running call: sound volumes, quality indicators
*
* When a call is running, it is possible to retrieve in real time current measured volumes and quality indicator.
*
**/
/**
* @defgroup media_parameters Controlling media parameters
**/
......
......@@ -223,7 +223,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
/* this function is called internally to get rid of a call.
It performs the following tasks:
- remove the call from the internal list of calls
- unref the LinphoneCall object
- update the call logs accordingly
*/
......@@ -586,6 +585,17 @@ void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int
cp->audio_bw=bandwidth;
}
#ifdef VIDEO_ENABLED
/**
* Request remote side to send us a Video Fast Update.
**/
void linphone_call_send_vfu_request(LinphoneCall *call)
{
if (LinphoneCallStreamsRunning == linphone_call_get_state(call))
sal_call_send_vfu_request(call->op);
}
#endif
/**
*
**/
......@@ -659,6 +669,7 @@ void linphone_call_init_media_streams(LinphoneCall *call){
int enabled=lp_config_get_int(lc->config,"sound","noisegate",0);
audio_stream_enable_noise_gate(audiostream,enabled);
}
if (lc->a_rtp)
rtp_session_set_transports(audiostream->session,lc->a_rtp,lc->a_rtcp);
......@@ -772,9 +783,6 @@ static void post_configure_audio_streams(LinphoneCall*call){
}
}
static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){
int bw;
const MSList *elem;
......@@ -782,15 +790,17 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m
bool_t first=TRUE;
int remote_bw=0;
LinphoneCore *lc=call->core;
int up_ptime=0;
*used_pt=-1;
for(elem=desc->payloads;elem!=NULL;elem=elem->next){
PayloadType *pt=(PayloadType*)elem->data;
int number;
if (first) {
if ((pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND) && first) {
if (desc->type==SalAudio){
linphone_core_update_allocated_audio_bandwidth_in_call(call,pt);
up_ptime=linphone_core_get_upload_ptime(lc);
}
*used_pt=payload_type_get_number(pt);
first=FALSE;
......@@ -812,8 +822,11 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m
pt->normal_bitrate=-1;
}
if (desc->ptime>0){
up_ptime=desc->ptime;
}
if (up_ptime>0){
char tmp[40];
snprintf(tmp,sizeof(tmp),"ptime=%i",desc->ptime);
snprintf(tmp,sizeof(tmp),"ptime=%i",up_ptime);
payload_type_append_send_fmtp(pt,tmp);
}
number=payload_type_get_number(pt);
......@@ -843,6 +856,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
SalProtoRtpAvp,SalVideo);
#endif
bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc);
if(call->audiostream == NULL)
{
......@@ -866,7 +880,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
const char *playfile=lc->play_file;
const char *recfile=lc->rec_file;
call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt);
bool_t use_ec;
bool_t use_ec,use_arc_audio=use_arc;
if (used_pt!=-1){
if (playcard==NULL) {
......@@ -897,11 +911,17 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
playcard=NULL;
}
use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc);
#if defined(VIDEO_ENABLED) && defined(ANDROID)
/*On android we have to disable the echo canceller to preserve CPU for video codecs */
if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL)
#if defined(VIDEO_ENABLED)
if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){
/*when video is used, do not make adaptive rate control on audio, it is stupid.*/
use_arc_audio=FALSE;
#if defined(ANDROID)
/*On android we have to disable the echo canceller to preserve CPU for video codecs */
use_ec=FALSE;
#endif
}
#endif
audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc_audio);
audio_stream_start_full(
call->audiostream,
call->audio_profile,
......@@ -1005,6 +1025,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
audio_stream_get_local_rtp_stats (st,&log->local_stats);
log->quality=audio_stream_get_average_quality_rating(st);
}
void linphone_call_stop_media_streams(LinphoneCall *call){
......@@ -1041,16 +1062,7 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
}
}
#ifdef VIDEO_ENABLED
/**
* Request remote side to send us VFU.
**/
void linphone_call_send_vfu_request(LinphoneCall *call)
{
if (LinphoneCallStreamsRunning == linphone_call_get_state(call))
sal_call_send_vfu_request(call->op);
}
#endif
void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t enable) {
if (call!=NULL && call->audiostream!=NULL && call->audiostream->ec){
......@@ -1090,6 +1102,11 @@ bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call){
}
}
/**
* @addtogroup call_misc
* @{
**/
/**
* Returns the measured sound volume played locally (received from remote)
* It is expressed in dbm0.
......@@ -1120,6 +1137,45 @@ float linphone_call_get_record_volume(LinphoneCall *call){
return LINPHONE_VOLUME_DB_LOWEST;
}
/**
* Obtain real-time quality rating of the call
*
* Based on local RTP statistics and RTCP feedback, a quality rating is computed and updated
* during all the duration of the call. This function returns its value at the time of the function call.
* It is expected that the rating is updated at least every 5 seconds or so.
* The rating is a floating point number comprised between 0 and 5.
*
* 4-5 = good quality <br>
* 3-4 = average quality <br>
* 2-3 = poor quality <br>
* 1-2 = very poor quality <br>
* 0-1 = can't be worse, mostly unusable <br>
*
* @returns The function returns -1 if no quality measurement is available, for example if no
* active audio stream exist. Otherwise it returns the quality rating.
**/
float linphone_call_get_current_quality(LinphoneCall *call){
if (call->audiostream){
return audio_stream_get_quality_rating(call->audiostream);
}
return -1;
}
/**
* Returns call quality averaged over all the duration of the call.
*
* See linphone_call_get_current_quality() for more details about quality measurement.
**/
float linphone_call_get_average_quality(LinphoneCall *call){
if (call->audiostream){
return audio_stream_get_average_quality_rating(call->audiostream);
}
return -1;
}
/**
* @}
**/
static void display_bandwidth(RtpSession *as, RtpSession *vs){
ms_message("bandwidth usage: audio=[d=%.1f,u=%.1f] video=[d=%.1f,u=%.1f] kbit/sec",
......@@ -1172,6 +1228,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
if (call->videostream!=NULL)
video_stream_iterate(call->videostream);
#endif
if (call->audiostream!=NULL)
audio_stream_iterate(call->audiostream);
if (one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 )
disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout);
if (disconnected)
......
......@@ -124,6 +124,7 @@ void call_logs_write_to_config_file(LinphoneCore *lc){
lp_config_set_string(cfg,logsection,"start_date",cl->start_date);
lp_config_set_int(cfg,logsection,"duration",cl->duration);
if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey);
lp_config_set_float(cfg,logsection,"quality",cl->quality);
}
for(;i<lc->max_call_logs;++i){
snprintf(logsection,sizeof(logsection),"call_log_%i",i);
......@@ -151,6 +152,7 @@ static void call_logs_read_from_config_file(LinphoneCore *lc){
cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
if (tmp) cl->refkey=ms_strdup(tmp);
cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
lc->call_logs=ms_list_append(lc->call_logs,cl);
}else break;
}
......@@ -464,6 +466,7 @@ static void sip_config_read(LinphoneCore *lc)
sal_use_rport(lc->sal,lp_config_get_int(lc->config,"sip","use_rport",1));
sal_use_101(lc->sal,lp_config_get_int(lc->config,"sip","use_101",1));
sal_reuse_authorization(lc->sal, lp_config_get_int(lc->config,"sip","reuse_authorization",0));
tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
linphone_core_set_use_rfc2833_for_dtmf(lc,tmp);
......@@ -780,6 +783,26 @@ static void autoreplier_config_init(LinphoneCore *lc)
}
*/
/**
* Enable adaptive rate control (experimental feature, audio-only).
*
* Adaptive rate control consists in using RTCP feedback provided information to dynamically
* control the output bitrate of the encoders, so that we can adapt to the network conditions and
* available bandwidth.
**/
void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled){
lp_config_set_int(lc->config,"net","adaptive_rate_control",(int)enabled);
}
/**
* Returns whether adaptive rate control is enabled.
*
* See linphone_core_enable_adaptive_rate_control().
**/
bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){
return lp_config_get_int(lc->config,"net","adaptive_rate_control",FALSE);
}
/**
* Sets maximum available download bandwidth
*
......@@ -839,16 +862,38 @@ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){
return lc->net_conf.upload_bw;
}
/**
* set audio packetization time linphone expect to received from peer
* Set audio packetization time linphone expects to receive from peer
*/
void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) {
lc->net_conf.down_ptime=ptime;
}
int linphone_core_get_download_ptime(LinphoneCore *lc) {
/**
* Get audio packetization time linphone expects to receive from peer
*/
int linphone_core_get_download_ptime(LinphoneCore *lc) {
return lc->net_conf.down_ptime;
}
/**
* Set audio packetization time linphone will send (in absence of requirement from peer)
* A value of 0 stands for the current codec default packetization time.
*
**/
void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){
lp_config_set_int(lc->config,"rtp","upload_ptime",ptime);
}
/**
* Set audio packetization time linphone will send (in absence of requirement from peer)
* A value of 0 stands for the current codec default packetization time.
*
**/
int linphone_core_get_upload_ptime(LinphoneCore *lc){
return lp_config_get_int(lc->config,"rtp","upload_ptime",0);
}
/**
* Returns liblinphone's version as a string.
......@@ -1373,13 +1418,13 @@ static int apply_transports(LinphoneCore *lc){
sal_unlisten_ports (sal);
if (tr->udp_port>0){
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportDatagram,FALSE)!=0){
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
transport_error(lc,"UDP",tr->udp_port);
return -1;
}
}
if (tr->tcp_port>0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportStream,FALSE)!=0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
transport_error(lc,"TCP",tr->tcp_port);
}
}
......@@ -1636,9 +1681,9 @@ void linphone_core_iterate(LinphoneCore *lc){
linphone_core_start_invite() */
calls=calls->next;
if (call->state==LinphoneCallOutgoingInit && (curtime-call->start_time>=2)){
/*start the call even if the OPTIONS reply did not arrive*/
linphone_core_start_invite(lc,call,NULL);
}
/*start the call even if the OPTIONS reply did not arrive*/
linphone_core_start_invite(lc,call,NULL);
}
if (call->dir==LinphoneCallIncoming && call->state==LinphoneCallOutgoingRinging){
elapsed=curtime-call->start_time;
ms_message("incoming call ringing for %i seconds",elapsed);
......@@ -1996,7 +2041,6 @@ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddr
**/
LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params)
{
int err=0;
const char *route=NULL;
const char *from=NULL;
LinphoneProxyConfig *proxy=NULL;
......@@ -2049,7 +2093,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
lc->current_call=call;
linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call");
if (dest_proxy!=NULL || lc->sip_conf.ping_with_options==FALSE){
err=linphone_core_start_invite(lc,call,dest_proxy);
linphone_core_start_invite(lc,call,dest_proxy);
}else{
/*defer the start of the call after the OPTIONS ping*/
call->ping_op=sal_op_new(lc->sal);
......@@ -4079,7 +4123,7 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l
return p;
}
const char *linphone_error_to_string(LinphoneReason err){
const char *linphone_reason_to_string(LinphoneReason err){
switch(err){
case LinphoneReasonNone:
return "No error";
......@@ -4092,6 +4136,10 @@ const char *linphone_error_to_string(LinphoneReason err){
}
return "unknown error";
}
const char *linphone_error_to_string(LinphoneReason err){
return linphone_reason_to_string(err);
}
/**
* Enables signaling keep alive
*/
......
......@@ -152,6 +152,7 @@ typedef struct _LinphoneCallLog{
void *user_pointer;
rtp_stats_t local_stats;
rtp_stats_t remote_stats;
float quality;
struct _LinphoneCore *lc;
} LinphoneCallLog;
......@@ -255,6 +256,8 @@ LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
float linphone_call_get_play_volume(LinphoneCall *call);
float linphone_call_get_record_volume(LinphoneCall *call);
float linphone_call_get_current_quality(LinphoneCall *call);
float linphone_call_get_average_quality(LinphoneCall *call);
void *linphone_call_get_user_pointer(LinphoneCall *call);
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
/**
......@@ -702,18 +705,25 @@ void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw);
int linphone_core_get_download_bandwidth(const LinphoneCore *lc);
int linphone_core_get_upload_bandwidth(const LinphoneCore *lc);
void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled);
bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc);
/**
* set audio packetization time linphone expect to received from peer
* set audio packetization time linphone expect to receive from peer
* @ingroup media_parameters
*
*/
void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime);
/**
* get audio packetization time linphone expect to received from peer, 0 means unspecified
* get audio packetization time linphone expect to receive from peer, 0 means unspecified
* @ingroup media_parameters
*/
int linphone_core_get_download_ptime(LinphoneCore *lc);
void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime);
int linphone_core_get_upload_ptime(LinphoneCore *lc);
/* returns a MSList of PayloadType */
const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc);
......
......@@ -1023,6 +1023,18 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getReplacedCall( JNIEnv
return (jlong)linphone_call_get_replaced_call((LinphoneCall*)ptr);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getCurrentQuality( JNIEnv* env
,jobject thiz
,jlong ptr) {
return (jfloat)linphone_call_get_current_quality((LinphoneCall*)ptr);
}
extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getAverageQuality( JNIEnv* env
,jobject thiz
,jlong ptr) {
return (jfloat)linphone_call_get_average_quality((LinphoneCall*)ptr);
}
//LinphoneFriend
extern "C" long Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env
......@@ -1194,6 +1206,15 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNI
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadPtime(JNIEnv *env, jobject thiz, jlong lc, jint ptime){
linphone_core_set_download_ptime((LinphoneCore *)lc, (int) ptime);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadPtime(JNIEnv *env, jobject thiz, jlong lc, jint ptime){
linphone_core_set_upload_ptime((LinphoneCore *)lc, (int) ptime);
}
extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_getState(JNIEnv* env,jobject thiz,jlong ptr) {
return (int) linphone_proxy_config_get_state((const LinphoneProxyConfig *) ptr);
}
......
......@@ -307,9 +307,14 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke
void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
char tmp[30];
snprintf(tmp,30,"%i",value);
snprintf(tmp,sizeof(tmp),"%i",value);
lp_config_set_string(lpconfig,section,key,tmp);
}
void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key, float value){
char tmp[30];
snprintf(tmp,sizeof(tmp),"%f",value);
lp_config_set_string(lpconfig,section,key,tmp);
lpconfig->modified++;
}
void lp_item_write(LpItem *item, FILE *file){
......
......@@ -86,6 +86,12 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke
* @ingroup misc
**/
void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value);
/**
* Sets a float config item
*
* @ingroup misc
**/
void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key, float value);
/**
* Writes the config file to disk.
*
......
......@@ -250,7 +250,6 @@ LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate,
lsd_player_init(&lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd);
ms_filter_set_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0]);
ms_filter_enable_synchronous_notifcations (lsd->branches[0].player,TRUE);
for(i=1;i<MAX_BRANCHES;++i){
mp.pin=i;
lsd_player_init(&lsd->branches[i],mp,MS_FILE_PLAYER_ID,lsd);
......
......@@ -61,7 +61,7 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
}
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
const MSList *e2;
const MSList *e2,*e1;
MSList *res=NULL;
PayloadType *matched;
bool_t found_codec=FALSE;
......@@ -85,6 +85,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
newp=payload_type_clone(matched);
if (p2->send_fmtp)
payload_type_set_send_fmtp(newp,p2->send_fmtp);
newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND;
res=ms_list_append(res,newp);
/* we should use the remote numbering even when parsing a response */
payload_type_set_number(newp,remote_number);
......@@ -96,7 +97,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
Indeed despite we must sent with the remote numbering, we must be able to receive with
our local one.
*/
newp=payload_type_clone(matched);
newp=payload_type_clone(newp);
payload_type_set_number(newp,local_number);
res=ms_list_append(res,newp);
}
......@@ -104,6 +105,26 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate);
}
}
if (reading_response){
/* add remaning local payload as CAN_RECV only so that if we are in front of a non-compliant equipment we are still able to decode the RTP stream*/
for(e1=local;e1!=NULL;e1=e1->next){
PayloadType *p1=(PayloadType*)e1->data;
bool_t found=FALSE;
for(e2=res;e2!=NULL;e2=e2->next){
PayloadType *p2=(PayloadType*)e2->data;
if (payload_type_get_number(p2)==payload_type_get_number(p1)){
found=TRUE;
break;
}
}
if (!found){
ms_message("Adding %s/%i for compatibility, just in case.",p1->mime_type,p1->clock_rate);
p1=payload_type_clone(p1);
p1->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV;
res=ms_list_append(res,p1);
}
}
}
return res;
}
......
......@@ -259,7 +259,7 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
linphone_core_get_sip_transports(obj->lc,&tr);
if (tr.udp_port <= 0 && tr.tcp_port>0) {
sal_address_add_param(contact,"transport","tcp");
sal_address_set_param(contact,"transport","TCP");
}
ret=linphone_address_as_string(contact);
linphone_address_destroy(contact);
......@@ -269,10 +269,6 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
}
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
const char *id_str;
if (obj->reg_identity!=NULL) id_str=obj->reg_identity;
else id_str=linphone_core_get_primary_contact(obj->lc);
if (obj->reg_sendregister){
char *contact;
if (obj->op)
......
......@@ -24,7 +24,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**/
#include "sal.h"
const char* sal_transport_to_string(SalTransport transport) {
switch (transport) {
case SalTransportUDP:return "UDP";
case SalTransportTCP: return "TCP";
case SalTransportTLS:return "TLS";
case SalTransportDTLS:return "DTLS";
default: {
ms_fatal("Unexpected transport [%i]",transport);
return NULL;
}
}
}
SalTransport sal_transport_parse(const char* param) {
if (strcasecmp("UDP",param)==0) return SalTransportUDP;
if (strcasecmp("TCP",param)==0) return SalTransportTCP;
if (strcasecmp("TLS",param)==0) return SalTransportTLS;
if (strcasecmp("DTLS",param)==0) return SalTransportDTLS;
ms_error("Unkown transport type[%s], returning UDP", param);
return SalTransportUDP;
}
SalMediaDescription *sal_media_description_new(){
SalMediaDescription *md=ms_new0(SalMediaDescription,1);
md->refcount=1;
......@@ -309,3 +329,4 @@ void sal_auth_info_delete(const SalAuthInfo* auth_info) {
if (auth_info->password) ms_free(auth_info->password);
ms_free((void*)auth_info);
}
......@@ -28,6 +28,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mscommon.h"
/*Dirty hack, keep in sync with mediastreamer2/include/mediastream.h */
#ifndef PAYLOAD_TYPE_FLAG_CAN_RECV
#define PAYLOAD_TYPE_FLAG_CAN_RECV PAYLOAD_TYPE_USER_FLAG_1
#define PAYLOAD_TYPE_FLAG_CAN_SEND PAYLOAD_TYPE_USER_FLAG_2
#endif
struct Sal;
typedef struct Sal Sal;
......@@ -40,6 +45,15 @@ struct SalAddress;
typedef struct SalAddress SalAddress;
typedef enum {
SalTransportUDP, /*UDP*/
SalTransportTCP, /*TCP*/
SalTransportTLS, /*TLS*/
SalTransportDTLS /*DTLS*/
}SalTransport;
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
/* Address manipulation API*/
SalAddress * sal_address_new(const char *uri);
SalAddress * sal_address_clone(const SalAddress *addr);
......@@ -49,7 +63,8 @@ char *sal_address_get_display_name_unquoted(const SalAddress *addr);
const char *sal_address_get_username(const SalAddress *addr);
const char *sal_address_get_domain(const SalAddress *addr);
const char * sal_address_get_port(const SalAddress *addr);
int sal_address_get_port_int(const SalAddress *uri);
int sal_address_get_port_int(const SalAddress *addr);
SalTransport sal_address_get_transport(const SalAddress* addr);
void sal_address_set_display_name(SalAddress *addr, const char *display_name);
void sal_address_set_username(SalAddress *addr, const char *username);
......@@ -60,8 +75,8 @@ void sal_address_clean(SalAddress *addr);
char *sal_address_as_string(const SalAddress *u);
char *sal_address_as_string_uri_only(const SalAddress *u);
void sal_address_destroy(SalAddress *u);
void sal_address_add_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_transport(SalAddress* addr,SalTransport transport);
Sal * sal_init();
......@@ -69,10 +84,6 @@ void sal_uninit(Sal* sal);
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
typedef enum {
SalTransportDatagram,
SalTransportStream
}SalTransport;
typedef enum {
SalAudio,
......@@ -261,6 +272,7 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value);
unsigned int sal_get_keepalive_period(Sal *ctx);
void sal_use_session_timers(Sal *ctx, int expires);
void sal_use_double_registrations(Sal *ctx, bool_t enabled);
void sal_reuse_authorization(Sal *ctx, bool_t enabled);
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
void sal_use_rport(Sal *ctx, bool_t use_rports);
void sal_use_101(Sal *ctx, bool_t use_101);
......@@ -313,6 +325,7 @@ int sal_call_send_dtmf(SalOp *h, char dtmf);
int sal_call_terminate(SalOp *h);
bool_t sal_call_autoanswer_asked(SalOp *op);
void sal_call_send_vfu_request(SalOp *h);
int sal_call_is_offerer(const SalOp *h);
/*Registration*/
int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
......@@ -337,6 +350,8 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus s
/*ping: main purpose is to obtain its own contact address behind firewalls*/
int sal_ping(SalOp *op, const char *from, const char *to);