Commit f8955003 authored by jehan's avatar jehan
Browse files

Merge branch 'master' of git.sv.gnu.org:/srv/git/linphone

parents 966ecb6a df987019
Simon MORLAT (simon dot morlat at linphone dot org) wrotes:
- main graphical program (gnome)
- RTP library (oRTP)
- SIP user-agent library (osipua)
- audio library (mediastreamer), for codec and i/o handling.
- sipomatic, the automatic sip replier, which is often used for testing.
Main authors:
Florian Wintertein < f-win at gmx dot net > wrotes the console version of linphone (linphonec)
in console/ directory.
Belledonne Communications SARL team:
Simon Morlat, Jehan Monnier, Guillaume Beraudo
Aymeric Moizard (jack at atosc dot org) wrotes:
- the oSIP SIP transactionnal stack (not part of linphone)
- some piece of code of the osip distribution have been reused in osipua
- presence information support in osipua
- and contributes to some parts of osipua (digest authentification)
For more information about oSIP, see http://osip.atosc.org
Contributors:
Sharath Udupa is developing the media_api, a usefull library to manage audio and video streams
for basic calls as well as conference.
Florian Wintertein < f-win at gmx dot net > originaly wrotes the console version of linphone (linphonec)
in console/ directory.
Sandro Santilli < strk at keybit dot net > wrote enhancements in the
console interface (readline, new commands) and some bug fixes for
the core api.
Bryan Ogawa ( bko at cisco dot com ) sent a patch that made the linphone-0.7.1 release.
This patch fixed several issues in the SIP part while working with proxies.
Koichi KUNITAKE < kunitake at linux-ipv6 dot org > has contributed a patch bringing
full IPv6 support.
The Speex codec is a project from Jean Marc Valin. See http://speex.sourceforge.net for more
information.
The GSM library was written by :
Jutta Degener and Carsten Bormann,Technische Universitaet Berlin.
The LPC10-1.5 library was written by:
Andy Fingerhut
Applied Research Laboratory <-- this line is optional if
Washington University, Campus Box 1045/Bryan 509 you have limited space
One Brookings Drive
Saint Louis, MO 63130-4899
jaf@arl.wustl.edu
http://www.arl.wustl.edu/~jaf/
See text files in gsmlib and lpc10-1.5 directories for further information.
G711 library has some code from the alsa-lib on http://www.alsa-project.org
Icons by Pablo Marcelo Moia.
console interface (readline, new commands).
Translations:
fr: Simon Morlat
en: Simon Morlat and Delphine Perreau
it: Alberto Zanoni <alberto.zanoni@-NO-SPAM-PLEASE!-tiscalinet.it>
de: Jean-Jacques Sarton <jj.sarton@-NO-SPAM-PLEASE-t-online.de>
es: Jesús Benítez <gnelson at inMail dot sk>
linphone-3.4.0 -- XXXXX
linphone-3.4.0 -- February 2nd, 2011
* implement multiple calls feature:
- call hold (with possibility to play a music file)
- call resume
......
......@@ -53,7 +53,7 @@ LOCAL_CFLAGS += \
-D_BYTE_ORDER=_LITTLE_ENDIAN \
-DORTP_INET6 \
-DENABLE_TRACE \
-DLINPHONE_VERSION=\"Linphone-3.3.x\" \
-DLINPHONE_VERSION=\"3.4.0\" \
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
-DLOG_DOMAIN=\"Linphone\"
......
dnl Process this file with autoconf to produce a configure script.
AC_INIT([linphone],[3.3.99.10],[linphone-developers@nongnu.org])
AC_INIT([linphone],[3.4.0],[linphone-developers@nongnu.org])
AC_CANONICAL_SYSTEM
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
......
......@@ -303,18 +303,30 @@ static void call_accepted(SalOp *op){
ms_free(msg);
}
linphone_core_update_streams (lc,call,md);
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
}else{
if (lc->vtable.display_status){
lc->vtable.display_status(lc,_("Call answered - connected."));
}
if (call->state==LinphoneCallStreamsRunning){
/*media was running before, the remote as acceted a call modification (that is
a reinvite made by us. We must notify the application this reinvite was accepted*/
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
}else{
if (call->state==LinphoneCallResuming){
if (lc->vtable.display_status){
lc->vtable.display_status(lc,_("Call resumed."));
}
}else{
if (lc->vtable.display_status){
char *tmp=linphone_call_get_remote_address_as_string (call);
char *msg=ms_strdup_printf(_("Call answered by %s."),tmp);
lc->vtable.display_status(lc,msg);
ms_free(tmp);
ms_free(msg);
}
}
}
linphone_core_update_streams (lc,call,md);
linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
lc->current_call=call;
}
}else{
/*send a bye*/
......@@ -349,6 +361,7 @@ static void call_ack(SalOp *op){
}
}
/* this callback is called when an incoming re-INVITE modifies the session*/
static void call_updating(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
......@@ -360,32 +373,22 @@ static void call_updating(SalOp *op){
if (md && !sal_media_description_empty(md))
{
if ((call->state==LinphoneCallPausedByRemote || call->state==LinphoneCallPaused) &&
sal_media_description_has_dir(md,SalStreamSendRecv) && strcmp(md->addr,"0.0.0.0")!=0){
/*make sure we can be resumed */
if (lc->current_call!=NULL && lc->current_call!=call){
ms_warning("Attempt to be resumed but already in call with somebody else!");
/*we are actively running another call, reject with a busy*/
sal_call_decline (op,SalReasonBusy,NULL);
return;
}
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We have been resumed..."));
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
}
else if(call->state==LinphoneCallStreamsRunning &&
( sal_media_description_has_dir(md,SalStreamRecvOnly)
|| sal_media_description_has_dir(md,SalStreamInactive)
|| strcmp(md->addr,"0.0.0.0")==0)){
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We are being paused..."));
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
if (lc->current_call!=call){
ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call);
if (sal_media_description_has_dir(call->localdesc,SalStreamSendRecv)){
ms_message("Our local status is SalStreamSendRecv");
if (sal_media_description_has_dir (md,SalStreamRecvOnly) || sal_media_description_has_dir(md,SalStreamInactive)){
/* we are being paused */
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We are being paused..."));
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
}else if (!sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && sal_media_description_has_dir(md,SalStreamSendRecv)){
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We have been resumed..."));
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
lc->current_call=call;
}else{
prevstate=call->state;
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
}
}else{
prevstate=call->state;
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
}
/*accept the modification (sends a 200Ok)*/
sal_call_accept(op);
......
......@@ -110,18 +110,18 @@ static void ecc_play_tones(EcCalibrator *ecc){
/*play an initial tone to startup the audio playback/capture*/
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
sleep(2);
ms_sleep(2);
ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc);
tone.frequency=2000;
tone.duration=100;
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
sleep(1);
ms_sleep(1);
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
sleep(1);
ms_sleep(1);
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
sleep(1);
ms_sleep(1);
if (ecc->sent_count==3 && ecc->recv_count==3){
int delay=ecc->acc/3;
......
......@@ -34,6 +34,13 @@
/**
* @defgroup call_control Placing and receiving calls
*
* The #LinphoneCall object represents an incoming or outgoing call managed by the #LinphoneCore.
* Outgoing calls can be created using linphone_core_invite() or linphone_core_invite_address(), while incoming calls are notified to the application
* through the LinphoneCoreVTable::call_state_changed callback.
*
* See the basic call \ref basic_call_tutorials "tutorial".
*
**/
/**
......
......@@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msequalizer.h"
#include "mediastreamer2/msfileplayer.h"
#include "mediastreamer2/msjpegwriter.h"
#include "mediastreamer2/mseventqueue.h"
#ifdef VIDEO_ENABLED
static MSWebCam *get_nowebcam_device(){
......@@ -473,6 +474,20 @@ int linphone_call_get_duration(const LinphoneCall *call){
return time(NULL)-call->media_start_time;
}
/**
* Returns the call object this call is replacing, if any.
* Call replacement can occur during call transfers.
* By default, the core automatically terminates the replaced call and accept the new one.
* This function allows the application to know whether a new incoming call is a one that replaces another one.
**/
LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call){
SalOp *op=sal_call_get_replaces(call->op);
if (op){
return (LinphoneCall*)sal_op_get_user_pointer(op);
}
return NULL;
}
/**
* Indicate whether camera input should be sent to remote end.
**/
......@@ -505,21 +520,21 @@ int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){
}
/**
*
* Returns TRUE if camera pictures are sent to the remote party.
**/
bool_t linphone_call_camera_enabled (const LinphoneCall *call){
return call->camera_active;
}
/**
*
* Enable video stream.
**/
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
cp->has_video=enabled;
}
/**
*
* Returns whether video is enabled.
**/
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
return cp->has_video;
......@@ -969,6 +984,7 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
video_stream_stop(call->videostream);
call->videostream=NULL;
}
ms_event_queue_skip(call->core->msevq);
#endif
if (call->audio_profile){
......
......@@ -49,6 +49,8 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val);
#define LOCAL_RING "rings/oldphone.wav"
/* same for remote ring (ringback)*/
#define REMOTE_RING "ringback.wav"
#define HOLD_MUSIC "rings/toy-mono.wav"
extern SalCallbacks linphone_sal_callbacks;
......@@ -452,6 +454,8 @@ static void sound_config_read(LinphoneCore *lc)
tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING;
}
linphone_core_set_ringback(lc,tmpbuf);
linphone_core_set_play_file(lc,lp_config_get_string(lc->config,"sound","hold_music",PACKAGE_SOUND_DIR "/" HOLD_MUSIC));
check_sound_device(lc);
lc->sound_conf.latency=0;
......@@ -571,6 +575,7 @@ static void sip_config_read(LinphoneCore *lc)
lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
sal_use_double_registrations(lc->sal,lp_config_get_int(lc->config,"sip","use_double_registrations",1));
}
static void rtp_config_read(LinphoneCore *lc)
......@@ -2199,7 +2204,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Modifying call parameters..."));
sal_call_set_local_media_description (call->op,call->localdesc);
err=sal_call_update(call->op);
err=sal_call_update(call->op,"Media parameters update");
}else{
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL){
......@@ -2426,13 +2431,23 @@ LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc)
int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call)
{
LinphoneCall *call = the_call;
const char *subject=NULL;
if (call->state!=LinphoneCallStreamsRunning && call->state!=LinphoneCallPausedByRemote){
ms_warning("Cannot pause this call, it is not active.");
return -1;
}
if (sal_call_hold(call->op,TRUE) != 0)
if (sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv)){
sal_media_description_set_dir(call->localdesc,SalStreamSendOnly);
subject="Call on hold";
}else if (sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly)){
sal_media_description_set_dir(call->localdesc,SalStreamSendOnly);
subject="Call on hold for me too";
}else{
ms_error("No reason to pause this call, it is already paused or inactive.");
return -1;
}
if (sal_call_update(call->op,subject) != 0)
{
if (lc->vtable.display_warning)
lc->vtable.display_warning(lc,_("Could not pause the call"));
......@@ -2482,14 +2497,14 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
return -1;
}
ms_message("Resuming call %p",call);
if(sal_call_hold(call->op,FALSE) != 0){
sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
if(sal_call_update(call->op,"Call resuming") != 0){
return -1;
}
linphone_call_set_state (call,LinphoneCallResuming,"Resuming");
snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",linphone_call_get_remote_address_as_string(call));
if (lc->vtable.display_status)
lc->vtable.display_status(lc,temp);
lc->current_call=call;
return 0;
}
......@@ -3386,6 +3401,10 @@ void linphone_core_use_preview_window(LinphoneCore *lc, bool_t yesno){
}
static MSVideoSizeDef supported_resolutions[]={
#ifdef ENABLE_HD
{ {MS_VIDEO_SIZE_1080P_W,MS_VIDEO_SIZE_1080P_H} , "1080p" },
{ {MS_VIDEO_SIZE_720P_W,MS_VIDEO_SIZE_720P_H} , "1080p" },
#endif
{ {MS_VIDEO_SIZE_SVGA_W,MS_VIDEO_SIZE_SVGA_H} , "svga" },
{ {MS_VIDEO_SIZE_4CIF_W,MS_VIDEO_SIZE_4CIF_H} , "4cif" },
{ {MS_VIDEO_SIZE_VGA_W,MS_VIDEO_SIZE_VGA_H} , "vga" },
......@@ -3696,7 +3715,7 @@ void sip_config_uninit(LinphoneCore *lc)
linphone_proxy_config_write_to_config_file(lc->config,NULL,i);
for (i=0;i<20;i++){
linphone_core_iterate(lc);
sal_iterate(lc->sal);
#ifndef WIN32
usleep(100000);
#else
......
......@@ -185,6 +185,7 @@ void linphone_call_params_destroy(LinphoneCallParams *cp);
/**
* Enum describing failure reasons.
* @ingroup initializing
**/
enum _LinphoneReason{
LinphoneReasonNone,
......@@ -203,8 +204,13 @@ const char *linphone_reason_to_string(LinphoneReason err);
struct _LinphoneCall;
typedef struct _LinphoneCall LinphoneCall;
/**
* LinphoneCallState enum represents the different state a call can reach into.
* The application is notified of state changes through the LinphoneCoreVTable::call_state_changed callback.
* @ingroup call_control
**/
typedef enum _LinphoneCallState{
LinphoneCallIdle,
LinphoneCallIdle, /**<Initial call state */
LinphoneCallIncomingReceived, /**<This is a new incoming call */
LinphoneCallOutgoingInit, /**<An outgoing call is started */
LinphoneCallOutgoingProgress, /**<An outgoing call is in progress */
......@@ -239,6 +245,7 @@ void linphone_call_unref(LinphoneCall *call);
LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
const char *linphone_call_get_refer_to(const LinphoneCall *call);
bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call);
int linphone_call_get_duration(const LinphoneCall *call);
const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call);
void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled);
......@@ -302,11 +309,11 @@ typedef struct _LinphoneProxyConfig LinphoneProxyConfig;
* LinphoneRegistrationState describes proxy registration states.
**/
typedef enum _LinphoneRegistrationState{
LinphoneRegistrationNone,
LinphoneRegistrationProgress,
LinphoneRegistrationOk,
LinphoneRegistrationCleared,
LinphoneRegistrationFailed
LinphoneRegistrationNone, /**<Initial state for registrations */
LinphoneRegistrationProgress, /**<Registration is in progress */
LinphoneRegistrationOk, /**< Registration is successful */
LinphoneRegistrationCleared, /**< Unregistration succeeded */
LinphoneRegistrationFailed /**<Registration failed */
}LinphoneRegistrationState;
/**
......@@ -485,6 +492,17 @@ void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
/**
* @}
*/
/**
* @addtogroup initializing
* @{
**/
/**
* LinphoneGlobalState describes the global state of the LinphoneCore object.
* It is notified via the LinphoneCoreVTable::global_state_changed
**/
typedef enum _LinphoneGlobalState{
LinphoneGlobalOff,
LinphoneGlobalStartup,
......@@ -494,11 +512,6 @@ typedef enum _LinphoneGlobalState{
const char *linphone_global_state_to_string(LinphoneGlobalState gs);
/**
* @addtogroup initializing
* @{
**/
/**Call state notification callback prototype*/
typedef void (*LinphoneGlobalStateCb)(struct _LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
......
......@@ -989,6 +989,12 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isEchoLimiterEnabled
return linphone_call_echo_limiter_enabled((LinphoneCall*)ptr);
}
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getReplacedCall( JNIEnv* env
,jobject thiz
,jlong ptr) {
return (jlong)linphone_call_get_replaced_call((LinphoneCall*)ptr);
}
//LinphoneFriend
extern "C" long Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env
......
......@@ -109,7 +109,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
static SalStreamDir compute_dir_outgoing(SalStreamDir local, SalStreamDir answered){
SalStreamDir res=local;
if (local==SalStreamSendRecv){
if (answered==SalStreamRecvOnly){
......@@ -124,6 +124,30 @@ static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
return res;
}
static SalStreamDir compute_dir_incoming(SalStreamDir local, SalStreamDir offered){
SalStreamDir res=SalStreamSendRecv;
if (local==SalStreamSendRecv){
if (offered==SalStreamSendOnly)
res=SalStreamRecvOnly;
else if (offered==SalStreamRecvOnly)
res=SalStreamSendOnly;
else if (offered==SalStreamInactive)
res=SalStreamInactive;
else
res=SalStreamSendRecv;
}else if (local==SalStreamSendOnly){
if (offered==SalStreamRecvOnly || offered==SalStreamSendRecv)
res=SalStreamSendOnly;
else res=SalStreamInactive;
}else if (local==SalStreamRecvOnly){
if (offered==SalStreamSendOnly || offered==SalStreamSendRecv)
res=SalStreamRecvOnly;
else
res=SalStreamInactive;
}else res=SalStreamInactive;
return res;
}
static void initiate_outgoing(const SalStreamDescription *local_offer,
const SalStreamDescription *remote_answer,
SalStreamDescription *result){
......@@ -131,7 +155,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
result->proto=local_offer->proto;
result->type=local_offer->type;
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
if (result->payloads && !only_telephone_event(result->payloads)){
strcpy(result->addr,remote_answer->addr);
......@@ -150,13 +174,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
result->proto=local_cap->proto;
result->type=local_cap->type;
if (remote_offer->dir==SalStreamSendOnly)
result->dir=SalStreamRecvOnly;
else if (remote_offer->dir==SalStreamRecvOnly){
result->dir=SalStreamSendOnly;
}else if (remote_offer->dir==SalStreamInactive){
result->dir=SalStreamInactive;
}else result->dir=SalStreamSendRecv;
result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
if (result->payloads && !only_telephone_event(result->payloads)){
strcpy(result->addr,local_cap->addr);
result->port=local_cap->port;
......
......@@ -79,19 +79,41 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_
}
}
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
static bool_t is_null_address(const char *addr){
return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0;
}
/*check for the presence of at least one stream with requested direction */
static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
int i;
bool_t found=FALSE;
/* we are looking for at least one stream with requested direction, inactive streams are ignored*/
for(i=0;i<md->nstreams;++i){
const SalStreamDescription *ss=&md->streams[i];
if (ss->dir==stream_dir) found=TRUE;
else{
if (ss->dir!=SalStreamInactive) return FALSE;
}
if (ss->dir==stream_dir) return TRUE;
if (stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->addr)))
return TRUE;
}
return found;
return FALSE;
}
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
if (stream_dir==SalStreamRecvOnly){
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
else return TRUE;
}else if (stream_dir==SalStreamSendOnly){
if (has_dir(md,SalStreamRecvOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
else return TRUE;
}else if (stream_dir==SalStreamSendRecv){
return has_dir(md,SalStreamSendRecv);
}else{
/*SalStreamInactive*/
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv) || has_dir(md,SalStreamRecvOnly))
return FALSE;
else return TRUE;
}
return FALSE;
}
/*
......
......@@ -257,6 +257,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_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
int sal_iterate(Sal *sal);
MSList * sal_get_pending_auths(Sal *sal);
......@@ -292,8 +293,7 @@ int sal_call_notify_ringing(SalOp *h, bool_t early_media);
/*accept an incoming call or, during a call accept a reINVITE*/
int sal_call_accept(SalOp*h);
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
int sal_call_hold(SalOp *h, bool_t holdon);
int sal_call_update(SalOp *h);
int sal_call_update(SalOp *h, const char *subject);
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
int sal_call_refer(SalOp *h, const char *refer_to);
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h);
......
......@@ -264,6 +264,7 @@ Sal * sal_init(){
eXosip_init();
sal=ms_new0(Sal,1);
sal->keepalive_period=30;
sal->double_reg=TRUE;
return sal;
}
......@@ -397,6 +398,10 @@ MSList *sal_get_pending_auths(Sal *sal){
return ms_list_copy(sal->pending_auths);
}
void sal_use_double_registrations(Sal *ctx, bool_t enabled){
ctx->double_reg=enabled;
}
static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){
osip_via_t *via=NULL;
osip_generic_param_t *param=NULL;
......@@ -840,6 +845,9 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){