/* $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 <pjnath/ice_session.h>
#include <pj/addr_resolv.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/hash.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/rand.h>
#include <pj/string.h>

/* String names for candidate types */
static const char *cand_type_names[] =
{
    "host",
    "srflx",
    "prflx",
    "relay"

};

/* String names for pj_ice_sess_check_state */
#if PJ_LOG_MAX_LEVEL >= 4
static const char *check_state_name[] = 
{
    "Frozen",
    "Waiting",
    "In Progress",
    "Succeeded",
    "Failed"
};

static const char *clist_state_name[] =
{
    "Idle",
    "Running",
    "Completed"
};
#endif	/* PJ_LOG_MAX_LEVEL >= 4 */

static const char *role_names[] = 
{
    "Unknown",
    "Controlled",
    "Controlling"
};

enum timer_type
{
    TIMER_NONE,			/**< Timer not active			*/
    TIMER_COMPLETION_CALLBACK,	/**< Call on_ice_complete() callback    */
    TIMER_CONTROLLED_WAIT_NOM,	/**< Controlled agent is waiting for 
				     controlling agent to send connectivity
				     check with nominated flag after it has
				     valid check for every components.	*/
    TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity
				     checks with USE-CANDIDATE flag.	*/
    TIMER_KEEP_ALIVE		/**< ICE keep-alive timer.		*/

};

/* Candidate type preference */
static pj_uint8_t cand_type_prefs[PJ_ICE_CAND_TYPE_MAX] =
{
#if PJ_ICE_CAND_TYPE_PREF_BITS < 8
    /* Keep it to 2 bits */
    3,	    /**< PJ_ICE_HOST_PREF	*/
    1,	    /**< PJ_ICE_SRFLX_PREF.	*/
    2,	    /**< PJ_ICE_PRFLX_PREF	*/
    0	    /**< PJ_ICE_RELAYED_PREF	*/
#else
    /* Default ICE session preferences, according to draft-ice */
    126,    /**< PJ_ICE_HOST_PREF	*/
    100,    /**< PJ_ICE_SRFLX_PREF.	*/
    110,    /**< PJ_ICE_PRFLX_PREF	*/
    0	    /**< PJ_ICE_RELAYED_PREF	*/
#endif
};

#define THIS_FILE		"ice_session.c"
#define CHECK_NAME_LEN		128
#define LOG4(expr)		PJ_LOG(4,expr)
#define LOG5(expr)		PJ_LOG(4,expr)
#define GET_LCAND_ID(cand)	(unsigned)(cand - ice->lcand)
#define GET_CHECK_ID(cl, chk)	(chk - (cl)->checks)


/* The data that will be attached to the STUN session on each
 * component.
 */
typedef struct stun_data
{
    pj_ice_sess		*ice;
    unsigned		 comp_id;
    pj_ice_sess_comp	*comp;
} stun_data;


/* The data that will be attached to the timer to perform
 * periodic check.
 */
typedef struct timer_data
{
    pj_ice_sess		    *ice;
    pj_ice_sess_checklist   *clist;
} timer_data;


/* This is the data that will be attached as token to outgoing
 * STUN messages.
 */


/* Forward declarations */
static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te);
static void on_ice_complete(pj_ice_sess *ice, pj_status_t status);
static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now);
static void ice_on_destroy(void *obj);
static void destroy_ice(pj_ice_sess *ice,
			pj_status_t reason);
static pj_status_t start_periodic_check(pj_timer_heap_t *th, 
					pj_timer_entry *te);
static void start_nominated_check(pj_ice_sess *ice);
static void periodic_timer(pj_timer_heap_t *th, 
			  pj_timer_entry *te);
static void handle_incoming_check(pj_ice_sess *ice,
				  const pj_ice_rx_check *rcheck);

/* These are the callbacks registered to the STUN sessions */
static pj_status_t on_stun_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len);
static pj_status_t on_stun_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len);
static void on_stun_request_complete(pj_stun_session *stun_sess,
				     pj_status_t status,
				     void *token,
				     pj_stun_tx_data *tdata,
				     const pj_stun_msg *response,
				     const pj_sockaddr_t *src_addr,
				     unsigned src_addr_len);
static pj_status_t on_stun_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len);

/* These are the callbacks for performing STUN authentication */
static pj_status_t stun_auth_get_auth(void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *nonce);
static pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,
				      void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *username,
				      pj_str_t *nonce,
				      pj_stun_passwd_type *data_type,
				      pj_str_t *data);
static pj_status_t stun_auth_get_password(const pj_stun_msg *msg,
					  void *user_data, 
					  const pj_str_t *realm,
					  const pj_str_t *username,
					  pj_pool_t *pool,
					  pj_stun_passwd_type *data_type,
					  pj_str_t *data);


PJ_DEF(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type)
{
    PJ_ASSERT_RETURN(type <= PJ_ICE_CAND_TYPE_RELAYED, "???");
    return cand_type_names[type];
}


PJ_DEF(const char*) pj_ice_sess_role_name(pj_ice_sess_role role)
{
    switch (role) {
    case PJ_ICE_SESS_ROLE_UNKNOWN:
	return "Unknown";
    case PJ_ICE_SESS_ROLE_CONTROLLED:
	return "Controlled";
    case PJ_ICE_SESS_ROLE_CONTROLLING:
	return "Controlling";
    default:
	return "??";
    }
}


/* Get the prefix for the foundation */
static int get_type_prefix(pj_ice_cand_type type)
{
    switch (type) {
    case PJ_ICE_CAND_TYPE_HOST:	    return 'H';
    case PJ_ICE_CAND_TYPE_SRFLX:    return 'S';
    case PJ_ICE_CAND_TYPE_PRFLX:    return 'P';
    case PJ_ICE_CAND_TYPE_RELAYED:  return 'R';
    default:
	pj_assert(!"Invalid type");
	return 'U';
    }
}

/* Calculate foundation:
 * Two candidates have the same foundation when they are "similar" - of
 * the same type and obtained from the same host candidate and STUN
 * server using the same protocol.  Otherwise, their foundation is
 * different.
 */
PJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool,
				    pj_str_t *foundation,
				    pj_ice_cand_type type,
				    const pj_sockaddr *base_addr)
{
#if PJNATH_ICE_PRIO_STD
    char buf[64];
    pj_uint32_t val;

    if (base_addr->addr.sa_family == pj_AF_INET()) {
	val = pj_ntohl(base_addr->ipv4.sin_addr.s_addr);
    } else {
	val = pj_hash_calc(0, pj_sockaddr_get_addr(base_addr),
			   pj_sockaddr_get_addr_len(base_addr));
    }
    pj_ansi_snprintf(buf, sizeof(buf), "%c%x",
		     get_type_prefix(type), val);
    pj_strdup2(pool, foundation, buf);
#else
    /* Much shorter version, valid for candidates added by
     * pj_ice_strans.
     */
    foundation->ptr = (char*) pj_pool_alloc(pool, 1);
    *foundation->ptr = (char)get_type_prefix(type);
    foundation->slen = 1;

    PJ_UNUSED_ARG(base_addr);
#endif
}


/* Init component */
static pj_status_t init_comp(pj_ice_sess *ice,
			     unsigned comp_id,
			     pj_ice_sess_comp *comp)
{
    pj_stun_session_cb sess_cb;
    pj_stun_auth_cred auth_cred;
    stun_data *sd;
    pj_status_t status;

    /* Init STUN callbacks */
    pj_bzero(&sess_cb, sizeof(sess_cb));
    sess_cb.on_request_complete = &on_stun_request_complete;
    sess_cb.on_rx_indication = &on_stun_rx_indication;
    sess_cb.on_rx_request = &on_stun_rx_request;
    sess_cb.on_send_msg = &on_stun_send_msg;

    /* Create STUN session for this candidate */
    status = pj_stun_session_create(&ice->stun_cfg, NULL, 
			            &sess_cb, PJ_TRUE,
			            ice->grp_lock,
				    &comp->stun_sess);
    if (status != PJ_SUCCESS)
	return status;

    /* Associate data with this STUN session */
    sd = PJ_POOL_ZALLOC_T(ice->pool, struct stun_data);
    sd->ice = ice;
    sd->comp_id = comp_id;
    sd->comp = comp;
    pj_stun_session_set_user_data(comp->stun_sess, sd);

    /* Init STUN authentication credential */
    pj_bzero(&auth_cred, sizeof(auth_cred));
    auth_cred.type = PJ_STUN_AUTH_CRED_DYNAMIC;
    auth_cred.data.dyn_cred.get_auth = &stun_auth_get_auth;
    auth_cred.data.dyn_cred.get_cred = &stun_auth_get_cred;
    auth_cred.data.dyn_cred.get_password = &stun_auth_get_password;
    auth_cred.data.dyn_cred.user_data = comp->stun_sess;
    pj_stun_session_set_credential(comp->stun_sess, PJ_STUN_AUTH_SHORT_TERM,
				   &auth_cred);

    return PJ_SUCCESS;
}


/* Init options with default values */
PJ_DEF(void) pj_ice_sess_options_default(pj_ice_sess_options *opt)
{
    opt->aggressive = PJ_TRUE;
    opt->nominated_check_delay = PJ_ICE_NOMINATED_CHECK_DELAY;
    opt->controlled_agent_want_nom_timeout = 
	ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT;
}

/*
 * Create ICE session.
 */
PJ_DEF(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg,
				       const char *name,
				       pj_ice_sess_role role,
				       unsigned comp_cnt,
				       const pj_ice_sess_cb *cb,
				       const pj_str_t *local_ufrag,
				       const pj_str_t *local_passwd,
				       pj_grp_lock_t *grp_lock,
				       pj_ice_sess **p_ice)
{
    pj_pool_t *pool;
    pj_ice_sess *ice;
    unsigned i;
    pj_status_t status;

    PJ_ASSERT_RETURN(stun_cfg && cb && p_ice, PJ_EINVAL);

    if (name == NULL)
	name = "icess%p";

    pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS, 
			  PJNATH_POOL_INC_ICE_SESS, NULL);
    ice = PJ_POOL_ZALLOC_T(pool, pj_ice_sess);
    ice->pool = pool;
    ice->role = role;
    ice->tie_breaker.u32.hi = pj_rand();
    ice->tie_breaker.u32.lo = pj_rand();
    ice->prefs = cand_type_prefs;
    pj_ice_sess_options_default(&ice->opt);

    pj_timer_entry_init(&ice->timer, TIMER_NONE, (void*)ice, &on_timer);

    pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name),
		     name, ice);

    if (grp_lock) {
	ice->grp_lock = grp_lock;
    } else {
	status = pj_grp_lock_create(pool, NULL, &ice->grp_lock);
	if (status != PJ_SUCCESS) {
	    pj_pool_release(pool);
	    return status;
	}
    }

    pj_grp_lock_add_ref(ice->grp_lock);
    pj_grp_lock_add_handler(ice->grp_lock, pool, ice,
                            &ice_on_destroy);

    pj_memcpy(&ice->cb, cb, sizeof(*cb));
    pj_memcpy(&ice->stun_cfg, stun_cfg, sizeof(*stun_cfg));

    ice->comp_cnt = comp_cnt;
    for (i=0; i<comp_cnt; ++i) {
	pj_ice_sess_comp *comp;
	comp = &ice->comp[i];
	comp->valid_check = NULL;
	comp->nominated_check = NULL;

	status = init_comp(ice, i+1, comp);
	if (status != PJ_SUCCESS) {
	    destroy_ice(ice, status);
	    return status;
	}
    }

    /* Initialize transport datas */
    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {
	ice->tp_data[i].transport_id = i;
	ice->tp_data[i].has_req_data = PJ_FALSE;
    }

    if (local_ufrag == NULL) {
	ice->rx_ufrag.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);
	pj_create_random_string(ice->rx_ufrag.ptr, PJ_ICE_UFRAG_LEN);
	ice->rx_ufrag.slen = PJ_ICE_UFRAG_LEN;
    } else {
	pj_strdup(ice->pool, &ice->rx_ufrag, local_ufrag);
    }

    if (local_passwd == NULL) {
	ice->rx_pass.ptr = (char*) pj_pool_alloc(ice->pool, PJ_ICE_UFRAG_LEN);
	pj_create_random_string(ice->rx_pass.ptr, PJ_ICE_UFRAG_LEN);
	ice->rx_pass.slen = PJ_ICE_UFRAG_LEN;
    } else {
	pj_strdup(ice->pool, &ice->rx_pass, local_passwd);
    }

    pj_list_init(&ice->early_check);

    /* Done */
    *p_ice = ice;

    LOG4((ice->obj_name, 
	 "ICE session created, comp_cnt=%d, role is %s agent",
	 comp_cnt, role_names[ice->role]));

    return PJ_SUCCESS;
}


/*
 * Get the value of various options of the ICE session.
 */
PJ_DEF(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice,
					    pj_ice_sess_options *opt)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);
    pj_memcpy(opt, &ice->opt, sizeof(*opt));
    return PJ_SUCCESS;
}

/*
 * Specify various options for this ICE session.
 */
PJ_DEF(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice,
					    const pj_ice_sess_options *opt)
{
    PJ_ASSERT_RETURN(ice && opt, PJ_EINVAL);
    pj_memcpy(&ice->opt, opt, sizeof(*opt));
    LOG5((ice->obj_name, "ICE nomination type set to %s",
	  (ice->opt.aggressive ? "aggressive" : "regular")));
    return PJ_SUCCESS;
}


/*
 * Callback to really destroy the session
 */
static void ice_on_destroy(void *obj)
{
    pj_ice_sess *ice = (pj_ice_sess*) obj;

    if (ice->pool) {
	pj_pool_t *pool = ice->pool;
	ice->pool = NULL;
	pj_pool_release(pool);
    }
    LOG4((THIS_FILE, "ICE session %p destroyed", ice));
}

/*
 * Destroy
 */
static void destroy_ice(pj_ice_sess *ice,
			pj_status_t reason)
{
    unsigned i;

    if (reason == PJ_SUCCESS) {
	LOG4((ice->obj_name, "Destroying ICE session %p", ice));
    }

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    ice->is_destroying = PJ_TRUE;

    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->timer, PJ_FALSE);

    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].stun_sess) {
	    pj_stun_session_destroy(ice->comp[i].stun_sess);
	    ice->comp[i].stun_sess = NULL;
	}
    }

    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->clist.timer,
                                   PJ_FALSE);

    pj_grp_lock_dec_ref(ice->grp_lock);
    pj_grp_lock_release(ice->grp_lock);
}


/*
 * Destroy
 */
PJ_DEF(pj_status_t) pj_ice_sess_destroy(pj_ice_sess *ice)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);
    destroy_ice(ice, PJ_SUCCESS);
    return PJ_SUCCESS;
}


/*
 * Change session role. 
 */
PJ_DEF(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice,
					    pj_ice_sess_role new_role)
{
    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    if (new_role != ice->role) {
	ice->role = new_role;
	LOG4((ice->obj_name, "Role changed to %s", role_names[new_role]));
    }

    return PJ_SUCCESS;
}


/*
 * Change type preference
 */
PJ_DEF(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
					  const pj_uint8_t prefs[4])
{
    unsigned i;
    PJ_ASSERT_RETURN(ice && prefs, PJ_EINVAL);
    ice->prefs = (pj_uint8_t*) pj_pool_calloc(ice->pool, PJ_ICE_CAND_TYPE_MAX,
					      sizeof(pj_uint8_t));
    for (i=0; i<PJ_ICE_CAND_TYPE_MAX; ++i) {
#if PJ_ICE_CAND_TYPE_PREF_BITS < 8
	pj_assert(prefs[i] < (2 << PJ_ICE_CAND_TYPE_PREF_BITS));
#endif
	ice->prefs[i] = prefs[i];
    }
    return PJ_SUCCESS;
}


/* Find component by ID */
static pj_ice_sess_comp *find_comp(const pj_ice_sess *ice, unsigned comp_id)
{
    pj_assert(comp_id > 0 && comp_id <= ice->comp_cnt);
    return (pj_ice_sess_comp*) &ice->comp[comp_id-1];
}


/* Callback by STUN authentication when it needs to send 401 */
static pj_status_t stun_auth_get_auth(void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *nonce)
{
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(pool);

    realm->slen = 0;
    nonce->slen = 0;

    return PJ_SUCCESS;
}


/* Get credential to be sent with outgoing message */
static pj_status_t stun_auth_get_cred(const pj_stun_msg *msg,
				      void *user_data,
				      pj_pool_t *pool,
				      pj_str_t *realm,
				      pj_str_t *username,
				      pj_str_t *nonce,
				      pj_stun_passwd_type *data_type,
				      pj_str_t *data)
{
    pj_stun_session *sess = (pj_stun_session *)user_data;
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;

    PJ_UNUSED_ARG(pool);
    realm->slen = nonce->slen = 0;

    if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) {
	/* Outgoing responses need to have the same credential as
	 * incoming requests.
	 */
	*username = ice->rx_uname;
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->rx_pass;
    }
    else {
	*username = ice->tx_uname;
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->tx_pass;
    }

    return PJ_SUCCESS;
}

/* Get password to be used to authenticate incoming message */
static pj_status_t stun_auth_get_password(const pj_stun_msg *msg,
					  void *user_data, 
					  const pj_str_t *realm,
					  const pj_str_t *username,
					  pj_pool_t *pool,
					  pj_stun_passwd_type *data_type,
					  pj_str_t *data)
{
    pj_stun_session *sess = (pj_stun_session *)user_data;
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;

    PJ_UNUSED_ARG(realm);
    PJ_UNUSED_ARG(pool);

    if (PJ_STUN_IS_SUCCESS_RESPONSE(msg->hdr.type) ||
	PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
    {
	/* Incoming response is authenticated with TX credential */
	/* Verify username */
	if (pj_strcmp(username, &ice->tx_uname) != 0)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);
	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->tx_pass;

    } else {
	/* Incoming request is authenticated with RX credential */
	/* The agent MUST accept a credential if the username consists
	 * of two values separated by a colon, where the first value is
	 * equal to the username fragment generated by the agent in an offer
	 * or answer for a session in-progress, and the MESSAGE-INTEGRITY 
	 * is the output of a hash of the password and the STUN packet's 
	 * contents.
	 */
	const char *pos;
	pj_str_t ufrag;

	pos = (const char*)pj_memchr(username->ptr, ':', username->slen);
	if (pos == NULL)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);

	ufrag.ptr = (char*)username->ptr;
	ufrag.slen = (pos - username->ptr);

	if (pj_strcmp(&ufrag, &ice->rx_ufrag) != 0)
	    return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNAUTHORIZED);

	*data_type = PJ_STUN_PASSWD_PLAIN;
	*data = ice->rx_pass;

    }

    return PJ_SUCCESS;
}


static pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice,
				  pj_ice_cand_type type,
				  pj_uint32_t local_pref,
				  pj_uint32_t comp_id)
{
#if PJNATH_ICE_PRIO_STD
    return ((ice->prefs[type] & 0xFF) << 24) + 
	   ((local_pref & 0xFFFF)    << 8) +
	   (((256 - comp_id) & 0xFF) << 0);
#else
    enum {
	type_mask   = ((2 << PJ_ICE_CAND_TYPE_PREF_BITS) - 1),
	local_mask  = ((2 << PJ_ICE_LOCAL_PREF_BITS) - 1),
	comp_mask   = ((2 << PJ_ICE_COMP_BITS) - 1),

	comp_shift  = 0,
	local_shift = (PJ_ICE_COMP_BITS),
	type_shift  = (comp_shift + local_shift),

	max_comp    = (2<<PJ_ICE_COMP_BITS),
    };

    return ((ice->prefs[type] & type_mask) << type_shift) + 
	   ((local_pref & local_mask) << local_shift) +
	   (((max_comp - comp_id) & comp_mask) << comp_shift);
#endif
}


/*
 * Add ICE candidate
 */
PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
					 unsigned comp_id,
					 unsigned transport_id,
					 pj_ice_cand_type type,
					 pj_uint16_t local_pref,
					 const pj_str_t *foundation,
					 const pj_sockaddr_t *addr,
					 const pj_sockaddr_t *base_addr,
					 const pj_sockaddr_t *rel_addr,
					 int addr_len,
					 unsigned *p_cand_id)
{
    pj_ice_sess_cand *lcand;
    pj_status_t status = PJ_SUCCESS;
    char address[PJ_INET6_ADDRSTRLEN];

    PJ_ASSERT_RETURN(ice && comp_id && 
		     foundation && addr && base_addr && addr_len,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->lcand_cnt >= PJ_ARRAY_SIZE(ice->lcand)) {
	status = PJ_ETOOMANY;
	goto on_error;
    }

    lcand = &ice->lcand[ice->lcand_cnt];
    lcand->comp_id = (pj_uint8_t)comp_id;
    lcand->transport_id = (pj_uint8_t)transport_id;
    lcand->type = type;
    pj_strdup(ice->pool, &lcand->foundation, foundation);
    lcand->prio = CALC_CAND_PRIO(ice, type, local_pref, lcand->comp_id);
    pj_sockaddr_cp(&lcand->addr, addr);
    pj_sockaddr_cp(&lcand->base_addr, base_addr);
    if (rel_addr == NULL)
	rel_addr = base_addr;
    pj_memcpy(&lcand->rel_addr, rel_addr, addr_len);

    pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address,
                                                   sizeof(address), 0));
    LOG4((ice->obj_name, 
	 "Candidate %d added: comp_id=%d, type=%s, foundation=%.*s, "
	 "addr=%s:%d, base=%s:%d, prio=0x%x (%u)",
	 ice->lcand_cnt, 
	 lcand->comp_id, 
	 cand_type_names[lcand->type],
	 (int)lcand->foundation.slen,
	 lcand->foundation.ptr,
	 ice->tmp.txt, 
	  pj_sockaddr_get_port(&lcand->addr),
	  pj_sockaddr_print(&lcand->base_addr, address, sizeof(address), 0),
	  pj_sockaddr_get_port(&lcand->base_addr),
	 lcand->prio, lcand->prio));

    if (p_cand_id)
	*p_cand_id = ice->lcand_cnt;

    ++ice->lcand_cnt;

on_error:
    pj_grp_lock_release(ice->grp_lock);
    return status;
}


/* Find default candidate ID for the component */
PJ_DEF(pj_status_t) pj_ice_sess_find_default_cand(pj_ice_sess *ice,
						  unsigned comp_id,
						  int *cand_id)
{
    unsigned i;

    PJ_ASSERT_RETURN(ice && comp_id && cand_id, PJ_EINVAL);
    PJ_ASSERT_RETURN(comp_id <= ice->comp_cnt, PJ_EINVAL);

    *cand_id = -1;

    pj_grp_lock_acquire(ice->grp_lock);

    /* First find in valid list if we have nominated pair */
    for (i=0; i<ice->valid_list.count; ++i) {
	pj_ice_sess_check *check = &ice->valid_list.checks[i];
	
	if (check->lcand->comp_id == comp_id) {
	    *cand_id = GET_LCAND_ID(check->lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* If there's no nominated pair, find relayed candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    lcand->type == PJ_ICE_CAND_TYPE_RELAYED) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* If there's no relayed candidate, find reflexive candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    (lcand->type == PJ_ICE_CAND_TYPE_SRFLX ||
	     lcand->type == PJ_ICE_CAND_TYPE_PRFLX)) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* Otherwise return host candidate */
    for (i=0; i<ice->lcand_cnt; ++i) {
	pj_ice_sess_cand *lcand = &ice->lcand[i];
	if (lcand->comp_id==comp_id &&
	    lcand->type == PJ_ICE_CAND_TYPE_HOST) 
	{
	    *cand_id = GET_LCAND_ID(lcand);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}
    }

    /* Still no candidate is found! :( */
    pj_grp_lock_release(ice->grp_lock);

    pj_assert(!"Should have a candidate by now");
    return PJ_EBUG;
}


#ifndef MIN
#   define MIN(a,b) (a < b ? a : b)
#endif

#ifndef MAX
#   define MAX(a,b) (a > b ? a : b)
#endif

static pj_timestamp CALC_CHECK_PRIO(const pj_ice_sess *ice, 
				    const pj_ice_sess_cand *lcand,
				    const pj_ice_sess_cand *rcand)
{
    pj_uint32_t O, A;
    pj_timestamp prio;

    /* Original formula:
     *   pair priority = 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0)
     */

    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {
	O = lcand->prio; 
	A = rcand->prio;
    } else {
	O = rcand->prio;
	A = lcand->prio;
    }

    /*
    return ((pj_uint64_t)1 << 32) * MIN(O, A) +
	   (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0);
    */

    prio.u32.hi = MIN(O,A);
    prio.u32.lo = (MAX(O, A) << 1) + (O>A ? 1 : 0);

    return prio;
}


PJ_INLINE(int) CMP_CHECK_PRIO(const pj_ice_sess_check *c1,
			      const pj_ice_sess_check *c2)
{
    return pj_cmp_timestamp(&c1->prio, &c2->prio);
}


#if PJ_LOG_MAX_LEVEL >= 4
static const char *dump_check(char *buffer, unsigned bufsize,
			      const pj_ice_sess_checklist *clist,
			      const pj_ice_sess_check *check)
{
    const pj_ice_sess_cand *lcand = check->lcand;
    const pj_ice_sess_cand *rcand = check->rcand;
    char laddr[PJ_INET6_ADDRSTRLEN], raddr[PJ_INET6_ADDRSTRLEN];
    int len;

    PJ_CHECK_STACK();

    len = pj_ansi_snprintf(buffer, bufsize,
			   "%d: [%d] %s:%d-->%s:%d",
			   (int)GET_CHECK_ID(clist, check),
			   check->lcand->comp_id,
			   pj_sockaddr_print(&lcand->addr, laddr,
			                     sizeof(laddr), 0),
			   pj_sockaddr_get_port(&lcand->addr),
			   pj_sockaddr_print(&rcand->addr, raddr,
			                     sizeof(raddr), 0),
			   pj_sockaddr_get_port(&rcand->addr));

    if (len < 0)
	len = 0;
    else if (len >= (int)bufsize)
	len = bufsize - 1;

    buffer[len] = '\0';
    return buffer;
}

static void dump_checklist(const char *title, pj_ice_sess *ice, 
			   const pj_ice_sess_checklist *clist)
{
    unsigned i;

    LOG4((ice->obj_name, "%s", title));
    for (i=0; i<clist->count; ++i) {
	const pj_ice_sess_check *c = &clist->checks[i];
	LOG4((ice->obj_name, " %s (%s, state=%s)",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, c),
	     (c->nominated ? "nominated" : "not nominated"), 
	     check_state_name[c->state]));
    }
}

#else
#define dump_checklist(title, ice, clist)
#endif

static void check_set_state(pj_ice_sess *ice, pj_ice_sess_check *check,
			    pj_ice_sess_check_state st, 
			    pj_status_t err_code)
{
    pj_assert(check->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);

    LOG5((ice->obj_name, "Check %s: state changed from %s to %s",
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), &ice->clist, check),
	 check_state_name[check->state],
	 check_state_name[st]));
    check->state = st;
    check->err_code = err_code;
}

static void clist_set_state(pj_ice_sess *ice, pj_ice_sess_checklist *clist,
			    pj_ice_sess_checklist_state st)
{
    if (clist->state != st) {
	LOG5((ice->obj_name, "Checklist: state changed from %s to %s",
	     clist_state_name[clist->state],
	     clist_state_name[st]));
	clist->state = st;
    }
}

/* Sort checklist based on priority */
static void sort_checklist(pj_ice_sess *ice, pj_ice_sess_checklist *clist)
{
    unsigned i;
    pj_ice_sess_check **check_ptr[PJ_ICE_MAX_COMP*2];
    unsigned check_ptr_cnt = 0;

    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].valid_check) {
	    check_ptr[check_ptr_cnt++] = &ice->comp[i].valid_check;
	}
	if (ice->comp[i].nominated_check) {
	    check_ptr[check_ptr_cnt++] = &ice->comp[i].nominated_check;
	}
    }

    pj_assert(clist->count > 0);
    for (i=0; i<clist->count-1; ++i) {
	unsigned j, highest = i;

	for (j=i+1; j<clist->count; ++j) {
	    if (CMP_CHECK_PRIO(&clist->checks[j], &clist->checks[highest]) > 0) {
		highest = j;
	    }
	}

	if (highest != i) {
	    pj_ice_sess_check tmp;
	    unsigned k;

	    pj_memcpy(&tmp, &clist->checks[i], sizeof(pj_ice_sess_check));
	    pj_memcpy(&clist->checks[i], &clist->checks[highest], 
		      sizeof(pj_ice_sess_check));
	    pj_memcpy(&clist->checks[highest], &tmp, 
		      sizeof(pj_ice_sess_check));

	    /* Update valid and nominated check pointers, since we're moving
	     * around checks
	     */
	    for (k=0; k<check_ptr_cnt; ++k) {
		if (*check_ptr[k] == &clist->checks[highest])
		    *check_ptr[k] = &clist->checks[i];
		else if (*check_ptr[k] == &clist->checks[i])
		    *check_ptr[k] = &clist->checks[highest];
	    }
	}
    }
}

/* Prune checklist, this must have been done after the checklist
 * is sorted.
 */
static pj_status_t prune_checklist(pj_ice_sess *ice, 
				   pj_ice_sess_checklist *clist)
{
    unsigned i;

    /* Since an agent cannot send requests directly from a reflexive
     * candidate, but only from its base, the agent next goes through the
     * sorted list of candidate pairs.  For each pair where the local
     * candidate is server reflexive, the server reflexive candidate MUST be
     * replaced by its base.  Once this has been done, the agent MUST prune
     * the list.  This is done by removing a pair if its local and remote
     * candidates are identical to the local and remote candidates of a pair
     * higher up on the priority list.  The result is a sequence of ordered
     * candidate pairs, called the check list for that media stream.    
     */
    /* First replace SRFLX candidates with their base */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_cand *srflx = clist->checks[i].lcand;

	if (clist->checks[i].lcand->type == PJ_ICE_CAND_TYPE_SRFLX) {
	    /* Find the base for this candidate */
	    unsigned j;
	    for (j=0; j<ice->lcand_cnt; ++j) {
		pj_ice_sess_cand *host = &ice->lcand[j];

		if (host->type != PJ_ICE_CAND_TYPE_HOST)
		    continue;

		if (pj_sockaddr_cmp(&srflx->base_addr, &host->addr) == 0) {
		    /* Replace this SRFLX with its BASE */
		    clist->checks[i].lcand = host;
		    break;
		}
	    }

	    if (j==ice->lcand_cnt) {
		char baddr[PJ_INET6_ADDRSTRLEN];
		/* Host candidate not found this this srflx! */
		LOG4((ice->obj_name, 
		      "Base candidate %s:%d not found for srflx candidate %d",
		      pj_sockaddr_print(&srflx->base_addr, baddr,
		                        sizeof(baddr), 0),
		      pj_sockaddr_get_port(&srflx->base_addr),
		      GET_LCAND_ID(clist->checks[i].lcand)));
		return PJNATH_EICENOHOSTCAND;
	    }
	}
    }

    /* Next remove a pair if its local and remote candidates are identical
     * to the local and remote candidates of a pair higher up on the priority
     * list
     */
    /*
     * Not in ICE!
     * Remove host candidates if their base are the the same!
     */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_cand *licand = clist->checks[i].lcand;
	pj_ice_sess_cand *ricand = clist->checks[i].rcand;
	unsigned j;

	for (j=i+1; j<clist->count;) {
	    pj_ice_sess_cand *ljcand = clist->checks[j].lcand;
	    pj_ice_sess_cand *rjcand = clist->checks[j].rcand;
	    const char *reason = NULL;

	    if ((licand == ljcand) && (ricand == rjcand)) {
		reason = "duplicate found";
	    } else if ((rjcand == ricand) &&
		       (pj_sockaddr_cmp(&ljcand->base_addr, 
				     &licand->base_addr)==0)) 
	    {
		reason = "equal base";
	    }

	    if (reason != NULL) {
		/* Found duplicate, remove it */
		LOG5((ice->obj_name, "Check %s pruned (%s)",
		      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
				 &ice->clist, &clist->checks[j]),
		      reason));

		pj_array_erase(clist->checks, sizeof(clist->checks[0]),
			       clist->count, j);
		--clist->count;

	    } else {
		++j;
	    }
	}
    }

    return PJ_SUCCESS;
}

/* Timer callback */
static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te)
{
    pj_ice_sess *ice = (pj_ice_sess*) te->user_data;
    enum timer_type type = (enum timer_type)te->id;

    PJ_UNUSED_ARG(th);

    pj_grp_lock_acquire(ice->grp_lock);

    te->id = TIMER_NONE;

    if (ice->is_destroying) {
	/* Stray timer, could happen when destroy is invoked while callback
	 * is pending. */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    switch (type) {
    case TIMER_CONTROLLED_WAIT_NOM:
	LOG4((ice->obj_name, 
	      "Controlled agent timed-out in waiting for the controlling "
	      "agent to send nominated check. Setting state to fail now.."));
	on_ice_complete(ice, PJNATH_EICENOMTIMEOUT);
	break;
    case TIMER_COMPLETION_CALLBACK:
	{
	    void (*on_ice_complete)(pj_ice_sess *ice, pj_status_t status);
	    pj_status_t ice_status;

	    /* Start keep-alive timer but don't send any packets yet.
	     * Need to do it here just in case app destroy the session
	     * in the callback.
	     */
	    if (ice->ice_status == PJ_SUCCESS)
		ice_keep_alive(ice, PJ_FALSE);

	    /* Release mutex in case app destroy us in the callback */
	    ice_status = ice->ice_status;
	    on_ice_complete = ice->cb.on_ice_complete;

	    /* Notify app about ICE completion*/
	    if (on_ice_complete)
		(*on_ice_complete)(ice, ice_status);
	}
	break;
    case TIMER_START_NOMINATED_CHECK:
	start_nominated_check(ice);
	break;
    case TIMER_KEEP_ALIVE:
	ice_keep_alive(ice, PJ_TRUE);
	break;
    case TIMER_NONE:
	/* Nothing to do, just to get rid of gcc warning */
	break;
    }

    pj_grp_lock_release(ice->grp_lock);
}

/* Send keep-alive */
static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now)
{
    if (send_now) {
	/* Send Binding Indication for the component */
	pj_ice_sess_comp *comp = &ice->comp[ice->comp_ka];
	pj_stun_tx_data *tdata;
	pj_ice_sess_check *the_check;
	pj_ice_msg_data *msg_data;
	int addr_len;
	pj_bool_t saved;
	pj_status_t status;

	/* Must have nominated check by now */
	pj_assert(comp->nominated_check != NULL);
	the_check = comp->nominated_check;

	/* Create the Binding Indication */
	status = pj_stun_session_create_ind(comp->stun_sess, 
					    PJ_STUN_BINDING_INDICATION,
					    &tdata);
	if (status != PJ_SUCCESS)
	    goto done;

	/* Need the transport_id */
	msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
	msg_data->transport_id = the_check->lcand->transport_id;

	/* Temporarily disable FINGERPRINT. The Binding Indication 
	 * SHOULD NOT contain any attributes.
	 */
	saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE);

	/* Send to session */
	addr_len = pj_sockaddr_get_len(&the_check->rcand->addr);
	status = pj_stun_session_send_msg(comp->stun_sess, msg_data,
					  PJ_FALSE, PJ_FALSE, 
					  &the_check->rcand->addr, 
					  addr_len, tdata);

	/* Restore FINGERPRINT usage */
	pj_stun_session_use_fingerprint(comp->stun_sess, saved);

done:
	ice->comp_ka = (ice->comp_ka + 1) % ice->comp_cnt;
    }

    if (ice->timer.id == TIMER_NONE) {
	pj_time_val delay = { 0, 0 };

	delay.msec = (PJ_ICE_SESS_KEEP_ALIVE_MIN + 
		      (pj_rand() % PJ_ICE_SESS_KEEP_ALIVE_MAX_RAND)) * 1000 / 
		     ice->comp_cnt;
	pj_time_val_normalize(&delay);

	pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                  &ice->timer, &delay,
	                                  TIMER_KEEP_ALIVE,
	                                  ice->grp_lock);

    } else {
	pj_assert(!"Not expected any timer active");
    }
}

/* This function is called when ICE processing completes */
static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
{
    if (!ice->is_complete) {
	ice->is_complete = PJ_TRUE;
	ice->ice_status = status;
    
	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);

	/* Log message */
	LOG4((ice->obj_name, "ICE process complete, status=%s", 
	     pj_strerror(status, ice->tmp.errmsg, 
			 sizeof(ice->tmp.errmsg)).ptr));

	dump_checklist("Valid list", ice, &ice->valid_list);

	/* Call callback */
	if (ice->cb.on_ice_complete) {
	    pj_time_val delay = {0, 0};

	    pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                      &ice->timer, &delay,
	                                      TIMER_COMPLETION_CALLBACK,
	                                      ice->grp_lock);
	}
    }
}

/* Update valid check and nominated check for the candidate */
static void update_comp_check(pj_ice_sess *ice, unsigned comp_id, 
			      pj_ice_sess_check *check)
{
    pj_ice_sess_comp *comp;

    comp = find_comp(ice, comp_id);
    if (comp->valid_check == NULL) {
	comp->valid_check = check;
    } else {
	if (CMP_CHECK_PRIO(comp->valid_check, check) < 0)
	    comp->valid_check = check;
    }

    if (check->nominated) {
	/* Update the nominated check for the component */
	if (comp->nominated_check == NULL) {
	    comp->nominated_check = check;
	} else {
	    if (CMP_CHECK_PRIO(comp->nominated_check, check) < 0)
		comp->nominated_check = check;
	}
    }
}

/* This function is called when one check completes */
static pj_bool_t on_check_complete(pj_ice_sess *ice,
				   pj_ice_sess_check *check)
{
    pj_ice_sess_comp *comp;
    unsigned i;

    pj_assert(check->state >= PJ_ICE_SESS_CHECK_STATE_SUCCEEDED);

    comp = find_comp(ice, check->lcand->comp_id);

    /* 7.1.2.2.2.  Updating Pair States
     * 
     * The agent sets the state of the pair that generated the check to
     * Succeeded.  The success of this check might also cause the state of
     * other checks to change as well.  The agent MUST perform the following
     * two steps:
     * 
     * 1.  The agent changes the states for all other Frozen pairs for the
     *     same media stream and same foundation to Waiting.  Typically
     *     these other pairs will have different component IDs but not
     *     always.
     */
    if (check->err_code==PJ_SUCCESS) {

	for (i=0; i<ice->clist.count; ++i) {
	    pj_ice_sess_check *c = &ice->clist.checks[i];
	    if (pj_strcmp(&c->lcand->foundation, &check->lcand->foundation)==0
		 && c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN)
	    {
		check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);
	    }
	}

	LOG5((ice->obj_name, "Check %d is successful%s",
	     GET_CHECK_ID(&ice->clist, check),
	     (check->nominated ? "  and nominated" : "")));

    }

    /* 8.2.  Updating States
     * 
     * For both controlling and controlled agents, the state of ICE
     * processing depends on the presence of nominated candidate pairs in
     * the valid list and on the state of the check list:
     *
     * o  If there are no nominated pairs in the valid list for a media
     *    stream and the state of the check list is Running, ICE processing
     *    continues.
     *
     * o  If there is at least one nominated pair in the valid list:
     *
     *    - The agent MUST remove all Waiting and Frozen pairs in the check
     *      list for the same component as the nominated pairs for that
     *      media stream
     *
     *    - If an In-Progress pair in the check list is for the same
     *      component as a nominated pair, the agent SHOULD cease
     *      retransmissions for its check if its pair priority is lower
     *      than the lowest priority nominated pair for that component
     */
    if (check->err_code==PJ_SUCCESS && check->nominated) {

	for (i=0; i<ice->clist.count; ++i) {

	    pj_ice_sess_check *c = &ice->clist.checks[i];

	    if (c->lcand->comp_id == check->lcand->comp_id) {

		if (c->state < PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {

		    /* Just fail Frozen/Waiting check */
		    LOG5((ice->obj_name, 
			 "Check %s to be failed because state is %s",
			 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
				    &ice->clist, c), 
			 check_state_name[c->state]));
		    check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,
				    PJ_ECANCELLED);

		} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS
			   && (PJ_ICE_CANCEL_ALL ||
			        CMP_CHECK_PRIO(c, check) < 0)) {

		    /* State is IN_PROGRESS, cancel transaction */
		    if (c->tdata) {
			LOG5((ice->obj_name, 
			     "Cancelling check %s (In Progress)",
			     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
					&ice->clist, c)));
			pj_stun_session_cancel_req(comp->stun_sess, 
						   c->tdata, PJ_FALSE, 0);
			c->tdata = NULL;
			check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_FAILED,
					PJ_ECANCELLED);
		    }
		}
	    }
	}
    }


    /* Still in 8.2.  Updating States
     * 
     * o  Once there is at least one nominated pair in the valid list for
     *    every component of at least one media stream and the state of the
     *    check list is Running:
     *    
     *    *  The agent MUST change the state of processing for its check
     *       list for that media stream to Completed.
     *    
     *    *  The agent MUST continue to respond to any checks it may still
     *       receive for that media stream, and MUST perform triggered
     *       checks if required by the processing of Section 7.2.
     *    
     *    *  The agent MAY begin transmitting media for this media stream as
     *       described in Section 11.1
     */

    /* See if all components have nominated pair. If they do, then mark
     * ICE processing as success, otherwise wait.
     */
    for (i=0; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].nominated_check == NULL)
	    break;
    }
    if (i == ice->comp_cnt) {
	/* All components have nominated pair */
	on_ice_complete(ice, PJ_SUCCESS);
	return PJ_TRUE;
    }

    /* Note: this is the stuffs that we don't do in 7.1.2.2.2, since our
     *       ICE session only supports one media stream for now:
     * 
     * 7.1.2.2.2.  Updating Pair States
     *
     * 2.  If there is a pair in the valid list for every component of this
     *     media stream (where this is the actual number of components being
     *     used, in cases where the number of components signaled in the SDP
     *     differs from offerer to answerer), the success of this check may
     *     unfreeze checks for other media streams. 
     */

    /* 7.1.2.3.  Check List and Timer State Updates
     * Regardless of whether the check was successful or failed, the
     * completion of the transaction may require updating of check list and
     * timer states.
     * 
     * If all of the pairs in the check list are now either in the Failed or
     * Succeeded state, and there is not a pair in the valid list for each
     * component of the media stream, the state of the check list is set to
     * Failed.  
     */

    /* 
     * See if all checks in the checklist have completed. If we do,
     * then mark ICE processing as failed.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->state < PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {
	    break;
	}
    }

    if (i == ice->clist.count) {
	/* All checks have completed, but we don't have nominated pair.
	 * If agent's role is controlled, check if all components have
	 * valid pair. If it does, this means the controlled agent has
	 * finished the check list and it's waiting for controlling
	 * agent to send checks with USE-CANDIDATE flag set.
	 */
	if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED) {
	    for (i=0; i < ice->comp_cnt; ++i) {
		if (ice->comp[i].valid_check == NULL)
		    break;
	    }

	    if (i < ice->comp_cnt) {
		/* This component ID doesn't have valid pair.
		 * Mark ICE as failed. 
		 */
		on_ice_complete(ice, PJNATH_EICEFAILED);
		return PJ_TRUE;
	    } else {
		/* All components have a valid pair.
		 * We should wait until we receive nominated checks.
		 */
		if (ice->timer.id == TIMER_NONE &&
		    ice->opt.controlled_agent_want_nom_timeout >= 0) 
		{
		    pj_time_val delay;

		    delay.sec = 0;
		    delay.msec = ice->opt.controlled_agent_want_nom_timeout;
		    pj_time_val_normalize(&delay);

		    pj_timer_heap_schedule_w_grp_lock(
					ice->stun_cfg.timer_heap,
		                        &ice->timer, &delay,
		                        TIMER_CONTROLLED_WAIT_NOM,
		                        ice->grp_lock);

		    LOG5((ice->obj_name, 
			  "All checks have completed. Controlled agent now "
			  "waits for nomination from controlling agent "
			  "(timeout=%d msec)",
			  ice->opt.controlled_agent_want_nom_timeout));
		}
		return PJ_FALSE;
	    }

	    /* Unreached */

	} else if (ice->is_nominating) {
	    /* We are controlling agent and all checks have completed but
	     * there's at least one component without nominated pair (or
	     * more likely we don't have any nominated pairs at all).
	     */
	    on_ice_complete(ice, PJNATH_EICEFAILED);
	    return PJ_TRUE;

	} else {
	    /* We are controlling agent and all checks have completed. If
	     * we have valid list for every component, then move on to
	     * sending nominated check, otherwise we have failed.
	     */
	    for (i=0; i<ice->comp_cnt; ++i) {
		if (ice->comp[i].valid_check == NULL)
		    break;
	    }

	    if (i < ice->comp_cnt) {
		/* At least one component doesn't have a valid check. Mark
		 * ICE as failed.
		 */
		on_ice_complete(ice, PJNATH_EICEFAILED);
		return PJ_TRUE;
	    }

	    /* Now it's time to send connectivity check with nomination 
	     * flag set.
	     */
	    LOG4((ice->obj_name, 
		  "All checks have completed, starting nominated checks now"));
	    start_nominated_check(ice);
	    return PJ_FALSE;
	}
    }

    /* If this connectivity check has been successful, scan all components
     * and see if they have a valid pair, if we are controlling and we haven't
     * started our nominated check yet.
     */
    if (check->err_code == PJ_SUCCESS && 
	ice->role==PJ_ICE_SESS_ROLE_CONTROLLING &&
	!ice->is_nominating &&
	ice->timer.id == TIMER_NONE) 
    {
	pj_time_val delay;

	for (i=0; i<ice->comp_cnt; ++i) {
	    if (ice->comp[i].valid_check == NULL)
		break;
	}

	if (i < ice->comp_cnt) {
	    /* Some components still don't have valid pair, continue
	     * processing.
	     */
	    return PJ_FALSE;
	}

	LOG4((ice->obj_name, 
	      "Scheduling nominated check in %d ms",
	      ice->opt.nominated_check_delay));

	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);

	/* All components have valid pair. Let connectivity checks run for
	 * a little bit more time, then start our nominated check.
	 */
	delay.sec = 0;
	delay.msec = ice->opt.nominated_check_delay;
	pj_time_val_normalize(&delay);

	pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
	                                  &ice->timer, &delay,
	                                  TIMER_START_NOMINATED_CHECK,
	                                  ice->grp_lock);
	return PJ_FALSE;
    }

    /* We still have checks to perform */
    return PJ_FALSE;
}


/* Create checklist by pairing local candidates with remote candidates */
PJ_DEF(pj_status_t) pj_ice_sess_create_check_list(
			      pj_ice_sess *ice,
			      const pj_str_t *rem_ufrag,
			      const pj_str_t *rem_passwd,
			      unsigned rcand_cnt,
			      const pj_ice_sess_cand rcand[])
{
    pj_ice_sess_checklist *clist;
    char buf[128];
    pj_str_t username;
    timer_data *td;
    unsigned i, j;
    unsigned highest_comp = 0;
    pj_status_t status;

    PJ_ASSERT_RETURN(ice && rem_ufrag && rem_passwd && rcand_cnt && rcand,
		     PJ_EINVAL);
    PJ_ASSERT_RETURN(rcand_cnt + ice->rcand_cnt <= PJ_ICE_MAX_CAND, 
		     PJ_ETOOMANY);

    pj_grp_lock_acquire(ice->grp_lock);

    /* Save credentials */
    username.ptr = buf;

    pj_strcpy(&username, rem_ufrag);
    pj_strcat2(&username, ":");
    pj_strcat(&username, &ice->rx_ufrag);

    pj_strdup(ice->pool, &ice->tx_uname, &username);
    pj_strdup(ice->pool, &ice->tx_ufrag, rem_ufrag);
    pj_strdup(ice->pool, &ice->tx_pass, rem_passwd);

    pj_strcpy(&username, &ice->rx_ufrag);
    pj_strcat2(&username, ":");
    pj_strcat(&username, rem_ufrag);

    pj_strdup(ice->pool, &ice->rx_uname, &username);


    /* Save remote candidates */
    ice->rcand_cnt = 0;
    for (i=0; i<rcand_cnt; ++i) {
	pj_ice_sess_cand *cn = &ice->rcand[ice->rcand_cnt];

	/* Ignore candidate which has no matching component ID */
	if (rcand[i].comp_id==0 || rcand[i].comp_id > ice->comp_cnt) {
	    continue;
	}

	if (rcand[i].comp_id > highest_comp)
	    highest_comp = rcand[i].comp_id;

	pj_memcpy(cn, &rcand[i], sizeof(pj_ice_sess_cand));
	pj_strdup(ice->pool, &cn->foundation, &rcand[i].foundation);
	ice->rcand_cnt++;
    }

    /* Generate checklist */
    clist = &ice->clist;
    for (i=0; i<ice->lcand_cnt; ++i) {
	for (j=0; j<ice->rcand_cnt; ++j) {

	    pj_ice_sess_cand *lcand = &ice->lcand[i];
	    pj_ice_sess_cand *rcand = &ice->rcand[j];
	    pj_ice_sess_check *chk = &clist->checks[clist->count];

	    if (clist->count >= PJ_ICE_MAX_CHECKS) {
		pj_grp_lock_release(ice->grp_lock);
		return PJ_ETOOMANY;
	    } 

	    /* A local candidate is paired with a remote candidate if
	     * and only if the two candidates have the same component ID 
	     * and have the same IP address version. 
	     */
	    if ((lcand->comp_id != rcand->comp_id) ||
		(lcand->addr.addr.sa_family != rcand->addr.addr.sa_family))
	    {
		continue;
	    }


	    chk->lcand = lcand;
	    chk->rcand = rcand;
	    chk->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;

	    chk->prio = CALC_CHECK_PRIO(ice, lcand, rcand);

	    clist->count++;
	}
    }

    /* This could happen if candidates have no matching address families */
    if (clist->count == 0) {
	LOG4((ice->obj_name,  "Error: no checklist can be created"));
	pj_grp_lock_release(ice->grp_lock);
	return PJ_ENOTFOUND;
    }

    /* Sort checklist based on priority */
    sort_checklist(ice, clist);

    /* Prune the checklist */
    status = prune_checklist(ice, clist);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(ice->grp_lock);
	return status;
    }

    /* Disable our components which don't have matching component */
    for (i=highest_comp; i<ice->comp_cnt; ++i) {
	if (ice->comp[i].stun_sess) {
	    pj_stun_session_destroy(ice->comp[i].stun_sess);
	    pj_bzero(&ice->comp[i], sizeof(ice->comp[i]));
	}
    }
    ice->comp_cnt = highest_comp;

    /* Init timer entry in the checklist. Initially the timer ID is FALSE
     * because timer is not running.
     */
    clist->timer.id = PJ_FALSE;
    td = PJ_POOL_ZALLOC_T(ice->pool, timer_data);
    td->ice = ice;
    td->clist = clist;
    clist->timer.user_data = (void*)td;
    clist->timer.cb = &periodic_timer;


    /* Log checklist */
    dump_checklist("Checklist created:", ice, clist);

    pj_grp_lock_release(ice->grp_lock);

    return PJ_SUCCESS;
}

/* Perform check on the specified candidate pair. */
static pj_status_t perform_check(pj_ice_sess *ice, 
				 pj_ice_sess_checklist *clist,
				 unsigned check_id,
				 pj_bool_t nominate)
{
    pj_ice_sess_comp *comp;
    pj_ice_msg_data *msg_data;
    pj_ice_sess_check *check;
    const pj_ice_sess_cand *lcand;
    const pj_ice_sess_cand *rcand;
    pj_uint32_t prio;
    pj_status_t status;

    check = &clist->checks[check_id];
    lcand = check->lcand;
    rcand = check->rcand;
    comp = find_comp(ice, lcand->comp_id);

    LOG5((ice->obj_name, 
	 "Sending connectivity check for check %s", 
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, check)));
    pj_log_push_indent();

    /* Create request */
    status = pj_stun_session_create_req(comp->stun_sess, 
					PJ_STUN_BINDING_REQUEST, PJ_STUN_MAGIC,
					NULL, &check->tdata);
    if (status != PJ_SUCCESS) {
	pjnath_perror(ice->obj_name, "Error creating STUN request", status);
	pj_log_pop_indent();
	return status;
    }

    /* Attach data to be retrieved later when STUN request transaction
     * completes and on_stun_request_complete() callback is called.
     */
    msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, pj_ice_msg_data);
    msg_data->transport_id = lcand->transport_id;
    msg_data->has_req_data = PJ_TRUE;
    msg_data->data.req.ice = ice;
    msg_data->data.req.clist = clist;
    msg_data->data.req.ckid = check_id;

    /* Add PRIORITY */
#if PJNATH_ICE_PRIO_STD
    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535, 
			  lcand->comp_id);
#else
    prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 0, 
			  lcand->comp_id);
#endif
    pj_stun_msg_add_uint_attr(check->tdata->pool, check->tdata->msg, 
			      PJ_STUN_ATTR_PRIORITY, prio);

    /* Add USE-CANDIDATE and set this check to nominated.
     * Also add ICE-CONTROLLING or ICE-CONTROLLED
     */
    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) {
	if (nominate) {
	    pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg,
				       PJ_STUN_ATTR_USE_CANDIDATE);
	    check->nominated = PJ_TRUE;
	}

	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, 
				    PJ_STUN_ATTR_ICE_CONTROLLING,
				    &ice->tie_breaker);

    } else {
	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, 
				    PJ_STUN_ATTR_ICE_CONTROLLED,
				    &ice->tie_breaker);
    }


    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the 
     * STUN session.
     */

    /* Initiate STUN transaction to send the request */
    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, 
				      PJ_TRUE, &rcand->addr, 
				      pj_sockaddr_get_len(&rcand->addr),
				      check->tdata);
    if (status != PJ_SUCCESS) {
	check->tdata = NULL;
	pjnath_perror(ice->obj_name, "Error sending STUN request", status);
	pj_log_pop_indent();
	return status;
    }

    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS, 
	            PJ_SUCCESS);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}


/* Start periodic check for the specified checklist.
 * This callback is called by timer on every Ta (20msec by default)
 */
static pj_status_t start_periodic_check(pj_timer_heap_t *th, 
					pj_timer_entry *te)
{
    timer_data *td;
    pj_ice_sess *ice;
    pj_ice_sess_checklist *clist;
    unsigned i, start_count=0;
    pj_status_t status;

    td = (struct timer_data*) te->user_data;
    ice = td->ice;
    clist = td->clist;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_SUCCESS;
    }

    /* Set timer ID to FALSE first */
    te->id = PJ_FALSE;

    /* Set checklist state to Running */
    clist_set_state(ice, clist, PJ_ICE_SESS_CHECKLIST_ST_RUNNING);

    LOG5((ice->obj_name, "Starting checklist periodic check"));
    pj_log_push_indent();

    /* Send STUN Binding request for check with highest priority on
     * Waiting state.
     */
    for (i=0; i<clist->count; ++i) {
	pj_ice_sess_check *check = &clist->checks[i];

	if (check->state == PJ_ICE_SESS_CHECK_STATE_WAITING) {
	    status = perform_check(ice, clist, i, ice->is_nominating);
	    if (status != PJ_SUCCESS) {
		pj_grp_lock_release(ice->grp_lock);
		pj_log_pop_indent();
		return status;
	    }

	    ++start_count;
	    break;
	}
    }

    /* If we don't have anything in Waiting state, perform check to
     * highest priority pair that is in Frozen state.
     */
    if (start_count==0) {
	for (i=0; i<clist->count; ++i) {
	    pj_ice_sess_check *check = &clist->checks[i];

	    if (check->state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
		status = perform_check(ice, clist, i, ice->is_nominating);
		if (status != PJ_SUCCESS) {
		    pj_grp_lock_release(ice->grp_lock);
		    pj_log_pop_indent();
		    return status;
		}

		++start_count;
		break;
	    }
	}
    }

    /* Cannot start check because there's no suitable candidate pair.
     */
    if (start_count!=0) {
	/* Schedule for next timer */
	pj_time_val timeout = {0, PJ_ICE_TA_VAL};

	pj_time_val_normalize(&timeout);
	pj_timer_heap_schedule_w_grp_lock(th, te, &timeout, PJ_TRUE,
	                                  ice->grp_lock);
    }

    pj_grp_lock_release(ice->grp_lock);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}


/* Start sending connectivity check with USE-CANDIDATE */
static void start_nominated_check(pj_ice_sess *ice)
{
    pj_time_val delay;
    unsigned i;
    pj_status_t status;

    LOG4((ice->obj_name, "Starting nominated check.."));
    pj_log_push_indent();

    pj_assert(ice->is_nominating == PJ_FALSE);

    /* Stop our timer if it's active */
    if (ice->timer.id == TIMER_START_NOMINATED_CHECK) {
	pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap, &ice->timer,
	                               TIMER_NONE);
    }

    /* For each component, set the check state of valid check with
     * highest priority to Waiting (it should have Success state now).
     */
    for (i=0; i<ice->comp_cnt; ++i) {
	unsigned j;
	const pj_ice_sess_check *vc = ice->comp[i].valid_check;

	pj_assert(ice->comp[i].nominated_check == NULL);
	pj_assert(vc->err_code == PJ_SUCCESS);

	for (j=0; j<ice->clist.count; ++j) {
	    pj_ice_sess_check *c = &ice->clist.checks[j];
	    if (c->lcand->transport_id == vc->lcand->transport_id &&
		c->rcand == vc->rcand)
	    {
		pj_assert(c->err_code == PJ_SUCCESS);
		c->state = PJ_ICE_SESS_CHECK_STATE_FROZEN;
		check_set_state(ice, c, PJ_ICE_SESS_CHECK_STATE_WAITING, 
			        PJ_SUCCESS);
		break;
	    }
	}
    }

    /* And (re)start the periodic check */
    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,
                                   &ice->clist.timer, PJ_FALSE);

    delay.sec = delay.msec = 0;
    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
                                               &ice->clist.timer, &delay,
                                               PJ_TRUE,
                                               ice->grp_lock);
    if (status == PJ_SUCCESS) {
	LOG5((ice->obj_name, "Periodic timer rescheduled.."));
    }

    ice->is_nominating = PJ_TRUE;
    pj_log_pop_indent();
}

/* Timer callback to perform periodic check */
static void periodic_timer(pj_timer_heap_t *th, 
			   pj_timer_entry *te)
{
    start_periodic_check(th, te);
}


/* Utility: find string in string array */
const pj_str_t *find_str(const pj_str_t *strlist[], unsigned count,
			 const pj_str_t *str)
{
    unsigned i;
    for (i=0; i<count; ++i) {
	if (pj_strcmp(strlist[i], str)==0)
	    return strlist[i];
    }
    return NULL;
}


/*
 * Start ICE periodic check. This function will return immediately, and
 * application will be notified about the connectivity check status in
 * #pj_ice_sess_cb callback.
 */
PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice)
{
    pj_ice_sess_checklist *clist;
    const pj_ice_sess_cand *cand0;
    const pj_str_t *flist[PJ_ICE_MAX_CAND]; // XXX
    pj_ice_rx_check *rcheck;
    unsigned i, flist_cnt = 0;
    pj_time_val delay;
    pj_status_t status;

    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    /* Checklist must have been created */
    PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP);

    /* Lock session */
    pj_grp_lock_acquire(ice->grp_lock);

    LOG4((ice->obj_name, "Starting ICE check.."));
    pj_log_push_indent();

    /* If we are using aggressive nomination, set the is_nominating state */
    if (ice->opt.aggressive)
	ice->is_nominating = PJ_TRUE;

    /* The agent examines the check list for the first media stream (a
     * media stream is the first media stream when it is described by
     * the first m-line in the SDP offer and answer).  For that media
     * stream, it:
     * 
     * -  Groups together all of the pairs with the same foundation,
     * 
     * -  For each group, sets the state of the pair with the lowest
     *    component ID to Waiting.  If there is more than one such pair,
     *    the one with the highest priority is used.
     */

    clist = &ice->clist;

    /* Pickup the first pair for component 1. */
    for (i=0; i<clist->count; ++i) {
	if (clist->checks[i].lcand->comp_id == 1)
	    break;
    }
    if (i == clist->count) {
	pj_assert(!"Unable to find checklist for component 1");
	pj_grp_lock_release(ice->grp_lock);
	pj_log_pop_indent();
	return PJNATH_EICEINCOMPID;
    }

    /* Set this check to WAITING only if state is frozen. It may be possible
     * that this check has already been started by a trigger check
     */
    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
	check_set_state(ice, &clist->checks[i], 
			PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);
    }

    cand0 = clist->checks[i].lcand;
    flist[flist_cnt++] = &clist->checks[i].lcand->foundation;

    /* Find all of the other pairs in that check list with the same
     * component ID, but different foundations, and sets all of their
     * states to Waiting as well.
     */
    for (++i; i<clist->count; ++i) {
	const pj_ice_sess_cand *cand1;

	cand1 = clist->checks[i].lcand;

	if (cand1->comp_id==cand0->comp_id &&
	    find_str(flist, flist_cnt, &cand1->foundation)==NULL)
	{
	    if (clist->checks[i].state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
		check_set_state(ice, &clist->checks[i], 
				PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS);
	    }
	    flist[flist_cnt++] = &cand1->foundation;
	}
    }

    /* First, perform all pending triggered checks, simultaneously. */
    rcheck = ice->early_check.next;
    while (rcheck != &ice->early_check) {
	LOG4((ice->obj_name, 
	      "Performing delayed triggerred check for component %d",
	      rcheck->comp_id));
	pj_log_push_indent();
	handle_incoming_check(ice, rcheck);
	rcheck = rcheck->next;
	pj_log_pop_indent();
    }
    pj_list_init(&ice->early_check);

    /* Start periodic check */
    /* We could start it immediately like below, but lets schedule timer 
     * instead to reduce stack usage:
     * return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer);
     */
    delay.sec = delay.msec = 0;
    status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
                                               &clist->timer, &delay,
                                               PJ_TRUE, ice->grp_lock);
    if (status != PJ_SUCCESS) {
	clist->timer.id = PJ_FALSE;
    }

    pj_grp_lock_release(ice->grp_lock);
    pj_log_pop_indent();
    return status;
}


//////////////////////////////////////////////////////////////////////////////

/* Callback called by STUN session to send the STUN message.
 * STUN session also doesn't have a transport, remember?!
 */
static pj_status_t on_stun_send_msg(pj_stun_session *sess,
				    void *token,
				    const void *pkt,
				    pj_size_t pkt_size,
				    const pj_sockaddr_t *dst_addr,
				    unsigned addr_len)
{
    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess);
    pj_ice_sess *ice = sd->ice;
    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;
    pj_status_t status;
    
    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	/* Stray retransmit timer that could happen while
	 * we're being destroyed */
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    status = (*ice->cb.on_tx_pkt)(ice, sd->comp_id, msg_data->transport_id,
				  pkt, pkt_size, dst_addr, addr_len);

    pj_grp_lock_release(ice->grp_lock);
    return status;
}


/* This callback is called when outgoing STUN request completed */
static void on_stun_request_complete(pj_stun_session *stun_sess,
				     pj_status_t status,
				     void *token,
				     pj_stun_tx_data *tdata,
				     const pj_stun_msg *response,
				     const pj_sockaddr_t *src_addr,
				     unsigned src_addr_len)
{
    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token;
    pj_ice_sess *ice;
    pj_ice_sess_check *check, *new_check;
    pj_ice_sess_cand *lcand;
    pj_ice_sess_checklist *clist;
    pj_stun_xor_mapped_addr_attr *xaddr;
    unsigned i;

    PJ_UNUSED_ARG(stun_sess);
    PJ_UNUSED_ARG(src_addr_len);

    pj_assert(msg_data->has_req_data);

    ice = msg_data->data.req.ice;
    clist = msg_data->data.req.clist;
    check = &clist->checks[msg_data->data.req.ckid];
    

    /* Mark STUN transaction as complete */
    pj_assert(tdata == check->tdata);
    check->tdata = NULL;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	/* Not sure if this is possible but just in case */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* Init lcand to NULL. lcand will be found from the mapped address
     * found in the response.
     */
    lcand = NULL;

    if (status != PJ_SUCCESS) {
	char errmsg[PJ_ERR_MSG_SIZE];

	if (status==PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ROLE_CONFLICT)) {

	    /* Role conclict response.
	     *
	     * 7.1.2.1.  Failure Cases:
	     *
	     * If the request had contained the ICE-CONTROLLED attribute, 
	     * the agent MUST switch to the controlling role if it has not
	     * already done so.  If the request had contained the 
	     * ICE-CONTROLLING attribute, the agent MUST switch to the 
	     * controlled role if it has not already done so.  Once it has
	     * switched, the agent MUST immediately retry the request with
	     * the ICE-CONTROLLING or ICE-CONTROLLED attribute reflecting 
	     * its new role.
	     */
	    pj_ice_sess_role new_role = PJ_ICE_SESS_ROLE_UNKNOWN;
	    pj_stun_msg *req = tdata->msg;

	    if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLING, 0)) {
		new_role = PJ_ICE_SESS_ROLE_CONTROLLED;
	    } else if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLED, 
					     0)) {
		new_role = PJ_ICE_SESS_ROLE_CONTROLLING;
	    } else {
		pj_assert(!"We should have put CONTROLLING/CONTROLLED attr!");
		new_role = PJ_ICE_SESS_ROLE_CONTROLLED;
	    }

	    if (new_role != ice->role) {
		LOG4((ice->obj_name, 
		      "Changing role because of role conflict response"));
		pj_ice_sess_change_role(ice, new_role);
	    }

	    /* Resend request */
	    LOG4((ice->obj_name, "Resending check because of role conflict"));
	    pj_log_push_indent();
	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0);
	    perform_check(ice, clist, msg_data->data.req.ckid, 
			  check->nominated || ice->is_nominating);
	    pj_log_pop_indent();
	    pj_grp_lock_release(ice->grp_lock);
	    return;
	}

	pj_strerror(status, errmsg, sizeof(errmsg));
	LOG4((ice->obj_name, 
	     "Check %s%s: connectivity check FAILED: %s",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
			&ice->clist, check),
	     (check->nominated ? " (nominated)" : " (not nominated)"),
	     errmsg));
	pj_log_push_indent();
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);
	on_check_complete(ice, check);
	pj_log_pop_indent();
	pj_grp_lock_release(ice->grp_lock);
	return;
    }


    /* 7.1.2.1.  Failure Cases
     *
     * The agent MUST check that the source IP address and port of the
     * response equals the destination IP address and port that the Binding
     * Request was sent to, and that the destination IP address and port of
     * the response match the source IP address and port that the Binding
     * Request was sent from.
     */
    if (pj_sockaddr_cmp(&check->rcand->addr, (const pj_sockaddr*)src_addr)!=0)
    {
	status = PJNATH_EICEINSRCADDR;
	LOG4((ice->obj_name, 
	     "Check %s%s: connectivity check FAILED: source address mismatch",
	     dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
			&ice->clist, check),
	     (check->nominated ? " (nominated)" : " (not nominated)")));
	pj_log_push_indent();
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status);
	on_check_complete(ice, check);
	pj_log_pop_indent();
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* 7.1.2.2.  Success Cases
     * 
     * A check is considered to be a success if all of the following are
     * true:
     * 
     * o  the STUN transaction generated a success response
     * 
     * o  the source IP address and port of the response equals the
     *    destination IP address and port that the Binding Request was sent
     *    to
     * 
     * o  the destination IP address and port of the response match the
     *    source IP address and port that the Binding Request was sent from
     */


    LOG4((ice->obj_name, 
	 "Check %s%s: connectivity check SUCCESS",
	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
		    &ice->clist, check),
	 (check->nominated ? " (nominated)" : " (not nominated)")));

    /* Get the STUN XOR-MAPPED-ADDRESS attribute. */
    xaddr = (pj_stun_xor_mapped_addr_attr*)
	    pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,0);
    if (!xaddr) {
	check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, 
			PJNATH_ESTUNNOMAPPEDADDR);
	on_check_complete(ice, check);
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    /* Find local candidate that matches the XOR-MAPPED-ADDRESS */
    pj_assert(lcand == NULL);
    for (i=0; i<ice->lcand_cnt; ++i) {
	if (pj_sockaddr_cmp(&xaddr->sockaddr, &ice->lcand[i].addr) == 0) {
	    /* Match */
	    lcand = &ice->lcand[i];
	    break;
	}
    }

    /* 7.1.2.2.1.  Discovering Peer Reflexive Candidates
     * If the transport address returned in XOR-MAPPED-ADDRESS does not match
     * any of the local candidates that the agent knows about, the mapped 
     * address represents a new candidate - a peer reflexive candidate.
     */
    if (lcand == NULL) {
	unsigned cand_id;
	pj_str_t foundation;

	pj_ice_calc_foundation(ice->pool, &foundation, PJ_ICE_CAND_TYPE_PRFLX,
			       &check->lcand->base_addr);

	/* Still in 7.1.2.2.1.  Discovering Peer Reflexive Candidates
	 * Its priority is set equal to the value of the PRIORITY attribute
         * in the Binding Request.
	 *
	 * I think the priority calculated by add_cand() should be the same
	 * as the one calculated in perform_check(), so there's no need to
	 * get the priority from the PRIORITY attribute.
	 */

	/* Add new peer reflexive candidate */
	status = pj_ice_sess_add_cand(ice, check->lcand->comp_id, 
				      msg_data->transport_id,
				      PJ_ICE_CAND_TYPE_PRFLX,
				      65535, &foundation,
				      &xaddr->sockaddr, 
				      &check->lcand->base_addr, 
				      &check->lcand->base_addr,
				      pj_sockaddr_get_len(&xaddr->sockaddr),
				      &cand_id);
	if (status != PJ_SUCCESS) {
	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, 
			    status);
	    on_check_complete(ice, check);
	    pj_grp_lock_release(ice->grp_lock);
	    return;
	}

	/* Update local candidate */
	lcand = &ice->lcand[cand_id];

    }

    /* 7.1.2.2.3.  Constructing a Valid Pair
     * Next, the agent constructs a candidate pair whose local candidate
     * equals the mapped address of the response, and whose remote candidate
     * equals the destination address to which the request was sent.    
     */

    /* Add pair to valid list, if it's not there, otherwise just update
     * nominated flag
     */
    for (i=0; i<ice->valid_list.count; ++i) {
	if (ice->valid_list.checks[i].lcand == lcand &&
	    ice->valid_list.checks[i].rcand == check->rcand)
	    break;
    }

    if (i==ice->valid_list.count) {
	pj_assert(ice->valid_list.count < PJ_ICE_MAX_CHECKS);
	new_check = &ice->valid_list.checks[ice->valid_list.count++];
	new_check->lcand = lcand;
	new_check->rcand = check->rcand;
	new_check->prio = CALC_CHECK_PRIO(ice, lcand, check->rcand);
	new_check->state = PJ_ICE_SESS_CHECK_STATE_SUCCEEDED;
	new_check->nominated = check->nominated;
	new_check->err_code = PJ_SUCCESS;
    } else {
	new_check = &ice->valid_list.checks[i];
	ice->valid_list.checks[i].nominated = check->nominated;
    }

    /* Update valid check and nominated check for the component */
    update_comp_check(ice, new_check->lcand->comp_id, new_check);

    /* Sort valid_list (must do so after update_comp_check(), otherwise
     * new_check will point to something else (#953)
     */
    sort_checklist(ice, &ice->valid_list);

    /* 7.1.2.2.2.  Updating Pair States
     * 
     * The agent sets the state of the pair that generated the check to
     * Succeeded.  The success of this check might also cause the state of
     * other checks to change as well.
     */
    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_SUCCEEDED, 
		    PJ_SUCCESS);

    /* Perform 7.1.2.2.2.  Updating Pair States.
     * This may terminate ICE processing.
     */
    if (on_check_complete(ice, check)) {
	/* ICE complete! */
	pj_grp_lock_release(ice->grp_lock);
	return;
    }

    pj_grp_lock_release(ice->grp_lock);
}


/* This callback is called by the STUN session associated with a candidate
 * when it receives incoming request.
 */
static pj_status_t on_stun_rx_request(pj_stun_session *sess,
				      const pj_uint8_t *pkt,
				      unsigned pkt_len,
				      const pj_stun_rx_data *rdata,
				      void *token,
				      const pj_sockaddr_t *src_addr,
				      unsigned src_addr_len)
{
    stun_data *sd;
    const pj_stun_msg *msg = rdata->msg;
    pj_ice_msg_data *msg_data;
    pj_ice_sess *ice;
    pj_stun_priority_attr *prio_attr;
    pj_stun_use_candidate_attr *uc_attr;
    pj_stun_uint64_attr *role_attr;
    pj_stun_tx_data *tdata;
    pj_ice_rx_check *rcheck, tmp_rcheck;
    pj_status_t status;

    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    
    /* Reject any requests except Binding request */
    if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) {
	pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, 
				NULL, token, PJ_TRUE, 
				src_addr, src_addr_len);
	return PJ_SUCCESS;
    }


    sd = (stun_data*) pj_stun_session_get_user_data(sess);
    ice = sd->ice;

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    /*
     * Note:
     *  Be aware that when STUN request is received, we might not get
     *  SDP answer yet, so we might not have remote candidates and
     *  checklist yet. This case will be handled after we send
     *  a response.
     */

    /* Get PRIORITY attribute */
    prio_attr = (pj_stun_priority_attr*)
	        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PRIORITY, 0);
    if (prio_attr == NULL) {
	LOG5((ice->obj_name, "Received Binding request with no PRIORITY"));
	pj_grp_lock_release(ice->grp_lock);
	return PJ_SUCCESS;
    }

    /* Get USE-CANDIDATE attribute */
    uc_attr = (pj_stun_use_candidate_attr*)
	      pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USE_CANDIDATE, 0);


    /* Get ICE-CONTROLLING or ICE-CONTROLLED */
    role_attr = (pj_stun_uint64_attr*)
	        pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLING, 0);
    if (role_attr == NULL) {
	role_attr = (pj_stun_uint64_attr*)
	            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICE_CONTROLLED, 0);
    }

    /* Handle the case when request comes before answer is received.
     * We need to put credential in the response, and since we haven't
     * got the response, copy the username from the request.
     */
    if (ice->rcand_cnt == 0) {
	pj_stun_string_attr *uname_attr;

	uname_attr = (pj_stun_string_attr*)
		     pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);
	pj_assert(uname_attr != NULL);
	pj_strdup(ice->pool, &ice->rx_uname, &uname_attr->value);
    }

    /* 7.2.1.1.  Detecting and Repairing Role Conflicts
     */
    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING &&
	role_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLING)
    {
	if (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {
	    /* Switch role to controlled */
	    LOG4((ice->obj_name, 
		  "Changing role because of ICE-CONTROLLING attribute"));
	    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLED);
	} else {
	    /* Generate 487 response */
	    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 
				    NULL, token, PJ_TRUE, 
				    src_addr, src_addr_len);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	}

    } else if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED &&
	       role_attr && role_attr->hdr.type == PJ_STUN_ATTR_ICE_CONTROLLED)
    {
	if (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) {
	    /* Generate 487 response */
	    pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 
				    NULL, token, PJ_TRUE, 
				    src_addr, src_addr_len);
	    pj_grp_lock_release(ice->grp_lock);
	    return PJ_SUCCESS;
	} else {
	    /* Switch role to controlled */
	    LOG4((ice->obj_name, 
		  "Changing role because of ICE-CONTROLLED attribute"));
	    pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLING);
	}
    }

    /* 
     * First send response to this request 
     */
    status = pj_stun_session_create_res(sess, rdata, 0, NULL, &tdata);
    if (status != PJ_SUCCESS) {
	pj_grp_lock_release(ice->grp_lock);
	return status;
    }

    /* Add XOR-MAPPED-ADDRESS attribute */
    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
					   PJ_STUN_ATTR_XOR_MAPPED_ADDR,
					   PJ_TRUE, src_addr, src_addr_len);

    /* Create a msg_data to be associated with this response */
    msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data);
    msg_data->transport_id = ((pj_ice_msg_data*)token)->transport_id;
    msg_data->has_req_data = PJ_FALSE;

    /* Send the response */
    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE,
				      src_addr, src_addr_len, tdata);


    /* 
     * Handling early check.
     *
     * It's possible that we receive this request before we receive SDP
     * answer. In this case, we can't perform trigger check since we
     * don't have checklist yet, so just save this check in a pending
     * triggered check array to be acted upon later.
     */
    if (ice->rcand_cnt == 0) {
	rcheck = PJ_POOL_ZALLOC_T(ice->pool, pj_ice_rx_check);
    } else {
	rcheck = &tmp_rcheck;
    }

    /* Init rcheck */
    rcheck->comp_id = sd->comp_id;
    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id;
    rcheck->src_addr_len = src_addr_len;
    pj_sockaddr_cp(&rcheck->src_addr, src_addr);
    rcheck->use_candidate = (uc_attr != NULL);
    rcheck->priority = prio_attr->value;
    rcheck->role_attr = role_attr;

    if (ice->rcand_cnt == 0) {
	/* We don't have answer yet, so keep this request for later */
	LOG4((ice->obj_name, "Received an early check for comp %d",
	      rcheck->comp_id));
	pj_list_push_back(&ice->early_check, rcheck);
    } else {
	/* Handle this check */
	handle_incoming_check(ice, rcheck);
    }

    pj_grp_lock_release(ice->grp_lock);
    return PJ_SUCCESS;
}


/* Handle incoming Binding request and perform triggered check.
 * This function may be called by on_stun_rx_request(), or when
 * SDP answer is received and we have received early checks.
 */
static void handle_incoming_check(pj_ice_sess *ice,
				  const pj_ice_rx_check *rcheck)
{
    pj_ice_sess_comp *comp;
    pj_ice_sess_cand *lcand = NULL;
    pj_ice_sess_cand *rcand;
    unsigned i;

    comp = find_comp(ice, rcheck->comp_id);

    /* Find remote candidate based on the source transport address of 
     * the request.
     */
    for (i=0; i<ice->rcand_cnt; ++i) {
	if (pj_sockaddr_cmp(&rcheck->src_addr, &ice->rcand[i].addr)==0)
	    break;
    }

    /* 7.2.1.3.  Learning Peer Reflexive Candidates
     * If the source transport address of the request does not match any
     * existing remote candidates, it represents a new peer reflexive remote
     * candidate.
     */
    if (i == ice->rcand_cnt) {
	char raddr[PJ_INET6_ADDRSTRLEN];
	if (ice->rcand_cnt >= PJ_ICE_MAX_CAND) {
	    LOG4((ice->obj_name, 
	          "Unable to add new peer reflexive candidate: too many "
		  "candidates already (%d)", PJ_ICE_MAX_CAND));
	    return;
	}

	rcand = &ice->rcand[ice->rcand_cnt++];
	rcand->comp_id = (pj_uint8_t)rcheck->comp_id;
	rcand->type = PJ_ICE_CAND_TYPE_PRFLX;
	rcand->prio = rcheck->priority;
	pj_sockaddr_cp(&rcand->addr, &rcheck->src_addr);

	/* Foundation is random, unique from other foundation */
	rcand->foundation.ptr = (char*) pj_pool_alloc(ice->pool, 36);
	rcand->foundation.slen = pj_ansi_snprintf(rcand->foundation.ptr, 36,
						  "f%p", 
						  rcand->foundation.ptr);

	LOG4((ice->obj_name, 
	      "Added new remote candidate from the request: %s:%d",
	      pj_sockaddr_print(&rcand->addr, raddr, sizeof(raddr), 0),
	      pj_sockaddr_get_port(&rcand->addr)));

    } else {
	/* Remote candidate found */
	rcand = &ice->rcand[i];
    }

#if 0
    /* Find again the local candidate by matching the base address
     * with the local candidates in the checklist. Checks may have
     * been pruned before, so it's possible that if we use the lcand
     * as it is, we wouldn't be able to find the check in the checklist
     * and we will end up creating a new check unnecessarily.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (/*c->lcand == lcand ||*/
	    pj_sockaddr_cmp(&c->lcand->base_addr, &lcand->base_addr)==0)
	{
	    lcand = c->lcand;
	    break;
	}
    }
#else
    /* Just get candidate with the highest priority and same transport ID
     * for the specified  component ID in the checklist.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->lcand->comp_id == rcheck->comp_id &&
	    c->lcand->transport_id == rcheck->transport_id) 
	{
	    lcand = c->lcand;
	    break;
	}
    }
    if (lcand == NULL) {
	/* Should not happen, but just in case remote is sending a
	 * Binding request for a component which it doesn't have.
	 */
	LOG4((ice->obj_name, 
	     "Received Binding request but no local candidate is found!"));
	return;
    }
#endif

    /* 
     * Create candidate pair for this request. 
     */

    /* 
     * 7.2.1.4.  Triggered Checks
     *
     * Now that we have local and remote candidate, check if we already
     * have this pair in our checklist.
     */
    for (i=0; i<ice->clist.count; ++i) {
	pj_ice_sess_check *c = &ice->clist.checks[i];
	if (c->lcand == lcand && c->rcand == rcand)
	    break;
    }

    /* If the pair is already on the check list:
     * - If the state of that pair is Waiting or Frozen, its state is
     *   changed to In-Progress and a check for that pair is performed
     *   immediately.  This is called a triggered check.
     *
     * - If the state of that pair is In-Progress, the agent SHOULD
     *   generate an immediate retransmit of the Binding Request for the
     *   check in progress.  This is to facilitate rapid completion of
     *   ICE when both agents are behind NAT.
     * 
     * - If the state of that pair is Failed or Succeeded, no triggered
     *   check is sent.
     */
    if (i != ice->clist.count) {
	pj_ice_sess_check *c = &ice->clist.checks[i];

	/* If USE-CANDIDATE is present, set nominated flag 
	 * Note: DO NOT overwrite nominated flag if one is already set.
	 */
	c->nominated = ((rcheck->use_candidate) || c->nominated);

	if (c->state == PJ_ICE_SESS_CHECK_STATE_FROZEN ||
	    c->state == PJ_ICE_SESS_CHECK_STATE_WAITING)
	{
	    /* See if we shall nominate this check */
	    pj_bool_t nominate = (c->nominated || ice->is_nominating);

	    LOG5((ice->obj_name, "Performing triggered check for check %d",i));
	    pj_log_push_indent();
	    perform_check(ice, &ice->clist, i, nominate);
	    pj_log_pop_indent();

	} else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) {
	    /* Should retransmit immediately
	     */
	    LOG5((ice->obj_name, "Triggered check for check %d not performed "
		  "because it's in progress. Retransmitting", i));
	    pj_log_push_indent();
	    pj_stun_session_retransmit_req(comp->stun_sess, c->tdata, PJ_FALSE);
	    pj_log_pop_indent();

	} else if (c->state == PJ_ICE_SESS_CHECK_STATE_SUCCEEDED) {
	    /* Check complete for this component.
	     * Note this may end ICE process.
	     */
	    pj_bool_t complete;
	    unsigned j;

	    /* If this check is nominated, scan the valid_list for the
	     * same check and update the nominated flag. A controlled 
	     * agent might have finished the check earlier.
	     */
	    if (rcheck->use_candidate) {
		for (j=0; j<ice->valid_list.count; ++j) {
		    pj_ice_sess_check *vc = &ice->valid_list.checks[j];
		    if (vc->lcand->transport_id == c->lcand->transport_id && 
			vc->rcand == c->rcand) 
		    {
			/* Set nominated flag */
			vc->nominated = PJ_TRUE;

			/* Update valid check and nominated check for the component */
			update_comp_check(ice, vc->lcand->comp_id, vc);

			LOG5((ice->obj_name, "Valid check %s is nominated", 
			      dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), 
					 &ice->valid_list, vc)));
		    }
		}
	    }

	    LOG5((ice->obj_name, "Triggered check for check %d not performed "
				"because it's completed", i));
	    pj_log_push_indent();
	    complete = on_check_complete(ice, c);
	    pj_log_pop_indent();
	    if (complete) {
		return;
	    }
	}

    }
    /* If the pair is not already on the check list:
     * - The pair is inserted into the check list based on its priority.
     * - Its state is set to In-Progress
     * - A triggered check for that pair is performed immediately.
     */
    /* Note: only do this if we don't have too many checks in checklist */
    else if (ice->clist.count < PJ_ICE_MAX_CHECKS) {

	pj_ice_sess_check *c = &ice->clist.checks[ice->clist.count];
	pj_bool_t nominate;

	c->lcand = lcand;
	c->rcand = rcand;
	c->prio = CALC_CHECK_PRIO(ice, lcand, rcand);
	c->state = PJ_ICE_SESS_CHECK_STATE_WAITING;
	c->nominated = rcheck->use_candidate;
	c->err_code = PJ_SUCCESS;

	nominate = (c->nominated || ice->is_nominating);

	LOG4((ice->obj_name, "New triggered check added: %d", 
	     ice->clist.count));
	pj_log_push_indent();
	perform_check(ice, &ice->clist, ice->clist.count++, nominate);
	pj_log_pop_indent();

    } else {
	LOG4((ice->obj_name, "Error: unable to perform triggered check: "
	     "TOO MANY CHECKS IN CHECKLIST!"));
    }
}


static pj_status_t on_stun_rx_indication(pj_stun_session *sess,
					 const pj_uint8_t *pkt,
					 unsigned pkt_len,
					 const pj_stun_msg *msg,
					 void *token,
					 const pj_sockaddr_t *src_addr,
					 unsigned src_addr_len)
{
    struct stun_data *sd;

    PJ_UNUSED_ARG(sess);
    PJ_UNUSED_ARG(pkt);
    PJ_UNUSED_ARG(pkt_len);
    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(token);
    PJ_UNUSED_ARG(src_addr);
    PJ_UNUSED_ARG(src_addr_len);

    sd = (struct stun_data*) pj_stun_session_get_user_data(sess);

    pj_log_push_indent();

    if (msg->hdr.type == PJ_STUN_BINDING_INDICATION) {
	LOG5((sd->ice->obj_name, "Received Binding Indication keep-alive "
	      "for component %d", sd->comp_id));
    } else {
	LOG4((sd->ice->obj_name, "Received unexpected %s indication "
	      "for component %d", pj_stun_get_method_name(msg->hdr.type), 
	      sd->comp_id));
    }

    pj_log_pop_indent();

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice,
					  unsigned comp_id,
					  const void *data,
					  pj_size_t data_len)
{
    pj_status_t status = PJ_SUCCESS;
    pj_ice_sess_comp *comp;
    pj_ice_sess_cand *cand;
    pj_uint8_t transport_id;
    pj_sockaddr addr;

    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL);
    
    /* It is possible that comp_cnt is less than comp_id, when remote
     * doesn't support all the components that we have.
     */
    if (comp_id > ice->comp_cnt) {
	return PJNATH_EICEINCOMPID;
    }

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    comp = find_comp(ice, comp_id);
    if (comp == NULL) {
	status = PJNATH_EICEINCOMPID;
	pj_grp_lock_release(ice->grp_lock);
	goto on_return;
    }

    if (comp->valid_check == NULL) {
	status = PJNATH_EICEINPROGRESS;
	pj_grp_lock_release(ice->grp_lock);
	goto on_return;
    }

    cand = comp->valid_check->lcand;
    transport_id = cand->transport_id;
    pj_sockaddr_cp(&addr, &comp->valid_check->rcand->addr);

    /* Release the mutex now to avoid deadlock (see ticket #1451). */
    pj_grp_lock_release(ice->grp_lock);

    PJ_RACE_ME(5);

    status = (*ice->cb.on_tx_pkt)(ice, comp_id, transport_id, 
				  data, data_len, 
				  &addr, 
				  pj_sockaddr_get_len(&addr));

on_return:
    return status;
}


PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice,
					  unsigned comp_id,
					  unsigned transport_id,
					  void *pkt,
					  pj_size_t pkt_size,
					  const pj_sockaddr_t *src_addr,
					  int src_addr_len)
{
    pj_status_t status = PJ_SUCCESS;
    pj_ice_sess_comp *comp;
    pj_ice_msg_data *msg_data = NULL;
    unsigned i;

    PJ_ASSERT_RETURN(ice, PJ_EINVAL);

    pj_grp_lock_acquire(ice->grp_lock);

    if (ice->is_destroying) {
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVALIDOP;
    }

    comp = find_comp(ice, comp_id);
    if (comp == NULL) {
	pj_grp_lock_release(ice->grp_lock);
	return PJNATH_EICEINCOMPID;
    }

    /* Find transport */
    for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {
	if (ice->tp_data[i].transport_id == transport_id) {
	    msg_data = &ice->tp_data[i];
	    break;
	}
    }
    if (msg_data == NULL) {
	pj_assert(!"Invalid transport ID");
	pj_grp_lock_release(ice->grp_lock);
	return PJ_EINVAL;
    }

    /* Don't check fingerprint. We only need to distinguish STUN and non-STUN
     * packets. We don't need to verify the STUN packet too rigorously, that
     * will be done by the user.
     */
    status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size, 
    			       PJ_STUN_IS_DATAGRAM |
    			         PJ_STUN_NO_FINGERPRINT_CHECK);
    if (status == PJ_SUCCESS) {
	status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size,
					   PJ_STUN_IS_DATAGRAM, msg_data,
					   NULL, src_addr, src_addr_len);
	if (status != PJ_SUCCESS) {
	    pj_strerror(status, ice->tmp.errmsg, sizeof(ice->tmp.errmsg));
	    LOG4((ice->obj_name, "Error processing incoming message: %s",
		  ice->tmp.errmsg));
	}
	pj_grp_lock_release(ice->grp_lock);
    } else {
	/* Not a STUN packet. Call application's callback instead, but release
	 * the mutex now or otherwise we may get deadlock.
	 */
	pj_grp_lock_release(ice->grp_lock);

	PJ_RACE_ME(5);

	(*ice->cb.on_rx_data)(ice, comp_id, transport_id, pkt, pkt_size, 
			      src_addr, src_addr_len);
	status = PJ_SUCCESS;
    }

    return status;
}


