/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjmedia/transport_ice.h>
#include <pjnath/errno.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/rand.h>

#define THIS_FILE   "transport_ice.c"
#if 0
#   define TRACE__(expr)    PJ_LOG(5,expr)
#else
#   define TRACE__(expr)
#endif

enum oa_role
{
    ROLE_NONE,
    ROLE_OFFERER,
    ROLE_ANSWERER
};

struct sdp_state
{
    unsigned		match_comp_cnt;	/* Matching number of components    */
    pj_bool_t		ice_mismatch;	/* Address doesn't match candidates */
    pj_bool_t		ice_restart;	/* Offer to restart ICE		    */
    pj_ice_sess_role	local_role;	/* Our role			    */
};

struct transport_ice
{
    pjmedia_transport	 base;
    pj_pool_t		*pool;
    int			 af;
    unsigned		 options;	/**< Transport options.		    */

    unsigned		 comp_cnt;
    pj_ice_strans	*ice_st;

    pjmedia_ice_cb	 cb;
    unsigned		 media_option;

    pj_bool_t		 initial_sdp;
    enum oa_role	 oa_role;	/**< Last role in SDP offer/answer  */
    struct sdp_state	 rem_offer_state;/**< Describes the remote offer    */

    void		*stream;
    pj_sockaddr		 remote_rtp;
    pj_sockaddr		 remote_rtcp;
    unsigned		 addr_len;	/**< Length of addresses.	    */

    pj_bool_t		 use_ice;
    pj_sockaddr		 rtp_src_addr;	/**< Actual source RTP address.	    */
    pj_sockaddr		 rtcp_src_addr;	/**< Actual source RTCP address.    */
    unsigned		 rtp_src_cnt;	/**< How many pkt from this addr.   */
    unsigned		 rtcp_src_cnt;  /**< How many pkt from this addr.   */

    unsigned		 tx_drop_pct;	/**< Percent of tx pkts to drop.    */
    unsigned		 rx_drop_pct;	/**< Percent of rx pkts to drop.    */

    void	       (*rtp_cb)(void*,
			         void*,
				 pj_ssize_t);
    void	       (*rtcp_cb)(void*,
				  void*,
				  pj_ssize_t);
};


/*
 * These are media transport operations.
 */
static pj_status_t transport_get_info (pjmedia_transport *tp,
				       pjmedia_transport_info *info);
static pj_status_t transport_attach   (pjmedia_transport *tp,
				       void *user_data,
				       const pj_sockaddr_t *rem_addr,
				       const pj_sockaddr_t *rem_rtcp,
				       unsigned addr_len,
				       void (*rtp_cb)(void*,
						      void*,
						      pj_ssize_t),
				       void (*rtcp_cb)(void*,
						       void*,
						       pj_ssize_t));
static void	   transport_detach   (pjmedia_transport *tp,
				       void *strm);
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
				       const pj_sockaddr_t *addr,
				       unsigned addr_len,
				       const void *pkt,
				       pj_size_t size);
static pj_status_t transport_media_create(pjmedia_transport *tp,
				       pj_pool_t *pool,
				       unsigned options,
				       const pjmedia_sdp_session *rem_sdp,
				       unsigned media_index);
static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
				        pj_pool_t *tmp_pool,
				        pjmedia_sdp_session *sdp_local,
				        const pjmedia_sdp_session *rem_sdp,
				        unsigned media_index);
static pj_status_t transport_media_start(pjmedia_transport *tp,
				       pj_pool_t *pool,
				       const pjmedia_sdp_session *sdp_local,
				       const pjmedia_sdp_session *rem_sdp,
				       unsigned media_index);
static pj_status_t transport_media_stop(pjmedia_transport *tp);
static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
				       pjmedia_dir dir,
				       unsigned pct_lost);
static pj_status_t transport_destroy  (pjmedia_transport *tp);

/*
 * And these are ICE callbacks.
 */
static void ice_on_rx_data(pj_ice_strans *ice_st, 
			   unsigned comp_id, 
			   void *pkt, pj_size_t size,
			   const pj_sockaddr_t *src_addr,
			   unsigned src_addr_len);
static void ice_on_ice_complete(pj_ice_strans *ice_st, 
				pj_ice_strans_op op,
			        pj_status_t status);


static pjmedia_transport_op transport_ice_op = 
{
    &transport_get_info,
    &transport_attach,
    &transport_detach,
    &transport_send_rtp,
    &transport_send_rtcp,
    &transport_send_rtcp2,
    &transport_media_create,
    &transport_encode_sdp,
    &transport_media_start,
    &transport_media_stop,
    &transport_simulate_lost,
    &transport_destroy
};

static const pj_str_t STR_RTP_AVP	= { "RTP/AVP", 7 };
static const pj_str_t STR_CANDIDATE	= { "candidate", 9};
static const pj_str_t STR_REM_CAND	= { "remote-candidates", 17 };
static const pj_str_t STR_ICE_LITE	= { "ice-lite", 8};
static const pj_str_t STR_ICE_MISMATCH	= { "ice-mismatch", 12};
static const pj_str_t STR_ICE_UFRAG	= { "ice-ufrag", 9 };
static const pj_str_t STR_ICE_PWD	= { "ice-pwd", 7 };
static const pj_str_t STR_IP4		= { "IP4", 3 };
static const pj_str_t STR_IP6		= { "IP6", 3 };
static const pj_str_t STR_RTCP		= { "rtcp", 4 };
static const pj_str_t STR_BANDW_RR	= { "RR", 2 };
static const pj_str_t STR_BANDW_RS	= { "RS", 2 };

enum {
    COMP_RTP = 1,
    COMP_RTCP = 2
};

/*
 * Create ICE media transport.
 */
PJ_DEF(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,
				       const char *name,
				       unsigned comp_cnt,
				       const pj_ice_strans_cfg *cfg,
				       const pjmedia_ice_cb *cb,
	    			       pjmedia_transport **p_tp)
{
    return pjmedia_ice_create2(endpt, name, comp_cnt, cfg, cb, 0, p_tp);
}

/*
 * Create ICE media transport.
 */
PJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
				        const char *name,
				        unsigned comp_cnt,
				        const pj_ice_strans_cfg *cfg,
				        const pjmedia_ice_cb *cb,
					unsigned options,
	    			        pjmedia_transport **p_tp)
{
    return pjmedia_ice_create3(endpt, name, comp_cnt, cfg, cb,
                               options, NULL, p_tp);
}

/*
 * Create ICE media transport.
 */
PJ_DEF(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
				        const char *name,
				        unsigned comp_cnt,
				        const pj_ice_strans_cfg *cfg,
				        const pjmedia_ice_cb *cb,
					unsigned options,
					void *user_data,
	    			        pjmedia_transport **p_tp)
{
    pj_pool_t *pool;
    pj_ice_strans_cb ice_st_cb;
    pj_ice_strans_cfg ice_st_cfg;
    struct transport_ice *tp_ice;
    pj_status_t status;

    PJ_ASSERT_RETURN(endpt && comp_cnt && cfg && p_tp, PJ_EINVAL);

    /* Create transport instance */
    pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);
    tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice);
    tp_ice->pool = pool;
    tp_ice->af = cfg->af;
    tp_ice->options = options;
    tp_ice->comp_cnt = comp_cnt;
    pj_ansi_strcpy(tp_ice->base.name, pool->obj_name);
    tp_ice->base.op = &transport_ice_op;
    tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE;
    tp_ice->base.user_data = user_data;
    tp_ice->initial_sdp = PJ_TRUE;
    tp_ice->oa_role = ROLE_NONE;
    tp_ice->use_ice = PJ_FALSE;

    pj_memcpy(&ice_st_cfg, cfg, sizeof(pj_ice_strans_cfg));
    if (cb)
	pj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb));

    /* Assign return value first because ICE might call callback
     * in create()
     */
    *p_tp = &tp_ice->base;

    /* Configure ICE callbacks */
    pj_bzero(&ice_st_cb, sizeof(ice_st_cb));
    ice_st_cb.on_ice_complete = &ice_on_ice_complete;
    ice_st_cb.on_rx_data = &ice_on_rx_data;

    /* Configure RTP socket buffer settings, if not set */
    if (ice_st_cfg.comp[COMP_RTP-1].so_rcvbuf_size == 0) {
	ice_st_cfg.comp[COMP_RTP-1].so_rcvbuf_size = 
			    PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE;
    }
    if (ice_st_cfg.comp[COMP_RTP-1].so_sndbuf_size == 0) {
	ice_st_cfg.comp[COMP_RTP-1].so_sndbuf_size = 
			    PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE;
    }

    /* Create ICE */
    status = pj_ice_strans_create(name, &ice_st_cfg, comp_cnt, tp_ice, 
				  &ice_st_cb, &tp_ice->ice_st);
    if (status != PJ_SUCCESS) {
	pj_pool_release(pool);
	*p_tp = NULL;
	return status;
    }

    /* Done */
    return PJ_SUCCESS;
}

PJ_DEF(pj_grp_lock_t *) pjmedia_ice_get_grp_lock(pjmedia_transport *tp)
{
    PJ_ASSERT_RETURN(tp, NULL);
    return pj_ice_strans_get_grp_lock(((struct transport_ice *)tp)->ice_st);
}

/* Disable ICE when SDP from remote doesn't contain a=candidate line */
static void set_no_ice(struct transport_ice *tp_ice, const char *reason,
		       pj_status_t err)
{
    if (err != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];
	pj_strerror(err, errmsg, sizeof(errmsg));
	PJ_LOG(4,(tp_ice->base.name, 
		  "Stopping ICE, reason=%s:%s", reason, errmsg));
    } else {
	PJ_LOG(4,(tp_ice->base.name, 
		  "Stopping ICE, reason=%s", reason));
    }

    if (tp_ice->ice_st) {
	pj_ice_strans_stop_ice(tp_ice->ice_st);
    }

    tp_ice->use_ice = PJ_FALSE;
}


/* Create SDP candidate attribute */
static int print_sdp_cand_attr(char *buffer, int max_len,
			       const pj_ice_sess_cand *cand)
{
    char ipaddr[PJ_INET6_ADDRSTRLEN+2];
    int len, len2;

    len = pj_ansi_snprintf( buffer, max_len,
			    "%.*s %u UDP %u %s %u typ ",
			    (int)cand->foundation.slen,
			    cand->foundation.ptr,
			    (unsigned)cand->comp_id,
			    cand->prio,
			    pj_sockaddr_print(&cand->addr, ipaddr, 
					      sizeof(ipaddr), 0),
			    (unsigned)pj_sockaddr_get_port(&cand->addr));
    if (len < 1 || len >= max_len)
	return -1;

    switch (cand->type) {
    case PJ_ICE_CAND_TYPE_HOST:
	len2 = pj_ansi_snprintf(buffer+len, max_len-len, "host");
	break;
    case PJ_ICE_CAND_TYPE_SRFLX:
    case PJ_ICE_CAND_TYPE_RELAYED:
    case PJ_ICE_CAND_TYPE_PRFLX:
	len2 = pj_ansi_snprintf(buffer+len, max_len-len,
			        "%s raddr %s rport %d",
				pj_ice_get_cand_type_name(cand->type),
				pj_sockaddr_print(&cand->rel_addr, ipaddr,
						  sizeof(ipaddr), 0),
				(int)pj_sockaddr_get_port(&cand->rel_addr));
	break;
    default:
	pj_assert(!"Invalid candidate type");
	len2 = -1;
	break;
    }
    if (len2 < 1 || len2 >= max_len-len)
	return -1;

    return len+len2;
}


/* Get ice-ufrag and ice-pwd attribute */
static void get_ice_attr(const pjmedia_sdp_session *rem_sdp,
			 const pjmedia_sdp_media *rem_m,
			 const pjmedia_sdp_attr **p_ice_ufrag,
			 const pjmedia_sdp_attr **p_ice_pwd)
{
    pjmedia_sdp_attr *attr;

    /* Find ice-ufrag attribute in media descriptor */
    attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,
				 &STR_ICE_UFRAG, NULL);
    if (attr == NULL) {
	/* Find ice-ufrag attribute in session descriptor */
	attr = pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,
				     &STR_ICE_UFRAG, NULL);
    }
    *p_ice_ufrag = attr;

    /* Find ice-pwd attribute in media descriptor */
    attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr,
				 &STR_ICE_PWD, NULL);
    if (attr == NULL) {
	/* Find ice-pwd attribute in session descriptor */
	attr = pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,
				     &STR_ICE_PWD, NULL);
    }
    *p_ice_pwd = attr;
}


/* Encode and add "a=ice-mismatch" attribute in the SDP */
static void encode_ice_mismatch(pj_pool_t *sdp_pool,
				pjmedia_sdp_session *sdp_local,
				unsigned media_index)
{
    pjmedia_sdp_attr *attr;
    pjmedia_sdp_media *m = sdp_local->media[media_index];

    attr = PJ_POOL_ALLOC_T(sdp_pool, pjmedia_sdp_attr);
    attr->name = STR_ICE_MISMATCH;
    attr->value.slen = 0;
    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);
}


/* Encode ICE information in SDP */
static pj_status_t encode_session_in_sdp(struct transport_ice *tp_ice,
					 pj_pool_t *sdp_pool,
					 pjmedia_sdp_session *sdp_local,
					 unsigned media_index,
					 unsigned comp_cnt,
					 pj_bool_t restart_session)
{
    enum { 
	ATTR_BUF_LEN = 160,	/* Max len of a=candidate attr */
	RATTR_BUF_LEN= 160	/* Max len of a=remote-candidates attr */
    };
    pjmedia_sdp_media *m = sdp_local->media[media_index];
    pj_str_t local_ufrag, local_pwd;
    pjmedia_sdp_attr *attr;
    pj_status_t status;

    /* Must have a session */
    PJ_ASSERT_RETURN(pj_ice_strans_has_sess(tp_ice->ice_st), PJ_EBUG);

    /* Get ufrag and pwd from current session */
    pj_ice_strans_get_ufrag_pwd(tp_ice->ice_st, &local_ufrag, &local_pwd,
				NULL, NULL);

    /* The listing of candidates depends on whether ICE has completed
     * or not. When ICE has completed:
     *
     * 9.1.2.2: Existing Media Streams with ICE Completed
     *   The agent MUST include a candidate attributes for candidates
     *   matching the default destination for each component of the 
     *   media stream, and MUST NOT include any other candidates.
     *
     * When ICE has not completed, we shall include all candidates.
     *
     * Except when we have detected that remote is offering to restart
     * the session, in this case we will answer with full ICE SDP and
     * new ufrag/pwd pair.
     */
    if (!restart_session && pj_ice_strans_sess_is_complete(tp_ice->ice_st) &&
	pj_ice_strans_get_state(tp_ice->ice_st) != PJ_ICE_STRANS_STATE_FAILED)
    {
	const pj_ice_sess_check *check;
	char *attr_buf;
	pjmedia_sdp_conn *conn;
	pjmedia_sdp_attr *a_rtcp;
	pj_str_t rem_cand;
	unsigned comp;

	/* Encode ice-ufrag attribute */
	attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr,
				       &local_ufrag);
	pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	/* Encode ice-pwd attribute */
	attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, 
				       &local_pwd);
	pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	/* Prepare buffer */
	attr_buf = (char*) pj_pool_alloc(sdp_pool, ATTR_BUF_LEN);
	rem_cand.ptr = (char*) pj_pool_alloc(sdp_pool, RATTR_BUF_LEN);
	rem_cand.slen = 0;

	/* 9.1.2.2: Existing Media Streams with ICE Completed
	 *   The default destination for media (i.e., the values of 
	 *   the IP addresses and ports in the m and c line used for
	 *   that media stream) MUST be the local candidate from the
	 *   highest priority nominated pair in the valid list for each
	 *   component.
	 */
	check = pj_ice_strans_get_valid_pair(tp_ice->ice_st, 1);
	if (check == NULL) {
	    pj_assert(!"Shouldn't happen");
	    return PJ_EBUG;
	}

	/* Override connection line address and media port number */
	conn = m->conn;
	if (conn == NULL)
	    conn = sdp_local->conn;

	conn->addr.ptr = (char*) pj_pool_alloc(sdp_pool, 
					       PJ_INET6_ADDRSTRLEN);
	pj_sockaddr_print(&check->lcand->addr, conn->addr.ptr, 
			  PJ_INET6_ADDRSTRLEN, 0);
	conn->addr.slen = pj_ansi_strlen(conn->addr.ptr);
	m->desc.port = pj_sockaddr_get_port(&check->lcand->addr);

	/* Override address RTCP attribute if it's present */
	if (comp_cnt == 2 &&
	    (check = pj_ice_strans_get_valid_pair(tp_ice->ice_st, 
						  COMP_RTCP)) != NULL &&
	    (a_rtcp = pjmedia_sdp_attr_find(m->attr_count, m->attr, 
					    &STR_RTCP, 0)) != NULL) 
	{
	    pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a_rtcp);

	    a_rtcp = pjmedia_sdp_attr_create_rtcp(sdp_pool, 
						  &check->lcand->addr);
	    if (a_rtcp)
		pjmedia_sdp_attr_add(&m->attr_count, m->attr, a_rtcp);
	}

	/* Encode only candidates matching the default destination 
	 * for each component 
	 */
	for (comp=0; comp < comp_cnt; ++comp) {
	    int len;
	    pj_str_t value;

	    /* Get valid pair for this component */
	    check = pj_ice_strans_get_valid_pair(tp_ice->ice_st, comp+1);
	    if (check == NULL)
		continue;

	    /* Print and add local candidate in the pair */
	    value.ptr = attr_buf;
	    value.slen = print_sdp_cand_attr(attr_buf, ATTR_BUF_LEN, 
					     check->lcand);
	    if (value.slen < 0) {
		pj_assert(!"Not enough attr_buf to print candidate");
		return PJ_EBUG;
	    }

	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_CANDIDATE.ptr,
					   &value);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	    /* Append to a=remote-candidates attribute */
	    if (pj_ice_strans_get_role(tp_ice->ice_st) == 
				    PJ_ICE_SESS_ROLE_CONTROLLING) 
	    {
		char rem_addr[PJ_INET6_ADDRSTRLEN];

		pj_sockaddr_print(&check->rcand->addr, rem_addr, 
				  sizeof(rem_addr), 0);
		len = pj_ansi_snprintf(
			   rem_cand.ptr + rem_cand.slen,
			   RATTR_BUF_LEN - rem_cand.slen,
			   "%s%u %s %u", 
			   (rem_cand.slen==0? "" : " "),
			   comp+1, rem_addr,
			   pj_sockaddr_get_port(&check->rcand->addr)
			   );
		if (len < 1 || len >= RATTR_BUF_LEN - rem_cand.slen) {
		    pj_assert(!"Not enough buffer to print "
			       "remote-candidates");
		    return PJ_EBUG;
		}

		rem_cand.slen += len;
	    }
	}

	/* 9.1.2.2: Existing Media Streams with ICE Completed
	 *   In addition, if the agent is controlling, it MUST include
	 *   the a=remote-candidates attribute for each media stream 
	 *   whose check list is in the Completed state.  The attribute
	 *   contains the remote candidates from the highest priority 
	 *   nominated pair in the valid list for each component of that
	 *   media stream.
	 */
	if (pj_ice_strans_get_role(tp_ice->ice_st) == 
				    PJ_ICE_SESS_ROLE_CONTROLLING) 
	{
	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_REM_CAND.ptr, 
					   &rem_cand);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);
	}

    } else if (pj_ice_strans_has_sess(tp_ice->ice_st) &&
	       pj_ice_strans_get_state(tp_ice->ice_st) !=
		        PJ_ICE_STRANS_STATE_FAILED)
    {
	/* Encode all candidates to SDP media */
	char *attr_buf;
	unsigned comp;

	/* If ICE is not restarted, encode current ICE ufrag/pwd.
	 * Otherwise generate new one.
	 */
	if (!restart_session) {
	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr,
					   &local_ufrag);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, 
					   &local_pwd);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	} else {
	    pj_str_t str;

	    str.slen = PJ_ICE_UFRAG_LEN;
	    str.ptr = (char*) pj_pool_alloc(sdp_pool, str.slen);
	    pj_create_random_string(str.ptr, str.slen);
	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_UFRAG.ptr, &str);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);

	    str.ptr = (char*) pj_pool_alloc(sdp_pool, str.slen);
	    pj_create_random_string(str.ptr, str.slen);
	    attr = pjmedia_sdp_attr_create(sdp_pool, STR_ICE_PWD.ptr, &str);
	    pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);
	}

	/* Create buffer to encode candidates as SDP attribute */
	attr_buf = (char*) pj_pool_alloc(sdp_pool, ATTR_BUF_LEN);

	for (comp=0; comp < comp_cnt; ++comp) {
	    unsigned cand_cnt;
	    pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];
	    unsigned i;

	    cand_cnt = PJ_ARRAY_SIZE(cand);
	    status = pj_ice_strans_enum_cands(tp_ice->ice_st, comp+1,
					      &cand_cnt, cand);
	    if (status != PJ_SUCCESS)
		return status;

	    for (i=0; i<cand_cnt; ++i) {
		pj_str_t value;

		value.slen = print_sdp_cand_attr(attr_buf, ATTR_BUF_LEN, 
						 &cand[i]);
		if (value.slen < 0) {
		    pj_assert(!"Not enough attr_buf to print candidate");
		    return PJ_EBUG;
		}

		value.ptr = attr_buf;
		attr = pjmedia_sdp_attr_create(sdp_pool, 
					       STR_CANDIDATE.ptr,
					       &value);
		pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr);
	    }
	}
    } else {
	/* ICE has failed, application should have terminated this call */
    }

    /* Removing a=rtcp line when there is only one component. */
    if (comp_cnt == 1) {
	attr = pjmedia_sdp_attr_find(m->attr_count, m->attr, &STR_RTCP, NULL);
	if (attr)
	    pjmedia_sdp_attr_remove(&m->attr_count, m->attr, attr);
        /* If RTCP is not in use, we MUST send b=RS:0 and b=RR:0. */
        pj_assert(m->bandw_count + 2 <= PJ_ARRAY_SIZE(m->bandw));
        if (m->bandw_count + 2 <= PJ_ARRAY_SIZE(m->bandw)) {
            m->bandw[m->bandw_count] = PJ_POOL_ZALLOC_T(sdp_pool,
                                                        pjmedia_sdp_bandw);
            pj_memcpy(&m->bandw[m->bandw_count]->modifier, &STR_BANDW_RS,
                      sizeof(pj_str_t));
            m->bandw_count++;
            m->bandw[m->bandw_count] = PJ_POOL_ZALLOC_T(sdp_pool,
                                                        pjmedia_sdp_bandw);
            pj_memcpy(&m->bandw[m->bandw_count]->modifier, &STR_BANDW_RR,
                      sizeof(pj_str_t));
            m->bandw_count++;
        }
    }
    

    return PJ_SUCCESS;
}


/* Parse a=candidate line */
static pj_status_t parse_cand(const char *obj_name,
			      pj_pool_t *pool,
			      const pj_str_t *orig_input,
			      pj_ice_sess_cand *cand)
{
    pj_str_t input;
    char *token, *host;
    int af;
    pj_str_t s;
    pj_status_t status = PJNATH_EICEINCANDSDP;

    pj_bzero(cand, sizeof(*cand));
    pj_strdup_with_null(pool, &input, orig_input);

    PJ_UNUSED_ARG(obj_name);

    /* Foundation */
    token = strtok(input.ptr, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE foundation in candidate"));
	goto on_return;
    }
    pj_strdup2(pool, &cand->foundation, token);

    /* Component ID */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE component ID in candidate"));
	goto on_return;
    }
    cand->comp_id = (pj_uint8_t) atoi(token);

    /* Transport */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE transport in candidate"));
	goto on_return;
    }
    if (pj_ansi_stricmp(token, "UDP") != 0) {
	TRACE__((obj_name, 
		 "Expecting ICE UDP transport only in candidate"));
	goto on_return;
    }

    /* Priority */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE priority in candidate"));
	goto on_return;
    }
    cand->prio = atoi(token);

    /* Host */
    host = strtok(NULL, " ");
    if (!host) {
	TRACE__((obj_name, "Expecting ICE host in candidate"));
	goto on_return;
    }
    /* Detect address family */
    if (pj_ansi_strchr(host, ':'))
	af = pj_AF_INET6();
    else
	af = pj_AF_INET();
    /* Assign address */
    if (pj_sockaddr_init(af, &cand->addr, pj_cstr(&s, host), 0)) {
	TRACE__((obj_name, "Invalid ICE candidate address"));
	goto on_return;
    }

    /* Port */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE port number in candidate"));
	goto on_return;
    }
    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)atoi(token));

    /* typ */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
	goto on_return;
    }
    if (pj_ansi_stricmp(token, "typ") != 0) {
	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
	goto on_return;
    }

    /* candidate type */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE candidate type in candidate"));
	goto on_return;
    }

    if (pj_ansi_stricmp(token, "host") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_HOST;

    } else if (pj_ansi_stricmp(token, "srflx") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_SRFLX;

    } else if (pj_ansi_stricmp(token, "relay") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_RELAYED;

    } else if (pj_ansi_stricmp(token, "prflx") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_PRFLX;

    } else {
	PJ_LOG(5,(obj_name, "Invalid ICE candidate type %s in candidate", 
		  token));
	goto on_return;
    }

    status = PJ_SUCCESS;

on_return:
    return status;
}


/* Create initial SDP offer */
static pj_status_t create_initial_offer(struct transport_ice *tp_ice,
					pj_pool_t *sdp_pool,
					pjmedia_sdp_session *loc_sdp,
					unsigned media_index)
{
    pj_status_t status;

    /* Encode ICE in SDP */
    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, 
				   tp_ice->comp_cnt, PJ_FALSE);
    if (status != PJ_SUCCESS) {
	set_no_ice(tp_ice, "Error encoding SDP answer", status);
	return status;
    }

    return PJ_SUCCESS;
}


/* Verify incoming offer */
static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
				  pj_pool_t *tmp_pool,
				  const pjmedia_sdp_session *rem_sdp,
				  unsigned media_index,
				  pj_ice_sess_role current_ice_role,
				  struct sdp_state *sdp_state)
{
    const pjmedia_sdp_media *rem_m;
    const pjmedia_sdp_attr *ufrag_attr, *pwd_attr;
    const pjmedia_sdp_conn *rem_conn;
    pj_bool_t comp1_found=PJ_FALSE, comp2_found=PJ_FALSE, has_rtcp=PJ_FALSE;
    pj_sockaddr rem_conn_addr, rtcp_addr;
    unsigned i;
    pj_status_t status;

    rem_m = rem_sdp->media[media_index];

    /* Get the "ice-ufrag" and "ice-pwd" attributes */
    get_ice_attr(rem_sdp, rem_m, &ufrag_attr, &pwd_attr);

    /* If "ice-ufrag" or "ice-pwd" are not found, disable ICE */
    if (ufrag_attr==NULL || pwd_attr==NULL) {
	sdp_state->match_comp_cnt = 0;
	return PJ_SUCCESS;
    }

    /* Verify that default target for each component matches one of the 
     * candidate for the component. Otherwise stop ICE with ICE ice_mismatch 
     * error.
     */

    /* Component 1 is the c= line */
    rem_conn = rem_m->conn;
    if (rem_conn == NULL)
	rem_conn = rem_sdp->conn;
    if (!rem_conn)
	return PJMEDIA_SDP_EMISSINGCONN;

    /* Verify address family matches */
    if ((tp_ice->af==pj_AF_INET() && 
	 pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) ||
	(tp_ice->af==pj_AF_INET6() && 
	 pj_strcmp(&rem_conn->addr_type, &STR_IP6)!=0))
    {
	return PJMEDIA_SDP_ETPORTNOTEQUAL;
    }

    /* Assign remote connection address */
    status = pj_sockaddr_init(tp_ice->af, &rem_conn_addr, &rem_conn->addr,
			      (pj_uint16_t)rem_m->desc.port);
    if (status != PJ_SUCCESS)
	return status;

    if (tp_ice->comp_cnt > 1) {
	const pjmedia_sdp_attr *attr;

	/* Get default RTCP candidate from a=rtcp line, if present, otherwise
	 * calculate default RTCP candidate from default RTP target.
	 */
	attr = pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr, 
				     &STR_RTCP, NULL);
	has_rtcp = (attr != NULL);

	if (attr) {
	    pjmedia_sdp_rtcp_attr rtcp_attr;

	    status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp_attr);
	    if (status != PJ_SUCCESS) {
		/* Error parsing a=rtcp attribute */
		return status;
	    }
    	
	    if (rtcp_attr.addr.slen) {
		/* Verify address family matches */
		if ((tp_ice->af==pj_AF_INET() && 
		     pj_strcmp(&rtcp_attr.addr_type, &STR_IP4)!=0) ||
		    (tp_ice->af==pj_AF_INET6() && 
		     pj_strcmp(&rtcp_attr.addr_type, &STR_IP6)!=0))
		{
		    return PJMEDIA_SDP_ETPORTNOTEQUAL;
		}

		/* Assign RTCP address */
		status = pj_sockaddr_init(tp_ice->af, &rtcp_addr,
					  &rtcp_attr.addr,
					  (pj_uint16_t)rtcp_attr.port);
		if (status != PJ_SUCCESS) {
		    return PJMEDIA_SDP_EINRTCP;
		}
	    } else {
		/* Assign RTCP address */
		status = pj_sockaddr_init(tp_ice->af, &rtcp_addr, 
					  NULL, 
					  (pj_uint16_t)rtcp_attr.port);
		if (status != PJ_SUCCESS) {
		    return PJMEDIA_SDP_EINRTCP;
		}
		pj_sockaddr_copy_addr(&rtcp_addr, &rem_conn_addr);
	    }
	} else {
	    unsigned rtcp_port;
    	
	    rtcp_port = pj_sockaddr_get_port(&rem_conn_addr) + 1;
	    pj_sockaddr_cp(&rtcp_addr, &rem_conn_addr);
	    pj_sockaddr_set_port(&rtcp_addr, (pj_uint16_t)rtcp_port);
	}
    }

    /* Find the default addresses in a=candidate attributes. 
     */
    for (i=0; i<rem_m->attr_count; ++i) {
	pj_ice_sess_cand cand;

	if (pj_strcmp(&rem_m->attr[i]->name, &STR_CANDIDATE)!=0)
	    continue;

	status = parse_cand(tp_ice->base.name, tmp_pool, 
			    &rem_m->attr[i]->value, &cand);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(4,(tp_ice->base.name, 
		      "Error in parsing SDP candidate attribute '%.*s', "
		      "candidate is ignored",
		      (int)rem_m->attr[i]->value.slen, 
		      rem_m->attr[i]->value.ptr));
	    continue;
	}

	if (!comp1_found && cand.comp_id==COMP_RTP &&
	    pj_sockaddr_cmp(&rem_conn_addr, &cand.addr)==0) 
	{
	    comp1_found = PJ_TRUE;
	} else if (!comp2_found && cand.comp_id==COMP_RTCP &&
		    pj_sockaddr_cmp(&rtcp_addr, &cand.addr)==0) 
	{
	    comp2_found = PJ_TRUE;
	}

	if (cand.comp_id == COMP_RTCP)
	    has_rtcp = PJ_TRUE;

	if (comp1_found && (comp2_found || tp_ice->comp_cnt==1))
	    break;
    }

    /* Check matched component count and ice_mismatch */
    if (comp1_found && (tp_ice->comp_cnt==1 || !has_rtcp)) {
	sdp_state->match_comp_cnt = 1;
	sdp_state->ice_mismatch = PJ_FALSE;
    } else if (comp1_found && comp2_found) {
	sdp_state->match_comp_cnt = 2;
	sdp_state->ice_mismatch = PJ_FALSE;
    } else {
	sdp_state->match_comp_cnt = (tp_ice->comp_cnt > 1 && has_rtcp)? 2 : 1;
	sdp_state->ice_mismatch = PJ_TRUE;
    }


    /* Detect remote restarting session */
    if (pj_ice_strans_has_sess(tp_ice->ice_st) &&
	(pj_ice_strans_sess_is_running(tp_ice->ice_st) ||
	 pj_ice_strans_sess_is_complete(tp_ice->ice_st))) 
    {
	pj_str_t rem_run_ufrag, rem_run_pwd;
	pj_ice_strans_get_ufrag_pwd(tp_ice->ice_st, NULL, NULL,
				    &rem_run_ufrag, &rem_run_pwd);
	if (pj_strcmp(&ufrag_attr->value, &rem_run_ufrag) ||
	    pj_strcmp(&pwd_attr->value, &rem_run_pwd))
	{
	    /* Remote offers to restart ICE */
	    sdp_state->ice_restart = PJ_TRUE;
	} else {
	    sdp_state->ice_restart = PJ_FALSE;
	}
    } else {
	sdp_state->ice_restart = PJ_FALSE;
    }

    /* Detect our role */
    if (current_ice_role==PJ_ICE_SESS_ROLE_CONTROLLING) {
	sdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLING;
    } else {
	if (pjmedia_sdp_attr_find(rem_sdp->attr_count, rem_sdp->attr,
				  &STR_ICE_LITE, NULL) != NULL)
	{
	    /* Remote is ICE Lite */
	    sdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLING;
	} else {
	    sdp_state->local_role = PJ_ICE_SESS_ROLE_CONTROLLED;
	}
    }

    PJ_LOG(4,(tp_ice->base.name, 
	      "Processing SDP: support ICE=%u, common comp_cnt=%u, "
	      "ice_mismatch=%u, ice_restart=%u, local_role=%s",
	      (sdp_state->match_comp_cnt != 0), 
	      sdp_state->match_comp_cnt, 
	      sdp_state->ice_mismatch, 
	      sdp_state->ice_restart,
	      pj_ice_sess_role_name(sdp_state->local_role)));

    return PJ_SUCCESS;

}


/* Verify incoming offer and create initial answer */
static pj_status_t create_initial_answer(struct transport_ice *tp_ice,
					 pj_pool_t *sdp_pool,
					 pjmedia_sdp_session *loc_sdp,
					 const pjmedia_sdp_session *rem_sdp,
					 unsigned media_index)
{
    const pjmedia_sdp_media *rem_m = rem_sdp->media[media_index];
    pj_status_t status;

    /* Check if media is removed (just in case) */
    if (rem_m->desc.port == 0) {
	return PJ_SUCCESS;
    }

    /* Verify the offer */
    status = verify_ice_sdp(tp_ice, sdp_pool, rem_sdp, media_index, 
			    PJ_ICE_SESS_ROLE_CONTROLLED, 
			    &tp_ice->rem_offer_state);
    if (status != PJ_SUCCESS) {
	set_no_ice(tp_ice, "Invalid SDP offer", status);
	return status;
    }

    /* Does remote support ICE? */
    if (tp_ice->rem_offer_state.match_comp_cnt==0) {
	set_no_ice(tp_ice, "No ICE found in SDP offer", PJ_SUCCESS);
	return PJ_SUCCESS;
    }

    /* ICE ice_mismatch? */
    if (tp_ice->rem_offer_state.ice_mismatch) {
	set_no_ice(tp_ice, "ICE ice_mismatch in remote offer", PJ_SUCCESS);
	encode_ice_mismatch(sdp_pool, loc_sdp, media_index);
	return PJ_SUCCESS;
    }

    /* Encode ICE in SDP */
    status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index, 
				   tp_ice->rem_offer_state.match_comp_cnt,
				   PJ_FALSE);
    if (status != PJ_SUCCESS) {
	set_no_ice(tp_ice, "Error encoding SDP answer", status);
	return status;
    }

    return PJ_SUCCESS;
}


/* Create subsequent SDP offer */
static pj_status_t create_subsequent_offer(struct transport_ice *tp_ice,
					   pj_pool_t *sdp_pool,
					   pjmedia_sdp_session *loc_sdp,
					   unsigned media_index)
{
    unsigned comp_cnt;

    if (pj_ice_strans_has_sess(tp_ice->ice_st) == PJ_FALSE) {
	/* We don't have ICE */
	return PJ_SUCCESS;
    }

    comp_cnt = pj_ice_strans_get_running_comp_cnt(tp_ice->ice_st);
    return encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,
				 comp_cnt, PJ_FALSE);
}


/* Create subsequent SDP answer */
static pj_status_t create_subsequent_answer(struct transport_ice *tp_ice,
					    pj_pool_t *sdp_pool,
					    pjmedia_sdp_session *loc_sdp,
					    const pjmedia_sdp_session *rem_sdp,
					    unsigned media_index)
{
    pj_status_t status;

    /* We have a session */
    status = verify_ice_sdp(tp_ice, sdp_pool, rem_sdp, media_index, 
			    PJ_ICE_SESS_ROLE_CONTROLLED, 
			    &tp_ice->rem_offer_state);
    if (status != PJ_SUCCESS) {
	/* Something wrong with the offer */
	return status;
    }

    if (pj_ice_strans_has_sess(tp_ice->ice_st)) {
	/*
	 * Received subsequent offer while we have ICE active.
	 */

	if (tp_ice->rem_offer_state.match_comp_cnt == 0) {
	    /* Remote no longer offers ICE */
	    return PJ_SUCCESS;
	}

	if (tp_ice->rem_offer_state.ice_mismatch) {
	    encode_ice_mismatch(sdp_pool, loc_sdp, media_index);
	    return PJ_SUCCESS;
	}

	status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,
				       tp_ice->rem_offer_state.match_comp_cnt,
				       tp_ice->rem_offer_state.ice_restart);
	if (status != PJ_SUCCESS)
	    return status;

	/* Done */

    } else {
	/*
	 * Received subsequent offer while we DON'T have ICE active.
	 */

	if (tp_ice->rem_offer_state.match_comp_cnt == 0) {
	    /* Remote does not support ICE */
	    return PJ_SUCCESS;
	}

	if (tp_ice->rem_offer_state.ice_mismatch) {
	    encode_ice_mismatch(sdp_pool, loc_sdp, media_index);
	    return PJ_SUCCESS;
	}

	/* Looks like now remote is offering ICE, so we need to create
	 * ICE session now.
	 */
	status = pj_ice_strans_init_ice(tp_ice->ice_st, 
					PJ_ICE_SESS_ROLE_CONTROLLED,
					NULL, NULL);
	if (status != PJ_SUCCESS) {
	    /* Fail to create new ICE session */
	    return status;
	}

	status = encode_session_in_sdp(tp_ice, sdp_pool, loc_sdp, media_index,
				       tp_ice->rem_offer_state.match_comp_cnt,
				       tp_ice->rem_offer_state.ice_restart);
	if (status != PJ_SUCCESS)
	    return status;

	/* Done */
    }

    return PJ_SUCCESS;
}


/*
 * For both UAC and UAS, pass in the SDP before sending it to remote.
 * This will add ICE attributes to the SDP.
 */
static pj_status_t transport_media_create(pjmedia_transport *tp,
				          pj_pool_t *sdp_pool,
					  unsigned options,
					  const pjmedia_sdp_session *rem_sdp,
					  unsigned media_index)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    pj_ice_sess_role ice_role;
    pj_status_t status;

    PJ_UNUSED_ARG(media_index);
    PJ_UNUSED_ARG(sdp_pool);

    tp_ice->media_option = options;
    tp_ice->oa_role = ROLE_NONE;
    tp_ice->initial_sdp = PJ_TRUE;

    /* Init ICE, the initial role is set now based on availability of
     * rem_sdp, but it will be checked again later.
     */
    ice_role = (rem_sdp==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING : 
				PJ_ICE_SESS_ROLE_CONTROLLED);
    status = pj_ice_strans_init_ice(tp_ice->ice_st, ice_role, NULL, NULL);

    /* Done */
    return status;
}


static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
				        pj_pool_t *sdp_pool,
				        pjmedia_sdp_session *sdp_local,
				        const pjmedia_sdp_session *rem_sdp,
				        unsigned media_index)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    pj_status_t status;

    /* Validate media transport */
    /* This transport only support RTP/AVP transport, unless if
     * transport checking is disabled
     */
    if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) {
	pjmedia_sdp_media *loc_m, *rem_m;

	rem_m = rem_sdp? rem_sdp->media[media_index] : NULL;
	loc_m = sdp_local->media[media_index];

	if (pj_stricmp(&loc_m->desc.transport, &STR_RTP_AVP) ||
	   (rem_m && pj_stricmp(&rem_m->desc.transport, &STR_RTP_AVP)))
	{
	    pjmedia_sdp_media_deactivate(sdp_pool, loc_m);
	    return PJMEDIA_SDP_EINPROTO;
	}
    }

    if (tp_ice->initial_sdp) {
	if (rem_sdp) {
	    status = create_initial_answer(tp_ice, sdp_pool, sdp_local, 
					   rem_sdp, media_index);
	} else {
	    status = create_initial_offer(tp_ice, sdp_pool, sdp_local,
					  media_index);
	}
    } else {
	if (rem_sdp) {
	    status = create_subsequent_answer(tp_ice, sdp_pool, sdp_local,
					      rem_sdp, media_index);
	} else {
	    status = create_subsequent_offer(tp_ice, sdp_pool, sdp_local,
					     media_index);
	}
    }

    if (status==PJ_SUCCESS) {
	if (rem_sdp)
	    tp_ice->oa_role = ROLE_ANSWERER;
	else
	    tp_ice->oa_role = ROLE_OFFERER;
    }

    return status;
}


/* Start ICE session with the specified remote SDP */
static pj_status_t start_ice(struct transport_ice *tp_ice,
			     pj_pool_t *tmp_pool,
			     const pjmedia_sdp_session *rem_sdp,
			     unsigned media_index)
{
    pjmedia_sdp_media *rem_m = rem_sdp->media[media_index];
    const pjmedia_sdp_attr *ufrag_attr, *pwd_attr;
    pj_ice_sess_cand *cand;
    unsigned i, cand_cnt;
    pj_status_t status;

    get_ice_attr(rem_sdp, rem_m, &ufrag_attr, &pwd_attr);

    /* Allocate candidate array */
    cand = (pj_ice_sess_cand*)
	   pj_pool_calloc(tmp_pool, PJ_ICE_MAX_CAND, 
			  sizeof(pj_ice_sess_cand));

    /* Get all candidates in the media */
    cand_cnt = 0;
    for (i=0; i<rem_m->attr_count && cand_cnt < PJ_ICE_MAX_CAND; ++i) {
	pjmedia_sdp_attr *attr;

	attr = rem_m->attr[i];

	if (pj_strcmp(&attr->name, &STR_CANDIDATE)!=0)
	    continue;

	/* Parse candidate */
	status = parse_cand(tp_ice->base.name, tmp_pool, &attr->value, 
			    &cand[cand_cnt]);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(4,(tp_ice->base.name, 
		      "Error in parsing SDP candidate attribute '%.*s', "
		      "candidate is ignored",
		      (int)attr->value.slen, attr->value.ptr));
	    continue;
	}

	cand_cnt++;
    }

    /* Start ICE */
    return pj_ice_strans_start_ice(tp_ice->ice_st, &ufrag_attr->value, 
				   &pwd_attr->value, cand_cnt, cand);
}


/*
 * Start ICE checks when both offer and answer have been negotiated
 * by SDP negotiator.
 */
static pj_status_t transport_media_start(pjmedia_transport *tp,
				         pj_pool_t *tmp_pool,
				         const pjmedia_sdp_session *sdp_local,
				         const pjmedia_sdp_session *rem_sdp,
				         unsigned media_index)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    pjmedia_sdp_media *rem_m;
    enum oa_role current_oa_role;
    pj_bool_t initial_oa;
    pj_status_t status;

    PJ_ASSERT_RETURN(tp && tmp_pool && rem_sdp, PJ_EINVAL);
    PJ_ASSERT_RETURN(media_index < rem_sdp->media_count, PJ_EINVAL);

    rem_m = rem_sdp->media[media_index];

    initial_oa = tp_ice->initial_sdp;
    current_oa_role = tp_ice->oa_role;

    /* SDP has been negotiated */
    tp_ice->initial_sdp = PJ_FALSE;
    tp_ice->oa_role = ROLE_NONE;

    /* Nothing to do if we don't have ICE session */
    if (pj_ice_strans_has_sess(tp_ice->ice_st) == PJ_FALSE) {
	return PJ_SUCCESS;
    }

    /* Special case for Session Timer. The re-INVITE for session refresh
     * doesn't call transport_encode_sdp(), causing current_oa_role to
     * be set to ROLE_NONE. This is a workaround.
     */
    if (current_oa_role == ROLE_NONE) {
	current_oa_role = ROLE_OFFERER;
    }

    /* Processing depends on the offer/answer role */
    if (current_oa_role == ROLE_OFFERER) {
	/*
	 * We are offerer. So this will be the first time we see the
	 * remote's SDP.
	 */
	struct sdp_state answer_state;

	/* Verify the answer */
	status = verify_ice_sdp(tp_ice, tmp_pool, rem_sdp, media_index, 
				PJ_ICE_SESS_ROLE_CONTROLLING, &answer_state);
	if (status != PJ_SUCCESS) {
	    /* Something wrong in the SDP answer */
	    set_no_ice(tp_ice, "Invalid remote SDP answer", status);
	    return status;
	}

	/* Does it have ICE? */
	if (answer_state.match_comp_cnt == 0) {
	    /* Remote doesn't support ICE */
	    set_no_ice(tp_ice, "Remote answer doesn't support ICE", 
		       PJ_SUCCESS);
	    return PJ_SUCCESS;
	}

	/* Check if remote has reported ice-mismatch */
	if (pjmedia_sdp_attr_find(rem_m->attr_count, rem_m->attr, 
				  &STR_ICE_MISMATCH, NULL) != NULL)
	{
	    /* Remote has reported ice-mismatch */
	    set_no_ice(tp_ice, 
		       "Remote answer contains 'ice-mismatch' attribute", 
		       PJ_SUCCESS);
	    return PJ_SUCCESS;
	}

	/* Check if remote has indicated a restart */
	if (answer_state.ice_restart) {
	    PJ_LOG(2,(tp_ice->base.name, 
		      "Warning: remote has signalled ICE restart in SDP "
		      "answer which is disallowed. Remote ICE negotiation"
		      " may fail."));
	}

	/* Check if the answer itself is mismatched */
	if (answer_state.ice_mismatch) {
	    /* This happens either when a B2BUA modified remote answer but
	     * strangely didn't modify our offer, or remote is not capable
	     * of detecting mismatch in our offer (it didn't put 
	     * 'ice-mismatch' attribute in the answer).
	     */
	    PJ_LOG(2,(tp_ice->base.name, 
		      "Warning: remote answer mismatch, but it does not "
		      "reject our offer with 'ice-mismatch'. ICE negotiation "
		      "may fail"));
	}

	/* Do nothing if ICE is complete or running */
	if (pj_ice_strans_sess_is_running(tp_ice->ice_st)) {
	    PJ_LOG(4,(tp_ice->base.name,
		      "Ignored offer/answer because ICE is running"));
	    return PJ_SUCCESS;
	}

	if (pj_ice_strans_sess_is_complete(tp_ice->ice_st)) {
	    PJ_LOG(4,(tp_ice->base.name, "ICE session unchanged"));
	    return PJ_SUCCESS;
	}

	/* Start ICE */

    } else {
	/*
	 * We are answerer. We've seen and negotiated remote's SDP
	 * before, and the result is in "rem_offer_state".
	 */
	const pjmedia_sdp_attr *ufrag_attr, *pwd_attr;

	/* Check for ICE in remote offer */
	if (tp_ice->rem_offer_state.match_comp_cnt == 0) {
	    /* No ICE attribute present */
	    set_no_ice(tp_ice, "Remote no longer offers ICE",
		       PJ_SUCCESS);
	    return PJ_SUCCESS;
	}

	/* Check for ICE ice_mismatch condition in the offer */
	if (tp_ice->rem_offer_state.ice_mismatch) {
	    set_no_ice(tp_ice, "Remote offer mismatch: ", 
		       PJNATH_EICEMISMATCH);
	    return PJ_SUCCESS;
	}

	/* If ICE is complete and remote doesn't request restart,
	 * then leave the session as is.
	 */
	if (!initial_oa && tp_ice->rem_offer_state.ice_restart == PJ_FALSE) {
	    /* Remote has not requested ICE restart, so session is
	     * unchanged.
	     */
	    PJ_LOG(4,(tp_ice->base.name, "ICE session unchanged"));
	    return PJ_SUCCESS;
	}

	/* Either remote has requested ICE restart or this is our
	 * first answer. 
	 */

	/* Stop ICE */
	if (!initial_oa) {
	    set_no_ice(tp_ice, "restarting by remote request..", PJ_SUCCESS);

	    /* We have put new ICE ufrag and pwd in the answer. Now
	     * create a new ICE session with that ufrag/pwd pair.
	     */
	    get_ice_attr(sdp_local, sdp_local->media[media_index], 
			 &ufrag_attr, &pwd_attr);
	    status = pj_ice_strans_init_ice(tp_ice->ice_st, 
					    tp_ice->rem_offer_state.local_role,
					    &ufrag_attr->value, 
					    &pwd_attr->value);
	    if (status != PJ_SUCCESS) {
		PJ_LOG(1,(tp_ice->base.name, 
			  "ICE re-initialization failed (status=%d)!",
			  status));
		return status;
	    }
	}

	/* Ticket #977: Update role if turns out we're supposed to be the 
	 * Controlling agent (e.g. when talking to ice-lite peer). 
	 */
	if (tp_ice->rem_offer_state.local_role==PJ_ICE_SESS_ROLE_CONTROLLING &&
	    pj_ice_strans_has_sess(tp_ice->ice_st)) 
	{
	    pj_ice_strans_change_role(tp_ice->ice_st, 
				      PJ_ICE_SESS_ROLE_CONTROLLING);
	}


	/* start ICE */
    }

    /* Now start ICE */
    status = start_ice(tp_ice, tmp_pool, rem_sdp, media_index);
    if (status != PJ_SUCCESS) {
	PJ_LOG(1,(tp_ice->base.name, 
		  "ICE restart failed (status=%d)!",
		  status));
	return status;
    }

    /* Done */
    tp_ice->use_ice = PJ_TRUE;

    return PJ_SUCCESS;
}


static pj_status_t transport_media_stop(pjmedia_transport *tp)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    
    set_no_ice(tp_ice, "media stop requested", PJ_SUCCESS);

    return PJ_SUCCESS;
}


static pj_status_t transport_get_info(pjmedia_transport *tp,
				      pjmedia_transport_info *info)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    pj_ice_sess_cand cand;
    pj_status_t status;

    pj_bzero(&info->sock_info, sizeof(info->sock_info));
    info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;

    /* Get RTP default address */
    status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 1, &cand);
    if (status != PJ_SUCCESS)
	return status;

    pj_sockaddr_cp(&info->sock_info.rtp_addr_name, &cand.addr);

    /* Get RTCP default address */
    if (tp_ice->comp_cnt > 1) {
	status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 2, &cand);
	if (status != PJ_SUCCESS)
	    return status;

	pj_sockaddr_cp(&info->sock_info.rtcp_addr_name, &cand.addr);
    }

    /* Set remote address originating RTP & RTCP if this transport has 
     * ICE activated or received any packets.
     */
    if (tp_ice->use_ice || tp_ice->rtp_src_cnt) {
	info->src_rtp_name  = tp_ice->rtp_src_addr;
    }
    if (tp_ice->use_ice || tp_ice->rtcp_src_cnt) {
	info->src_rtcp_name = tp_ice->rtcp_src_addr;
    }

    /* Fill up transport specific info */
    if (info->specific_info_cnt < PJ_ARRAY_SIZE(info->spc_info)) {
	pjmedia_transport_specific_info *tsi;
	pjmedia_ice_transport_info *ii;
	unsigned i;

	pj_assert(sizeof(*ii) <= sizeof(tsi->buffer));
	tsi = &info->spc_info[info->specific_info_cnt++];
	tsi->type = PJMEDIA_TRANSPORT_TYPE_ICE;
	tsi->cbsize = sizeof(*ii);

	ii = (pjmedia_ice_transport_info*) tsi->buffer;
	pj_bzero(ii, sizeof(*ii));

	ii->active = tp_ice->use_ice;

	if (pj_ice_strans_has_sess(tp_ice->ice_st))
	    ii->role = pj_ice_strans_get_role(tp_ice->ice_st);
	else
	    ii->role = PJ_ICE_SESS_ROLE_UNKNOWN;
	ii->sess_state = pj_ice_strans_get_state(tp_ice->ice_st);
	ii->comp_cnt = pj_ice_strans_get_running_comp_cnt(tp_ice->ice_st);
	
	for (i=1; i<=ii->comp_cnt && i<=PJ_ARRAY_SIZE(ii->comp); ++i) {
	    const pj_ice_sess_check *chk;

	    chk = pj_ice_strans_get_valid_pair(tp_ice->ice_st, i);
	    if (chk) {
		ii->comp[i-1].lcand_type = chk->lcand->type;
		pj_sockaddr_cp(&ii->comp[i-1].lcand_addr,
		               &chk->lcand->addr);
		ii->comp[i-1].rcand_type = chk->rcand->type;
		pj_sockaddr_cp(&ii->comp[i-1].rcand_addr,
		               &chk->rcand->addr);
	    }
	}
    }

    return PJ_SUCCESS;
}


static pj_status_t transport_attach  (pjmedia_transport *tp,
				      void *stream,
				      const pj_sockaddr_t *rem_addr,
				      const pj_sockaddr_t *rem_rtcp,
				      unsigned addr_len,
				      void (*rtp_cb)(void*,
						     void*,
						     pj_ssize_t),
				      void (*rtcp_cb)(void*,
						      void*,
						      pj_ssize_t))
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;

    tp_ice->stream = stream;
    tp_ice->rtp_cb = rtp_cb;
    tp_ice->rtcp_cb = rtcp_cb;

    pj_memcpy(&tp_ice->remote_rtp, rem_addr, addr_len);
    pj_memcpy(&tp_ice->remote_rtcp, rem_rtcp, addr_len);
    tp_ice->addr_len = addr_len;

    /* Init source RTP & RTCP addresses and counter */
    tp_ice->rtp_src_addr = tp_ice->remote_rtp;
    tp_ice->rtcp_src_addr = tp_ice->remote_rtcp;
    tp_ice->rtp_src_cnt = 0;
    tp_ice->rtcp_src_cnt = 0;

    return PJ_SUCCESS;
}


static void transport_detach(pjmedia_transport *tp,
			     void *strm)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;

    /* TODO: need to solve ticket #460 here */

    tp_ice->rtp_cb = NULL;
    tp_ice->rtcp_cb = NULL;
    tp_ice->stream = NULL;

    PJ_UNUSED_ARG(strm);
}


static pj_status_t transport_send_rtp(pjmedia_transport *tp,
				      const void *pkt,
				      pj_size_t size)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;

    /* Simulate packet lost on TX direction */
    if (tp_ice->tx_drop_pct) {
	if ((pj_rand() % 100) <= (int)tp_ice->tx_drop_pct) {
	    PJ_LOG(5,(tp_ice->base.name, 
		      "TX RTP packet dropped because of pkt lost "
		      "simulation"));
	    return PJ_SUCCESS;
	}
    }

    return pj_ice_strans_sendto(tp_ice->ice_st, 1, 
			        pkt, size, &tp_ice->remote_rtp,
				tp_ice->addr_len);
}


static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size)
{
    return transport_send_rtcp2(tp, NULL, 0, pkt, size);
}

static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
				        const pj_sockaddr_t *addr,
				        unsigned addr_len,
				        const void *pkt,
				        pj_size_t size)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;
    if (tp_ice->comp_cnt > 1) {
	if (addr == NULL) {
	    addr = &tp_ice->remote_rtcp;
	    addr_len = pj_sockaddr_get_len(addr);
	}
	return pj_ice_strans_sendto(tp_ice->ice_st, 2, pkt, size, 
				    addr, addr_len);
    } else {
	return PJ_SUCCESS;
    }
}


static void ice_on_rx_data(pj_ice_strans *ice_st, unsigned comp_id, 
			   void *pkt, pj_size_t size,
			   const pj_sockaddr_t *src_addr,
			   unsigned src_addr_len)
{
    struct transport_ice *tp_ice;
    pj_bool_t discard = PJ_FALSE;

    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);

    if (comp_id==1 && tp_ice->rtp_cb) {

	/* Simulate packet lost on RX direction */
	if (tp_ice->rx_drop_pct) {
	    if ((pj_rand() % 100) <= (int)tp_ice->rx_drop_pct) {
		PJ_LOG(5,(tp_ice->base.name, 
			  "RX RTP packet dropped because of pkt lost "
			  "simulation"));
		return;
	    }
	}

	/* See if source address of RTP packet is different than the 
	 * configured address, and switch RTP remote address to 
	 * source packet address after several consecutive packets
	 * have been received.
	 */
	if (!tp_ice->use_ice) {
	    pj_bool_t enable_switch =
		    ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0);

	    if (!enable_switch ||
		pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) == 0)
	    {
		/* Don't switch while we're receiving from remote_rtp */
		tp_ice->rtp_src_cnt = 0;
	    } else {

		++tp_ice->rtp_src_cnt;

		/* Check if the source address is recognized. */
		if (pj_sockaddr_cmp(src_addr, &tp_ice->rtp_src_addr) != 0) {
		    /* Remember the new source address. */
		    pj_sockaddr_cp(&tp_ice->rtp_src_addr, src_addr);
		    /* Reset counter */
		    tp_ice->rtp_src_cnt = 0;
		    discard = PJ_TRUE;
		}

		if (tp_ice->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {
		    discard = PJ_TRUE;
		} else {
		    char addr_text[80];

		    /* Set remote RTP address to source address */
		    pj_sockaddr_cp(&tp_ice->remote_rtp, &tp_ice->rtp_src_addr);
		    tp_ice->addr_len = pj_sockaddr_get_len(&tp_ice->remote_rtp);

		    /* Reset counter */
		    tp_ice->rtp_src_cnt = 0;

		    PJ_LOG(4,(tp_ice->base.name,
			      "Remote RTP address switched to %s",
			      pj_sockaddr_print(&tp_ice->remote_rtp, addr_text,
						sizeof(addr_text), 3)));

		    /* Also update remote RTCP address if actual RTCP source
		     * address is not heard yet.
		     */
		    if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) {
			pj_uint16_t port;

			pj_sockaddr_cp(&tp_ice->remote_rtcp, 
				       &tp_ice->remote_rtp);

			port = (pj_uint16_t)
			       (pj_sockaddr_get_port(&tp_ice->remote_rtp)+1);
			pj_sockaddr_set_port(&tp_ice->remote_rtcp, port);

			PJ_LOG(4,(tp_ice->base.name,
				  "Remote RTCP address switched to predicted "
				  "address %s",
				  pj_sockaddr_print(&tp_ice->remote_rtcp, 
						    addr_text,
						    sizeof(addr_text), 3)));
		    }
		}
	    }
	}

	if (!discard)
	    (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size);

    } else if (comp_id==2 && tp_ice->rtcp_cb) {

	/* Check if RTCP source address is the same as the configured
	 * remote address, and switch the address when they are
	 * different.
	 */
	if (!tp_ice->use_ice &&
	    (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0)
	{
	    if (pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) == 0) {
		tp_ice->rtcp_src_cnt = 0;
	    } else {
		char addr_text[80];

		++tp_ice->rtcp_src_cnt;
		if (tp_ice->rtcp_src_cnt < PJMEDIA_RTCP_NAT_PROBATION_CNT) {
		    discard = PJ_TRUE;
		} else {
		    tp_ice->rtcp_src_cnt = 0;
		    pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr);
		    pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr);

		    pj_assert(tp_ice->addr_len==pj_sockaddr_get_len(src_addr));

		    PJ_LOG(4,(tp_ice->base.name,
			      "Remote RTCP address switched to %s",
			      pj_sockaddr_print(&tp_ice->remote_rtcp,
			                        addr_text, sizeof(addr_text),
			                        3)));
		}
	    }
	}

	if (!discard)
	    (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size);
    }

    PJ_UNUSED_ARG(src_addr_len);
}


static void ice_on_ice_complete(pj_ice_strans *ice_st, 
				pj_ice_strans_op op,
			        pj_status_t result)
{
    struct transport_ice *tp_ice;

    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);

    /* Notify application */
    if (tp_ice->cb.on_ice_complete)
	(*tp_ice->cb.on_ice_complete)(&tp_ice->base, op, result);
}


/* Simulate lost */
static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
					   pjmedia_dir dir,
					   unsigned pct_lost)
{
    struct transport_ice *ice = (struct transport_ice*) tp;

    PJ_ASSERT_RETURN(tp && pct_lost <= 100, PJ_EINVAL);

    if (dir & PJMEDIA_DIR_ENCODING)
	ice->tx_drop_pct = pct_lost;

    if (dir & PJMEDIA_DIR_DECODING)
	ice->rx_drop_pct = pct_lost;

    return PJ_SUCCESS;
}


/*
 * Destroy ICE media transport.
 */
static pj_status_t transport_destroy(pjmedia_transport *tp)
{
    struct transport_ice *tp_ice = (struct transport_ice*)tp;

    if (tp_ice->ice_st) {
	pj_ice_strans_destroy(tp_ice->ice_st);
	tp_ice->ice_st = NULL;
    }

    if (tp_ice->pool) {
	pj_pool_t *pool = tp_ice->pool;
	tp_ice->pool = NULL;
	pj_pool_release(pool);
    }

    return PJ_SUCCESS;
}

