Commit 5c939acd authored by Yann Diorcet's avatar Yann Diorcet
Browse files

Merge branch 'upnp'

Conflicts:
	coreapi/callbacks.c
	coreapi/linphonecore.c
	gtk/Makefile.am
	mediastreamer2
parents 39bbe265 8fed4df3
......@@ -161,6 +161,32 @@ AC_ARG_ENABLE(tools,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
esac],[build_tools=check])
dnl check for installed version of libupnp
AC_ARG_ENABLE(upnp,
[AS_HELP_STRING([--disable-upnp], [Disable uPnP support])],
[case "${enableval}" in
yes) build_upnp=true ;;
no) build_upnp=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-upnp) ;;
esac],[build_upnp=auto])
if test "$build_upnp" != "false" ; then
PKG_CHECK_MODULES([LIBUPNP], [libupnp], [build_upnp=true],
[
if test "$build_upnp" == "true" ; then
AC_MSG_ERROR([libupnp not found.])
else
build_upnp=false
fi
])
fi
AM_CONDITIONAL(BUILD_UPNP, test x$build_upnp != xfalse)
if test "$build_upnp" != "false" ; then
AC_DEFINE(BUILD_UPNP, 1, [Define if upnp enabled])
fi
dnl check libxml2 (needed for tools)
if test "$build_tools" != "false" ; then
PKG_CHECK_MODULES(LIBXML2, [libxml-2.0],[],
......
......@@ -206,7 +206,7 @@ static LPC_COMMAND commands[] = {
{ "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode",
"'autoanswer' \t: show current autoanswer mode\n"
"'autoanswer enable'\t: enable autoanswer mode\n"
"'autoanswer disable'\t: disable autoanswer mode \n"},
"'autoanswer disable'\t: disable autoanswer mode��\n"},
{ "proxy", lpc_cmd_proxy, "Manage proxies",
"'proxy list' : list all proxy setups.\n"
"'proxy add' : add a new proxy setup.\n"
......@@ -896,6 +896,9 @@ lpc_cmd_firewall(LinphoneCore *lc, char *args)
case LinphonePolicyUseIce:
linphonec_out("Using ice with stun server %s to discover firewall address\n", setting ? setting : linphone_core_get_stun_server(lc));
break;
case LinphonePolicyUseUpnp:
linphonec_out("Using uPnP IGD protocol\n");
break;
}
return 1;
}
......
......@@ -47,15 +47,21 @@ liblinphone_la_SOURCES=\
lsd.c linphonecore_utils.h \
ec-calibrator.c \
conference.c \
linphone_tunnel.cc \
$(GITVERSION_FILE)
if BUILD_UPNP
liblinphone_la_SOURCES+=upnp.c upnp.h
endif
if BUILD_WIZARD
liblinphone_la_SOURCES+=sipwizard.c
endif
liblinphone_la_SOURCES+=linphone_tunnel_config.c
if BUILD_TUNNEL
liblinphone_la_SOURCES+=TunnelManager.cc TunnelManager.hh
liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh
else
liblinphone_la_SOURCES+=linphone_tunnel_stubs.c
endif
......
......@@ -261,6 +261,13 @@ static void call_received(SalOp *h){
ms_message("Defer ringing to gather ICE candidates");
return;
}
#ifdef BUILD_UPNP
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseUpnp) && (call->upnp_session != NULL)) {
/* Defer ringing until the end of the ICE candidates gathering process. */
ms_message("Defer ringing to gather uPnP candidates");
return;
}
#endif //BUILD_UPNP
linphone_core_notify_incoming_call(lc,call);
}
......@@ -334,6 +341,11 @@ static void call_accepted(SalOp *op){
if (call->ice_session != NULL) {
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
}
#ifdef BUILD_UPNP
if (call->upnp_session != NULL) {
linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op));
}
#endif //BUILD_UPNP
md=sal_call_get_final_media_description(op);
call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
......@@ -426,6 +438,12 @@ static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
linphone_core_update_ice_from_remote_media_description(call,rmd);
linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session);
}
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
linphone_core_update_upnp_from_remote_media_description(call, rmd);
linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
}
#endif //BUILD_UPNP
linphone_call_update_remote_session_id_and_ver(call);
sal_call_accept(call->op);
md=sal_call_get_final_media_description(call->op);
......@@ -522,6 +540,10 @@ static void call_terminated(SalOp *op, const char *from){
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call terminated."));
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(call);
#endif //BUILD_UPNP
linphone_call_set_state(call, LinphoneCallEnd,"Call ended");
}
......@@ -618,6 +640,11 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
/*resume to the call that send us the refer automatically*/
linphone_core_resume_call(lc,call->referer);
}
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(call);
#endif //BUILD_UPNP
if (sr == SalReasonDeclined) {
call->reason=LinphoneReasonDeclined;
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
......
......@@ -23,9 +23,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef TUNNEL_ENABLED
#include "TunnelManager.hh"
#endif
#include "linphone_tunnel.h"
#include "linphonecore.h"
#include "private.h"
......@@ -35,67 +33,6 @@ LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){
return lc->tunnel;
}
struct _LinphoneTunnelConfig {
char *host;
int port;
int remote_udp_mirror_port;
int delay;
};
LinphoneTunnelConfig *linphone_tunnel_config_new() {
LinphoneTunnelConfig *ltc = ms_new0(LinphoneTunnelConfig,1);
ltc->remote_udp_mirror_port = 12345;
ltc->delay = 1000;
return ltc;
}
void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host) {
if(tunnel->host != NULL) {
ms_free(tunnel->host);
tunnel->host = NULL;
}
if(host != NULL && strlen(host)) {
tunnel->host = ms_strdup(host);
}
}
const char *linphone_tunnel_config_get_host(LinphoneTunnelConfig *tunnel) {
return tunnel->host;
}
void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port) {
tunnel->port = port;
}
int linphone_tunnel_config_get_port(LinphoneTunnelConfig *tunnel) {
return tunnel->port;
}
void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port) {
tunnel->remote_udp_mirror_port = remote_udp_mirror_port;
}
int linphone_tunnel_config_get_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel) {
return tunnel->remote_udp_mirror_port;
}
void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay) {
tunnel->delay = delay;
}
int linphone_tunnel_config_get_delay(LinphoneTunnelConfig *tunnel) {
return tunnel->delay;
}
void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) {
if(tunnel->host != NULL) {
ms_free(tunnel->host);
}
ms_free(tunnel);
}
#ifdef TUNNEL_ENABLED
struct _LinphoneTunnel {
belledonnecomm::TunnelManager *manager;
MSList *config_list;
......@@ -122,16 +59,16 @@ void linphone_tunnel_destroy(LinphoneTunnel *tunnel){
static char *linphone_tunnel_config_to_string(const LinphoneTunnelConfig *tunnel_config) {
char *str = NULL;
if(tunnel_config->remote_udp_mirror_port != -1) {
if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) != -1) {
str = ms_strdup_printf("%s:%d:%d:%d",
tunnel_config->host,
tunnel_config->port,
tunnel_config->remote_udp_mirror_port,
tunnel_config->delay);
linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config),
linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
linphone_tunnel_config_get_delay(tunnel_config));
} else {
str = ms_strdup_printf("%s:%d",
tunnel_config->host,
tunnel_config->port);
linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config));
}
return str;
}
......@@ -209,11 +146,14 @@ static void linphone_tunnel_save_config(LinphoneTunnel *tunnel) {
static void linphone_tunnel_add_server_intern(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config) {
if(tunnel_config->remote_udp_mirror_port == -1) {
bcTunnel(tunnel)->addServer(tunnel_config->host, tunnel_config->port);
if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) == -1) {
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config));
} else {
bcTunnel(tunnel)->addServer(tunnel_config->host, tunnel_config->port,
tunnel_config->remote_udp_mirror_port, tunnel_config->delay);
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config),
linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
linphone_tunnel_config_get_delay(tunnel_config));
}
tunnel->config_list = ms_list_append(tunnel->config_list, tunnel_config);
}
......@@ -385,60 +325,3 @@ void linphone_tunnel_configure(LinphoneTunnel *tunnel){
linphone_tunnel_enable(tunnel, enabled);
}
#else
/*stubs to avoid to have #ifdef TUNNEL_ENABLED in upper layers*/
void linphone_tunnel_destroy(LinphoneTunnel *tunnel){
}
void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){
}
void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){
}
const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){
return NULL;
}
void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){
}
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){
}
bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel){
return FALSE;
}
void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t enabled, OrtpLogFunc logHandler){
}
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel *tunnel, const char* username,const char* passwd){
}
void linphone_tunnel_set_http_proxy(LinphoneTunnel*tunnel, const char *host, int port, const char* username,const char* passwd){
}
void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int *port, const char **username, const char **passwd){
}
void linphone_tunnel_reconnect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
}
#endif
......@@ -68,7 +68,7 @@ void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *h
*
* @param tunnel configuration object
*/
const char *linphone_tunnel_config_get_host(LinphoneTunnelConfig *tunnel);
const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel);
/**
* Set tls port of server.
......@@ -83,7 +83,7 @@ void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port);
*
* @param tunnel configuration object
*/
int linphone_tunnel_config_get_port(LinphoneTunnelConfig *tunnel);
int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel);
/**
* Set the remote port on the tunnel server side used to test udp reachability.
......@@ -98,7 +98,7 @@ void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tun
*
* @param tunnel configuration object
*/
int linphone_tunnel_config_get_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel);
int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel);
/**
* Set the udp packet round trip delay in ms for a tunnel configuration.
......@@ -113,7 +113,7 @@ void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay);
*
* @param tunnel configuration object
*/
int linphone_tunnel_config_get_delay(LinphoneTunnelConfig *tunnel);
int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel);
/**
* Destroy a tunnel configuration
......
/***************************************************************************
* linphone_tunnel_config.c
*
* Copyright 2012 Belledonne Communications
****************************************************************************/
/*
* 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 "linphone_tunnel.h"
struct _LinphoneTunnelConfig {
char *host;
int port;
int remote_udp_mirror_port;
int delay;
};
LinphoneTunnelConfig *linphone_tunnel_config_new() {
LinphoneTunnelConfig *ltc = ms_new0(LinphoneTunnelConfig,1);
ltc->remote_udp_mirror_port = 12345;
ltc->delay = 1000;
return ltc;
}
void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host) {
if(tunnel->host != NULL) {
ms_free(tunnel->host);
tunnel->host = NULL;
}
if(host != NULL && strlen(host)) {
tunnel->host = ms_strdup(host);
}
}
const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel) {
return tunnel->host;
}
void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port) {
tunnel->port = port;
}
int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel) {
return tunnel->port;
}
void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port) {
tunnel->remote_udp_mirror_port = remote_udp_mirror_port;
}
int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel) {
return tunnel->remote_udp_mirror_port;
}
void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay) {
tunnel->delay = delay;
}
int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel) {
return tunnel->delay;
}
void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) {
if(tunnel->host != NULL) {
ms_free(tunnel->host);
}
ms_free(tunnel);
}
/***************************************************************************
* linphone_tunnel.cc
*
* Fri Dec 9, 2011
* Copyright 2011 Belledonne Communications
* Author: Guillaume Beraudo
* Email: guillaume dot beraudo at linphone dot 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 "linphone_tunnel.h"
#include "linphonecore.h"
#include "private.h"
#include "lpconfig.h"
LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){
return lc->tunnel;
}
/*stubs to avoid to have #ifdef TUNNEL_ENABLED in upper layers*/
void linphone_tunnel_destroy(LinphoneTunnel *tunnel){
}
void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){
}
void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){
}
const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){
return NULL;
}
void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){
}
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){
}
bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel){
return FALSE;
}
void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t enabled, OrtpLogFunc logHandler){
}
void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel *tunnel, const char* username,const char* passwd){
}
void linphone_tunnel_set_http_proxy(LinphoneTunnel*tunnel, const char *host, int port, const char* username,const char* passwd){
}
void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int *port, const char **username, const char **passwd){
}
void linphone_tunnel_reconnect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
}
......@@ -302,6 +302,12 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
linphone_core_update_local_media_description_from_ice(md, call->ice_session);
linphone_core_update_ice_state_in_call_stats(call);
}
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
linphone_core_update_local_media_description_from_upnp(md, call->upnp_session);
linphone_core_update_upnp_state_in_call_stats(call);
}
#endif //BUILD_UPNP
linphone_address_destroy(addr);
call->localdesc=md;
if (old_md) sal_media_description_unref(old_md);
......@@ -435,6 +441,11 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
stats->received_rtcp = NULL;
stats->sent_rtcp = NULL;
stats->ice_state = LinphoneIceStateNotActivated;
#ifdef BUILD_UPNP
stats->upnp_state = LinphoneUpnpStateIdle;
#else
stats->upnp_state = LinphoneUpnpStateNotAvailable;
#endif //BUILD_UPNP
}
......@@ -468,6 +479,11 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) {
call->ping_time=linphone_core_run_stun_tests(call->core,call);
}
#ifdef BUILD_UPNP
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseUpnp) {
call->upnp_session = linphone_upnp_session_new(call);
}
#endif //BUILD_UPNP
call->camera_active=params->has_video;
discover_mtu(lc,linphone_address_get_domain (to));
......@@ -529,6 +545,19 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
case LinphonePolicyUseStun:
call->ping_time=linphone_core_run_stun_tests(call->core,call);
/* No break to also destroy ice session in this case. */
break;
case LinphonePolicyUseUpnp:
#ifdef BUILD_UPNP
call->upnp_session = linphone_upnp_session_new(call);
if (call->upnp_session != NULL) {
linphone_call_init_media_streams(call);
if (linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op))<0) {
/* uPnP port mappings failed, proceed with the call anyway. */
linphone_call_delete_upnp_session(call);
}
}
#endif //BUILD_UPNP
break;
default:
break;
}
......@@ -677,6 +706,9 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
static void linphone_call_destroy(LinphoneCall *obj)
{
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(obj);
#endif //BUILD_UPNP
linphone_call_delete_ice_session(obj);
if (obj->op!=NULL) {
sal_op_release(obj->op);
......@@ -1746,6 +1778,15 @@ void linphone_call_delete_ice_session(LinphoneCall *call){
}
}
#ifdef BUILD_UPNP
void linphone_call_delete_upnp_session(LinphoneCall *call){
if(call->upnp_session!=NULL) {
linphone_upnp_session_destroy(call->upnp_session);
call->upnp_session=NULL;
}
}
#endif //BUILD_UPNP
static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
audio_stream_get_local_rtp_stats (st,&log->local_stats);
log->quality=audio_stream_get_average_quality_rating(st);
......@@ -2056,6 +2097,11 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
report_bandwidth(call,as,vs);
ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load);
}
#ifdef BUILD_UPNP
linphone_upnp_call_process(call);
#endif //BUILD_UPNP
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL) {