diff options
-rw-r--r-- | agent/address.h | 170 | ||||
-rw-r--r-- | agent/agent.c | 72 | ||||
-rw-r--r-- | agent/agent.h | 112 | ||||
-rw-r--r-- | agent/candidate.h | 10 | ||||
-rw-r--r-- | agent/debug.h | 13 | ||||
-rw-r--r-- | docs/reference/libnice/Makefile.am | 2 | ||||
-rw-r--r-- | docs/reference/libnice/libnice-sections.txt | 52 |
7 files changed, 395 insertions, 36 deletions
diff --git a/agent/address.h b/agent/address.h index b5d4436..89c5740 100644 --- a/agent/address.h +++ b/agent/address.h @@ -38,6 +38,16 @@ #ifndef _ADDRESS_H #define _ADDRESS_H +/** + * SECTION:address + * @short_description: IP address convenience library + * @stability: Stable + * + * The #NiceAddress structure will allow you to easily set/get and modify an IPv4 + * or IPv6 address in order to communicate with the #NiceAgent. + */ + + #include <glib.h> #ifdef G_OS_WIN32 @@ -52,11 +62,15 @@ G_BEGIN_DECLS -#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN - -typedef struct _NiceAddress NiceAddress; -/* note: clients need to know the storage size, so needs to be public */ +/** + * NiceAddress: + * @addr: Generic sockaddr address + * @ip4: IPv4 sockaddr address + * @ip6: IPv6 sockaddr address + * + * The #NiceAddress structure that represents an IPv4 or IPv6 address. + */ struct _NiceAddress { union @@ -68,45 +82,193 @@ struct _NiceAddress }; +/** + * NICE_ADDRESS_STRING_LEN: + * + * The maximum string length representation of an address. + * When using nice_address_to_string() make sure the string has a size of + * at least %NICE_ADDRESS_STRING_LEN + */ +#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN + +typedef struct _NiceAddress NiceAddress; + + +/** + * nice_address_init: + * @addr: The #NiceAddress to init + * + * Initialize a #NiceAddress into an undefined address + */ +void +nice_address_init (NiceAddress *addr); + +/** + * nice_address_new: + * + * Create a new #NiceAddress with undefined address + * You must free it with nice_address_free() + * + * Returns: The new #NiceAddress + */ NiceAddress * nice_address_new (void); +/** + * nice_address_free: + * @addr: The #NiceAddress to free + * + * Frees a #NiceAddress created with nice_address_new() or nice_address_dup() + */ void nice_address_free (NiceAddress *addr); +/** + * nice_address_dup: + * @addr: The #NiceAddress to dup + * + * Creates a new #NiceAddress with the same address as @addr + * + * Returns: The new #NiceAddress + */ NiceAddress * nice_address_dup (const NiceAddress *addr); + +/** + * nice_address_set_ipv4: + * @addr: The #NiceAddress to modify + * @addr_ipv4: The IPv4 address + * + * Set @addr to an IPv4 address using the data from @addr_ipv4 + * + <note> + <para> + This function will reset the port to 0, so make sure you call it before + nice_address_set_port() + </para> + </note> + */ void nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4); + +/** + * nice_address_set_ipv6: + * @addr: The #NiceAddress to modify + * @addr_ipv6: The IPv6 address + * + * Set @addr to an IPv6 address using the data from @addr_ipv6 + * + <note> + <para> + This function will reset the port to 0, so make sure you call it before + nice_address_set_port() + </para> + </note> + */ void nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6); + +/** + * nice_address_set_port: + * @addr: The #NiceAddress to modify + * @port: The port to set + * + * Set the port of @addr to @port + */ void nice_address_set_port (NiceAddress *addr, guint port); +/** + * nice_address_get_port: + * @addr: The #NiceAddress to query + * + * Retreive the port of @addr + * + * Returns: The port of @addr + */ guint nice_address_get_port (const NiceAddress *addr); +/** + * nice_address_set_from_string: + * @addr: The #NiceAddress to modify + * @str: The string to set + * + * Sets an IPv4 or IPv6 address from the string @str + * + * Returns: %TRUE if success, %FALSE on error + */ gboolean nice_address_set_from_string (NiceAddress *addr, const gchar *str); +/** + * nice_address_set_from_sockaddr: + * @addr: The #NiceAddress to modify + * @sin: The sockaddr to set + * + * Sets an IPv4 or IPv6 address from the sockaddr structure @sin + * + */ void nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin); + +/** + * nice_address_copy_to_sockaddr: + * @addr: The #NiceAddress to query + * @sin: The sockaddr to fill + * + * Fills the sockaddr structure @sin with the address contained in @addr + * + */ void nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *sin); +/** + * nice_address_equal: + * @a: First #NiceAddress to compare + * @b: Second #NiceAddress to compare + * + * Compares two #NiceAddress structures to see if they contain the same address + * + * Returns: %TRUE if @a and @b are the same address, %FALSE if they are different + */ gboolean nice_address_equal (const NiceAddress *a, const NiceAddress *b); +/** + * nice_address_to_string: + * @addr: The #NiceAddress to query + * @dst: The string to fill + * + * Transforms the address @addr into a human readable string + * + */ void nice_address_to_string (const NiceAddress *addr, gchar *dst); +/** + * nice_address_is_private: + * @addr: The #NiceAddress to query + * + * Verifies if the address in @addr is a private address or not + * + * Returns: %TRUE if @addr is a private address, %FALSE otherwise + */ gboolean nice_address_is_private (const NiceAddress *addr); +/** + * nice_address_is_valid: + * @addr: The #NiceAddress to query + * + * Validate whether the #NiceAddress @addr is a valid IPv4 or IPv6 address + * + * Returns: %TRUE if @addr is valid, %FALSE otherwise + */ G_GNUC_WARN_UNUSED_RESULT gboolean nice_address_is_valid (const NiceAddress *addr); diff --git a/agent/agent.c b/agent/agent.c index 6aeadd5..1769799 100644 --- a/agent/agent.c +++ b/agent/agent.c @@ -193,7 +193,12 @@ nice_agent_class_init (NiceAgentClass *klass) gobject_class->dispose = nice_agent_dispose; /* install properties */ - + /** + * NiceAgent:main-context: + * + * A GLib main context is needed for all timeouts used by libnice. + * This is a property being set by the nice_agent_new() call. + */ g_object_class_install_property (gobject_class, PROP_MAIN_CONTEXT, g_param_spec_pointer ( "main-context", @@ -201,6 +206,13 @@ nice_agent_class_init (NiceAgentClass *klass) "The GMainContext to use for timeouts", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NiceAgent:compatibility: + * + * The Nice agent can work in various compatibility modes depending on + * what the application/peer needs. + * <para> See also: #NiceCompatibility</para> + */ g_object_class_install_property (gobject_class, PROP_COMPATIBILITY, g_param_spec_uint ( "compatibility", @@ -264,7 +276,14 @@ nice_agent_class_init (NiceAgentClass *klass) /* install signals */ - /* signature: void cb(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer self) */ + /** + * NiceAgent::component-state-changed + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @state: The #NiceComponentState of the component + * + * This signal is fired whenever a component's state changes + */ signals[SIGNAL_COMPONENT_STATE_CHANGED] = g_signal_new ( "component-state-changed", @@ -279,7 +298,13 @@ nice_agent_class_init (NiceAgentClass *klass) G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); - /* signature: void cb(NiceAgent *agent, gpointer self) */ + /** + * NiceAgent::candidate-gathering-done: + * @stream_id: The ID of the stream + * + * This signal is fired whenever a stream has finished gathering its + * candidates after a call to nice_agent_gather_candidates() + */ signals[SIGNAL_CANDIDATE_GATHERING_DONE] = g_signal_new ( "candidate-gathering-done", @@ -293,8 +318,16 @@ nice_agent_class_init (NiceAgentClass *klass) 1, G_TYPE_UINT, G_TYPE_INVALID); - /* signature: void cb(NiceAgent *agent, guint stream_id, guint component_id, - gchar *lfoundation, gchar* rfoundation, gpointer self) */ + /** + * NiceAgent::new-selected-pair + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @lfoundation: The local foundation of the selected candidate pair + * @rfoundation: The remote foundation of the selected candidate pair + * + * This signal is fired once a candidate pair is selected for data transfer for + * a stream's component + */ signals[SIGNAL_NEW_SELECTED_PAIR] = g_signal_new ( "new-selected-pair", @@ -309,7 +342,15 @@ nice_agent_class_init (NiceAgentClass *klass) G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - /* signature: void cb(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation) */ + /** + * NiceAgent::new-candidate + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @foundation: The foundation of the new candidate + * + * This signal is fired when the agent discovers a new candidate + * <para> See also: #NiceAgent::candidates-gathering-done </para> + */ signals[SIGNAL_NEW_CANDIDATE] = g_signal_new ( "new-candidate", @@ -324,7 +365,16 @@ nice_agent_class_init (NiceAgentClass *klass) G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); - /* signature: void cb(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation) */ + /** + * NiceAgent::new-remote-candidate + * @stream_id: The ID of the stream + * @component_id: The ID of the component + * @foundation: The foundation of the new candidate + * + * This signal is fired when the agent discovers a new remote candidate. + * This can happen with peer reflexive candidates. + * <para> See also: #NiceAgent::candidates-gathering-done </para> + */ signals[SIGNAL_NEW_REMOTE_CANDIDATE] = g_signal_new ( "new-remote-candidate", @@ -339,7 +389,13 @@ nice_agent_class_init (NiceAgentClass *klass) G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); - /* signature: void cb(NiceAgent *agent, guint stream_id, gpointer self) */ + /** + * NiceAgent::initial-binding-request-received + * @stream_id: The ID of the stream + * + * This signal is fired when we received our first binding request from + * the peer. + */ signals[SIGNAL_INITIAL_BINDING_REQUEST_RECEIVED] = g_signal_new ( "initial-binding-request-received", diff --git a/agent/agent.h b/agent/agent.h index e3baab6..e64b3c3 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -39,20 +39,84 @@ #ifndef _AGENT_H #define _AGENT_H +/** + * SECTION:agent + * @short_description: ICE agent API implementation + * @see_also: #NiceCandidate + * @see_also: #NiceAddress + * @include: agent.h + * @stability: Stable + * + * The #NiceAgent is your main object when using libnice. + * It is the agent that will take care of everything relating to ICE. + * It will take care of discovering your local candidates and do + * connectivity checks to create a stream of data between you and your peer. + * + <example> + <title>Simple example on how to use libnice</title> + <programlisting> + NiceAddress base_addr; + guint stream_id; + gchar buffer[] = "hello world!"; + GSList *lcands = NULL; + + // Create a nice agent + NiceAgent *agent = nice_agent_new (NULL, NICE_COMPATIBILITY_DRAFT19); + + // Specify which local interface to use + nice_address_set_from_string (&base_addr, "127.0.0.1"); + nice_agent_add_local_address (agent, &base_addr); + + // Connect the signals + g_signal_connect (G_OBJECT (agent), "candidate-gathering-done", + G_CALLBACK (cb_candidate_gathering_done), NULL); + g_signal_connect (G_OBJECT (lagent), "component-state-changed", + G_CALLBACK (cb_component_state_changed), NULL); + g_signal_connect (G_OBJECT (lagent), "new-selected-pair", + G_CALLBACK (cb_new_selected_pair), NULL); + + // Create a new stream with one component and start gathering candidates + stream_id = nice_agent_add_stream (agent, 1); + nice_agent_gather_candidates (agent, stream_id); + + // Attach to the component to receive the data + nice_agent_attach_recv (agent, stream_id, 1, NULL, + cb_nice_recv, NULL); + + // ... Wait until the signal candidate-gathering-done is fired ... + lcands = nice_agent_get_local_candidates(agent, stream_id, 1); + + // ... Send local candidates to the peer and set the peer's remote candidates + nice_agent_set_remote_candidates (agent, stream_id, 1, rcands); + + // ... Wait until the signal new-selected-pair is fired ... + // Send our message! + nice_agent_send (lagent, ls_id, 1, sizeof(buffer), buffer); + + // Anything received will be received through the cb_nice_recv callback + + // Destroy the object + g_object_unref(agent); + + </programlisting> + </example> + */ + + #include <glib-object.h> +/** + * NiceAgent: + * + * The #NiceAgent is the main GObject of the libnice library and represents + * the ICE agent. + */ typedef struct _NiceAgent NiceAgent; #include "address.h" #include "candidate.h" #include "debug.h" -/** - * SECTION:agent - * @short_description: ICE agent API implementation - * - * - */ G_BEGIN_DECLS @@ -78,7 +142,6 @@ G_BEGIN_DECLS (G_TYPE_INSTANCE_GET_CLASS ((obj), \ NICE_TYPE_AGENT, NiceAgentClass)) - typedef struct _NiceAgentClass NiceAgentClass; struct _NiceAgentClass @@ -109,6 +172,7 @@ GType nice_agent_get_type (void); * is now final * @NICE_COMPONENT_STATE_FAILED: Connectivity checks have been completed, * but connectivity was not established + * @NICE_COMPONENT_STATE_LAST: Dummy state * * An enum representing the state of a component. * See #NiceAgent::component-state-changed @@ -151,6 +215,7 @@ typedef enum * @NICE_COMPATIBILITY_DRAFT19: Use compatibility for ICE Draft 19 specs * @NICE_COMPATIBILITY_GOOGLE: Use compatibility for Google Talk specs * @NICE_COMPATIBILITY_MSN: Use compatibility for MSN Messenger specs + * @NICE_COMPATIBILITY_LAST: Dummy last compatibility mode * * An enum to specify which compatible specifications the #NiceAgent should use. * Use with nice_agent_new() @@ -187,8 +252,9 @@ typedef void (*NiceAgentRecvFunc) ( * @compat: The compatibility mode of the agent * * Create a new #NiceAgent. + * The returned object must be freed with g_object_unref() * - * Returns: the new agent GObject + * Returns: The new agent GObject */ NiceAgent * nice_agent_new (GMainContext *ctx, NiceCompatibility compat); @@ -344,7 +410,8 @@ nice_agent_get_local_credentials ( * <note> <para> - NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit for remote candidates + NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit + for remote candidates </para> </note> * @@ -372,11 +439,13 @@ nice_agent_add_remote_candidate ( * <note> <para> - NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit for remote candidates + NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit + for remote candidates </para> </note> * - * Returns: The number of candidates added, negative on fatal (memory allocs) errors + * Returns: The number of candidates added, + * negative on fatal (memory allocs) errors **/ int nice_agent_set_remote_candidates ( @@ -419,7 +488,8 @@ nice_agent_send ( * @stream_id: The ID of the stream * @component_id: The ID of the component * - * Retreive from the agent the list of all local candidates for a stream's component + * Retreive from the agent the list of all local candidates + * for a stream's component * <note> <para> @@ -450,12 +520,13 @@ nice_agent_get_local_candidates ( * <note> <para> - The caller owns the returned GSList but not the candidates contained within it. + The caller owns the returned GSList but not the candidates + contained within it. </para> <para> The list of remote candidates can change during processing. - The client should register for the #NiceAgent::new-remote-candidate signal to - get notification of new remote candidates. + The client should register for the #NiceAgent::new-remote-candidate signal + to get notified of new remote candidates. </para> </note> * @@ -490,11 +561,12 @@ nice_agent_restart ( * @stream_id: The ID of stream * @component_id: The ID of the component * @ctx: The Glib Mainloop Context to use for listening on the component - * @func: The callback function to be called when data is received on the component + * @func: The callback function to be called when data is received on + * the stream's component * @data: user data associated with the callback * - * Attaches the stream's component's sockets to the Glib Mainloop Context in order - * to be notified whenever data becomes available for a component. + * Attaches the stream's component's sockets to the Glib Mainloop Context in + * order to be notified whenever data becomes available for a component. * * Returns: %TRUE on success, %FALSE if the stream or component IDs are invalid. */ @@ -543,8 +615,8 @@ nice_agent_set_selected_pair ( * for a given stream's component. This is used to force the selection of * a specific remote candidate even when connectivity checks are failing * (e.g. non-ICE compatible candidates). - * Calling this function will disable all further ICE processing (connection check, - * state machine updates, etc). Note that keepalives will + * Calling this function will disable all further ICE processing + * (connection check, state machine updates, etc). Note that keepalives will * continue to be sent. * * Returns: %TRUE on success, %FALSE on failure diff --git a/agent/candidate.h b/agent/candidate.h index 0133bf0..64eda59 100644 --- a/agent/candidate.h +++ b/agent/candidate.h @@ -43,8 +43,13 @@ /** * SECTION:candidate * @short_description: ICE candidate representation + * @see_also: #NiceAddress + * @stability: Stable * - * + * A representation of an ICE candidate. Make sure you read the ICE drafts[1] to + * understand correctly the concept of ICE candidates. + * + * [1] http://tools.ietf.org/wg/mmusic/draft-ietf-mmusic-ice/ */ @@ -206,7 +211,8 @@ gfloat nice_candidate_msn_priority (NiceCandidate *candidate); guint32 -nice_candidate_ice_priority_full (guint type_pref, guint local_pref, guint component_id); +nice_candidate_ice_priority_full (guint type_pref, guint local_pref, + guint component_id); guint32 nice_candidate_ice_priority (const NiceCandidate *candidate); diff --git a/agent/debug.h b/agent/debug.h index d360772..eff1bc6 100644 --- a/agent/debug.h +++ b/agent/debug.h @@ -40,8 +40,19 @@ /** * SECTION:debug * @short_description: Debug messages utility functions + * @stability: More flags are to come and a better API to + * enable/disable each flag should be added. Unstable * - * + * Libnice can output a lot of information when debug messages are enabled. + * This can significantly help track down problems and/or understand what + * it's doing. + * You can enable/disable the debug messages by calling nice_debug_enable() + * or nice_debug_disable() and choosing whether you want only ICE debug messages + * or also stun debug messages. + * By default, the debug messages are disabled, unless the environment variable + * NICE_DEBUG is set, in which case, it must contain a comma separated list of + * flags specifying which debug to enable. The flags can be "nice", "stun", + * or "all" to enable all debug messages. */ diff --git a/docs/reference/libnice/Makefile.am b/docs/reference/libnice/Makefile.am index 63cd82d..f334336 100644 --- a/docs/reference/libnice/Makefile.am +++ b/docs/reference/libnice/Makefile.am @@ -38,7 +38,7 @@ FIXXREF_OPTIONS= # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB=$(DOC_SOURCE_DIR)/agent.h $(DOC_SOURCE_DIR)/address.h $(DOC_SOURCE_DIR)/debug.h $(DOC_SOURCE_DIR)/candidate.h -CFILE_GLOB= +CFILE_GLOB=$(DOC_SOURCE_DIR)/agent.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h diff --git a/docs/reference/libnice/libnice-sections.txt b/docs/reference/libnice/libnice-sections.txt index 94208b9..ab83f88 100644 --- a/docs/reference/libnice/libnice-sections.txt +++ b/docs/reference/libnice/libnice-sections.txt @@ -33,6 +33,7 @@ NICE_AGENT_CLASS NICE_IS_AGENT_CLASS NICE_AGENT_GET_CLASS <SUBSECTION Private> +NiceAgentClass </SECTION> <SECTION> @@ -75,6 +76,7 @@ nice_candidate_pair_priority <TITLE>NiceAddress</TITLE> NICE_ADDRESS_STRING_LEN NiceAddress +nice_address_init nice_address_new nice_address_free nice_address_dup @@ -90,3 +92,53 @@ nice_address_to_string nice_address_is_private nice_address_is_valid </SECTION> + + + +<SECTION> +<FILE>component</FILE> +<SUBSECTION Private> +Component +CandidatePair +IncomingCheck +component_new +component_free +component_find_socket_by_fd +component_find_pair +component_restart +component_update_selected_pair +component_find_remote_candidate +component_set_selected_remote_candidate +</SECTION> + +<SECTION> +<FILE>agent-priv</FILE> +<SUBSECTION Private> +NICE_AGENT_TIMER_TA_DEFAULT +NICE_AGENT_TIMER_TR_DEFAULT +NICE_AGENT_TIMER_TR_MIN +NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT +MAX_STUN_DATAGRAM_PAYLOAD +NiceAgent +agent_find_component +agent_find_stream +agent_gathering_done +agent_signal_gathering_done +agent_signal_new_selected_pair +agent_signal_component_state_change +agent_signal_new_candidate +agent_signal_new_remote_candidate +agent_signal_initial_binding_request_received +agent_candidate_pair_priority +agent_timeout_add_with_context +priv_attach_stream_component_socket +</SECTION> + +<SECTION> +<FILE>agent-signals-marshal</FILE> +<SUBSECTION Private> +agent_marshal_VOID__UINT_UINT_UINT +agent_marshal_VOID__UINT_UINT_STRING_STRING +agent_marshal_VOID__UINT_UINT_STRING +agent_marshal_VOID__UINT +</SECTION> |