Commit 02ff6c5f authored by Youness Alaoui's avatar Youness Alaoui

Add UPnP support to libnice

parent c4968e09
...@@ -12,12 +12,13 @@ AM_CFLAGS = \ ...@@ -12,12 +12,13 @@ AM_CFLAGS = \
-DG_LOG_DOMAIN=\"libnice\" \ -DG_LOG_DOMAIN=\"libnice\" \
$(ERROR_CFLAGS) \ $(ERROR_CFLAGS) \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(GUPNP_CFLAGS) \
-I $(top_srcdir) \ -I $(top_srcdir) \
-I $(top_srcdir)/random \ -I $(top_srcdir)/random \
-I $(top_srcdir)/socket \ -I $(top_srcdir)/socket \
-I $(top_srcdir)/stun -I $(top_srcdir)/stun
COMMON_LDADD = libagent.la $(GLIB_LIBS) COMMON_LDADD = libagent.la $(GLIB_LIBS) (GUPNP_LIBS)
dist_noinst_DATA = agent-signals-marshal.list dist_noinst_DATA = agent-signals-marshal.list
noinst_LTLIBRARIES = libagent.la noinst_LTLIBRARIES = libagent.la
......
...@@ -41,6 +41,13 @@ ...@@ -41,6 +41,13 @@
/* note: this is a private header part of agent.h */ /* note: this is a private header part of agent.h */
#ifdef HAVE_CONFIG_H
# include <config.h>
#else
#define NICEAPI_EXPORT
#endif
#include <glib.h> #include <glib.h>
#include "agent.h" #include "agent.h"
...@@ -53,6 +60,10 @@ ...@@ -53,6 +60,10 @@
#include "stun/usages/turn.h" #include "stun/usages/turn.h"
#include "stun/usages/ice.h" #include "stun/usages/ice.h"
#ifdef HAVE_GUPNP
#include <libgupnp-igd/gupnp-simple-igd.h>
#endif
/* XXX: starting from ICE ID-18, Ta SHOULD now be set according /* XXX: starting from ICE ID-18, Ta SHOULD now be set according
* to session bandwidth -> this is not yet implemented in NICE */ * to session bandwidth -> this is not yet implemented in NICE */
...@@ -101,6 +112,13 @@ struct _NiceAgent ...@@ -101,6 +112,13 @@ struct _NiceAgent
GStaticRecMutex mutex; /* Mutex used for thread-safe lib */ GStaticRecMutex mutex; /* Mutex used for thread-safe lib */
NiceCompatibility compatibility; /* property: Compatibility mode */ NiceCompatibility compatibility; /* property: Compatibility mode */
StunAgent stun_agent; /* STUN agent */ StunAgent stun_agent; /* STUN agent */
#ifdef HAVE_GUPNP
GUPnPSimpleIgd* upnp; /* GUPnP Single IGD agent */
gboolean upnp_enabled; /* whether UPnP discovery is enabled */
guint upnp_timeout; /* UPnP discovery timeout */
GSList *upnp_mapping; /* list of Candidates being mapped */
GSource *upnp_timer_source; /* source of upnp timeout timer */
#endif
/* XXX: add pointer to internal data struct for ABI-safe extensions */ /* XXX: add pointer to internal data struct for ABI-safe extensions */
}; };
......
...@@ -94,7 +94,11 @@ enum ...@@ -94,7 +94,11 @@ enum
PROP_PROXY_IP, PROP_PROXY_IP,
PROP_PROXY_PORT, PROP_PROXY_PORT,
PROP_PROXY_USERNAME, PROP_PROXY_USERNAME,
PROP_PROXY_PASSWORD PROP_PROXY_PASSWORD,
#ifdef HAVE_GUPNP
PROP_UPNP,
PROP_UPNP_TIMEOUT
#endif
}; };
...@@ -116,6 +120,8 @@ static gboolean priv_attach_stream_component (NiceAgent *agent, ...@@ -116,6 +120,8 @@ static gboolean priv_attach_stream_component (NiceAgent *agent,
Component *component); Component *component);
static void priv_detach_stream_component (Stream *stream, Component *component); static void priv_detach_stream_component (Stream *stream, Component *component);
static void priv_free_upnp (NiceAgent *agent);
StunUsageIceCompatibility StunUsageIceCompatibility
agent_to_ice_compatibility (NiceAgent *agent) agent_to_ice_compatibility (NiceAgent *agent)
{ {
...@@ -292,7 +298,7 @@ nice_agent_class_init (NiceAgentClass *klass) ...@@ -292,7 +298,7 @@ nice_agent_class_init (NiceAgentClass *klass)
"stun-pacing-timer", "stun-pacing-timer",
"STUN pacing timer", "STUN pacing timer",
"Timer 'Ta' (msecs) used in the IETF ICE specification for pacing candidate gathering and sending of connectivity checks", "Timer 'Ta' (msecs) used in the IETF ICE specification for pacing candidate gathering and sending of connectivity checks",
1, 0xffffffff, 1, 0xffffffff,
NICE_AGENT_TIMER_TA_DEFAULT, NICE_AGENT_TIMER_TA_DEFAULT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
...@@ -302,7 +308,7 @@ nice_agent_class_init (NiceAgentClass *klass) ...@@ -302,7 +308,7 @@ nice_agent_class_init (NiceAgentClass *klass)
"max-connectivity-checks", "max-connectivity-checks",
"Maximum number of connectivity checks", "Maximum number of connectivity checks",
"Upper limit for the total number of connectivity checks performed", "Upper limit for the total number of connectivity checks performed",
0, 0xffffffff, 0, 0xffffffff,
0, /* default set in init */ 0, /* default set in init */
G_PARAM_READWRITE)); G_PARAM_READWRITE));
...@@ -348,6 +354,27 @@ nice_agent_class_init (NiceAgentClass *klass) ...@@ -348,6 +354,27 @@ nice_agent_class_init (NiceAgentClass *klass)
NULL, NULL,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
#ifdef HAVE_GUPNP
g_object_class_install_property (gobject_class, PROP_UPNP,
g_param_spec_boolean (
"upnp",
"Use UPnP",
"Whether the agent should use UPnP to open a port in the router and "
"get the external IP",
TRUE, /* enable UPnP by default */
G_PARAM_READWRITE| G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, PROP_UPNP_TIMEOUT,
g_param_spec_uint (
"upnp-timeout",
"Timeout for UPnP discovery",
"The maximum amount of time to wait for UPnP discovery to finish before "
"signaling the candidate-gathering-done signal",
100, 60000,
2000,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
#endif
/* install signals */ /* install signals */
/** /**
...@@ -603,6 +630,16 @@ nice_agent_get_property ( ...@@ -603,6 +630,16 @@ nice_agent_get_property (
g_value_set_string (value, agent->proxy_password); g_value_set_string (value, agent->proxy_password);
break; break;
#ifdef HAVE_GUPNP
case PROP_UPNP:
g_value_set_boolean (value, agent->upnp_enabled);
break;
case PROP_UPNP_TIMEOUT:
g_value_set_uint (value, agent->upnp_timeout);
break;
#endif
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
...@@ -698,6 +735,15 @@ nice_agent_set_property ( ...@@ -698,6 +735,15 @@ nice_agent_set_property (
agent->proxy_password = g_value_dup_string (value); agent->proxy_password = g_value_dup_string (value);
break; break;
#ifdef HAVE_GUPNP
case PROP_UPNP_TIMEOUT:
agent->upnp_timeout = g_value_get_uint (value);
break;
case PROP_UPNP:
agent->upnp_enabled = g_value_get_boolean (value);
break;
#endif
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
...@@ -744,7 +790,10 @@ void agent_gathering_done (NiceAgent *agent) ...@@ -744,7 +790,10 @@ void agent_gathering_done (NiceAgent *agent)
} }
} }
agent_signal_gathering_done (agent); if (agent->discovery_timer_source == NULL &&
agent->upnp_timer_source == NULL) {
agent_signal_gathering_done (agent);
}
} }
void agent_signal_gathering_done (NiceAgent *agent) void agent_signal_gathering_done (NiceAgent *agent)
...@@ -932,7 +981,6 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent, ...@@ -932,7 +981,6 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent,
socket = nice_http_socket_new (socket, &turn->server, socket = nice_http_socket_new (socket, &turn->server,
agent->proxy_username, agent->proxy_password); agent->proxy_username, agent->proxy_password);
} else { } else {
/* TODO add HTTP support */
nice_socket_free (socket); nice_socket_free (socket);
socket = NULL; socket = NULL;
} }
...@@ -1077,6 +1125,136 @@ nice_agent_set_relay_info(NiceAgent *agent, ...@@ -1077,6 +1125,136 @@ nice_agent_set_relay_info(NiceAgent *agent,
return TRUE; return TRUE;
} }
#ifdef HAVE_GUPNP
static gboolean priv_upnp_timeout_cb (gpointer user_data)
{
NiceAgent *agent = (NiceAgent*)user_data;
GSList *i;
g_static_rec_mutex_lock (&agent->mutex);
nice_debug ("Agent %p : UPnP port mapping timed out", agent);
for (i = agent->upnp_mapping; i; i = i->next) {
NiceAddress *a = i->data;
nice_address_free (a);
}
g_slist_free (agent->upnp_mapping);
agent->upnp_mapping = NULL;
if (agent->upnp_timer_source != NULL) {
g_source_destroy (agent->upnp_timer_source);
g_source_unref (agent->upnp_timer_source);
agent->upnp_timer_source = NULL;
}
agent_gathering_done (agent);
g_static_rec_mutex_unlock (&agent->mutex);
return FALSE;
}
static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto,
gchar *external_ip, gchar *replaces_external_ip, guint external_port,
gchar *local_ip, guint local_port, gchar *description, gpointer user_data)
{
NiceAgent *agent = (NiceAgent*)user_data;
NiceAddress localaddr;
NiceAddress externaddr;
GSList *i, *j, *k;
g_static_rec_mutex_lock (&agent->mutex);
nice_debug ("Agent %p : Sucessfully mapped %s:%d to %s:%d", agent, local_ip,
local_port, external_ip, external_port);
nice_address_set_from_string (&localaddr, local_ip);
nice_address_set_port (&localaddr, local_port);
nice_address_set_from_string (&externaddr, external_ip);
nice_address_set_port (&externaddr, external_port);
for (i = agent->upnp_mapping; i; i = i->next) {
NiceAddress *addr = i->data;
if (nice_address_equal (&localaddr, addr)) {
agent->upnp_mapping = g_slist_remove (agent->upnp_mapping, addr);
nice_address_free (addr);
break;
}
}
for (i = agent->streams; i; i = i->next) {
Stream *stream = i->data;
for (j = stream->components; j; j = j->next) {
Component *component = j->data;
for (k = component->local_candidates; k; k = k->next) {
NiceCandidate *local_candidate = k->data;
if (nice_address_equal (&localaddr, &local_candidate->base_addr)) {
discovery_add_server_reflexive_candidate (
agent,
stream->id,
component->id,
&externaddr,
local_candidate->sockptr);
goto end;
}
}
}
}
end:
if (g_slist_length (agent->upnp_mapping)) {
if (agent->upnp_timer_source != NULL) {
g_source_destroy (agent->upnp_timer_source);
g_source_unref (agent->upnp_timer_source);
agent->upnp_timer_source = NULL;
}
agent_gathering_done (agent);
}
g_static_rec_mutex_unlock (&agent->mutex);
}
static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error,
gchar *proto, guint external_port, gchar *local_ip, guint local_port,
gchar *description, gpointer user_data)
{
NiceAgent *agent = (NiceAgent*)user_data;
NiceAddress localaddr;
GSList *i;
g_static_rec_mutex_lock (&agent->mutex);
nice_debug ("Agent %p : Error mapping %s:%d to %d (%d) : %s", agent, local_ip,
local_port, external_port, error->domain, error->message);
nice_address_set_from_string (&localaddr, local_ip);
nice_address_set_port (&localaddr, local_port);
for (i = agent->upnp_mapping; i; i = i->next) {
NiceAddress *addr = i->data;
if (nice_address_equal (&localaddr, addr)) {
agent->upnp_mapping = g_slist_remove (agent->upnp_mapping, addr);
nice_address_free (addr);
break;
}
}
if (g_slist_length (agent->upnp_mapping)) {
if (agent->upnp_timer_source != NULL) {
g_source_destroy (agent->upnp_timer_source);
g_source_unref (agent->upnp_timer_source);
agent->upnp_timer_source = NULL;
}
agent_gathering_done (agent);
}
g_static_rec_mutex_unlock (&agent->mutex);
}
#endif
NICEAPI_EXPORT void NICEAPI_EXPORT void
nice_agent_gather_candidates ( nice_agent_gather_candidates (
...@@ -1097,6 +1275,31 @@ nice_agent_gather_candidates ( ...@@ -1097,6 +1275,31 @@ nice_agent_gather_candidates (
nice_debug ("Agent %p : In %s mode, starting candidate gathering.", agent, nice_debug ("Agent %p : In %s mode, starting candidate gathering.", agent,
agent->full_mode ? "ICE-FULL" : "ICE-LITE"); agent->full_mode ? "ICE-FULL" : "ICE-LITE");
#ifdef HAVE_GUPNP
priv_free_upnp (agent);
if (agent->upnp_enabled) {
agent->upnp = gupnp_simple_igd_new (agent->main_context);
agent->upnp_timer_source = agent_timeout_add_with_context (agent,
agent->upnp_timeout, priv_upnp_timeout_cb, agent);
g_object_set (agent->upnp, "request-timeout", 1, NULL);
if (agent->upnp) {
g_signal_connect (agent->upnp, "mapped-external-port",
G_CALLBACK (_upnp_mapped_external_port), agent);
g_signal_connect (agent->upnp, "error-mapping-port",
G_CALLBACK (_upnp_error_mapping_port), agent);
} else {
nice_debug ("Agent %p : Error creating UPnP Simple IGD agent", agent);
}
} else {
nice_debug ("Agent %p : UPnP property Disabled", agent);
}
#else
nice_debug ("Agent %p : libnice compiled without UPnP support", agent);
#endif
/* if no local addresses added, generate them ourselves */ /* if no local addresses added, generate them ourselves */
if (agent->local_addresses == NULL) { if (agent->local_addresses == NULL) {
GList *addresses = nice_interfaces_get_local_ips (FALSE); GList *addresses = nice_interfaces_get_local_ips (FALSE);
...@@ -1120,6 +1323,11 @@ nice_agent_gather_candidates ( ...@@ -1120,6 +1323,11 @@ nice_agent_gather_candidates (
NiceAddress *addr = i->data; NiceAddress *addr = i->data;
NiceCandidate *host_candidate; NiceCandidate *host_candidate;
#ifdef HAVE_GUPNP
gchar local_ip[NICE_ADDRESS_STRING_LEN];
nice_address_to_string (addr, local_ip);
#endif
for (n = 0; n < stream->n_components; n++) { for (n = 0; n < stream->n_components; n++) {
Component *component = stream_find_component_by_id (stream, n + 1); Component *component = stream_find_component_by_id (stream, n + 1);
host_candidate = discovery_add_local_host_candidate (agent, stream->id, host_candidate = discovery_add_local_host_candidate (agent, stream->id,
...@@ -1130,11 +1338,23 @@ nice_agent_gather_candidates ( ...@@ -1130,11 +1338,23 @@ nice_agent_gather_candidates (
break; break;
} }
#ifdef HAVE_GUPNP
if (agent->upnp_enabled) {
NiceAddress *addr = nice_address_dup (&host_candidate->base_addr);
nice_debug ("Agent %p: Adding UPnP port %s:%d", agent, local_ip,
nice_address_get_port (&host_candidate->base_addr));
gupnp_simple_igd_add_port (agent->upnp, "UDP",
nice_address_get_port (&host_candidate->base_addr),
local_ip, 0, 6000, PACKAGE_STRING);
agent->upnp_mapping = g_slist_prepend (agent->upnp_mapping, addr);
}
#endif
if (agent->full_mode && if (agent->full_mode &&
agent->stun_server_ip) { agent->stun_server_ip) {
NiceAddress stun_server; NiceAddress stun_server;
if (nice_address_set_from_string (&stun_server, agent->stun_server_ip)) { if (nice_address_set_from_string (&stun_server, agent->stun_server_ip)) {
gboolean res; gboolean res;
nice_address_set_port (&stun_server, agent->stun_server_port); nice_address_set_port (&stun_server, agent->stun_server_port);
res = res =
...@@ -1191,6 +1411,31 @@ nice_agent_gather_candidates ( ...@@ -1191,6 +1411,31 @@ nice_agent_gather_candidates (
g_static_rec_mutex_unlock (&agent->mutex); g_static_rec_mutex_unlock (&agent->mutex);
} }
static void priv_free_upnp (NiceAgent *agent)
{
GSList *i;
#ifdef HAVE_GUPNP
if (agent->upnp) {
g_object_unref (agent->upnp);
agent->upnp = NULL;
}
for (i = agent->upnp_mapping; i; i = i->next) {
NiceAddress *a = i->data;
nice_address_free (a);
}
g_slist_free (agent->upnp_mapping);
agent->upnp_mapping = NULL;
if (agent->upnp_timer_source != NULL) {
g_source_destroy (agent->upnp_timer_source);
g_source_unref (agent->upnp_timer_source);
agent->upnp_timer_source = NULL;
}
#endif
}
static void priv_remove_keepalive_timer (NiceAgent *agent) static void priv_remove_keepalive_timer (NiceAgent *agent)
{ {
if (agent->keepalive_timer_source != NULL) { if (agent->keepalive_timer_source != NULL) {
...@@ -1660,6 +1905,7 @@ nice_agent_restart ( ...@@ -1660,6 +1905,7 @@ nice_agent_restart (
return res; return res;
} }
static void static void
nice_agent_dispose (GObject *object) nice_agent_dispose (GObject *object)
{ {
...@@ -1703,6 +1949,8 @@ nice_agent_dispose (GObject *object) ...@@ -1703,6 +1949,8 @@ nice_agent_dispose (GObject *object)
nice_rng_free (agent->rng); nice_rng_free (agent->rng);
agent->rng = NULL; agent->rng = NULL;
priv_free_upnp (agent);
if (G_OBJECT_CLASS (nice_agent_parent_class)->dispose) if (G_OBJECT_CLASS (nice_agent_parent_class)->dispose)
G_OBJECT_CLASS (nice_agent_parent_class)->dispose (object); G_OBJECT_CLASS (nice_agent_parent_class)->dispose (object);
......
...@@ -102,7 +102,7 @@ void discovery_free (NiceAgent *agent) ...@@ -102,7 +102,7 @@ void discovery_free (NiceAgent *agent)
/* /*
* Prunes the list of discovery processes for items related * Prunes the list of discovery processes for items related
* to stream 'stream_id'. * to stream 'stream_id'.
* *
* @return TRUE on success, FALSE on a fatal error * @return TRUE on success, FALSE on a fatal error
*/ */
...@@ -316,7 +316,7 @@ static void priv_assign_foundation (NiceAgent *agent, NiceCandidate *candidate) ...@@ -316,7 +316,7 @@ static void priv_assign_foundation (NiceAgent *agent, NiceCandidate *candidate)
} }
} }
} }
g_snprintf (candidate->foundation, NICE_CANDIDATE_MAX_FOUNDATION, "%u", agent->next_candidate_id++); g_snprintf (candidate->foundation, NICE_CANDIDATE_MAX_FOUNDATION, "%u", agent->next_candidate_id++);
} }
...@@ -436,7 +436,7 @@ NiceCandidate *discovery_add_local_host_candidate ( ...@@ -436,7 +436,7 @@ NiceCandidate *discovery_add_local_host_candidate (
if (udp_socket) if (udp_socket)
nice_socket_free (udp_socket); nice_socket_free (udp_socket);
} }
return candidate; return candidate;
} }
...@@ -446,7 +446,7 @@ NiceCandidate *discovery_add_local_host_candidate ( ...@@ -446,7 +446,7 @@ NiceCandidate *discovery_add_local_host_candidate (
* *
* @return pointer to the created candidate, or NULL on error * @return pointer to the created candidate, or NULL on error
*/ */
NiceCandidate* NiceCandidate*
discovery_add_server_reflexive_candidate ( discovery_add_server_reflexive_candidate (
NiceAgent *agent, NiceAgent *agent,
guint stream_id, guint stream_id,
......
...@@ -66,7 +66,6 @@ AC_CHECK_LIB(rt, clock_gettime, [LIBRT="-lrt"], [LIBRT=""]) ...@@ -66,7 +66,6 @@ AC_CHECK_LIB(rt, clock_gettime, [LIBRT="-lrt"], [LIBRT=""])
AC_CHECK_FUNCS([poll]) AC_CHECK_FUNCS([poll])
AC_SUBST(LIBRT) AC_SUBST(LIBRT)
PKG_CHECK_MODULES(GLIB, [dnl PKG_CHECK_MODULES(GLIB, [dnl
glib-2.0 >= 2.10 dnl glib-2.0 >= 2.10 dnl
gobject-2.0 >= 2.10 dnl gobject-2.0 >= 2.10 dnl
...@@ -102,6 +101,31 @@ AC_SUBST(gstplugindir) ...@@ -102,6 +101,31 @@ AC_SUBST(gstplugindir)
AM_CONDITIONAL(WITH_GSTREAMER, test "$with_gstreamer" = yes) AM_CONDITIONAL(WITH_GSTREAMER, test "$with_gstreamer" = yes)
AC_ARG_ENABLE([gupnp],
AC_HELP_STRING([--disable-gupnp], [Disable GUPnP IGD support]),
[case "${enableval}" in
yes) WANT_GUPNP=yes ;;
no) WANT_GUPNP=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-gupnp) ;;
esac],
WANT_GUPNP=test)
HAVE_GUPNP=no
if test "x$WANT_GUPNP" != "xno"; then
PKG_CHECK_MODULES(GUPNP, [ gupnp-igd-1.0 ],
[ HAVE_GUPNP=yes ],
[ HAVE_GUPNP=no ])
fi
if test "x$WANT_GUPNP" = "xyes" && test "x$HAVE_GUPNP" = "xno"; then
AC_ERROR([Requested GUPnP IGD, but it is not available])
fi
if test "x$HAVE_GUPNP" = "xyes"; then
AC_DEFINE(HAVE_GUPNP,,[Have the GUPnP IGD library])
fi
AC_SUBST(HAVE_GUPNP)
dnl Test coverage dnl Test coverage
AC_ARG_ENABLE([coverage], AC_ARG_ENABLE([coverage],
[AS_HELP_STRING([--enable-coverage], [AS_HELP_STRING([--enable-coverage],
......
...@@ -12,6 +12,7 @@ AM_CFLAGS = \ ...@@ -12,6 +12,7 @@ AM_CFLAGS = \
-DG_LOG_DOMAIN=\"libnice-socket\" \ -DG_LOG_DOMAIN=\"libnice-socket\" \
$(ERROR_CFLAGS) \ $(ERROR_CFLAGS) \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(GUPNP_CFLAGS) \
-I $(top_srcdir)/random \ -I $(top_srcdir)/random \
-I $(top_srcdir)/agent \ -I $(top_srcdir)/agent \
-I $(top_srcdir)/ -I $(top_srcdir)/
......
...@@ -11,13 +11,14 @@ include $(top_srcdir)/common.mk ...@@ -11,13 +11,14 @@ include $(top_srcdir)/common.mk
AM_CFLAGS = \ AM_CFLAGS = \
$(ERROR_CFLAGS) \ $(ERROR_CFLAGS) \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
$(GUPNP_CFLAGS) \
-I $(top_srcdir) \ -I $(top_srcdir) \
-I $(top_srcdir)/agent \ -I $(top_srcdir)/agent \
-I $(top_srcdir)/random \ -I $(top_srcdir)/random \
-I $(top_srcdir)/socket \ -I $(top_srcdir)/socket \
-I $(top_srcdir)/stun -I $(top_srcdir)/stun
COMMON_LDADD = $(top_builddir)/agent/libagent.la $(top_builddir)/socket/libsocket.la $(GLIB_LIBS) COMMON_LDADD = $(top_builddir)/agent/libagent.la $(top_builddir)/socket/libsocket.la $(GLIB_LIBS) $(GUPNP_LIBS)
check_PROGRAMS = \ check_PROGRAMS = \
test-bsd \ test-bsd \
......
...@@ -214,6 +214,8 @@ int main (void) ...@@ -214,6 +214,8 @@ int main (void)
g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
g_object_set (G_OBJECT (lagent), "upnp", FALSE, NULL);
g_object_set (G_OBJECT (ragent), "upnp", FALSE, NULL);
/* step: add a timer to catch state changes triggered by signals */ /* step: add a timer to catch state changes triggered by signals */
timer_id = g_timeout_add (30000, timer_cb, NULL); timer_id = g_timeout_add (30000, timer_cb, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment