diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2008-04-22 16:14:00 +0000 |
---|---|---|
committer | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2008-04-22 16:14:00 +0000 |
commit | 93ac1313641efe0ae41ebc3544e7230e54477289 (patch) | |
tree | bb9cacf031d73b78457c7fd5f0085bbed4741f05 | |
parent | 8d3f8b25fba619794e8ffe6908227499fd28bb94 (diff) | |
download | libnice-93ac1313641efe0ae41ebc3544e7230e54477289.tar.gz |
Adding compatibility mode and improvements on the main loop integration.
darcs-hash:20080422161414-4f0f6-388208b2ac7bb2a7ab06e48151e2152fc0621331.gz
-rw-r--r-- | agent/agent-priv.h | 4 | ||||
-rw-r--r-- | agent/agent.c | 192 | ||||
-rw-r--r-- | agent/agent.h | 14 | ||||
-rw-r--r-- | agent/candidate.c | 15 | ||||
-rw-r--r-- | agent/candidate.h | 3 | ||||
-rw-r--r-- | agent/component.h | 1 | ||||
-rw-r--r-- | agent/conncheck.c | 26 | ||||
-rw-r--r-- | agent/discovery.c | 6 | ||||
-rw-r--r-- | nice/libnice.sym | 2 |
9 files changed, 169 insertions, 94 deletions
diff --git a/agent/agent-priv.h b/agent/agent-priv.h index 32b7198..e766cf9 100644 --- a/agent/agent-priv.h +++ b/agent/agent-priv.h @@ -80,10 +80,7 @@ struct _NiceAgent GSList *local_addresses; /**< list of NiceAddresses for local interfaces */ GSList *streams; /**< list of Stream objects */ - gboolean main_context_set; /**< is the main context set */ GMainContext *main_context; /**< main context pointer */ - NiceAgentRecvFunc read_func; /**< callback for media deliver */ - gpointer read_func_data; /**< media delivery callback context */ guint next_candidate_id; /**< id of next created candidate */ guint next_stream_id; /**< id of next created candidate */ NiceRNG *rng; /**< random number generator */ @@ -95,6 +92,7 @@ struct _NiceAgent guint64 tie_breaker; /**< tie breaker (ICE sect 5.2 "Determining Role" ID-19) */ GMutex * mutex; /* Mutex used for thread-safe lib */ + NiceCompatibility compatibility; /* property: Compatibility mode */ /* XXX: add pointer to internal data struct for ABI-safe extensions */ }; diff --git a/agent/agent.c b/agent/agent.c index 4e632ff..325c86f 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -74,7 +74,8 @@ G_DEFINE_TYPE (NiceAgent, nice_agent, G_TYPE_OBJECT); enum { PROP_SOCKET_FACTORY = 1, - PROP_STUN_SERVER, + PROP_COMPATIBILITY, + PROP_STUN_SERVER, PROP_STUN_SERVER_PORT, PROP_TURN_SERVER, PROP_TURN_SERVER_PORT, @@ -99,8 +100,13 @@ enum static guint signals[N_SIGNALS]; -static gboolean priv_attach_new_stream (NiceAgent *agent, Stream *stream); -static void priv_deattach_stream (Stream *stream); +static gboolean priv_attach_stream_component (NiceAgent *agent, + Stream *stream, + Component *component, + GMainContext *ctx, + NiceAgentRecvFunc func, + gpointer data ); +static void priv_dettach_stream_component (Stream *stream, Component *component); Stream *agent_find_stream (NiceAgent *agent, guint stream_id) { @@ -179,6 +185,15 @@ nice_agent_class_init (NiceAgentClass *klass) "The socket factory used to create new UDP sockets", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, PROP_COMPATIBILITY, + g_param_spec_uint ( + "compatibility", + "ICE specification compatibility", + "The compatibility mode for the agent", + NICE_COMPATIBILITY_ID19, NICE_COMPATIBILITY_MSN, + NICE_COMPATIBILITY_ID19, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, PROP_STUN_SERVER, g_param_spec_string ( "stun-server", @@ -366,6 +381,7 @@ nice_agent_init (NiceAgent *agent) agent->discovery_timer_id = 0; agent->conncheck_timer_id = 0; agent->keepalive_timer_id = 0; + agent->compatibility = NICE_COMPATIBILITY_ID19; agent->rng = nice_rng_new (); priv_generate_tie_breaker (agent); @@ -382,11 +398,17 @@ nice_agent_init (NiceAgent *agent) * Returns: the new agent **/ NICEAPI_EXPORT NiceAgent * -nice_agent_new (NiceUDPSocketFactory *factory) +nice_agent_new (NiceUDPSocketFactory *factory, + GMainContext *ctx, NiceCompatibility compat) { - return g_object_new (NICE_TYPE_AGENT, + NiceAgent *agent = g_object_new (NICE_TYPE_AGENT, "socket-factory", factory, + "compatibility", compat, NULL); + + agent->main_context = ctx; + + return agent; } @@ -407,6 +429,10 @@ nice_agent_get_property ( g_value_set_pointer (value, agent->socket_factory); break; + case PROP_COMPATIBILITY: + g_value_set_uint (value, agent->compatibility); + break; + case PROP_STUN_SERVER: g_value_set_string (value, agent->stun_server_ip); break; @@ -465,6 +491,10 @@ nice_agent_set_property ( agent->socket_factory = g_value_get_pointer (value); break; + case PROP_COMPATIBILITY: + agent->compatibility = g_value_get_uint (value); + break; + case PROP_STUN_SERVER: agent->stun_server_ip = g_value_dup_string (value); break; @@ -690,11 +720,6 @@ nice_agent_add_stream ( } - /* step: attach the newly created sockets to the mainloop - * context */ - if (agent->main_context_set && stream->id > 0) - priv_attach_new_stream (agent, stream); - /* note: no async discoveries pending, signal that we are ready */ if (agent->discovery_unsched_items == 0) agent_signal_gathering_done (agent); @@ -728,6 +753,7 @@ nice_agent_remove_stream ( /* note that streams/candidates can be in use by other threads */ Stream *stream; + GSList *i; g_mutex_lock (agent->mutex); stream = agent_find_stream (agent, stream_id); @@ -742,7 +768,10 @@ nice_agent_remove_stream ( discovery_prune_stream (agent, stream_id); /* remove the stream itself */ - priv_deattach_stream (stream); + for (i = stream->components; i; i = i->next) { + priv_dettach_stream_component (stream, (Component *) i->data); + } + agent->streams = g_slist_remove (agent->streams, stream); stream_free (stream); @@ -943,9 +972,11 @@ nice_agent_get_local_credentials ( guint stream_id, const gchar **ufrag, const gchar **pwd) { - Stream *stream = agent_find_stream (agent, stream_id); + Stream *stream; g_mutex_lock (agent->mutex); + + stream = agent_find_stream (agent, stream_id); if (stream == NULL) { g_mutex_unlock (agent->mutex); return FALSE; @@ -990,6 +1021,10 @@ nice_agent_add_remote_candidate ( const gchar *password) { + /* XXX: to be deprecated */ + + g_mutex_lock (agent->mutex); + /* XXX: should we allow use of this method without an * initial call to nice_agent_set_remote_candidates() * with an empty set? */ @@ -1037,8 +1072,11 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo const GSList *i; int added = 0; - /* XXX: clean up existing remote candidates, and abort any - * connectivity checks using these candidates */ + + if (agent->discovery_unsched_items > 0) + return -1; + + g_mutex_lock (agent->mutex); for (i = candidates; i && added >= 0; i = i->next) { NiceCandidateDesc *d = (NiceCandidateDesc*) i->data; @@ -1589,6 +1627,8 @@ struct _IOCtx Stream *stream; Component *component; NiceUDPSocket *socket; + NiceAgentRecvFunc recv_func; + gpointer recv_data; }; @@ -1597,7 +1637,9 @@ io_ctx_new ( NiceAgent *agent, Stream *stream, Component *component, - NiceUDPSocket *socket) + NiceUDPSocket *socket, + NiceAgentRecvFunc func, + gpointer data) { IOCtx *ctx; @@ -1607,6 +1649,8 @@ io_ctx_new ( ctx->stream = stream; ctx->component = component; ctx->socket = socket; + ctx->recv_func = func; + ctx->recv_data = data; } return ctx; } @@ -1643,8 +1687,8 @@ nice_agent_g_source_cb ( MAX_STUN_DATAGRAM_PAYLOAD, buf); if (len > 0) - agent->read_func (agent, stream->id, component->id, - len, buf, agent->read_func_data); + ctx->recv_func (agent, stream->id, component->id, + len, buf, ctx->recv_data); g_mutex_unlock (agent->mutex); return TRUE; @@ -1654,38 +1698,38 @@ nice_agent_g_source_cb ( * Attaches socket handles of 'stream' to the main eventloop * context. * - * @pre agent->main_context_set == TRUE */ -static gboolean priv_attach_new_stream (NiceAgent *agent, Stream *stream) +static gboolean priv_attach_stream_component (NiceAgent *agent, + Stream *stream, + Component *component, + GMainContext *context, + NiceAgentRecvFunc func, + gpointer data) { - GSList *i, *j; + GSList *i; - for (i = stream->components; i; i = i->next) { - Component *component = i->data; - - for (j = component->sockets; j; j = j->next) { - NiceUDPSocket *udp_socket = j->data; - GIOChannel *io; - GSource *source; - IOCtx *ctx; - GSList *modified_list; - - io = g_io_channel_unix_new (udp_socket->fileno); - /* note: without G_IO_ERR the glib mainloop goes into - * busyloop if errors are encountered */ - source = g_io_create_watch (io, G_IO_IN | G_IO_ERR); - ctx = io_ctx_new (agent, stream, component, udp_socket); - g_source_set_callback (source, (GSourceFunc) nice_agent_g_source_cb, - ctx, (GDestroyNotify) io_ctx_free); - g_debug ("Attach source %p (stream %u).", source, stream->id); - g_source_attach (source, NULL); - modified_list = g_slist_append (component->gsources, source); - if (!modified_list) { - g_source_destroy (source); - return FALSE; - } - component->gsources = modified_list; + for (i = component->sockets; i; i = i->next) { + NiceUDPSocket *udp_socket = i->data; + GIOChannel *io; + GSource *source; + IOCtx *ctx; + GSList *modified_list; + + io = g_io_channel_unix_new (udp_socket->fileno); + /* note: without G_IO_ERR the glib mainloop goes into + * busyloop if errors are encountered */ + source = g_io_create_watch (io, G_IO_IN | G_IO_ERR); + ctx = io_ctx_new (agent, stream, component, udp_socket, func, data); + g_source_set_callback (source, (GSourceFunc) nice_agent_g_source_cb, + ctx, (GDestroyNotify) io_ctx_free); + g_debug ("Attach source %p (stream %u).", source, stream->id); + g_source_attach (source, context); + modified_list = g_slist_append (component->gsources, source); + if (!modified_list) { + g_source_destroy (source); + return FALSE; } + component->gsources = modified_list; } return TRUE; @@ -1695,59 +1739,51 @@ static gboolean priv_attach_new_stream (NiceAgent *agent, Stream *stream) * Detaches socket handles of 'stream' from the main eventloop * context. * - * @pre agent->main_context_set == TRUE */ -static void priv_deattach_stream (Stream *stream) +static void priv_dettach_stream_component (Stream *stream, Component *component) { - GSList *i, *j; - - for (i = stream->components; i; i = i->next) { - Component *component = i->data; - - for (j = component->gsources; j; j = j->next) { - GSource *source = j->data; - g_debug ("Detach source %p (stream %u).", source, stream->id); - g_source_destroy (source); - } + GSList *i; - g_slist_free (component->gsources), - component->gsources = NULL; + for (i = component->gsources; i; i = i->next) { + GSource *source = i->data; + g_debug ("Detach source %p (stream %u).", source, stream->id); + g_source_destroy (source); } + + g_slist_free (component->gsources); + component->gsources = NULL; } NICEAPI_EXPORT gboolean -nice_agent_main_context_attach ( +nice_agent_attach_recv ( NiceAgent *agent, + guint stream_id, + guint component_id, GMainContext *ctx, NiceAgentRecvFunc func, gpointer data) { - GSList *i; + Component *component = NULL; + Stream *stream = NULL; + gboolean res = TRUE; g_mutex_lock (agent->mutex); - if (agent->main_context_set) { - g_mutex_unlock (agent->mutex); - return FALSE; - } /* attach candidates */ - for (i = agent->streams; i; i = i->next) { - Stream *stream = i->data; - gboolean res = priv_attach_new_stream (agent, stream); - if (!res) { - g_mutex_unlock (agent->mutex); - return FALSE; - } + /* step: check that params specify an existing pair */ + if (!agent_find_component (agent, stream_id, component_id, + &stream, &component) || component == NULL) { + g_mutex_unlock (agent->mutex); + return FALSE; } - - agent->main_context = ctx; - agent->main_context_set = TRUE; - agent->read_func = func; - agent->read_func_data = data; + + priv_dettach_stream_component (stream, component); + if (func != NULL) + res = priv_attach_stream_component (agent, stream, component, ctx, func, data); g_mutex_unlock (agent->mutex); - return TRUE; + return res; } /** diff --git a/agent/agent.h b/agent/agent.h index 961cd96..72a14b1 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -96,6 +96,13 @@ typedef enum NICE_COMPONENT_TYPE_RTCP = 2 } NiceComponentType; +typedef enum +{ + NICE_COMPATIBILITY_ID19 = 1, + NICE_COMPATIBILITY_GOOGLE = 2, + NICE_COMPATIBILITY_MSN = 3 +} NiceCompatibility; + typedef struct _NiceCandidateDesc NiceCandidateDesc; struct _NiceCandidateDesc { @@ -125,7 +132,8 @@ struct _NiceAgentClass GType nice_agent_get_type (void); NiceAgent * -nice_agent_new (NiceUDPSocketFactory *factory); +nice_agent_new (NiceUDPSocketFactory *factory, + GMainContext *ctx, NiceCompatibility compat); gboolean nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr); @@ -218,8 +226,10 @@ nice_agent_restart ( NiceAgent *agent); gboolean -nice_agent_main_context_attach ( +nice_agent_attach_recv ( NiceAgent *agent, + guint stream_id, + guint component_id, GMainContext *ctx, NiceAgentRecvFunc func, gpointer data); diff --git a/agent/candidate.c b/agent/candidate.c index b0d3025..4e180c8 100644 --- a/agent/candidate.c +++ b/agent/candidate.c @@ -94,6 +94,21 @@ nice_candidate_jingle_priority (NiceCandidate *candidate) return 0; } +NICEAPI_EXPORT gfloat +nice_candidate_msn_priority (NiceCandidate *candidate) +{ + switch (candidate->type) + { + case NICE_CANDIDATE_TYPE_HOST: return 0.830; + case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: return 0.550; + case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: return 0.550; + case NICE_CANDIDATE_TYPE_RELAYED: return 0.450; + } + + /* appease GCC */ + return 0; +} + /** * ICE 4.1.2.1. "Recommended Formula" (ID-19): diff --git a/agent/candidate.h b/agent/candidate.h index 2f1de45..4c89851 100644 --- a/agent/candidate.h +++ b/agent/candidate.h @@ -91,6 +91,9 @@ nice_candidate_free (NiceCandidate *candidate); gfloat nice_candidate_jingle_priority (NiceCandidate *candidate); +gfloat +nice_candidate_msn_priority (NiceCandidate *candidate); + guint32 nice_candidate_ice_priority_full (guint type_pref, guint local_pref, guint component_id); diff --git a/agent/component.h b/agent/component.h index fd42810..4b7bf85 100644 --- a/agent/component.h +++ b/agent/component.h @@ -46,6 +46,7 @@ G_BEGIN_DECLS + /* (ICE ยง4.1.1.1, ID-19) ""For RTP-based media streams, the RTP itself has a component * ID of 1, and RTCP a component ID of 2. If an agent is using RTCP it MUST * obtain a candidate for it. If an agent is using both RTP and RTCP, it diff --git a/agent/conncheck.c b/agent/conncheck.c index e53742b..fe64a95 100644 --- a/agent/conncheck.c +++ b/agent/conncheck.c @@ -481,14 +481,20 @@ gboolean conn_check_schedule_next (NiceAgent *agent) res = priv_conn_check_tick_unlocked ((gpointer) agent); /* step: schedule timer if not running yet */ - if (res && agent->conncheck_timer_id == 0) - agent->conncheck_timer_id = - g_timeout_add (agent->timer_ta, priv_conn_check_tick, agent); + if (res && agent->conncheck_timer_id == 0) { + GSource *source = g_timeout_source_new (agent->timer_ta); + g_source_set_callback (source, priv_conn_check_tick, agent, NULL); + agent->conncheck_timer_id = g_source_attach (source, agent->main_context); + g_source_unref (source); + } /* step: also start the keepalive timer */ - if (agent->keepalive_timer_id == 0) - agent->keepalive_timer_id = - g_timeout_add (NICE_AGENT_TIMER_TR_DEFAULT, priv_conn_keepalive_tick, agent); + if (agent->keepalive_timer_id == 0) { + GSource *source = g_timeout_source_new (NICE_AGENT_TIMER_TR_DEFAULT); + g_source_set_callback (source, priv_conn_keepalive_tick, agent, NULL); + agent->keepalive_timer_id = g_source_attach (source, agent->main_context); + g_source_unref (source); + } } @@ -950,13 +956,17 @@ static gboolean priv_create_check_username (NiceAgent *agent, CandidateCheckPair if (pair && pair->remote && pair->remote->username && pair->local && pair->local->username) { - g_snprintf (dest, dest_len, "%s:%s", pair->remote->username, pair->local->username); + g_snprintf (dest, dest_len, "%s%s%s", pair->remote->username, + agent->compatibility == NICE_COMPATIBILITY_ID19 ? ":" : "", + pair->local->username); return TRUE; } stream = agent_find_stream (agent, pair->stream_id); if (stream) { - g_snprintf (dest, dest_len, "%s:%s", stream->remote_ufrag, stream->local_ufrag); + g_snprintf (dest, dest_len, "%s%s%s", stream->remote_ufrag, + agent->compatibility == NICE_COMPATIBILITY_ID19 ? ":" : "", + stream->local_ufrag); return TRUE; } diff --git a/agent/discovery.c b/agent/discovery.c index 14d0d9c..17d86b3 100644 --- a/agent/discovery.c +++ b/agent/discovery.c @@ -597,8 +597,10 @@ void discovery_schedule (NiceAgent *agent) /* step: run first iteration immediately */ gboolean res = priv_discovery_tick_unlocked (agent); if (res == TRUE) { - agent->discovery_timer_id = - g_timeout_add (agent->timer_ta, priv_discovery_tick, agent); + GSource *source = g_timeout_source_new (agent->timer_ta); + g_source_set_callback (source, priv_discovery_tick, agent, NULL); + agent->discovery_timer_id = g_source_attach (source, agent->main_context); + g_source_unref (source); } } } diff --git a/nice/libnice.sym b/nice/libnice.sym index aa3ac1d..1c201de 100644 --- a/nice/libnice.sym +++ b/nice/libnice.sym @@ -14,11 +14,11 @@ nice_address_to_string nice_agent_add_local_address nice_agent_add_remote_candidate nice_agent_add_stream +nice_agent_attach_recv nice_agent_get_local_candidates nice_agent_get_local_credentials nice_agent_get_remote_candidates nice_agent_get_type -nice_agent_main_context_attach nice_agent_new nice_agent_poll_read nice_agent_recv |