Index: pjproject/trunk/pjnath/include/pjnath/ice.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1106)
+++ pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1110)
@@ -22,5 +22,5 @@
 /**
  * @file ice.h
- * @brief ICE.
+ * @brief ICE session management
  */
 #include <pjnath/types.h>
@@ -32,5 +32,4 @@
  * @defgroup PJNATH_ICE Interactive Connectivity Establishment (ICE)
  * @brief Interactive Connectivity Establishment (ICE)
- * @ingroup PJNATH
  */
 
@@ -40,8 +39,28 @@
 
 /**
- * @defgroup PJNATH_ICE_STREAM Transport Independent ICE Media Stream
- * @brief Transport Independent ICE Media Stream
+ * @defgroup PJNATH_ICE_SESSION ICE Session
+ * @brief Transport Independent ICE Session
  * @ingroup PJNATH_ICE
  * @{
+ *
+ * This module describes #pj_ice, a transport independent ICE session,
+ * part of PJNATH - the Open Source NAT helper library.
+ *
+ * An ICE session, represented by #pj_ice structure, is the lowest 
+ * abstraction of ICE in PJNATH, and it is used to perform and manage
+ * connectivity checks of transport address candidates <b>within a
+ * single media stream</b> (note: this differs from what is described
+ * in ICE draft, where an ICE session manages the whole media sessions
+ * rather than just a single stream).
+ *
+ * The ICE session described here is independent from any transports,
+ * meaning that the actual network I/O for this session would have to
+ * be performed by the application, or higher layer abstraction. 
+ * Using this framework, application would give any incoming packets to
+ * the ICE session, and it would provide the ICE session with a callback
+ * to send outgoing message.
+ *
+ * For higher abstraction of ICE where transport is included, please 
+ * see \ref PJNATH_ICE_STREAM_TRANSPORT.
  */
 
@@ -51,35 +70,46 @@
 typedef enum pj_ice_cand_type
 {
-    PJ_ICE_CAND_TYPE_HOST,
-    PJ_ICE_CAND_TYPE_SRFLX,
-    PJ_ICE_CAND_TYPE_PRFLX,
-    PJ_ICE_CAND_TYPE_RELAYED
+    PJ_ICE_CAND_TYPE_HOST,	/**< ICE host candidate.		*/
+    PJ_ICE_CAND_TYPE_SRFLX,	/**< ICE server reflexive candidate.	*/
+    PJ_ICE_CAND_TYPE_PRFLX,	/**< ICE peer reflexive candidate.	*/
+    PJ_ICE_CAND_TYPE_RELAYED	/**< ICE relayed candidate.		*/
 } pj_ice_cand_type;
 
-/**
- *
+
+/**
+ * This enumeration describes the default preference for the ICE
+ * candidate types as described by ICE standard.
  */
 enum pj_ice_type_pref
 {
-    PJ_ICE_HOST_PREF	    = 126,
-    PJ_ICE_SRFLX_PREF	    = 100,
-    PJ_ICE_PRFLX_PREF	    = 110,
-    PJ_ICE_RELAYED_PREF	    = 0
+    PJ_ICE_HOST_PREF	    = 126,  /**< Preference value for host.	*/
+    PJ_ICE_SRFLX_PREF	    = 100,  /**< Preference value for SRFLX.	*/
+    PJ_ICE_PRFLX_PREF	    = 110,  /**< Preference value for PRFLX	*/
+    PJ_ICE_RELAYED_PREF	    = 0	    /**< Preference value for relay	*/
 };
 
+/** Forward declaration for pj_ice */
 typedef struct pj_ice pj_ice;
+
+/** Forward declaration for pj_ice_check */
 typedef struct pj_ice_check pj_ice_check;
 
-#define PJ_ICE_MAX_CAND	    16
-#define PJ_ICE_MAX_COMP	    8
-#define PJ_ICE_MAX_CHECKS   32
-#define PJ_ICE_TA_VAL	    20
-
-/**
- * ICE component
+
+/**
+ * This structure describes ICE component. 
+ * A media stream may require multiple components, each of which has 
+ * to work for the media stream as a whole to work.  For media streams
+ * based on RTP, there are two components per media stream - one for RTP,
+ * and one for RTCP.
  */
 typedef struct pj_ice_comp
 {
+    /**
+     * The pointer to ICE check which was nominated for this component.
+     * The value will be NULL if a nominated check has not been found
+     * for this component.
+     */
     pj_ice_check	*valid_check;
+
 } pj_ice_comp;
 
@@ -87,62 +117,251 @@
 /**
  * This structure describes an ICE candidate.
+ * ICE candidate is a transport address that is to be tested by ICE
+ * procedures in order to determine its suitability for usage for
+ * receipt of media.  Candidates also have properties - their type
+ * (server reflexive, relayed or host), priority, foundation, and
+ * base.
  */
 typedef struct pj_ice_cand
 {
+    /**
+     * The component ID of this candidate. Note that component IDs starts
+     * with one for RTP and two for RTCP. In other words, it's not zero
+     * based.
+     */
     pj_uint32_t		 comp_id;
+
+    /**
+     * The candidate type, as described in #pj_ice_cand_type enumeration.
+     */
     pj_ice_cand_type	 type;
+
+    /**
+     * The foundation string, which is an identifier which value will be
+     * equivalent for two candidates that are of the same type, share the 
+     * same base, and come from the same STUN server. The foundation is 
+     * used to optimize ICE performance in the Frozen algorithm.
+     */
     pj_str_t		 foundation;
+
+    /**
+     * The candidate's priority, a 32-bit unsigned value which value will be
+     * calculated by the ICE session when a candidate is registered to the
+     * ICE session.
+     */
     pj_uint32_t		 prio;
+
+    /**
+     * IP address of this candidate. For host candidates, this represents
+     * the local address of the socket. For reflexive candidates, the value
+     * will be the public address allocated in NAT router for the host
+     * candidate and as reported in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS
+     * attribute of STUN Binding request. For relayed candidate, the value 
+     * will be the address allocated in the TURN server by STUN Allocate
+     * request.
+     */
     pj_sockaddr		 addr;
+
+    /**
+     * Base address of this candidate. "Base" refers to the address an agent 
+     * sends from for a particular candidate.  For host candidates, the base
+     * is the same as the host candidate itself. For reflexive candidates, 
+     * the base is the local IP address of the socket. For relayed candidates,
+     * the base address is the transport address allocated in the TURN server
+     * for this candidate.
+     */
     pj_sockaddr		 base_addr;
+
+    /**
+     * Related address, which is used for informational only and is not used
+     * in any way by the ICE session.
+     */
     pj_sockaddr		 rel_addr;
+
+    /**
+     * The STUN session to be used to send and receive STUN messages for this
+     * candidate.
+     */
     pj_stun_session	*stun_sess;
+
 } pj_ice_cand;
 
+
+/**
+ * This enumeration describes the state of ICE check.
+ */
 typedef enum pj_ice_check_state
 {
+    /**
+     * A check for this pair hasn't been performed, and it can't
+     * yet be performed until some other check succeeds, allowing this
+     * pair to unfreeze and move into the Waiting state.
+     */
     PJ_ICE_CHECK_STATE_FROZEN,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_WAITING,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_IN_PROGRESS,
+
+    /**
+     * A check has not been performed for this pair, and can be
+     * performed as soon as it is the highest priority Waiting pair on
+     * the check list.
+     */
     PJ_ICE_CHECK_STATE_SUCCEEDED,
+
+    /**
+     * A check for this pair was already done and failed, either
+     * never producing any response or producing an unrecoverable failure
+     * response.
+     */
     PJ_ICE_CHECK_STATE_FAILED
+
 } pj_ice_check_state;
 
 
+/**
+ * This structure describes an ICE connectivity check. An ICE check
+ * contains a candidate pair, and will involve sending STUN Binding 
+ * Request transaction for the purposes of verifying connectivity. 
+ * A check is sent from the local candidate to the remote candidate 
+ * of a candidate pair.
+ */
 struct pj_ice_check
 {
+    /**
+     * Pointer to local candidate entry of this check.
+     */
     pj_ice_cand		*lcand;
+
+    /**
+     * Pointer to remote candidate entry of this check.
+     */
     pj_ice_cand		*rcand;
 
+    /**
+     * Check priority.
+     */
     pj_uint64_t		 prio;
+
+    /**
+     * Connectivity check state.
+     */
     pj_ice_check_state	 state;
+
+    /**
+     * STUN transmit data containing STUN Binding request that was sent 
+     * as part of this check. The value will only be set when this check 
+     * has a pending transaction, and is used to cancel the transaction
+     * when other check has succeeded.
+     */
     pj_stun_tx_data	*tdata;
+
+    /**
+     * Flag to indicate whether this check is nominated. A nominated check
+     * contains USE-CANDIDATE attribute in its STUN Binding request.
+     */
     pj_bool_t		 nominated;
+
+    /**
+     * When the check failed, this will contain the failure status of the
+     * STUN transaction.
+     */
     pj_status_t		 err_code;
 };
 
 
+/**
+ * This enumeration describes ICE checklist state.
+ */
 typedef enum pj_ice_checklist_state
 {
+    /**
+     * The checklist is not yet running.
+     */
     PJ_ICE_CHECKLIST_ST_IDLE,
+
+    /**
+     * In this state, ICE checks are still in progress for this
+     * media stream.
+     */
     PJ_ICE_CHECKLIST_ST_RUNNING,
+
+    /**
+     * In this state, ICE checks have completed for this media stream,
+     * either successfully or with failure.
+     */
     PJ_ICE_CHECKLIST_ST_COMPLETED
+
 } pj_ice_checklist_state;
 
+
+/**
+ * This structure represents ICE check list, that is an ordered set of 
+ * candidate pairs that an agent will use to generate checks.
+ */
 typedef struct pj_ice_checklist
 {
+    /**
+     * The checklist state.
+     */
     pj_ice_checklist_state   state;
+
+    /**
+     * Number of candidate pairs (checks).
+     */
     unsigned		     count;
+
+    /**
+     * Array of candidate pairs (checks).
+     */
     pj_ice_check	     checks[PJ_ICE_MAX_CHECKS];
+
+    /**
+     * A timer used to perform periodic check for this checklist.
+     */
     pj_timer_entry	     timer;
+
 } pj_ice_checklist;
 
 
 /**
- * ICE sock callback.
+ * This structure contains callbacks that will be called by the ICE
+ * session.
  */
 typedef struct pj_ice_cb
 {
+    /**
+     * An optional callback that will be called by the ICE session when
+     * ICE negotiation has completed, successfully or with failure.
+     *
+     * @param ice	    The ICE session.
+     * @param status	    Will contain PJ_SUCCESS if ICE negotiation is
+     *			    successful, or some error code.
+     */
     void	(*on_ice_complete)(pj_ice *ice, pj_status_t status);
+
+    /**
+     * A mandatory callback which will be called by the ICE session when
+     * it needs to send outgoing STUN packet. 
+     *
+     * @param ice	    The ICE session.
+     * @param comp_id	    ICE component ID.
+     * @param cand_id	    ICE candidate ID.
+     * @param pkt	    The STUN packet.
+     * @param size	    The size of the packet.
+     * @param dst_addr	    Packet destination address.
+     * @param dst_addr_len  Length of destination address.
+     */
     pj_status_t (*on_tx_pkt)(pj_ice *ice, unsigned comp_id, 
 			     unsigned cand_id,
@@ -150,4 +369,17 @@
 			     const pj_sockaddr_t *dst_addr,
 			     unsigned dst_addr_len);
+
+    /**
+     * A mandatory callback which will be called by the ICE session when
+     * it receives packet which is not part of ICE negotiation.
+     *
+     * @param ice	    The ICE session.
+     * @param comp_id	    ICE component ID.
+     * @param pkt	    The whole packet.
+     * @param size	    Size of the packet.
+     * @param src_addr	    Source address where this packet was received 
+     *			    from.
+     * @param src_addr_len  The length of source address.
+     */
     void	(*on_rx_data)(pj_ice *ice, unsigned comp_id,
 			      void *pkt, pj_size_t size,
@@ -157,57 +389,108 @@
 
 
+/**
+ * This enumeration describes ICE role.
+ */
 typedef enum pj_ice_role
 {
+    /**
+     * The ICE agent is in controlled role.
+     */
     PJ_ICE_ROLE_CONTROLLED,
+
+    /**
+     * The ICE agent is in controlling role.
+     */
     PJ_ICE_ROLE_CONTROLLING
+
 } pj_ice_role;
 
-/**
- * ICE structure.
+
+/**
+ * This structure describes the ICE session. For this version of PJNATH,
+ * an ICE session corresponds to a single media stream (unlike the ICE
+ * session described in the ICE standard where an ICE session covers the
+ * whole media and may consist of multiple media streams). The decision
+ * to support only a single media session was chosen for simplicity,
+ * while still allowing application to utilize multiple media streams by
+ * creating multiple ICE sessions, one for each media stream.
  */
 struct pj_ice
 {
-    char		obj_name[PJ_MAX_OBJ_NAME];
-
-    pj_pool_t		*pool;
-    void		*user_data;
-    pj_mutex_t		*mutex;
-    pj_ice_role		 role;
-    pj_bool_t		 is_complete;
-    pj_status_t		 ice_status;
-    pj_ice_cb		 cb;
-
-    pj_stun_config	 stun_cfg;
+    char		obj_name[PJ_MAX_OBJ_NAME];  /**< Object name.	    */
+
+    pj_pool_t		*pool;			    /**< Pool instance.	    */
+    void		*user_data;		    /**< App. data.	    */
+    pj_mutex_t		*mutex;			    /**< Mutex.		    */
+    pj_ice_role		 role;			    /**< ICE role.	    */
+    pj_bool_t		 is_complete;		    /**< Complete?	    */
+    pj_status_t		 ice_status;		    /**< Error status.	    */
+    pj_ice_cb		 cb;			    /**< Callback.	    */
+
+    pj_stun_config	 stun_cfg;		    /**< STUN settings.	    */
 
     /* STUN credentials */
-    pj_str_t		 tx_ufrag;
-    pj_str_t		 tx_uname;
-    pj_str_t		 tx_pass;
-    pj_str_t		 rx_ufrag;
-    pj_str_t		 rx_uname;
-    pj_str_t		 rx_pass;
+    pj_str_t		 tx_ufrag;		    /**< Remote ufrag.	    */
+    pj_str_t		 tx_uname;		    /**< Uname for TX.	    */
+    pj_str_t		 tx_pass;		    /**< Remote password.   */
+    pj_str_t		 rx_ufrag;		    /**< Local ufrag.	    */
+    pj_str_t		 rx_uname;		    /**< Uname for RX	    */
+    pj_str_t		 rx_pass;		    /**< Local password.    */
 
     /* Components */
-    unsigned		 comp_cnt;
-    pj_ice_comp		 comp[PJ_ICE_MAX_COMP];
+    unsigned		 comp_cnt;		    /**< # of components.   */
+    pj_ice_comp		 comp[PJ_ICE_MAX_COMP];	    /**< Component array    */
 
     /* Local candidates */
-    unsigned		 lcand_cnt;
-    pj_ice_cand		 lcand[PJ_ICE_MAX_CAND];
+    unsigned		 lcand_cnt;		    /**< # of local cand.   */
+    pj_ice_cand		 lcand[PJ_ICE_MAX_CAND];    /**< Array of cand.	    */
 
     /* Remote candidates */
-    unsigned		 rcand_cnt;
-    pj_ice_cand		 rcand[PJ_ICE_MAX_CAND];
+    unsigned		 rcand_cnt;		    /**< # of remote cand.  */
+    pj_ice_cand		 rcand[PJ_ICE_MAX_CAND];    /**< Array of cand.	    */
 
     /* Checklist */
-    pj_ice_checklist	 clist;
+    pj_ice_checklist	 clist;			    /**< Active checklist   */
     
     /* Valid list */
-    pj_ice_checklist	 valid_list;
+    pj_ice_checklist	 valid_list;		    /**< Valid list.	    */
 };
 
+
+/**
+ * This is a utility function to retrieve the string name for the
+ * particular candidate type.
+ *
+ * @param type	    Candidate type.
+ *
+ * @return	    The string representation of the candidate type.
+ */
 PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type);
 
 
+/**
+ * Create ICE session with the specified role and number of components.
+ * Application would typically need to create an ICE session before
+ * sending an offer or upon receiving one. After the session is created,
+ * application can register candidates to the ICE session by calling
+ * #pj_ice_add_cand() function.
+ *
+ * @param stun_cfg	The STUN configuration settings, containing among
+ *			other things the timer heap instance to be used
+ *			by the ICE session.
+ * @param name		Optional name to identify this ICE instance in
+ *			the log file.
+ * @param role		ICE role.
+ * @param comp_cnt	Number of components.
+ * @param cb		ICE callback.
+ * @param local_ufrag	Optional string to be used as local username to
+ *			authenticate incoming STUN binding request. If
+ *			the value is NULL, a random string will be 
+ *			generated.
+ * @param local_passwd	Optional string to be used as local password.
+ * @param p_ice		Pointer to receive the ICE session instance.
+ *
+ * @return		PJ_SUCCESS if ICE session is created successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
 				   const char *name,
@@ -218,5 +501,32 @@
 				   const pj_str_t *local_passwd,
 				   pj_ice **p_ice);
+
+/**
+ * Destroy ICE session.
+ *
+ * @param ice		ICE session instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
 PJ_DECL(pj_status_t) pj_ice_destroy(pj_ice *ice);
+
+
+/**
+ * Add a candidate to this ICE session. 
+ *
+ * @param ice		ICE session instance.
+ * @param comp_id	Component ID of this candidate.
+ * @param type		Candidate type.
+ * @param local_pref	Local preference for this candidate, which
+ *			normally should be set to 65535.
+ * @param foundation	Foundation identification.
+ * @param addr		The candidate address.
+ * @param base_addr	The candidate's base address.
+ * @param rel_addr	Optional related address.
+ * @param addr_len	Length of addresses.
+ * @param p_cand_id	Optional pointer to receive the candidate ID.
+ *
+ * @return		PJ_SUCCESS if candidate is successfully added.
+ */
 PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
 				     unsigned comp_id,
@@ -228,10 +538,45 @@
 				     const pj_sockaddr_t *rel_addr,
 				     int addr_len,
-				     unsigned *cand_id);
-
+				     unsigned *p_cand_id);
+
+/**
+ * Find default candidate for the specified component ID, using this
+ * rule:
+ *  - if the component has a successful candidate pair, then the
+ *    local candidate of this pair will be returned.
+ *  - otherwise a relay, reflexive, or host candidate will be selected 
+ *    on that specified order.
+ *
+ * @param ice		The ICE session instance.
+ * @param comp_id	The component ID.
+ * @param p_cand_id	Pointer to receive the candidate ID.
+ *
+ * @return		PJ_SUCCESS if a candidate has been selected.
+ */
 PJ_DECL(pj_status_t) pj_ice_find_default_cand(pj_ice *ice,
 					      unsigned comp_id,
-					      int *cand_id);
-
+					      int *p_cand_id);
+
+/**
+ * Pair the local and remote candidates to create check list. Application
+ * typically would call this function after receiving SDP containing ICE
+ * candidates from the remote host (either upon receiving the initial
+ * offer, for UAS, or upon receiving the answer, for UAC).
+ *
+ * Note that ICE connectivity check will not start until application calls
+ * #pj_ice_start_check().
+ *
+ * @param ice		ICE session instance.
+ * @param rem_ufrag	Remote ufrag, as seen in the SDP received from 
+ *			the remote agent.
+ * @param rem_passwd	Remote password, as seen in the SDP received from
+ *			the remote agent.
+ * @param rem_cand_cnt	Number of remote candidates.
+ * @param rem_cand	Remote candidate array. Remote candidates are
+ *			gathered from the SDP received from the remote 
+ *			agent.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
 					      const pj_str_t *rem_ufrag,
@@ -239,10 +584,53 @@
 					      unsigned rem_cand_cnt,
 					      const pj_ice_cand rem_cand[]);
+
+/**
+ * Start ICE periodic check. This function will return immediately, and
+ * application will be notified about the connectivity check status in
+ * #pj_ice_cb callback.
+ *
+ * @param ice		The ICE session instance.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_start_check(pj_ice *ice);
 
+
+/**
+ * Send data using this ICE session. If ICE checks have not produced a
+ * valid check for the specified component ID, this function will return
+ * with failure. Otherwise ICE session will send the packet to remote
+ * destination using the nominated local candidate for the specified
+ * component.
+ *
+ * @param ice		The ICE session.
+ * @param comp_id	Component ID.
+ * @param data		The data or packet to be sent.
+ * @param data_len	Size of data or packet, in bytes.
+ *
+ * @return		PJ_SUCCESS if data is sent successfully.
+ */
 PJ_DECL(pj_status_t) pj_ice_send_data(pj_ice *ice,
 				      unsigned comp_id,
 				      const void *data,
 				      pj_size_t data_len);
+
+/**
+ * Report the arrival of packet to the ICE session. Since ICE session
+ * itself doesn't have any transports, it relies on application or
+ * higher layer component to give incoming packets to the ICE session.
+ * If the packet is not a STUN packet, this packet will be given back
+ * to application via \a on_rx_data() callback in #pj_ice_cb.
+ *
+ * @param ice		The ICE session.
+ * @param comp_id	Component ID.
+ * @param cand_id	Candidate ID.
+ * @param pkt		Incoming packet.
+ * @param pkt_size	Size of incoming packet.
+ * @param src_addr	Source address of the packet.
+ * @param src_addr_len	Length of the address.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
 PJ_DECL(pj_status_t) pj_ice_on_rx_pkt(pj_ice *ice,
 				      unsigned comp_id,
