Index: pjproject/trunk/pjnath/include/pjnath/ice_strans.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/ice_strans.h	(revision 1487)
+++ pjproject/trunk/pjnath/include/pjnath/ice_strans.h	(revision 1988)
@@ -26,4 +26,6 @@
  */
 #include <pjnath/ice_session.h>
+#include <pjnath/stun_sock.h>
+#include <pjnath/turn_sock.h>
 #include <pjlib-util/resolver.h>
 #include <pj/ioqueue.h>
@@ -45,5 +47,5 @@
  *
  * ICE stream transport, as represented by #pj_ice_strans structure, is an ICE
- * capable component for transporting media streams within a media session. 
+ * capable class for transporting media streams within a media session. 
  * It consists of one or more transport sockets (typically two for RTP
  * based communication - one for RTP and one for RTCP), and an 
@@ -51,128 +53,19 @@
  * various candidates of the transport addresses.
  *
- * \section PJNATH_ICE_STREAM_TRANSPORT_USING Using the ICE Stream Transport
- *
- * Application may use the ICE stream transport in two ways:
- *  - it can create the ICE stream transports once during application 
- *    initialization and keep them alive throughout application lifetime, or
- *  - it can create and destroy the ICE stream transport as needed everytime 
- *     a call is made and destroyed. 
- *
- * Keeping the ICE stream transport alive throughout
- * application's lifetime is normally preferable, as initializing the
- * ICE stream transport may incur delay because the ICE stream transport
- * would need to communicate with the STUN/TURN server to get the
- * server reflexive and relayed candidates for the transports.
- *
- * Regardless of which usage scenario is being used, the ICE stream
- * transport is capable for restarting the ICE session being used and to
- * send STUN keep-alives for its STUN server reflexive and relayed
- * candidates. When ICE stream transport detects that the STUN mapped
- * address has changed in the keep-alive response, it will automatically
- * update its address to the new address, and notify the application via
- * \a on_addr_change() function of the #pj_ice_strans_cb callback.
- *
- * \subsection PJNATH_ICE_ST_TRA_INIT Initialization
- *
- * Application creates the ICE stream transport by calling 
- * #pj_ice_strans_create() function. Among other things, application needs
- * to specify:
- *	- STUN configuration (pj_stun_config), containing STUN settings
- *	  such as timeout values and the instances of timer heap and
- *	  ioqueue.
- *	- Session name, useful for identifying this session in the log.
- *	- Number of ICE components.
- *	- Arbitrary user data, useful when associating the ICE session
- *	  with some application's data structure.
- *	- A callback (#pj_ice_strans_cb) to receive events from the ICE
- *	  stream transport. Two of the most important fields in this
- *	  callback structure are \a on_rx_data() to notify application
- *	  about incoming data (perhaps RTP or RTCP packet), and
- *	  \a on_ice_complete() to notify application that ICE negotiation
- *	  has completed, either successfully or with failure.
- *
- * After the ICE stream transport is created, application may set up the
- * STUN servers to be used to obtain STUN server reflexive and relayed
- * candidate, by calling #pj_ice_strans_set_stun_domain() or 
- * #pj_ice_strans_set_stun_srv().
- *
- * Application then creates each component by calling 
- * #pj_ice_strans_create_comp(); this would create an actual socket
- * which listens to the specified local address, and it would also
- * perform lookup to find various transport address candidates for this
- * socket.
- *
- * Adding component may involve contacting STUN and TURN servers to get
- * STUN mapped address and allocate TURN relay channel, and this process
- * may take some time to complete. Once application has added all
- * components, it can check whether server reflexive and relayed 
- * candidates have been acquired, by calling #pj_ice_strans_get_comps_status().
- * 
- * \subsection PJNATH_ICE_ST_TRA_INIT_ICE Starting ICE Session
- *
- * When application is about to send an offer containing ICE capability,
- * or when it receives an offer containing ICE capability, it would
- * create the ICE session by calling #pj_ice_strans_init_ice(). This would
- * register all transport address aliases for each component to the ICE
- * session as candidates. After this application can enumerate all local
- * candidates by calling #pj_ice_strans_enum_cands(), and encode these
- * candidates in the SDP to be sent to remote agent.
- *
- * \subsection PJNATH_ICE_ST_TRA_START Starting Connectivity Checks
- *
- * Once application receives the SDP from remote, it pairs local candidates
- * with remote candidates, and can start ICE connectivity checks. This is
- * done by calling #pj_ice_strans_start_ice(), specifying
- * the remote candidate list, and remote username and password. If the
- * pairing process is successful, ICE connectivity checks will begin
- * immediately. The ICE session/transport will then notify the application 
- * via the callback when ICE connectivity checks completes, either 
- * successfully or with failure.
- *
- * \subsection PJNATH_ICE_ST_TRA_SEND_RECV Sending and Receiving Data
- *
- * Application can send data (normally RTP or RTCP packets) at any time
- * by calling #pj_ice_strans_sendto(). This function takes a destination
- * address as one of the arguments, and this destination address should
- * be taken from the default transport address of the component (that is
- * the address in SDP c= and m= lines, or in a=rtcp attribute). 
- * If ICE negotiation is in progress, this function will send the data 
- * to the destination address. Otherwise if ICE negotiation has completed
- * successfully, this function will send the data to the nominated remote 
- * address, as negotiated by ICE.
- *
- * Upon receiving incoming data (that is a non-STUN  message), the ICE
- * stream transport will notify the application by calling \a on_rx_data()
- * of the #pj_ice_strans_cb callback.
- *
- * \subsection PJNATH_ICE_ST_TRA_STOP Stopping ICE Session
- *
- * Once the call is terminated, application no longer needs to keep the
- * ICE session, so it should call #pj_ice_strans_stop_ice() to destroy the
- * ICE session within this ICE stream transport. Note that this WILL NOT
- * destroy the sockets/transports, it only destroys the ICE session
- * within this ICE stream transport. It is recommended that application 
- * retains the ICE stream transport to speed up the process of setting up
- * the next call. The ICE stream transport will continue to send STUN 
- * keep-alive packets to keep the NAT binding open and to detect change 
- * in STUN mapped address.
- *
- * \subsection PJNATH_ICE_ST_TRA_RESTART Restarting ICE Session
- *
- * When a new call is made, application can repeat the above
- * #pj_ice_strans_init_ice() to #pj_ice_strans_stop_ice() cycle for 
- * the new call, using this same ICE stream transport.
- *
- * \subsection PJNATH_ICE_ST_TRA_DESTROY Destroying ICE Stream Transport
- *
- * Finally, when the ICE stream transport itself is no longer needed,
- * for example when the application quits, application should call
- * #pj_ice_strans_destroy() to release back all resources allocated by this
- * ICE stream transport.
- *
  */
 
 /** Forward declaration for ICE stream transport. */
 typedef struct pj_ice_strans pj_ice_strans;
+
+/** Transport operation types to be reported on \a on_status() callback */
+typedef enum pj_ice_strans_op
+{
+    /** Initialization (candidate gathering) */
+    PJ_ICE_STRANS_OP_INIT,
+
+    /** Negotiation */
+    PJ_ICE_STRANS_OP_NEGOTIATION
+
+} pj_ice_strans_op;
 
 /** 
@@ -201,193 +94,198 @@
 
     /**
-     * This callback will be called when ICE checks have completed.
-     * This callback is optional.
+     * Callback to report status.
      * 
      * @param ice_st	    The ICE stream transport.
-     * @param status	    The ICE connectivity check status.
+     * @param op	    The operation
+     * @param status	    Operation status.
      */
     void    (*on_ice_complete)(pj_ice_strans *ice_st, 
+			       pj_ice_strans_op op,
 			       pj_status_t status);
 
-    /**
-     * This callback will be called when ICE transport has detected that
-     * the STUN mapped address of a candidate has changed.
+} pj_ice_strans_cb;
+
+
+/**
+ * This structure describes ICE stream transport configuration. Application
+ * should initialize the structure by calling #pj_ice_strans_cfg_default()
+ * before changing the settings.
+ */
+typedef struct pj_ice_strans_cfg
+{
+    /**
+     * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)
+     * is supported, and this is the default value.
+     */
+    int			af;
+
+    /**
+     * STUN configuration which contains the timer heap and
+     * ioqueue instance to be used, and STUN retransmission
+     * settings. This setting is mandatory.
      *
-     * @param ice_st	    The ICE stream transport.
-     * @param comp_id	    Component ID.
-     * @param cand_id	    Candidate ID.
-     */
-    void    (*on_addr_change)(pj_ice_strans *ice_st, 
-			      unsigned comp_id, 
-			      unsigned cand_id);
-			      
-} pj_ice_strans_cb;
-
-
-/**
- * Various flags that can be specified when creating a component with
- * #pj_ice_strans_create_comp(). These options may be combined together
- * with bitmask operation.
- */
-enum pj_ice_strans_option
-{
-    /**
-     * If this option is specified, only a listening socket will be
-     * created for the component, and no candidate will be added to
-     * the component. Application must add the component manually
-     * by inspecting the socket and transport address of the component.
-     */
-    PJ_ICE_ST_OPT_DONT_ADD_CAND = 1,
-
-    /**
-     * If this option is specified, then no STUN reflexive candidate
-     * will be added to the component.
-     */
-    PJ_ICE_ST_OPT_DISABLE_STUN	= 2,
-
-    /**
-     * If this option is specified, then no STUN relay candidate
-     * will be added to the component.
-     */
-    PJ_ICE_ST_OPT_DISABLE_RELAY	= 4,
-
-    /**
-     * If this option is specified, then when the function fails to
-     * bind the socket to the specified port, it WILL NOT try to
-     * bind the socket to the next available port.
+     * The default value is all zero. Application must initialize
+     * this setting with #pj_stun_config_init().
+     */
+    pj_stun_config	 stun_cfg;
+
+    /**
+     * DNS resolver to be used to resolve servers. If DNS SRV
+     * resolution is required, the resolver must be set.
      *
-     * If this option is NOT specified, then the function will try to
-     * bind the socket to next port+2, repetitively until the socket
-     * is bound successfully.
-     */
-    PJ_ICE_ST_OPT_NO_PORT_RETRY	= 8,
-};
-
-
-/**
- * This structure describes ICE stream transport candidate. A "candidate"
- * in ICE stream transport can be viewed as alias transport address
- * for the socket.
- */
-typedef struct pj_ice_strans_cand
-{
-    /**
-     * Candidate type.
-     */
-    pj_ice_cand_type	type;
-
-    /** 
-     * Status of this candidate. This status is useful for ICE reflexive
-     * and relay candidate, where the address needs to be resolved 
-     * asynchronously by sending STUN request to STUN server.
-     *
-     * The value will be PJ_SUCCESS if candidate address has been resolved
-     * successfully, PJ_EPENDING when the address resolution process is
-     * in progress, or other value when the address resolution has
-     * completed with failure.
-     */
-    pj_status_t		status;
-
-    /**
-     * The candidate transport address.
-     */
-    pj_sockaddr		addr;
-
-    /**
-     * The ICE session candidate ID after this candidate has been registered
-     * to an ICE session. Before ICE session is created, or after ICE
-     * session has been destroyed, the value will be -1.
-     */
-    int			ice_cand_id;
-
-    /**
-     * Local preference value, which typically is 65535.
-     */
-    pj_uint16_t		local_pref;
-
-    /**
-     * Foundation associated with this candidate, which value normally will be
-     * calculated by the function.
-     */
-    pj_str_t		foundation;
-
-} pj_ice_strans_cand;
-
-
-/**
- * This structure describes an ICE stream transport component. A component
- * in ICE stream transport typically corresponds to a single socket created
- * for this component, and bound to a specific transport address. This
- * component may have multiple alias addresses, for example one alias 
- * address for each interfaces in multi-homed host, another for server
- * reflexive alias, and another for relayed alias. For each transport
- * address alias, an ICE stream transport candidate (#pj_ice_strans_cand) will
- * be created, and these candidates will eventually registered to the ICE
- * session.
- */
-typedef struct pj_ice_strans_comp
-{
-    pj_ice_strans	*ice_st;	/**< ICE stream transport.	*/
-    unsigned		 comp_id;	/**< Component ID.		*/
-    pj_uint32_t		 options;	/**< Option flags.		*/
-    pj_sock_t		 sock;		/**< Socket descriptor.		*/
-
-    pj_stun_session	*stun_sess;	/**< STUN session.		*/
-    pj_uint8_t		 ka_tsx_id[12];	/**< ID for keep STUN alives	*/
-
-    pj_sockaddr		 local_addr;	/**< Local/base address.	*/
-
-    unsigned		 pending_cnt;	/**< Pending resolution cnt.	*/
-    pj_status_t		 last_status;	/**< Last status.		*/
-
-    unsigned		 cand_cnt;	/**< # of candidates/aliaes.	*/
-    pj_ice_strans_cand	 cand_list[PJ_ICE_ST_MAX_CAND];	/**< Cand array	*/
-    int			 default_cand;	/**< Default candidate selected	*/
-
-    pj_ioqueue_key_t	*key;		/**< ioqueue key.		*/
-    pj_uint8_t		 pkt[1500];	/**< Incoming packet buffer.	*/
-    pj_ioqueue_op_key_t	 read_op;	/**< ioqueue read operation key	*/
-    pj_ioqueue_op_key_t	 write_op;	/**< ioqueue write op. key	*/
-    pj_sockaddr		 src_addr;	/**< source packet address buf.	*/
-    int			 src_addr_len;	/**< length of src addr. buf.	*/
-
-} pj_ice_strans_comp;
-
-
-/**
- * This structure represents the ICE stream transport.
- */
-struct pj_ice_strans
-{
-    char		     obj_name[PJ_MAX_OBJ_NAME];	/**< Log ID.	*/
-
-    pj_pool_t		    *pool;	/**< Pool used by this object.	*/
-    void		    *user_data;	/**< Application data.		*/
-    pj_stun_config	     stun_cfg;	/**< STUN settings.		*/
-    pj_ice_strans_cb	     cb;	/**< Application callback.	*/
-
-    pj_ice_sess		    *ice;	/**< ICE session.		*/
-
-    unsigned		     comp_cnt;	/**< Number of components.	*/
-    pj_ice_strans_comp	   **comp;	/**< Components array.		*/
-
-    pj_dns_resolver	    *resolver;	/**< The resolver instance.	*/
-    pj_bool_t		     has_rjob;	/**< Has pending resolve?	*/
-    pj_sockaddr_in	     stun_srv;	/**< STUN server address.	*/
-    pj_sockaddr_in	     turn_srv;	/**< TURN server address.	*/
-
-    pj_timer_entry	     ka_timer;	/**< STUN keep-alive timer.	*/
-};
-
-
-/**
- * Create the ICE stream transport containing the specified number of
- * components. After the ICE stream transport is created, application
- * may initialize the STUN server settings, and after that it has to 
- * initialize each components by calling #pj_ice_strans_create_comp()
- * function.
- *
- * @param stun_cfg	The STUN settings.
+     * The default value is NULL.
+     */
+    pj_dns_resolver	*resolver;
+
+    /**
+     * STUN and local transport settings. This specifies the 
+     * settings for local UDP socket, which will be resolved
+     * to get the STUN mapped address.
+     */
+    struct {
+	/**
+	 * Optional configuration for STUN transport. The default
+	 * value will be initialized with #pj_stun_sock_cfg_default().
+	 */
+	pj_stun_sock_cfg     cfg;
+
+	/**
+	 * Disable host candidates. When this option is set, no
+	 * host candidates will be added.
+	 *
+	 * Default: PJ_FALSE
+	 */
+	pj_bool_t	     no_host_cands;
+
+	/**
+	 * Include loopback addresses in the host candidates.
+	 *
+	 * Default: PJ_FALSE
+	 */
+	pj_bool_t	     loop_addr;
+
+	/**
+	 * Specify the STUN server domain or hostname or IP address.
+	 * If DNS SRV resolution is required, application must fill
+	 * in this setting with the domain name of the STUN server 
+	 * and set the resolver instance in the \a resolver field.
+	 * Otherwise if the \a resolver setting is not set, this
+	 * field will be resolved with hostname resolution and in
+	 * this case the \a port field must be set.
+	 *
+	 * The \a port field should also be set even when DNS SRV
+	 * resolution is used, in case the DNS SRV resolution fails.
+	 *
+	 * When this field is empty, STUN mapped address resolution
+	 * will not be performed. In this case only ICE host candidates
+	 * will be added to the ICE transport, unless if \a no_host_cands
+	 * field is set. In this case, both host and srflx candidates 
+	 * are disabled.
+	 *
+	 * The default value is empty.
+	 */
+	pj_str_t	     server;
+
+	/**
+	 * The port number of the STUN server, when \a server
+	 * field specifies a hostname rather than domain name. This
+	 * field should also be set even when the \a server
+	 * specifies a domain name, to allow DNS SRV resolution
+	 * to fallback to DNS A/AAAA resolution when the DNS SRV
+	 * resolution fails.
+	 *
+	 * The default value is PJ_STUN_PORT.
+	 */
+	pj_uint16_t	     port;
+
+    } stun;
+
+    /**
+     * TURN specific settings.
+     */
+    struct {
+	/**
+	 * Specify the TURN server domain or hostname or IP address.
+	 * If DNS SRV resolution is required, application must fill
+	 * in this setting with the domain name of the TURN server 
+	 * and set the resolver instance in the \a resolver field.
+	 * Otherwise if the \a resolver setting is not set, this
+	 * field will be resolved with hostname resolution and in
+	 * this case the \a port field must be set.
+	 *
+	 * The \a port field should also be set even when DNS SRV
+	 * resolution is used, in case the DNS SRV resolution fails.
+	 *
+	 * When this field is empty, relay candidate will not be
+	 * created.
+	 *
+	 * The default value is empty.
+	 */
+	pj_str_t	     server;
+
+	/**
+	 * The port number of the TURN server, when \a server
+	 * field specifies a hostname rather than domain name. This
+	 * field should also be set even when the \a server
+	 * specifies a domain name, to allow DNS SRV resolution
+	 * to fallback to DNS A/AAAA resolution when the DNS SRV
+	 * resolution fails.
+	 *
+	 * Default is zero.
+	 */
+	pj_uint16_t	     port;
+
+	/**
+	 * Type of connection to the TURN server.
+	 *
+	 * Default is PJ_TURN_TP_UDP.
+	 */
+	pj_turn_tp_type	     conn_type;
+
+	/**
+	 * Credential to be used for the TURN session. This setting
+	 * is mandatory.
+	 *
+	 * Default is to have no credential.
+	 */
+	pj_stun_auth_cred    auth_cred;
+
+	/**
+	 * Optional TURN Allocate parameter. The default value will be
+	 * initialized by #pj_turn_alloc_param_default().
+	 */
+	pj_turn_alloc_param  alloc_param;
+
+    } turn;
+
+} pj_ice_strans_cfg;
+
+
+/** 
+ * Initialize ICE transport configuration with default values.
+ *
+ * @param cfg		The configuration to be initialized.
+ */
+PJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg);
+
+
+/**
+ * Copy configuration.
+ *
+ * @param pool		Pool.
+ * @param dst		Destination.
+ * @param src		Source.
+ */
+PJ_DECL(void) pj_ice_strans_cfg_copy(pj_pool_t *pool,
+				     pj_ice_strans_cfg *dst,
+				     const pj_ice_strans_cfg *src);
+
+
+/**
+ * Create and initialize the ICE stream transport with the specified
+ * parameters. 
+ *
  * @param name		Optional name for logging identification.
+ * @param cfg		Configuration.
  * @param comp_cnt	Number of components.
  * @param user_data	Arbitrary user data to be associated with this
@@ -400,6 +298,6 @@
  *			successfully.
  */
-PJ_DECL(pj_status_t) pj_ice_strans_create(pj_stun_config *stun_cfg,
-					  const char *name,
+PJ_DECL(pj_status_t) pj_ice_strans_create(const char *name,
+					  const pj_ice_strans_cfg *cfg,
 					  unsigned comp_cnt,
 					  void *user_data,
@@ -420,131 +318,22 @@
 
 /**
- * Set the domain to be used when resolving the STUN servers. If application
- * wants to utillize STUN, then STUN server must be specified, either by
- * calling this function or by calling #pj_ice_strans_set_stun_srv().
- *
- * If application calls this function, then the STUN/TURN servers will
- * be resolved by querying DNS SRV records for the specified domain.
- *
- * @param ice_st	The ICE stream transport.
- * @param resolver	The resolver instance that will be used to
- *			resolve the STUN/TURN servers.
- * @param domain	The target domain.
- *
- * @return		PJ_SUCCESS if DNS SRV resolution job can be
- *			started. The resolution process itself will
- *			complete asynchronously.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st,
-						   pj_dns_resolver *resolver,
-						   const pj_str_t *domain);
-
-/**
- * Set the STUN and TURN server addresses. If application
- * wants to utillize STUN, then STUN server must be specified, either by
- * calling this function or by calling #pj_ice_strans_set_stun_domain().
- *
- * With this function, the STUN and TURN server addresses will be 
- * assigned immediately, that is no DNS resolution will need to be 
- * performed.
- *
- * @param ice_st	The ICE stream transport.
- * @param stun_srv	The STUN server address, or NULL if STUN
- *			reflexive candidate is not to be used.
- * @param turn_srv	The TURN server address, or NULL if STUN
- *			relay candidate is not to be used.
- *
- * @return		PJ_SUCCESS, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) 
-pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st,
-			    const pj_sockaddr_in *stun_srv,
-			    const pj_sockaddr_in *turn_srv);
-
-/**
- * Create and initialize the specified component. This function will
- * instantiate the socket descriptor for this component, optionally
- * bind the socket to the specified address (or bind to any address/port
- * if the \a addr parameter is NULL), and start finding all alias
- * addresses for this socket. For each alias addresses that if finds,
- * it will add an ICE stream transport candidate for this component.
- *
- * After all components have been initialized, application should poll
- * the #pj_ice_strans_get_comps_status() peridically to check if STUN
- * server reflexive and relayed candidates have been obtained
- * successfully.
- *
- * @param ice_st	The ICE stream transport.
- * @param comp_id	The component ID, which value must be greater than
- *			zero and less than or equal to the number of 
- *			components in this ICE stream transport.
- * @param options	Options, see #pj_ice_strans_option.
- * @param addr		Local address where socket will be bound to. This
- *			address will be used as follows:
- *			- if the value is NULL, then socket will be bound
- *			  to any available port.
- *			- if the value is not NULL, then if the port number
- *			  is not zero, it will used as the starting port 
- *			  where the socket will be bound to. If bind() to
- *			  this port fails, this function will try to bind
- *			  to port+2, repeatedly until it succeeded.
- *			  If application doesn't want this function to 
- *			  retry binding the socket to other port, it can
- *			  specify PJ_ICE_ST_OPT_NO_PORT_RETRY option.
- *			- if the value is not NULL, then if the address
- *			  is not INADDR_ANY, this function will bind the
- *			  socket to this particular interface only, and
- *			  no other host candidates will be added for this
- *			  socket.
- *			
- *
- * @return		PJ_SUCCESS, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_create_comp(pj_ice_strans *ice_st,
-					       unsigned comp_id,
-					       pj_uint32_t options,
-					       const pj_sockaddr_in *addr);
-
-/**
- * Manually add a candidate (transport address alias) for the specified
- * component. Normally application shouldn't need to use this function,
- * as candidates will be added automatically when component is created
- * with #pj_ice_strans_create_comp().
- *
- * @param ice_st	ICE stream transport.
- * @param comp_id	The component ID.
- * @param type		The candidate type.
- * @param local_pref	The local preference for this candidate
- *			(typically the value is 65535).
- * @param addr		The candidate address.
- * @param set_default	Set to non-zero to make this candidate the 
- *			default candidate for this component.
- *
- * @return		PJ_SUCCESS, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_add_cand(pj_ice_strans *ice_st,
-					    unsigned comp_id,
-					    pj_ice_cand_type type,
-					    pj_uint16_t local_pref,
-					    const pj_sockaddr_in *addr,
-					    pj_bool_t set_default);
-
-/**
- * Get the status of components in the ICE stream transports. Since
- * some IP address candidates have to be obtained asynchronously (for
- * example, the STUN reflexive or relay candidate), application can
- * use this function to know whether the address resolution has 
- * completed.
- *
- * @param ice_st	The ICE stream transport.
- *
- * @return		PJ_SUCCESS if all candidates have been resolved
- *			successfully, PJ_EPENDING if transport resolution
- *			is still in progress, or other status on failure.
- */
-PJ_DECL(pj_status_t) pj_ice_strans_get_comps_status(pj_ice_strans *ice_st);
+ * Get the user data associated with the ICE stream transport.
+ *
+ * @param ice_st	The ICE stream transport.
+ *
+ * @return		The user data.
+ */
+PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st);
+
 
 /**
  * Initialize the ICE session in the ICE stream transport.
+ * When application is about to send an offer containing ICE capability,
+ * or when it receives an offer containing ICE capability, it must
+ * call this function to initialize the internal ICE session. This would
+ * register all transport address aliases for each component to the ICE
+ * session as candidates. Then application can enumerate all local
+ * candidates by calling #pj_ice_strans_enum_cands(), and encode these
+ * candidates in the SDP to be sent to remote agent.
  *
  * @param ice_st	The ICE stream transport.
@@ -561,8 +350,8 @@
 
 /**
- * Enumerate the local candidates. This function can only be called
- * after the ICE session has been created in the ICE stream transport.
- *
- * @param ice_st	The ICE stream transport.
+ * Enumerate the local candidates for the specified component.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param comp_id	Component ID.
  * @param count		On input, it specifies the maximum number of
  *			elements. On output, it will be filled with
@@ -574,16 +363,62 @@
  */
 PJ_DECL(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st,
+					      unsigned comp_id,
 					      unsigned *count,
 					      pj_ice_sess_cand cand[]);
 
 /**
+ * Get the default candidate for the specified component. When this
+ * function is called before ICE negotiation completes, the default
+ * candidate is selected according to local preference criteria. When
+ * this function is called after ICE negotiation completes, the
+ * default candidate is the candidate that forms the valid pair.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param comp_id	Component ID.
+ * @param cand		Pointer to receive the default candidate
+ *			information.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_get_def_cand(pj_ice_strans *ice_st,
+						unsigned comp_id,
+						pj_ice_sess_cand *cand);
+
+/**
+ * Get the current ICE role. ICE session must have been initialized
+ * before this function can be called.
+ *
+ * @param ice_st	The ICE stream transport.
+ *
+ * @return		Current ICE role.
+ */
+PJ_DECL(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st);
+
+
+/**
+ * Change session role. This happens for example when ICE session was
+ * created with controlled role when receiving an offer, but it turns out
+ * that the offer contains "a=ice-lite" attribute when the SDP gets
+ * inspected. ICE session must have been initialized before this function
+ * can be called.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param new_role	The new role to be set.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st,
+					       pj_ice_sess_role new_role);
+
+
+/**
  * Start ICE connectivity checks. This function can only be called
- * after the ICE session has been created in the ICE stream transport.
- *
- * This function will pair the local and remote candidates to create 
- * check list. Once the check list is created and sorted based on the
- * priority, ICE periodic checks will be started. This function will 
- * return immediately, and application will be notified about the 
- * connectivity check status in the callback.
+ * after the ICE session has been created in the ICE stream transport
+ * with #pj_ice_strans_init_ice().
+ *
+ * This function must be called once application has received remote
+ * candidate list (typically from the remote SDP). This function pairs
+ * local candidates with remote candidates, and starts ICE connectivity
+ * checks. The ICE session/transport will then notify the application 
+ * via the callback when ICE connectivity checks completes, either 
+ * successfully or with failure.
  *
  * @param ice_st	The ICE stream transport.
@@ -592,18 +427,47 @@
  * @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.
+ * @param rcand_cnt	Number of remote candidates in the array.
+ * @param rcand		Remote candidates array.
  *
  * @return		PJ_SUCCESS, or the appropriate error code.
  */
-PJ_DECL(pj_status_t) 
-pj_ice_strans_start_ice( pj_ice_strans *ice_st,
-			 const pj_str_t *rem_ufrag,
-			 const pj_str_t *rem_passwd,
-			 unsigned rem_cand_cnt,
-			 const pj_ice_sess_cand rem_cand[]);
-
-/**
- * Stop and destroy the ICE session inside this media transport.
+PJ_DECL(pj_status_t) pj_ice_strans_start_ice(pj_ice_strans *ice_st,
+					     const pj_str_t *rem_ufrag,
+					     const pj_str_t *rem_passwd,
+					     unsigned rcand_cnt,
+					     const pj_ice_sess_cand rcand[]);
+
+/**
+ * Retrieve the candidate pair that has been nominated and successfully
+ * checked for the specified component. If ICE negotiation is still in
+ * progress or it has failed, this function will return NULL.
+ *
+ * @param ice_st	The ICE stream transport.
+ * @param comp_id	Component ID.
+ *
+ * @return		The valid pair as ICE checklist structure if the
+ *			pair exist.
+ */
+PJ_DECL(const pj_ice_sess_check*) 
+pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,
+			     unsigned comp_id);
+
+/**
+ * Stop and destroy the ICE session inside this media transport. Application
+ * needs to call this function once the media session is over (the call has
+ * been disconnected).
+ *
+ * Application MAY reuse this ICE stream transport for subsequent calls.
+ * In this case, it must call #pj_ice_strans_stop_ice() when the call is
+ * disconnected, and reinitialize the ICE stream transport for subsequent
+ * call with #pj_ice_strans_init_ice()/#pj_ice_strans_start_ice(). In this
+ * case, the ICE stream transport will maintain the internal sockets and
+ * continue to send STUN keep-alive packets and TURN Refresh request to 
+ * keep the NAT binding/TURN allocation open and to detect change in STUN
+ * mapped address.
+ *
+ * If application does not want to reuse the ICE stream transport for
+ * subsequent calls, it must call #pj_ice_strans_destroy() to destroy the
+ * ICE stream transport altogether.
  *
  * @param ice_st	The ICE stream transport.
@@ -615,9 +479,14 @@
 
 /**
- * Send outgoing packet using this transport. If ICE checks have not 
- * produced a valid check for the specified component ID, this function 
- * send to the destination address. Otherwise it will send the packet to
- * remote destination using the nominated local candidate as have been checked
- * previously.
+ * Send outgoing packet using this transport. 
+ * Application can send data (normally RTP or RTCP packets) at any time
+ * by calling this function. This function takes a destination
+ * address as one of the arguments, and this destination address should
+ * be taken from the default transport address of the component (that is
+ * the address in SDP c= and m= lines, or in a=rtcp attribute). 
+ * If ICE negotiation is in progress, this function will send the data 
+ * to the destination address. Otherwise if ICE negotiation has completed
+ * successfully, this function will send the data to the nominated remote 
+ * address, as negotiated by ICE.
  *
  * @param ice_st	The ICE stream transport.
