forked from mirrors/linphone-iphone
Merge branch 'master' of git.savannah.nongnu.org:/srv/git/linphone
Conflicts: mediastreamer2
This commit is contained in:
commit
f515a560bc
70 changed files with 9469 additions and 11347 deletions
60
AUTHORS
60
AUTHORS
|
|
@ -1,57 +1,13 @@
|
|||
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)
|
||||
Belledonne Communications SARL team:
|
||||
Simon Morlat, Jehan Monnier, Guillaume Beraudo
|
||||
|
||||
Contributors:
|
||||
|
||||
Florian Wintertein < f-win at gmx dot net > originaly wrotes the console version of linphone (linphonec)
|
||||
in console/ directory.
|
||||
|
||||
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
|
||||
|
||||
Sharath Udupa is developing the media_api, a usefull library to manage audio and video streams
|
||||
for basic calls as well as conference.
|
||||
|
||||
Sandro Santilli < strk at keybit dot net > wrote enhancements in the
|
||||
console interface (readline, new commands) and some bug fixes for
|
||||
the core api.
|
||||
console interface (readline, new commands).
|
||||
|
||||
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.
|
||||
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ ZIP_EXCLUDED=include lib \
|
|||
|
||||
SDK_ZIPFILE=$(shell cd $(top_builddir) && pwd)/lib$(PACKAGE)-win32-$(VERSION).zip
|
||||
SDK_EXCLUDED= \
|
||||
bin/linphone-3.exe \
|
||||
bin/linphone.exe \
|
||||
lib/*.la \
|
||||
share/linphone \
|
||||
share/pixmaps \
|
||||
|
|
|
|||
11
NEWS
11
NEWS
|
|
@ -1,4 +1,9 @@
|
|||
linphone-3.4.0 -- XXXXX
|
||||
linphone-3.4.1 -- February 17th, 2011
|
||||
* bugfixes
|
||||
* gtk executable is renamed "linphone" (was linphone-3 before)
|
||||
Requires mediastreamer-2.7.1
|
||||
|
||||
linphone-3.4.0 -- February 7th, 2011
|
||||
* implement multiple calls feature:
|
||||
- call hold (with possibility to play a music file)
|
||||
- call resume
|
||||
|
|
@ -6,8 +11,10 @@ linphone-3.4.0 -- XXXXX
|
|||
- creation of another outgoing call while already in call
|
||||
- blind call transfer
|
||||
- attended call transfer
|
||||
**CAUTION**: LinphoneCoreVTable has changed: pay attention to this when upgrading an old application to a newer liblinphone.
|
||||
* improve bandwidth management (one b=AS line is used for audio+video)
|
||||
* improvements in the echo limiter
|
||||
* improvements in the echo limiter performance
|
||||
* implement a echo calibration feature (see linphone_core_start_echo_calibration()).
|
||||
* stun support bugfixes
|
||||
* possibility to use two video windows, one for local preview, one for remote video (linphonec only)
|
||||
* optimize by not re-creating streams when SDP is unchanged during a reinvite
|
||||
|
|
|
|||
10
README
10
README
|
|
@ -5,16 +5,16 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
|
|||
- you need at least:
|
||||
- libosip2>=3.0.3
|
||||
- libeXosip2>=3.0.3
|
||||
- speex>=1.1.6
|
||||
- libreadline
|
||||
- speex>=1.2.0 (including libspeexdsp part)
|
||||
- libreadline (optional: for convenient command line in linphonec)
|
||||
+ gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional)
|
||||
+ if you want to gtk/glade interface:
|
||||
- gtk>=2.16.0
|
||||
- libglade>=2.2
|
||||
+ if you want video support:
|
||||
- SDL>=1.2.10
|
||||
- libavcodec (ffmpeg) from a year 2007 or later cvs/svn
|
||||
- libavcodec (ffmpeg)
|
||||
- libswscale (part of ffmpeg too) for better scaling performance
|
||||
- theora (optional)
|
||||
|
||||
with their corresponding -dev or -devel package if you don't use source packages.
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ Here is a short description of the content of the source tree.
|
|||
- coreapi/ is the central point of linphone, which handles relationship between sip signalisation and media
|
||||
streaming. It contains an easy to use api to create a sip phone.
|
||||
|
||||
- gtk-glade/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above.
|
||||
- gtk/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above.
|
||||
|
||||
- console/
|
||||
* linphonec.c is the main file for the console version of linphone.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ rm /lib/libgcc.a /lib/libmingw32.a /lib/libmingwex.a
|
|||
|
||||
#Remove libintl from gtk, we don't need it and it conflicts with the one supplied by mingw.
|
||||
rm /lib/libintl.dll.a
|
||||
rm /lib/libintl.la
|
||||
rm /lib/libintl.a
|
||||
rm /include/intl.h
|
||||
|
||||
* Download and install Inno Setup Compiler (required only if you run 'make setup.exe'). Add it to your windows Path environment variable.
|
||||
|
|
@ -56,7 +58,8 @@ rm /include/intl.h
|
|||
Get Linphone source code
|
||||
************************
|
||||
|
||||
Install msys-git from (http://code.google.com/p/msysgit/)
|
||||
Install msys-git from (http://code.google.com/p/msysgit/). During installation you are asked to make a choice about how line endings are treated by git.
|
||||
Choose "Checkout line endings as they are, commit as they are". THIS CHOICE IS VERY IMPORTANT. OTHERS BREAK AUTOMAKE.
|
||||
|
||||
It is recommended that you create a directory somewhere with a path without any spaces or ~ characters, for example
|
||||
c:\sources\
|
||||
|
|
|
|||
|
|
@ -46,13 +46,14 @@ LOCAL_SRC_FILES = \
|
|||
sal_eXosip2_sdp.c \
|
||||
offeranswer.c \
|
||||
callbacks.c \
|
||||
linphonecall.c
|
||||
linphonecall.c \
|
||||
ec-calibrator.c
|
||||
|
||||
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\"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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.1],[linphone-developers@nongnu.org])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
|
||||
|
||||
|
|
@ -298,7 +298,9 @@ AC_ARG_ENABLE(x11,
|
|||
if test "$video" = "true"; then
|
||||
|
||||
if test "$enable_x11" = "true"; then
|
||||
AC_CHECK_HEADERS(X11/Xlib.h)
|
||||
AC_CHECK_HEADERS(X11/Xlib.h)
|
||||
AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11")
|
||||
AC_SUBST(X11_LIBS)
|
||||
fi
|
||||
AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available])
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ linphonec_LDADD = $(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) \
|
|||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
$(OSIP_LIBS) \
|
||||
$(X11_LIBS)
|
||||
|
||||
if BUILD_WIN32
|
||||
#special build of linphonec to detach from the windows console
|
||||
|
|
@ -33,17 +34,6 @@ linphoned_LDADD=$(linphonec_LDADD)
|
|||
endif
|
||||
|
||||
|
||||
sipomatic_SOURCES=\
|
||||
sipomatic.c sipomatic.h
|
||||
sipomatic_CFLAGS= $(COMMON_CFLAGS) $(CONSOLE_FLAGS)
|
||||
|
||||
sipomatic_LDADD= $(INTLLIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
linphonecsh_SOURCES = shell.c
|
||||
linphonecsh_CFLAGS = $(CONSOLE_FLAGS)
|
||||
linphonecsh_LDADD = $(ORTP_LIBS)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ static int lpc_cmd_unregister(LinphoneCore *, char *);
|
|||
static int lpc_cmd_duration(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_status(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_ports(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_param(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_speak(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_acodec(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_vcodec(LinphoneCore *lc, char *args);
|
||||
|
|
@ -315,6 +316,10 @@ static LPC_COMMAND advanced_commands[] = {
|
|||
{ "ports", lpc_cmd_ports, "Network ports configuration",
|
||||
"'ports' \t: prints current used ports.\n"
|
||||
"'ports sip <port number>'\t: Sets the sip port.\n" },
|
||||
{ "param", lpc_cmd_param, "parameter set or read as normally given in .linphonerc",
|
||||
"'param <section> <parameter> [<value>]' \t: reads [sets] given parameter.\n"
|
||||
"NOTES: - changes may become effective after (re)establishing a sip connection.\n"
|
||||
" - upon exit, .linphonerc will reflect the updated state.\n" },
|
||||
{ "speak", lpc_cmd_speak, "Speak a sentence using espeak TTS engine",
|
||||
"This feature is available only in file mode. (see 'help soundcard')\n"
|
||||
"'speak <voice name> <sentence>' : speak a text using the specified espeak voice.\n"
|
||||
|
|
@ -473,7 +478,8 @@ lpc_cmd_help(LinphoneCore *lc, char *arg)
|
|||
}
|
||||
|
||||
linphonec_out("---------------------------\n");
|
||||
linphonec_out("Type 'help <command>' for more details or 'help advanced' to list additional commands.\n");
|
||||
linphonec_out("Type 'help <command>' for more details or\n");
|
||||
linphonec_out(" 'help advanced' to list additional commands.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2014,6 +2020,35 @@ static int lpc_cmd_ports(LinphoneCore *lc, char *args)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lpc_cmd_param(LinphoneCore *lc, char *args)
|
||||
{
|
||||
char section[20], param[20], value[50];
|
||||
const char *string;
|
||||
|
||||
if (args == NULL) {
|
||||
return 0;
|
||||
}
|
||||
switch (sscanf(args,"%s %s %s",section,param,value)) {
|
||||
// case 1 might show all current settings under a section
|
||||
case 2:
|
||||
string = lp_config_get_string(linphone_core_get_config(lc), section, param, "(undef)");
|
||||
linphonec_out("current value: %s\n", string);
|
||||
break;
|
||||
case 3:
|
||||
if (lp_config_get_string(linphone_core_get_config(lc), section, param, NULL) != NULL) {
|
||||
lp_config_set_string(linphone_core_get_config(lc), section, param, value);
|
||||
// no indication of existence
|
||||
linphonec_out("updated value: %s\n", value);
|
||||
} else {
|
||||
linphonec_out("only update of existing variables are allowed\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lpc_cmd_speak(LinphoneCore *lc, char *args){
|
||||
#ifndef WIN32
|
||||
char voice[64];
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@
|
|||
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
#include <X11/Xlib.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ liblinphone_la_SOURCES=\
|
|||
linphonecall.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
siplogin.c \
|
||||
lsd.c linphonecore_utils.h
|
||||
lsd.c linphonecore_utils.h \
|
||||
ec-calibrator.c
|
||||
|
||||
|
||||
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
|
||||
|
|
@ -49,7 +50,7 @@ if BUILD_WIN32
|
|||
liblinphone_la_LIBADD+=$(top_builddir)/oRTP/src/libortp.la
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS=test_lsd
|
||||
noinst_PROGRAMS=test_lsd test_ecc
|
||||
|
||||
test_lsd_SOURCES=test_lsd.c
|
||||
|
||||
|
|
@ -57,6 +58,14 @@ test_lsd_LDADD=liblinphone.la \
|
|||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
test_ecc_SOURCES=test_ecc.c
|
||||
|
||||
test_ecc_LDADD=liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(OSIP_CFLAGS) \
|
||||
|
|
|
|||
|
|
@ -235,10 +235,12 @@ static void call_ringing(SalOp *h){
|
|||
if (lc->ringstream!=NULL) return; /*already ringing !*/
|
||||
if (lc->sound_conf.play_sndcard!=NULL){
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
|
||||
ms_message("Remote ringing...");
|
||||
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
|
||||
linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing");
|
||||
}
|
||||
ms_message("Remote ringing...");
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Remote ringing..."));
|
||||
linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing");
|
||||
}else{
|
||||
/*accept early media */
|
||||
if (call->audiostream && call->audiostream->ticker!=NULL){
|
||||
|
|
@ -303,18 +305,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 +363,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 +375,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 (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");
|
||||
}
|
||||
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);
|
||||
}
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
/*accept the modification (sends a 200Ok)*/
|
||||
sal_call_accept(op);
|
||||
|
|
@ -501,6 +506,13 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
}
|
||||
}
|
||||
|
||||
static void call_released(SalOp *op){
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (call!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallReleased,"Call released");
|
||||
}else ms_error("call_released() for already destroyed call ?");
|
||||
}
|
||||
|
||||
static void auth_requested(SalOp *h, const char *realm, const char *username){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
|
||||
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username);
|
||||
|
|
@ -516,7 +528,7 @@ static void auth_requested(SalOp *h, const char *realm, const char *username){
|
|||
ai->usecount++;
|
||||
}else{
|
||||
if (ai && ai->works==FALSE) {
|
||||
register_failure(h, SalErrorFailure, SalReasonForbidden, _("Authentication failure"));
|
||||
sal_op_cancel_authentication(h);
|
||||
}
|
||||
if (lc->vtable.auth_info_requested)
|
||||
lc->vtable.auth_info_requested(lc,realm,username);
|
||||
|
|
@ -676,6 +688,7 @@ SalCallbacks linphone_sal_callbacks={
|
|||
call_updating,
|
||||
call_terminated,
|
||||
call_failure,
|
||||
call_released,
|
||||
auth_requested,
|
||||
auth_success,
|
||||
register_success,
|
||||
|
|
|
|||
179
coreapi/ec-calibrator.c
Normal file
179
coreapi/ec-calibrator.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2011 Belledonne Communications SARL
|
||||
Author: Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "mediastreamer2/mstonedetector.h"
|
||||
#include "mediastreamer2/dtmfgen.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void ecc_init_filters(EcCalibrator *ecc){
|
||||
ecc->ticker=ms_ticker_new();
|
||||
|
||||
ecc->sndread=ms_snd_card_create_reader(ecc->play_card);
|
||||
ecc->det=ms_filter_new(MS_TONE_DETECTOR_ID);
|
||||
ecc->rec=ms_filter_new(MS_FILE_REC_ID);
|
||||
|
||||
ms_filter_link(ecc->sndread,0,ecc->det,0);
|
||||
ms_filter_link(ecc->det,0,ecc->rec,0);
|
||||
|
||||
ecc->play=ms_filter_new(MS_FILE_PLAYER_ID);
|
||||
ecc->gen=ms_filter_new(MS_DTMF_GEN_ID);
|
||||
ecc->resampler=ms_filter_new(MS_RESAMPLE_ID);
|
||||
ecc->sndwrite=ms_snd_card_create_writer(ecc->capt_card);
|
||||
|
||||
ms_filter_link(ecc->play,0,ecc->gen,0);
|
||||
ms_filter_link(ecc->gen,0,ecc->resampler,0);
|
||||
ms_filter_link(ecc->resampler,0,ecc->sndwrite,0);
|
||||
unsigned int rate;
|
||||
ms_filter_call_method(ecc->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&rate);
|
||||
ms_filter_call_method(ecc->resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&rate);
|
||||
|
||||
ms_ticker_attach(ecc->ticker,ecc->play);
|
||||
ms_ticker_attach(ecc->ticker,ecc->sndread);
|
||||
}
|
||||
|
||||
static void ecc_deinit_filters(EcCalibrator *ecc){
|
||||
ms_ticker_detach(ecc->ticker,ecc->play);
|
||||
ms_ticker_detach(ecc->ticker,ecc->sndread);
|
||||
|
||||
ms_filter_unlink(ecc->play,0,ecc->gen,0);
|
||||
ms_filter_unlink(ecc->gen,0,ecc->resampler,0);
|
||||
ms_filter_unlink(ecc->resampler,0,ecc->sndwrite,0);
|
||||
|
||||
ms_filter_unlink(ecc->sndread,0,ecc->det,0);
|
||||
ms_filter_unlink(ecc->det,0,ecc->rec,0);
|
||||
|
||||
ms_filter_destroy(ecc->sndread);
|
||||
ms_filter_destroy(ecc->det);
|
||||
ms_filter_destroy(ecc->rec);
|
||||
ms_filter_destroy(ecc->play);
|
||||
ms_filter_destroy(ecc->gen);
|
||||
ms_filter_destroy(ecc->resampler);
|
||||
ms_filter_destroy(ecc->sndwrite);
|
||||
|
||||
ms_ticker_destroy(ecc->ticker);
|
||||
}
|
||||
|
||||
static void on_tone_sent(void *data, MSFilter *f, unsigned int event_id, void *arg){
|
||||
MSDtmfGenEvent *ev=(MSDtmfGenEvent*)arg;
|
||||
EcCalibrator *ecc=(EcCalibrator*)data;
|
||||
ecc->sent_count++;
|
||||
ecc->acc-=ev->tone_start_time;
|
||||
ms_message("Sent tone at %u",(unsigned int)ev->tone_start_time);
|
||||
}
|
||||
|
||||
static void on_tone_received(void *data, MSFilter *f, unsigned int event_id, void *arg){
|
||||
MSToneDetectorEvent *ev=(MSToneDetectorEvent*)arg;
|
||||
EcCalibrator *ecc=(EcCalibrator*)data;
|
||||
ecc->recv_count++;
|
||||
ecc->acc+=ev->tone_start_time;
|
||||
ms_message("Received tone at %u",(unsigned int)ev->tone_start_time);
|
||||
}
|
||||
|
||||
static void ecc_play_tones(EcCalibrator *ecc){
|
||||
MSDtmfGenCustomTone tone;
|
||||
MSToneDetectorDef expected_tone;
|
||||
|
||||
|
||||
ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc);
|
||||
|
||||
expected_tone.frequency=2000;
|
||||
expected_tone.min_duration=40;
|
||||
expected_tone.min_amplitude=0.02;
|
||||
|
||||
ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
|
||||
|
||||
tone.frequency=1000;
|
||||
tone.duration=1000;
|
||||
tone.amplitude=1.0;
|
||||
|
||||
/*play an initial tone to startup the audio playback/capture*/
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
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);
|
||||
ms_sleep(1);
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(1);
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(1);
|
||||
|
||||
if (ecc->sent_count==3 && ecc->recv_count==3){
|
||||
int delay=ecc->acc/3;
|
||||
if (delay<0){
|
||||
ms_error("Quite surprising calibration result, delay=%i",delay);
|
||||
ecc->status=LinphoneEcCalibratorFailed;
|
||||
}else{ms_message("Echo calibration estimated delay to be %i ms",delay);
|
||||
ecc->delay=delay;
|
||||
ecc->status=LinphoneEcCalibratorDone;
|
||||
}
|
||||
}else{
|
||||
ms_error("Echo calibration failed, tones received = %i",ecc->recv_count);
|
||||
ecc->status=LinphoneEcCalibratorFailed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void * ecc_thread(void *p){
|
||||
EcCalibrator *ecc=(EcCalibrator*)p;
|
||||
|
||||
ecc_init_filters(ecc);
|
||||
ecc_play_tones(ecc);
|
||||
ecc_deinit_filters(ecc);
|
||||
ms_thread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EcCalibrator * ec_calibrator_new(MSSndCard *play_card, MSSndCard *capt_card, LinphoneEcCalibrationCallback cb, void *cb_data ){
|
||||
EcCalibrator *ecc=ms_new0(EcCalibrator,1);
|
||||
|
||||
ecc->cb=cb;
|
||||
ecc->cb_data=cb_data;
|
||||
ecc->capt_card=capt_card;
|
||||
ecc->play_card=play_card;
|
||||
ms_thread_create(&ecc->thread,NULL,ecc_thread,ecc);
|
||||
return ecc;
|
||||
}
|
||||
|
||||
LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc){
|
||||
return ecc->status;
|
||||
}
|
||||
|
||||
void ec_calibrator_destroy(EcCalibrator *ecc){
|
||||
ms_thread_join(ecc->thread,NULL);
|
||||
ms_free(ecc);
|
||||
}
|
||||
|
||||
int linphone_core_start_echo_calibration(LinphoneCore *lc, LinphoneEcCalibrationCallback cb, void *cb_data){
|
||||
if (lc->ecc!=NULL){
|
||||
ms_error("Echo calibration is still on going !");
|
||||
return -1;
|
||||
}
|
||||
lc->ecc=ec_calibrator_new(lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard,cb,cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -277,7 +277,9 @@ SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os){
|
|||
}
|
||||
|
||||
void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os){
|
||||
//printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid);
|
||||
char *addr=linphone_address_as_string(linphone_friend_get_address(lf));
|
||||
ms_message("Want to notify %s, insub=%p",addr,lf->insub);
|
||||
ms_free(addr);
|
||||
if (lf->insub!=NULL){
|
||||
sal_notify_presence(lf->insub,linphone_online_status_to_sal(os),NULL);
|
||||
}
|
||||
|
|
@ -286,8 +288,6 @@ void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os){
|
|||
static void linphone_friend_unsubscribe(LinphoneFriend *lf){
|
||||
if (lf->outsub!=NULL) {
|
||||
sal_unsubscribe(lf->outsub);
|
||||
sal_op_release(lf->outsub);
|
||||
lf->outsub=NULL;
|
||||
lf->subscribe_active=FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -296,13 +296,19 @@ void linphone_friend_close_subscriptions(LinphoneFriend *lf){
|
|||
linphone_friend_unsubscribe(lf);
|
||||
if (lf->insub){
|
||||
sal_notify_close(lf->insub);
|
||||
sal_op_release(lf->insub);
|
||||
lf->insub=NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_destroy(LinphoneFriend *lf){
|
||||
|
||||
if (lf->insub) {
|
||||
sal_op_release(lf->insub);
|
||||
lf->insub=NULL;
|
||||
}
|
||||
if (lf->outsub){
|
||||
sal_op_release(lf->outsub);
|
||||
lf->outsub=NULL;
|
||||
}
|
||||
if (lf->uri!=NULL) linphone_address_destroy(lf->uri);
|
||||
if (lf->info!=NULL) buddy_info_free(lf->info);
|
||||
ms_free(lf);
|
||||
|
|
|
|||
|
|
@ -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".
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -95,7 +96,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 ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
|
||||
|
||||
|
|
@ -229,4 +230,6 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -73,7 +74,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 ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {
|
||||
|
|
@ -144,4 +145,5 @@ public class TutorialChatRoom implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -67,7 +68,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 ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
/*
|
||||
* Call state notification listener
|
||||
*/
|
||||
|
|
@ -153,4 +154,5 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -78,7 +79,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 ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
|
|
@ -184,4 +185,6 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(){
|
||||
|
|
@ -58,7 +59,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw
|
|||
return l;
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
const char *me=linphone_core_get_identity(lc);
|
||||
|
|
@ -66,6 +67,8 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa
|
|||
const char *username=linphone_address_get_username (addr);
|
||||
SalMediaDescription *md=sal_media_description_new();
|
||||
|
||||
md->session_id=session_id;
|
||||
md->session_ver=session_ver;
|
||||
md->nstreams=1;
|
||||
strncpy(md->addr,call->localip,sizeof(md->addr));
|
||||
strncpy(md->username,username,sizeof(md->username));
|
||||
|
|
@ -95,6 +98,22 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa
|
|||
return md;
|
||||
}
|
||||
|
||||
void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md){
|
||||
if (*md == NULL) {
|
||||
*md = _create_local_media_description(lc,call,0,0);
|
||||
} else {
|
||||
unsigned int id = (*md)->session_id;
|
||||
unsigned int ver = (*md)->session_ver+1;
|
||||
sal_media_description_unref(*md);
|
||||
*md = _create_local_media_description(lc,call,id,ver);
|
||||
}
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
unsigned int id=rand();
|
||||
return _create_local_media_description(lc,call,id,id);
|
||||
}
|
||||
|
||||
static int find_port_offset(LinphoneCore *lc){
|
||||
int offset;
|
||||
MSList *elem;
|
||||
|
|
@ -126,6 +145,7 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
|
|||
call->start_time=time(NULL);
|
||||
call->media_start_time=0;
|
||||
call->log=linphone_call_log_new(call, from, to);
|
||||
call->owns_call_log=TRUE;
|
||||
linphone_core_notify_all_friends(call->core,LinphoneStatusOnThePhone);
|
||||
port_offset=find_port_offset (call->core);
|
||||
if (port_offset==-1) return;
|
||||
|
|
@ -222,8 +242,10 @@ static void linphone_call_set_terminated(LinphoneCall *call){
|
|||
else status=LinphoneCallSuccess;
|
||||
|
||||
}
|
||||
call->owns_call_log=FALSE;
|
||||
linphone_call_log_completed(call->log,call, status);
|
||||
|
||||
|
||||
if (call == lc->current_call){
|
||||
ms_message("Resetting the current call");
|
||||
lc->current_call=NULL;
|
||||
|
|
@ -236,13 +258,6 @@ static void linphone_call_set_terminated(LinphoneCall *call){
|
|||
if (ms_list_size(lc->calls)==0)
|
||||
linphone_core_notify_all_friends(lc,lc->presence_mode);
|
||||
|
||||
if (call->op!=NULL) {
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs){
|
||||
|
|
@ -283,14 +298,23 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){
|
|||
return "LinphoneCallIncomingEarlyMedia";
|
||||
case LinphoneCallUpdated:
|
||||
return "LinphoneCallUpdated";
|
||||
case LinphoneCallReleased:
|
||||
return "LinphoneCallReleased";
|
||||
}
|
||||
return "undefined state";
|
||||
}
|
||||
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){
|
||||
LinphoneCore *lc=call->core;
|
||||
bool_t finalize_call=FALSE;
|
||||
|
||||
if (call->state!=cstate){
|
||||
if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){
|
||||
if (cstate!=LinphoneCallReleased){
|
||||
ms_warning("Spurious call state change from %s to %s, ignored.",linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
return;
|
||||
}
|
||||
}
|
||||
ms_message("Call %p: moving from state %s to %s",call,linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
if (cstate!=LinphoneCallRefered){
|
||||
|
|
@ -299,14 +323,20 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
call->state=cstate;
|
||||
}
|
||||
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
|
||||
finalize_call=TRUE;
|
||||
linphone_call_ref(call);
|
||||
linphone_call_set_terminated (call);
|
||||
}
|
||||
|
||||
if (lc->vtable.call_state_changed)
|
||||
lc->vtable.call_state_changed(lc,call,cstate,message);
|
||||
if (finalize_call)
|
||||
if (cstate==LinphoneCallReleased){
|
||||
if (call->op!=NULL) {
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -330,6 +360,8 @@ static void linphone_call_destroy(LinphoneCall *obj)
|
|||
if (obj->refer_to){
|
||||
ms_free(obj->refer_to);
|
||||
}
|
||||
if (obj->owns_call_log)
|
||||
linphone_call_log_destroy(obj->log);
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +505,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 +551,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 +1015,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)
|
||||
|
|
@ -590,6 +595,8 @@ static void rtp_config_read(LinphoneCore *lc)
|
|||
jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
|
||||
linphone_core_set_audio_jittcomp(lc,jitt_comp);
|
||||
jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60);
|
||||
if (jitt_comp==0) jitt_comp=60;
|
||||
lc->rtp_conf.video_jitt_comp=jitt_comp;
|
||||
nortp_timeout=lp_config_get_int(lc->config,"rtp","nortp_timeout",30);
|
||||
linphone_core_set_nortp_timeout(lc,nortp_timeout);
|
||||
rtp_no_xmit_on_audio_mute=lp_config_get_int(lc->config,"rtp","rtp_no_xmit_on_audio_mute",FALSE);
|
||||
|
|
@ -910,7 +917,8 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
|
|||
{
|
||||
memset (lc, 0, sizeof (LinphoneCore));
|
||||
lc->data=userdata;
|
||||
|
||||
lc->ringstream_autorelease=TRUE;
|
||||
|
||||
memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable));
|
||||
|
||||
linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
|
||||
|
|
@ -1635,6 +1643,19 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
one_second_elapsed=TRUE;
|
||||
}
|
||||
|
||||
if (lc->ecc!=NULL){
|
||||
LinphoneEcCalibratorStatus ecs=ec_calibrator_get_status(lc->ecc);
|
||||
if (ecs!=LinphoneEcCalibratorInProgress){
|
||||
if (lc->ecc->cb)
|
||||
lc->ecc->cb(lc,ecs,lc->ecc->delay,lc->ecc->cb_data);
|
||||
if (ecs==LinphoneEcCalibratorDone){
|
||||
lp_config_set_int(lc->config, "sound", "ec_delay",MAX(lc->ecc->delay-10,0));
|
||||
}
|
||||
ec_calibrator_destroy(lc->ecc);
|
||||
lc->ecc=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lc->preview_finished){
|
||||
lc->preview_finished=0;
|
||||
ring_stop(lc->ringstream);
|
||||
|
|
@ -1642,7 +1663,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
lc_callback_obj_invoke(&lc->preview_finished_cb,lc);
|
||||
}
|
||||
|
||||
if (lc->ringstream && lc->dmfs_playing_start_time!=0
|
||||
if (lc->ringstream && lc->ringstream_autorelease && lc->dmfs_playing_start_time!=0
|
||||
&& (curtime-lc->dmfs_playing_start_time)>5){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
|
|
@ -2176,15 +2197,13 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
|
|||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
int err=0;
|
||||
if (params!=NULL){
|
||||
if (call->localdesc)
|
||||
sal_media_description_unref(call->localdesc);
|
||||
call->params=*params;
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
update_local_media_description(lc,call,&call->localdesc);
|
||||
call->camera_active=params->has_video;
|
||||
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){
|
||||
|
|
@ -2411,13 +2430,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"));
|
||||
|
|
@ -2467,14 +2496,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;
|
||||
}
|
||||
|
||||
|
|
@ -2687,6 +2716,7 @@ static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap){
|
|||
* Returns true if the specified sound device can capture sound.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param devid the device name as returned by linphone_core_get_sound_devices()
|
||||
**/
|
||||
bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *devid){
|
||||
|
|
@ -2700,6 +2730,7 @@ bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *devi
|
|||
* Returns true if the specified sound device can play sound.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param devid the device name as returned by linphone_core_get_sound_devices()
|
||||
**/
|
||||
bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *devid){
|
||||
|
|
@ -2713,6 +2744,7 @@ bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *dev
|
|||
* Sets the sound device used for ringing.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param devid the device name as returned by linphone_core_get_sound_devices()
|
||||
**/
|
||||
int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
|
||||
|
|
@ -2727,6 +2759,7 @@ int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
|
|||
* Sets the sound device used for playback.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param devid the device name as returned by linphone_core_get_sound_devices()
|
||||
**/
|
||||
int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
|
||||
|
|
@ -2741,6 +2774,7 @@ int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
|
|||
* Sets the sound device used for capture.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param devid the device name as returned by linphone_core_get_sound_devices()
|
||||
**/
|
||||
int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid){
|
||||
|
|
@ -2755,6 +2789,7 @@ int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid){
|
|||
* Returns the name of the currently assigned sound device for ringing.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
**/
|
||||
const char * linphone_core_get_ringer_device(LinphoneCore *lc)
|
||||
{
|
||||
|
|
@ -2766,6 +2801,7 @@ const char * linphone_core_get_ringer_device(LinphoneCore *lc)
|
|||
* Returns the name of the currently assigned sound device for playback.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
**/
|
||||
const char * linphone_core_get_playback_device(LinphoneCore *lc)
|
||||
{
|
||||
|
|
@ -2776,6 +2812,7 @@ const char * linphone_core_get_playback_device(LinphoneCore *lc)
|
|||
* Returns the name of the currently assigned sound device for capture.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
**/
|
||||
const char * linphone_core_get_capture_device(LinphoneCore *lc)
|
||||
{
|
||||
|
|
@ -2785,8 +2822,10 @@ const char * linphone_core_get_capture_device(LinphoneCore *lc)
|
|||
/**
|
||||
* Returns an unmodifiable array of available sound devices.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* The array is NULL terminated.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
**/
|
||||
const char** linphone_core_get_sound_devices(LinphoneCore *lc){
|
||||
build_sound_devices_table(lc);
|
||||
|
|
@ -2829,14 +2868,17 @@ void linphone_core_set_sound_source(LinphoneCore *lc, char source)
|
|||
* Sets the path to a wav file used for ringing.
|
||||
*
|
||||
* @param path The file must be a wav 16bit linear. Local ring is disabled if null
|
||||
* @param lc The LinphoneCore object
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
void linphone_core_set_ring(LinphoneCore *lc,const char *path){
|
||||
if (lc->sound_conf.local_ring!=0){
|
||||
ms_free(lc->sound_conf.local_ring);
|
||||
lc->sound_conf.local_ring=NULL;
|
||||
}
|
||||
lc->sound_conf.local_ring=ms_strdup(path);
|
||||
if (path)
|
||||
lc->sound_conf.local_ring=ms_strdup(path);
|
||||
if ( linphone_core_ready(lc) && lc->sound_conf.local_ring)
|
||||
lp_config_set_string(lc->config,"sound","local_ring",lc->sound_conf.local_ring);
|
||||
}
|
||||
|
|
@ -2844,6 +2886,7 @@ void linphone_core_set_ring(LinphoneCore *lc,const char *path){
|
|||
/**
|
||||
* Returns the path to the wav file used for ringing.
|
||||
*
|
||||
* @param lc The LinphoneCore object
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
const char *linphone_core_get_ring(const LinphoneCore *lc){
|
||||
|
|
@ -3112,6 +3155,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
|
|||
* initiate future calls with video or not. The two boolean parameters indicate in which
|
||||
* direction video is enabled. Setting both to false disables video entirely.
|
||||
*
|
||||
* @param lc The LinphoneCore object
|
||||
* @param vcap_enabled indicates whether video capture is enabled
|
||||
* @param display_enabled indicates whether video display should be shown
|
||||
*
|
||||
|
|
@ -3191,6 +3235,7 @@ bool_t linphone_core_self_view_enabled(const LinphoneCore *lc){
|
|||
* Sets the active video device.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @param lc The LinphoneCore object
|
||||
* @param id the name of the video device as returned by linphone_core_get_video_devices()
|
||||
**/
|
||||
int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
|
||||
|
|
@ -3220,6 +3265,7 @@ int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
|
|||
/**
|
||||
* Returns the name of the currently active video device.
|
||||
*
|
||||
* @param lc The LinphoneCore object
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
const char *linphone_core_get_video_device(const LinphoneCore *lc){
|
||||
|
|
@ -3371,6 +3417,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" },
|
||||
|
|
@ -3519,8 +3569,10 @@ static MSFilter *get_dtmf_gen(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
if (lc->ringstream==NULL){
|
||||
float amp=0.1;
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard;
|
||||
lc->ringstream=ring_start(NULL,0,ringcard);
|
||||
ms_filter_call_method(lc->ringstream->gendtmf,MS_DTMF_GEN_SET_DEFAULT_AMPLITUDE,&);
|
||||
lc->dmfs_playing_start_time=time(NULL);
|
||||
}else{
|
||||
if (lc->dmfs_playing_start_time!=0)
|
||||
|
|
@ -3688,7 +3740,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
|
||||
|
|
@ -3825,7 +3877,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
usleep(50000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (lc->friends)
|
||||
ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions);
|
||||
linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down");
|
||||
|
|
@ -3839,12 +3890,13 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
lc->msevq=NULL;
|
||||
/* save all config */
|
||||
net_config_uninit(lc);
|
||||
sip_config_uninit(lc);
|
||||
rtp_config_uninit(lc);
|
||||
if (lc->ringstream) ring_stop(lc->ringstream);
|
||||
sound_config_uninit(lc);
|
||||
video_config_uninit(lc);
|
||||
codecs_config_uninit(lc);
|
||||
ui_config_uninit(lc);
|
||||
sip_config_uninit(lc);
|
||||
if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config);
|
||||
lp_config_destroy(lc->config);
|
||||
lc->config = NULL; /* Mark the config as NULL to block further calls */
|
||||
|
|
@ -3854,7 +3906,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
lc->call_logs=ms_list_free(lc->call_logs);
|
||||
|
||||
linphone_core_free_payload_types();
|
||||
|
||||
ortp_exit();
|
||||
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
|
||||
}
|
||||
|
|
@ -3875,8 +3926,24 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu
|
|||
}
|
||||
lc->netup_time=curtime;
|
||||
lc->network_reachable=isReachable;
|
||||
}
|
||||
if(!isReachable) {
|
||||
sal_unlisten_ports (lc->sal);
|
||||
} else {
|
||||
apply_transports(lc);
|
||||
}
|
||||
|
||||
}
|
||||
void linphone_core_refresh_registers(LinphoneCore* lc) {
|
||||
const MSList *elem=linphone_core_get_proxy_config_list(lc);
|
||||
for(;elem!=NULL;elem=elem->next){
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
|
||||
if (linphone_proxy_config_register_enabled(cfg) ) {
|
||||
cfg->registered=0;
|
||||
cfg->commit=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
|
||||
//first disable automatic mode
|
||||
if (lc->auto_net_state_mon) {
|
||||
|
|
@ -4044,4 +4111,31 @@ const char *linphone_error_to_string(LinphoneReason err){
|
|||
}
|
||||
return "unknown error";
|
||||
}
|
||||
/**
|
||||
* enable signaling keep alive
|
||||
*/
|
||||
void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable) {
|
||||
if (enable > 0) {
|
||||
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
|
||||
} else {
|
||||
sal_set_keepalive_period(lc->sal,0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Is signaling keep alive
|
||||
*/
|
||||
bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc) {
|
||||
return sal_get_keepalive_period(lc->sal) > 0;
|
||||
}
|
||||
|
||||
void linphone_core_start_dtmf_stream(LinphoneCore* lc) {
|
||||
get_dtmf_gen(lc); /*make sure ring stream is started*/
|
||||
lc->ringstream_autorelease=FALSE; /*disable autorelease mode*/
|
||||
}
|
||||
|
||||
void linphone_core_stop_dtmf_stream(LinphoneCore* lc) {
|
||||
if (lc->ringstream) ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -221,7 +227,8 @@ typedef enum _LinphoneCallState{
|
|||
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
|
||||
LinphoneCallUpdatedByRemote, /**<The call's parameters are updated, used for example when video is asked by remote */
|
||||
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
|
||||
LinphoneCallUpdated /**<The remote accepted the call update initiated by us */
|
||||
LinphoneCallUpdated, /**<The remote accepted the call update initiated by us */
|
||||
LinphoneCallReleased /**< The call object is no more retained by the core */
|
||||
} LinphoneCallState;
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs);
|
||||
|
|
@ -238,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);
|
||||
|
|
@ -301,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;
|
||||
|
||||
/**
|
||||
|
|
@ -484,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,
|
||||
|
|
@ -493,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);
|
||||
|
|
@ -919,6 +933,14 @@ void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t value);
|
|||
*/
|
||||
bool_t linphone_core_is_network_reachabled(LinphoneCore* lc);
|
||||
|
||||
/**
|
||||
* enable signaling keep alive. small udp packet sent periodically to keep udp NAT association
|
||||
*/
|
||||
void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable);
|
||||
/**
|
||||
* Is signaling keep alive
|
||||
*/
|
||||
bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc);
|
||||
|
||||
void *linphone_core_get_user_data(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -950,7 +972,11 @@ int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, r
|
|||
const MSList *linphone_core_get_calls(LinphoneCore *lc);
|
||||
|
||||
LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* force registration refresh to be initiated upon next iterate
|
||||
* @ingroup proxies
|
||||
*/
|
||||
void linphone_core_refresh_registers(LinphoneCore* lc);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <jni.h>
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
|
||||
#include "mediastreamer2/msjava.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -100,7 +101,10 @@ public:
|
|||
callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V");
|
||||
callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
|
||||
callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
|
||||
|
||||
/*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/
|
||||
ecCalibrationStatusId = env->GetMethodID(listernerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V");
|
||||
ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus"));
|
||||
ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;");
|
||||
/*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/
|
||||
newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V");
|
||||
|
||||
|
|
@ -165,6 +169,10 @@ public:
|
|||
jmethodID callStateId;
|
||||
jmethodID callStateFromIntId;
|
||||
|
||||
jclass ecCalibratorStatusClass;
|
||||
jmethodID ecCalibrationStatusId;
|
||||
jmethodID ecCalibratorStatusFromIntId;
|
||||
|
||||
jclass proxyClass;
|
||||
jmethodID proxyCtrId;
|
||||
|
||||
|
|
@ -290,6 +298,26 @@ public:
|
|||
,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from)
|
||||
,message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) {
|
||||
JNIEnv *env = 0;
|
||||
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);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->ecCalibrationStatusId
|
||||
,lcData->core
|
||||
,env->CallStaticObjectMethod(lcData->ecCalibratorStatusClass,lcData->ecCalibratorStatusFromIntId,(jint)status)
|
||||
,delay_ms
|
||||
,data ? data : NULL);
|
||||
if (data != NULL &&status !=LinphoneEcCalibratorInProgress ) {
|
||||
//final state, releasing global ref
|
||||
env->DeleteGlobalRef((jobject)data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
@ -615,6 +643,29 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableKeepAlive(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jboolean enable) {
|
||||
linphone_core_enable_keep_alive((LinphoneCore*)lc,enable);
|
||||
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isKeepAliveEnabled(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
return linphone_core_keep_alive_enabled((LinphoneCore*)lc);
|
||||
|
||||
}
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jobject data) {
|
||||
return linphone_core_start_echo_calibration((LinphoneCore*)lc
|
||||
, LinphoneCoreData::ecCalibrationStatus
|
||||
, data?env->NewGlobalRef(data):NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ProxyConfig
|
||||
|
|
@ -939,6 +990,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
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _LsdPlayer LsdPlayer;
|
||||
typedef struct _LinphoneSoundDaemon LinphoneSoundDaemon;
|
||||
|
|
@ -49,4 +52,35 @@ void linphone_sound_daemon_release_all_players(LinphoneSoundDaemon *obj);
|
|||
void linphone_core_use_sound_daemon(LinphoneCore *lc, LinphoneSoundDaemon *lsd);
|
||||
void linphone_sound_daemon_destroy(LinphoneSoundDaemon *obj);
|
||||
|
||||
/**
|
||||
* Enum describing the result of the echo canceller calibration process.
|
||||
**/
|
||||
typedef enum {
|
||||
LinphoneEcCalibratorInProgress,
|
||||
LinphoneEcCalibratorDone,
|
||||
LinphoneEcCalibratorFailed
|
||||
}LinphoneEcCalibratorStatus;
|
||||
|
||||
|
||||
typedef void (*LinphoneEcCalibrationCallback)(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data);
|
||||
|
||||
/**
|
||||
* Start an echo calibration of the sound devices, in order to find adequate settings for the echo canceller automatically.
|
||||
**/
|
||||
int linphone_core_start_echo_calibration(LinphoneCore *lc, LinphoneEcCalibrationCallback cb, void *cb_data);
|
||||
#if TARGET_OS_IPHONE
|
||||
/**
|
||||
* IOS special function to warm up dtmf feeback stream. #linphone_core_stop_dtmf_stream must be called before entering BG mode
|
||||
*/
|
||||
void linphone_core_start_dtmf_stream(const LinphoneCore* lc);
|
||||
/**
|
||||
* IOS special function to stop dtmf feed back function. Must be called before entering BG mode
|
||||
*/
|
||||
void linphone_core_stop_dtmf_stream(const LinphoneCore* lc);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -200,22 +218,30 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result, bool_t one_matching_codec){
|
||||
int i,j;
|
||||
int i;
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
for(i=0,j=0;i<remote_offer->nstreams;++i){
|
||||
for(i=0;i<remote_offer->nstreams;++i){
|
||||
rs=&remote_offer->streams[i];
|
||||
ms_message("Processing for stream %i",i);
|
||||
ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
|
||||
if (ls){
|
||||
initiate_incoming(ls,rs,&result->streams[j],one_matching_codec);
|
||||
++j;
|
||||
initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
|
||||
} else {
|
||||
/* create an inactive stream for the answer, as there where no matching stream a local capability */
|
||||
result->streams[i].dir=SalStreamInactive;
|
||||
result->streams[i].port=0;
|
||||
result->streams[i].type=rs->type;
|
||||
if (rs->type==SalOther){
|
||||
strncpy(result->streams[i].typeother,rs->typeother,sizeof(rs->typeother)-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
result->nstreams=j;
|
||||
result->nstreams=i;
|
||||
strcpy(result->username, local_capabilities->username);
|
||||
strcpy(result->addr,local_capabilities->addr);
|
||||
result->bandwidth=local_capabilities->bandwidth;
|
||||
result->session_ver=local_capabilities->session_ver;
|
||||
result->session_id=local_capabilities->session_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define _PRIVATE_H
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
#include "sal.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -97,6 +98,7 @@ struct _LinphoneCall
|
|||
bool_t camera_active;
|
||||
bool_t all_muted; /*this flag is set during early medias*/
|
||||
bool_t playing_ringbacktone;
|
||||
bool_t owns_call_log;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -424,6 +426,7 @@ struct _LinphoneCore
|
|||
unsigned long video_window_id;
|
||||
unsigned long preview_window_id;
|
||||
time_t netup_time; /*time when network went reachable */
|
||||
struct _EcCalibrator *ecc;
|
||||
bool_t use_files;
|
||||
bool_t apply_nat_settings;
|
||||
bool_t initial_subscribes_sent;
|
||||
|
|
@ -432,6 +435,7 @@ struct _LinphoneCore
|
|||
bool_t auto_net_state_mon;
|
||||
bool_t network_reachable;
|
||||
bool_t use_preview_window;
|
||||
bool_t ringstream_autorelease;
|
||||
};
|
||||
|
||||
bool_t linphone_core_can_we_add_call(LinphoneCore *lc);
|
||||
|
|
@ -443,6 +447,7 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc);
|
|||
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
|
||||
void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md);
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
|
||||
|
||||
|
|
@ -451,6 +456,27 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl
|
|||
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
|
||||
void _linphone_core_configure_resolver();
|
||||
|
||||
struct _EcCalibrator{
|
||||
ms_thread_t thread;
|
||||
MSSndCard *play_card,*capt_card;
|
||||
MSFilter *sndread,*det,*rec;
|
||||
MSFilter *play, *gen, *sndwrite,*resampler;
|
||||
MSTicker *ticker;
|
||||
LinphoneEcCalibrationCallback cb;
|
||||
void *cb_data;
|
||||
int recv_count;
|
||||
int sent_count;
|
||||
int64_t acc;
|
||||
int delay;
|
||||
LinphoneEcCalibratorStatus status;
|
||||
};
|
||||
|
||||
typedef struct _EcCalibrator EcCalibrator;
|
||||
|
||||
LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc);
|
||||
|
||||
void ec_calibrator_destroy(EcCalibrator *ecc);
|
||||
|
||||
#define HOLD_OFF (0)
|
||||
#define HOLD_ON (1)
|
||||
|
||||
|
|
|
|||
|
|
@ -249,13 +249,14 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
|
|||
if (host!=NULL){
|
||||
LinphoneAddress *contact;
|
||||
char localip[LINPHONE_IPADDR_SIZE];
|
||||
LCSipTransports tr;
|
||||
|
||||
linphone_core_get_local_ip(obj->lc,host,localip);
|
||||
contact=linphone_address_new(obj->reg_identity);
|
||||
linphone_address_set_domain (contact,localip);
|
||||
linphone_address_set_port_int(contact,linphone_core_get_sip_port(obj->lc));
|
||||
linphone_address_set_display_name(contact,NULL);
|
||||
LCSipTransports tr;
|
||||
|
||||
linphone_core_get_sip_transports(obj->lc,&tr);
|
||||
if (tr.udp_port <= 0 && tr.tcp_port>0) {
|
||||
sal_address_add_param(contact,"transport","tcp");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -128,7 +150,6 @@ static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
|
|||
}
|
||||
if (e1!=NULL || e2!=NULL){
|
||||
/*means one list is longer than the other*/
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ typedef struct SalEndpointCandidate{
|
|||
typedef struct SalStreamDescription{
|
||||
SalMediaProto proto;
|
||||
SalStreamType type;
|
||||
char typeother[32];
|
||||
char addr[64];
|
||||
int port;
|
||||
MSList *payloads; //<list of PayloadType
|
||||
|
|
@ -120,6 +121,8 @@ typedef struct SalMediaDescription{
|
|||
char username[64];
|
||||
int nstreams;
|
||||
int bandwidth;
|
||||
unsigned int session_ver;
|
||||
unsigned int session_id;
|
||||
SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
|
||||
} SalMediaDescription;
|
||||
|
||||
|
|
@ -192,6 +195,7 @@ typedef void (*SalOnCallAck)(SalOp *op);
|
|||
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE is received*/
|
||||
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
|
||||
typedef void (*SalOnCallReleased)(SalOp *salop);
|
||||
typedef void (*SalOnAuthRequested)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnAuthSuccess)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
|
||||
|
|
@ -215,6 +219,7 @@ typedef struct SalCallbacks{
|
|||
SalOnCallUpdating call_updating;
|
||||
SalOnCallTerminated call_terminated;
|
||||
SalOnCallFailure call_failure;
|
||||
SalOnCallReleased call_released;
|
||||
SalOnAuthRequested auth_requested;
|
||||
SalOnAuthSuccess auth_success;
|
||||
SalOnRegisterSuccess register_success;
|
||||
|
|
@ -249,7 +254,13 @@ ortp_socket_t sal_get_socket(Sal *ctx);
|
|||
void sal_set_user_agent(Sal *ctx, const char *user_agent);
|
||||
/*keepalive period in ms*/
|
||||
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
|
||||
/**
|
||||
* returns keepalive period in ms
|
||||
* 0 desactiaved
|
||||
* */
|
||||
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);
|
||||
|
|
@ -265,6 +276,7 @@ void sal_op_set_from(SalOp *op, const char *from);
|
|||
void sal_op_set_to(SalOp *op, const char *to);
|
||||
void sal_op_release(SalOp *h);
|
||||
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
|
||||
void sal_op_cancel_authentication(SalOp *h);
|
||||
void sal_op_set_user_pointer(SalOp *h, void *up);
|
||||
int sal_op_get_auth_requested(SalOp *h, const char **realm, const char **username);
|
||||
const char *sal_op_get_from(const SalOp *op);
|
||||
|
|
@ -285,8 +297,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);
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#include "sal_eXosip2.h"
|
||||
|
||||
#include "private.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
|
||||
|
||||
static void text_received(Sal *sal, eXosip_event_t *ev);
|
||||
|
||||
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
|
||||
|
|
@ -264,6 +266,7 @@ Sal * sal_init(){
|
|||
eXosip_init();
|
||||
sal=ms_new0(Sal,1);
|
||||
sal->keepalive_period=30;
|
||||
sal->double_reg=TRUE;
|
||||
return sal;
|
||||
}
|
||||
|
||||
|
|
@ -296,6 +299,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
|
|||
ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
|
||||
if (ctx->callbacks.call_terminated==NULL)
|
||||
ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
|
||||
if (ctx->callbacks.call_released==NULL)
|
||||
ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
|
||||
if (ctx->callbacks.call_updating==NULL)
|
||||
ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
|
||||
if (ctx->callbacks.auth_requested==NULL)
|
||||
|
|
@ -326,6 +331,7 @@ int sal_unlisten_ports(Sal *ctx){
|
|||
if (ctx->running){
|
||||
eXosip_quit();
|
||||
eXosip_init();
|
||||
ctx->running=FALSE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -334,13 +340,17 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
|
|||
int err;
|
||||
bool_t ipv6;
|
||||
int proto=IPPROTO_UDP;
|
||||
int keepalive = ctx->keepalive_period;
|
||||
|
||||
switch (tr) {
|
||||
case SalTransportDatagram:
|
||||
proto=IPPROTO_UDP;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
|
||||
break;
|
||||
case SalTransportStream:
|
||||
proto= IPPROTO_TCP;
|
||||
keepalive=-1;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
|
||||
break;
|
||||
default:
|
||||
ms_warning("unexpected proto, using datagram");
|
||||
|
|
@ -361,7 +371,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
|
|||
#ifdef HAVE_EXOSIP_GET_SOCKET
|
||||
ms_message("Exosip has socket number %i",eXosip_get_socket(proto));
|
||||
#endif
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
|
||||
|
||||
ctx->running=TRUE;
|
||||
return err;
|
||||
}
|
||||
|
|
@ -391,6 +401,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;
|
||||
|
|
@ -764,8 +778,6 @@ int sal_call_terminate(SalOp *h){
|
|||
if (err!=0){
|
||||
ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
|
||||
}
|
||||
sal_remove_call(h->base.root,h);
|
||||
h->cid=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +796,16 @@ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
|
|||
h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
|
||||
}
|
||||
}
|
||||
void sal_op_cancel_authentication(SalOp *h) {
|
||||
if (h->rid >0) {
|
||||
sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"));
|
||||
} else if (h->cid >0) {
|
||||
sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"),0);
|
||||
} else {
|
||||
ms_warning("Auth failure not handled");
|
||||
}
|
||||
|
||||
}
|
||||
static void set_network_origin(SalOp *op, osip_message_t *req){
|
||||
const char *received=NULL;
|
||||
int rport=5060;
|
||||
|
|
@ -836,6 +857,9 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
|
|||
if (ev->sid>0){
|
||||
return sal_find_out_subscribe(sal,ev->sid);
|
||||
}
|
||||
if (ev->nid>0){
|
||||
return sal_find_in_subscribe(sal,ev->nid);
|
||||
}
|
||||
if (ev->response) return sal_find_other(sal,ev->response);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1054,8 +1078,6 @@ static void call_terminated(Sal *sal, eXosip_event_t *ev){
|
|||
if (ev->request){
|
||||
osip_from_to_str(ev->request->from,&from);
|
||||
}
|
||||
sal_remove_call(sal,op);
|
||||
op->cid=-1;
|
||||
sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
|
||||
if (from) osip_free(from);
|
||||
}
|
||||
|
|
@ -1066,9 +1088,11 @@ static void call_released(Sal *sal, eXosip_event_t *ev){
|
|||
ms_warning("No op associated to this call_released()");
|
||||
return;
|
||||
}
|
||||
op->cid=-1;
|
||||
if (op->did==-1)
|
||||
sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487);
|
||||
if (ev->response==NULL){
|
||||
/* no response received so far */
|
||||
call_failure(sal,ev);
|
||||
}
|
||||
sal->callbacks.call_released(op);
|
||||
}
|
||||
|
||||
static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
|
||||
|
|
@ -1323,9 +1347,11 @@ static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
|
|||
sal->callbacks.dtmf_received(op, tmp[0]);
|
||||
}
|
||||
}
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,200,&ans);
|
||||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
eXosip_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1553,6 +1579,9 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori
|
|||
char *tmp;
|
||||
char port[20];
|
||||
SalAddress *addr;
|
||||
Sal *sal=op->base.root;
|
||||
|
||||
if (sal->double_reg==FALSE) return FALSE;
|
||||
|
||||
if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE;
|
||||
osip_message_get_contact(orig_request,0,&ctt);
|
||||
|
|
@ -1784,6 +1813,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
|
|||
other_request_reply(sal,ev);
|
||||
break;
|
||||
case EXOSIP_MESSAGE_REQUESTFAILURE:
|
||||
case EXOSIP_NOTIFICATION_REQUESTFAILURE:
|
||||
if (ev->response) {
|
||||
switch (ev->response->status_code) {
|
||||
case 407:
|
||||
|
|
@ -1982,6 +2012,9 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
|
|||
ctx->keepalive_period=value;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
|
||||
}
|
||||
unsigned int sal_get_keepalive_period(Sal *ctx) {
|
||||
return ctx->keepalive_period;
|
||||
}
|
||||
|
||||
const char * sal_address_get_port(const SalAddress *addr) {
|
||||
const osip_from_t *u=(const osip_from_t*)addr;
|
||||
|
|
@ -1997,47 +2030,18 @@ int sal_address_get_port_int(const SalAddress *uri) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a re-Invite used to hold the current call
|
||||
*/
|
||||
int sal_call_hold(SalOp *h, bool_t holdon)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
osip_message_t *reinvite=NULL;
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
|
||||
return -1;
|
||||
osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
osip_message_set_supported(reinvite, "timer");
|
||||
}
|
||||
//add something to say that the distant sip phone will be in sendonly/sendrecv mode
|
||||
if (h->base.local_media){
|
||||
h->sdp_offering=TRUE;
|
||||
sal_media_description_set_dir(h->base.local_media, holdon ? SalStreamSendOnly : SalStreamSendRecv);
|
||||
set_sdp_from_desc(reinvite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
eXosip_lock();
|
||||
err = eXosip_call_send_request(h->did, reinvite);
|
||||
eXosip_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sends a reinvite. Local media description may have changed by application since call establishment*/
|
||||
int sal_call_update(SalOp *h){
|
||||
int sal_call_update(SalOp *h, const char *subject){
|
||||
int err=0;
|
||||
osip_message_t *reinvite=NULL;
|
||||
|
||||
eXosip_lock();
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL){
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
|
||||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
eXosip_unlock();
|
||||
osip_message_set_subject(reinvite,osip_strdup("Phone call parameters updated"));
|
||||
osip_message_set_subject(reinvite,subject);
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct Sal{
|
|||
int keepalive_period;
|
||||
void *up;
|
||||
bool_t one_matching_codec;
|
||||
bool_t double_reg;
|
||||
};
|
||||
|
||||
struct SalOp{
|
||||
|
|
@ -78,6 +79,7 @@ void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev);
|
|||
|
||||
void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev);
|
||||
SalOp * sal_find_out_subscribe(Sal *sal, int sid);
|
||||
SalOp * sal_find_in_subscribe(Sal *sal, int nid);
|
||||
void sal_exosip_fix_route(SalOp *op);
|
||||
|
||||
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ SalOp * sal_find_out_subscribe(Sal *sal, int sid){
|
|||
op=(SalOp*)elem->data;
|
||||
if (op->sid==sid) return op;
|
||||
}
|
||||
ms_message("No op for sid %i",sid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ void sal_remove_out_subscribe(Sal *sal, SalOp *op){
|
|||
sal->out_subscribes=ms_list_remove(sal->out_subscribes,op);
|
||||
}
|
||||
|
||||
static SalOp * sal_find_in_subscribe(Sal *sal, int nid){
|
||||
SalOp * sal_find_in_subscribe(Sal *sal, int nid){
|
||||
const MSList *elem;
|
||||
SalOp *op;
|
||||
for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
|
||||
|
|
@ -569,6 +570,7 @@ int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_
|
|||
if (msg!=NULL){
|
||||
const char *identity=sal_op_get_contact(op);
|
||||
if (identity==NULL) identity=sal_op_get_to(op);
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,identity);
|
||||
add_presence_body(msg,status);
|
||||
eXosip_insubscription_send_request(op->did,msg);
|
||||
|
|
|
|||
|
|
@ -127,14 +127,18 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
|
|||
{
|
||||
sdp_message_t *local;
|
||||
int inet6;
|
||||
|
||||
char sessid[16];
|
||||
char sessver[16];
|
||||
|
||||
snprintf(sessid,16,"%i",desc->session_id);
|
||||
snprintf(sessver,16,"%i",desc->session_ver);
|
||||
sdp_message_init (&local);
|
||||
if (strchr(desc->addr,':')!=NULL){
|
||||
inet6=1;
|
||||
}else inet6=0;
|
||||
sdp_message_v_version_set (local, osip_strdup ("0"));
|
||||
sdp_message_o_origin_set (local, osip_strdup (desc->username),
|
||||
osip_strdup ("123456"), osip_strdup ("654321"),
|
||||
osip_strdup (sessid), osip_strdup (sessver),
|
||||
osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"),
|
||||
osip_strdup (desc->addr));
|
||||
sdp_message_s_name_set (local, osip_strdup ("A conversation"));
|
||||
|
|
@ -181,11 +185,23 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt)
|
|||
|
||||
|
||||
static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){
|
||||
const char *mt=desc->type==SalAudio ? "audio" : "video";
|
||||
const char *mt=NULL;
|
||||
const MSList *elem;
|
||||
const char *addr;
|
||||
const char *dir="sendrecv";
|
||||
int port;
|
||||
|
||||
switch (desc->type) {
|
||||
case SalAudio:
|
||||
mt="audio";
|
||||
break;
|
||||
case SalVideo:
|
||||
mt="video";
|
||||
break;
|
||||
case SalOther:
|
||||
mt=desc->typeother;
|
||||
break;
|
||||
}
|
||||
if (desc->candidates[0].addr[0]!='\0'){
|
||||
addr=desc->candidates[0].addr;
|
||||
port=desc->candidates[0].port;
|
||||
|
|
@ -310,7 +326,10 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
|
|||
stream->type=SalAudio;
|
||||
}else if (strcasecmp("video", mtype) == 0){
|
||||
stream->type=SalVideo;
|
||||
}else stream->type=SalOther;
|
||||
}else {
|
||||
stream->type=SalOther;
|
||||
strncpy(stream->typeother,mtype,sizeof(stream->typeother)-1);
|
||||
}
|
||||
for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){
|
||||
if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth);
|
||||
}
|
||||
|
|
|
|||
46
coreapi/test_ecc.c
Normal file
46
coreapi/test_ecc.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2011 Belledonne Communications SARL
|
||||
Author: Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
|
||||
static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data){
|
||||
ms_message("echo calibration finished %s.",status==LinphoneEcCalibratorDone ? "successfully" : "with faillure");
|
||||
if (status==LinphoneEcCalibratorDone) ms_message("Measured delay is %i",delay);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int count=0;
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
linphone_core_enable_logs(NULL);
|
||||
|
||||
linphone_core_start_echo_calibration(lc,calibration_finished,NULL);
|
||||
|
||||
while(count++<1000){
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(10000);
|
||||
}
|
||||
linphone_core_destroy(lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
2
gtk/.gitignore
vendored
2
gtk/.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
linphone-3
|
||||
linphone
|
||||
.libs
|
||||
.deps
|
||||
linphone.res
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ if BUILD_GTK_UI
|
|||
|
||||
BUILT_SOURCES=version_date.h
|
||||
|
||||
bin_PROGRAMS=linphone-3
|
||||
bin_PROGRAMS=linphone
|
||||
|
||||
linphone_3_SOURCES= \
|
||||
linphone_SOURCES= \
|
||||
main.c \
|
||||
propertybox.c \
|
||||
friendlist.c \
|
||||
|
|
@ -45,7 +45,7 @@ linphone_3_SOURCES= \
|
|||
loginframe.c \
|
||||
linphone.h
|
||||
|
||||
linphone_3_LDADD=$(ORTP_LIBS) \
|
||||
linphone_LDADD=$(ORTP_LIBS) \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(LIBGTK_LIBS) $(INTLLIBS)
|
||||
|
|
@ -56,10 +56,10 @@ if BUILD_WIN32
|
|||
linphone.res: $(LINPHONE_ICO_RC_FILE) $(LINPHONE_ICO_FILE)
|
||||
windres $(LINPHONE_ICO_RC_FILE) -O coff -o linphone.res
|
||||
|
||||
linphone_3_LDADD+=linphone.res -lwininet
|
||||
linphone_3_LDFLAGS=-Wl,--export-all-symbols -mwindows
|
||||
linphone_LDADD+=linphone.res -lwininet
|
||||
linphone_LDFLAGS=-Wl,--export-all-symbols -mwindows
|
||||
else
|
||||
linphone_3_LDFLAGS=-export-dynamic
|
||||
linphone_LDFLAGS=-export-dynamic
|
||||
endif
|
||||
|
||||
uidir=$(datadir)/linphone
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
|
|||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif");
|
||||
GtkWidget *answer_button;
|
||||
GtkWidget *image;
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Incoming call</b>"));
|
||||
gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
|
|
@ -209,14 +210,17 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
|
|||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
answer_button=linphone_gtk_get_widget(callview,"accept_call");
|
||||
gtk_button_set_image(GTK_BUTTON(answer_button),
|
||||
create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png")));
|
||||
image=create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"));
|
||||
if (with_pause){
|
||||
gtk_button_set_label(GTK_BUTTON(answer_button),
|
||||
_("Pause all calls\nand answer"));
|
||||
}else gtk_button_set_label(GTK_BUTTON(answer_button),_("Answer"));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),
|
||||
create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png")));
|
||||
gtk_button_set_image(GTK_BUTTON(answer_button),image);
|
||||
gtk_widget_show(image);
|
||||
|
||||
image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),image);
|
||||
gtk_widget_show(image);
|
||||
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="incoming_call">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="type">popup</property>
|
||||
<property name="title" translatable="yes">Linphone - Incoming call</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">notification</property>
|
||||
<property name="urgency_hint">True</property>
|
||||
<property name="deletable">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call from</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label43">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call</property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">spread</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="accept_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal handler="linphone_gtk_accept_call" name="clicked"/>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox17">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-yes</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label44">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Accept</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="decline_cal">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal handler="linphone_gtk_decline_call" name="clicked"/>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox20">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image13">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="decline_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Decline</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -1446,6 +1446,7 @@ int main(int argc, char *argv[]){
|
|||
|
||||
settings=gtk_settings_get_default();
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM));
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
|
||||
g_object_set(settings, "gtk-menu-images", TRUE, NULL);
|
||||
g_object_set(settings, "gtk-button-images", TRUE, NULL);
|
||||
#ifdef WIN32
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import java.util.Vector;
|
|||
* Object representing a Call. calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or passed to the application by listener {@link LinphoneCoreListener#callState(LinphoneCore, LinphoneCall, State, String)}
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public interface LinphoneCall {
|
||||
/**
|
||||
* Linphone call states
|
||||
|
|
@ -110,7 +110,11 @@ public interface LinphoneCall {
|
|||
* The remote accepted the call update initiated by us
|
||||
*/
|
||||
public static final State CallUpdated = new State(17, "CallUpdated");
|
||||
|
||||
|
||||
/**
|
||||
* The call object is now released.
|
||||
*/
|
||||
public static final State CallReleased = new State(18,"CallReleased");
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
|
|
@ -174,5 +178,9 @@ public interface LinphoneCall {
|
|||
* @return true if echo limiter is enabled.
|
||||
*/
|
||||
public boolean isEchoLimiterEnabled();
|
||||
|
||||
/**
|
||||
* Returns the object associated to a call this one is replacing.
|
||||
* Call replacement can occur during transfer scenarios.
|
||||
*/
|
||||
public LinphoneCall getReplacedCall();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ package org.linphone.core;
|
|||
import java.util.Vector;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public interface LinphoneCallLog {
|
||||
/**
|
||||
* Represents call status
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import java.util.Vector;
|
|||
* Linphone core main object created by method {@link LinphoneCoreFactory#createLinphoneCore(LinphoneCoreListener, String, String, Object)}.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public interface LinphoneCore {
|
||||
/**
|
||||
* linphone core states
|
||||
|
|
@ -179,6 +179,50 @@ public interface LinphoneCore {
|
|||
return mStringValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* EC Calibrator Status
|
||||
.
|
||||
*
|
||||
*/
|
||||
static public class EcCalibratorStatus {
|
||||
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* Calibration in progress
|
||||
*/
|
||||
static public EcCalibratorStatus InProgress = new EcCalibratorStatus(0,"InProgress");
|
||||
/**
|
||||
* Calibration done
|
||||
*/
|
||||
static public EcCalibratorStatus Done = new EcCalibratorStatus(1,"Done");
|
||||
/**
|
||||
* Calibration in progress
|
||||
*/
|
||||
static public EcCalibratorStatus Failed = new EcCalibratorStatus(2,"Failed");
|
||||
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private EcCalibratorStatus(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static EcCalibratorStatus fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
EcCalibratorStatus status = (EcCalibratorStatus) values.elementAt(i);
|
||||
if (status.mValue == value) return status;
|
||||
}
|
||||
throw new RuntimeException("status not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
public int value(){
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* clear all added proxy configs
|
||||
*/
|
||||
|
|
@ -386,10 +430,17 @@ public interface LinphoneCore {
|
|||
*/
|
||||
public boolean isEchoCancellationEnabled();
|
||||
/**
|
||||
* not implemented yet
|
||||
* set transport used for signaling (TCP or UDP)
|
||||
*
|
||||
* @param aTransport
|
||||
*/
|
||||
public void setSignalingTransport(Transport aTransport);
|
||||
/**
|
||||
* get transport used for signaling (TCP or UDP)
|
||||
*
|
||||
* @return Transport;
|
||||
*/
|
||||
public Transport getSignalingTransport();
|
||||
/**
|
||||
* not implemented
|
||||
* @param value
|
||||
|
|
@ -489,5 +540,20 @@ public interface LinphoneCore {
|
|||
public VideoSize getPreferredVideoSize();
|
||||
|
||||
public PayloadType[] listVideoCodecs();
|
||||
|
||||
/**
|
||||
* enable signaling keep alive. small udp packet sent periodically to keep udp NAT association
|
||||
*/
|
||||
void enableKeepAlive(boolean enable);
|
||||
/**
|
||||
* get keep elive mode
|
||||
* @return true if enable
|
||||
*/
|
||||
boolean isKeepAliveEnabled();
|
||||
/**
|
||||
* Start an echo calibration of the sound devices, in order to find adequate settings for the echo canceler automatically.
|
||||
* status is notified to {@link LinphoneCoreListener#ecCalibrationStatus(EcCalibratorStatus, int, Object)}
|
||||
* @param User object
|
||||
* @throws LinphoneCoreException if operation is still in progress;
|
||||
**/
|
||||
void startEchoCalibration(Object data) throws LinphoneCoreException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ package org.linphone.core;
|
|||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
abstract public class LinphoneCoreFactory {
|
||||
|
||||
private static String factoryName = "org.linphone.core.LinphoneCoreFactoryImpl";
|
||||
|
|
|
|||
|
|
@ -78,5 +78,14 @@ public interface LinphoneCoreListener {
|
|||
* @param message incoming message
|
||||
*/
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);
|
||||
/**
|
||||
* Invoked when echo cancalation calibration is completed
|
||||
* @param lc LinphoneCore
|
||||
* @param status
|
||||
* @param delay_ms echo delay
|
||||
* @param data
|
||||
*/
|
||||
void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import java.util.Vector;
|
|||
*
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public interface LinphoneFriend {
|
||||
/**
|
||||
* Enum controlling behavior for incoming subscription request.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import java.util.Vector;
|
|||
* Enum describing remote friend status
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public class OnlineStatus {
|
||||
|
||||
static private Vector values = new Vector();
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public final class VideoSize {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public String toString() {
|
||||
return "width = "+width + " height = " + height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
./bin/avcodec-52.dll
|
||||
./bin/avutil-50.dll
|
||||
./bin/libeXosip2-4.dll
|
||||
./bin/libeXosip2-6.dll
|
||||
./bin/libogg.dll
|
||||
./bin/libtheora.dll
|
||||
./bin/libxml2-2.dll
|
||||
./bin/libosip2-4.dll
|
||||
./bin/libosipparser2-4.dll
|
||||
./bin/libosip2-6.dll
|
||||
./bin/libosipparser2-6.dll
|
||||
./bin/swscale-0.dll
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,19 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
|
|||
#include "linphone-win32.filelist"
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\Linphone"; Filename: "{app}\bin\linphone-3.exe" ; WorkingDir: "{app}"
|
||||
Name: "{userdesktop}\Linphone"; Filename: "{app}\bin\linphone-3.exe"; WorkingDir: "{app}" ; Tasks: desktopicon
|
||||
Name: "{group}\Linphone"; Filename: "{app}\bin\linphone.exe" ; WorkingDir: "{app}"
|
||||
Name: "{userdesktop}\Linphone"; Filename: "{app}\bin\linphone.exe"; WorkingDir: "{app}" ; Tasks: desktopicon
|
||||
|
||||
[Registry]
|
||||
Root: HKCR; Subkey: "sip";
|
||||
Root: HKCR; Subkey: "sip"; ValueData: "URL: SIP protocol" ; ValueType:string
|
||||
Root: HKCR; Subkey: "sip"; ValueName: "EditFlags"; ValueData: "02 00 00 00" ; ValueType:binary
|
||||
Root: HKCR; Subkey: "sip"; ValueName: "URL Protocol" ; ValueType:string
|
||||
Root: HKCR; Subkey: "sip\DefaultIcon"; ValueData: "{app}\bin\linphone-3.exe"; ValueType:string ; Flags:uninsdeletekey
|
||||
Root: HKCR; Subkey: "sip\DefaultIcon"; ValueData: "{app}\bin\linphone.exe"; ValueType:string ; Flags:uninsdeletekey
|
||||
Root: HKCR; Subkey: "sip\shell"
|
||||
Root: HKCR; Subkey: "sip\shell\open"
|
||||
Root: HKCR; Subkey: "sip\shell\open\command"; ValueType:string ; ValueData: "{app}\bin\linphone-3.exe --workdir {app} --call %1"; Flags:uninsdeletekey
|
||||
Root: HKCR; Subkey: "sip\shell\open\command"; ValueType:string ; ValueData: "{app}\bin\linphone.exe --workdir {app} --call %1"; Flags:uninsdeletekey
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\bin\linphone-3.exe"; Description: "{cm:LaunchProgram,Linphone}"; WorkingDir: "{app}" ; Flags: nowait postinstall skipifsilent
|
||||
Filename: "{app}\bin\linphone.exe"; Description: "{cm:LaunchProgram,Linphone}"; WorkingDir: "{app}" ; Flags: nowait postinstall skipifsilent
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<kdevcustomproject>
|
||||
<run>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<mainprogram>gtk-glade/linphone-3</mainprogram>
|
||||
<mainprogram>gtk-glade/linphone</mainprogram>
|
||||
<programargs/>
|
||||
<globaldebugarguments/>
|
||||
<globalcwd/>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ coreapi/presence.c
|
|||
coreapi/friend.c
|
||||
coreapi/proxy.c
|
||||
coreapi/callbacks.c
|
||||
coreapi/sal_eXosip2.c
|
||||
mediastreamer2/src/alaw.c
|
||||
mediastreamer2/src/alsa.c
|
||||
mediastreamer2/src/aqsnd.c
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
|
||||
gtk/p2pwizard.ui
|
||||
|
|
|
|||
1401
po/pt_BR.po
1401
po/pt_BR.po
File diff suppressed because it is too large
Load diff
1610
po/zh_CN.po
1610
po/zh_CN.po
File diff suppressed because it is too large
Load diff
|
|
@ -11,7 +11,7 @@ MSX264_ZIP=$(WORKDIR)/msx264.zip
|
|||
INSTALL_ROOT=$(WORKDIR)/root
|
||||
FILELIST=$(WORKDIR)/linphone-bundle.filelist
|
||||
|
||||
LINPHONE_VERSION=strings $(INSTALL_ROOT)/bin/linphone-3.exe |grep linphone_ident | sed 's/linphone_ident_string=//'
|
||||
LINPHONE_VERSION=strings $(INSTALL_ROOT)/bin/linphone.exe |grep linphone_ident | sed 's/linphone_ident_string=//'
|
||||
|
||||
$(WORKDIR):
|
||||
mkdir -p $(WORKDIR)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ LINPHONE_RINGS=rings/orig.wav \
|
|||
rings/oldphone-mono-30s.caf \
|
||||
rings/rock.wav \
|
||||
rings/bigben.wav \
|
||||
rings/toy.wav \
|
||||
rings/toy-mono.wav \
|
||||
rings/sweet.wav \
|
||||
rings/synth.wav \
|
||||
rings/tapping.wav
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Comment=Linphone is a web-phone
|
|||
Comment[fr]=Linphone est un web-phone.
|
||||
Comment[de]=Linphone ist ein web-phone.
|
||||
Type=Application
|
||||
Exec=linphone-3
|
||||
Exec=linphone
|
||||
Icon=@prefix@/share/pixmaps/linphone/linphone.png
|
||||
Terminal=false
|
||||
Categories=Network;Telephony;
|
||||
Categories=Network;Telephony;
|
||||
|
|
|
|||
BIN
share/rings/toy-mono.wav
Normal file
BIN
share/rings/toy-mono.wav
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue