/* $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_srtp.h>
#include <pjmedia/endpoint.h>
#include <pjlib-util/base64.h>
#include <pj/assert.h>
#include <pj/ctype.h>
#include <pj/lock.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)

#include <srtp.h>

#define THIS_FILE   "transport_srtp.c"

/* Maximum size of outgoing packet */
#define MAX_RTP_BUFFER_LEN	    PJMEDIA_MAX_MTU
#define MAX_RTCP_BUFFER_LEN	    PJMEDIA_MAX_MTU

/* Maximum SRTP crypto key length */
#define MAX_KEY_LEN		    128

/* Initial value of probation counter. When probation counter > 0, 
 * it means SRTP is in probation state, and it may restart when
 * srtp_unprotect() returns err_status_replay_*
 */
#define PROBATION_CNT_INIT	    100

#define DEACTIVATE_MEDIA(pool, m)   pjmedia_sdp_media_deactivate(pool, m)

static const pj_str_t ID_RTP_AVP  = { "RTP/AVP", 7 };
static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 };
static const pj_str_t ID_INACTIVE = { "inactive", 8 };
static const pj_str_t ID_CRYPTO   = { "crypto", 6 };

typedef struct crypto_suite
{
    char		*name;
    cipher_type_id_t	 cipher_type;
    unsigned		 cipher_key_len;
    auth_type_id_t	 auth_type;
    unsigned		 auth_key_len;
    unsigned		 srtp_auth_tag_len;
    unsigned		 srtcp_auth_tag_len;
    sec_serv_t		 service;
} crypto_suite;

/* Crypto suites as defined on RFC 4568 */
static crypto_suite crypto_suites[] = {
    /* plain RTP/RTCP (no cipher & no auth) */
    {"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},

    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */
    {"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10, 
	sec_serv_conf_and_auth},

    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 4 octets */
    {"AES_CM_128_HMAC_SHA1_32", AES_128_ICM, 30, HMAC_SHA1, 20, 4, 10,
	sec_serv_conf_and_auth},

    /* 
     * F8_128_HMAC_SHA1_8 not supported by libsrtp?
     * {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none}
     */
};

typedef struct transport_srtp
{
    pjmedia_transport	 base;		    /**< Base transport interface.  */
    pj_pool_t		*pool;		    /**< Pool for transport SRTP.   */
    pj_lock_t		*mutex;		    /**< Mutex for libsrtp contexts.*/
    char		 rtp_tx_buffer[MAX_RTP_BUFFER_LEN];
    char		 rtcp_tx_buffer[MAX_RTCP_BUFFER_LEN];
    pjmedia_srtp_setting setting;
    unsigned		 media_option;

    /* SRTP policy */
    pj_bool_t		 session_inited;
    pj_bool_t		 offerer_side;
    pj_bool_t		 bypass_srtp;
    char		 tx_key[MAX_KEY_LEN];
    char		 rx_key[MAX_KEY_LEN];
    pjmedia_srtp_crypto  tx_policy;
    pjmedia_srtp_crypto  rx_policy;

    /* Temporary policy for negotiation */
    pjmedia_srtp_crypto  tx_policy_neg;
    pjmedia_srtp_crypto  rx_policy_neg;

    /* libSRTP contexts */
    srtp_t		 srtp_tx_ctx;
    srtp_t		 srtp_rx_ctx;

    /* Stream information */
    void		*user_data;
    void		(*rtp_cb)( void *user_data,
				   void *pkt,
				   pj_ssize_t size);
    void		(*rtcp_cb)(void *user_data,
				   void *pkt,
				   pj_ssize_t size);
        
    /* Transport information */
    pjmedia_transport	*member_tp; /**< Underlying transport.       */

    /* SRTP usage policy of peer. This field is updated when media is starting.
     * This is useful when SRTP is in optional mode and peer is using mandatory
     * mode, so when local is about to reinvite/update, it should offer 
     * RTP/SAVP instead of offering RTP/AVP.
     */
    pjmedia_srtp_use	 peer_use;

    /* When probation counter > 0, it means SRTP is in probation state, 
     * and it may restart when srtp_unprotect() returns err_status_replay_*
     */
    unsigned		 probation_cnt;
} transport_srtp;


/*
 * This callback is called by transport when incoming rtp is received
 */
static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size);

/*
 * This callback is called by transport when incoming rtcp is received
 */
static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size);


/*
 * 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 *sdp_pool,
				       unsigned options,
				       const pjmedia_sdp_session *sdp_remote,
				       unsigned media_index);
static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
				       pj_pool_t *sdp_pool,
				       pjmedia_sdp_session *sdp_local,
				       const pjmedia_sdp_session *sdp_remote,
				       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 *sdp_remote,
				       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);



static pjmedia_transport_op transport_srtp_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
};

/* This function may also be used by other module, e.g: pjmedia/errno.c,
 * it should have C compatible declaration.
 */
PJ_BEGIN_DECL
    const char* get_libsrtp_errstr(int err);
PJ_END_DECL

const char* get_libsrtp_errstr(int err)
{
#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
    static char *liberr[] = {
	"ok",				    /* err_status_ok            = 0  */
	"unspecified failure",		    /* err_status_fail          = 1  */
	"unsupported parameter",	    /* err_status_bad_param     = 2  */
	"couldn't allocate memory",	    /* err_status_alloc_fail    = 3  */
	"couldn't deallocate properly",	    /* err_status_dealloc_fail  = 4  */
	"couldn't initialize",		    /* err_status_init_fail     = 5  */
	"can't process as much data as requested", 
					    /* err_status_terminus      = 6  */
	"authentication failure",	    /* err_status_auth_fail     = 7  */
	"cipher failure",		    /* err_status_cipher_fail   = 8  */
	"replay check failed (bad index)",  /* err_status_replay_fail   = 9  */
	"replay check failed (index too old)", 
					    /* err_status_replay_old    = 10 */
	"algorithm failed test routine",    /* err_status_algo_fail     = 11 */
	"unsupported operation",	    /* err_status_no_such_op    = 12 */
	"no appropriate context found",	    /* err_status_no_ctx        = 13 */
	"unable to perform desired validation", 
					    /* err_status_cant_check    = 14 */
	"can't use key any more",	    /* err_status_key_expired   = 15 */
	"error in use of socket",	    /* err_status_socket_err    = 16 */
	"error in use POSIX signals",	    /* err_status_signal_err    = 17 */
	"nonce check failed",		    /* err_status_nonce_bad     = 18 */
	"couldn't read data",		    /* err_status_read_fail     = 19 */
	"couldn't write data",		    /* err_status_write_fail    = 20 */
	"error pasring data",		    /* err_status_parse_err     = 21 */
	"error encoding data",		    /* err_status_encode_err    = 22 */
	"error while using semaphores",	    /* err_status_semaphore_err = 23 */
	"error while using pfkey"	    /* err_status_pfkey_err     = 24 */
    };
    if (err >= 0 && err < (int)PJ_ARRAY_SIZE(liberr)) {
	return liberr[err];
    } else {
	static char msg[32];
	pj_ansi_snprintf(msg, sizeof(msg), "Unknown libsrtp error %d", err);
	return msg;
    }
#else
    static char msg[32];
    pj_ansi_snprintf(msg, sizeof(msg), "libsrtp error %d", err);
    return msg;
#endif
}

static pj_bool_t libsrtp_initialized;
static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt);

PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)
{
    if (libsrtp_initialized == PJ_FALSE) {
	err_status_t err;

	err = srtp_init();
	if (err != err_status_ok) { 
	    PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", 
		       get_libsrtp_errstr(err)));
	    return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
	}

	if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS)
	{
	    /* There will be memory leak when it fails to schedule libsrtp 
	     * deinitialization, however the memory leak could be harmless,
	     * since in modern OS's memory used by an application is released 
	     * when the application terminates.
	     */
	    PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit."));
	}

	libsrtp_initialized = PJ_TRUE;
    }
    
    return PJ_SUCCESS;
}

static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt)
{
    err_status_t err;

    /* Note that currently this SRTP init/deinit is not equipped with
     * reference counter, it should be safe as normally there is only
     * one single instance of media endpoint and even if it isn't, the
     * pjmedia_transport_srtp_create() will invoke SRTP init (the only
     * drawback should be the delay described by #788).
     */

    PJ_UNUSED_ARG(endpt);

    err = srtp_deinit();
    if (err != err_status_ok) {
	PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s", 
		   get_libsrtp_errstr(err)));
    }

    libsrtp_initialized = PJ_FALSE;
}


static int get_crypto_idx(const pj_str_t* crypto_name)
{
    int i;
    int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
    
    /* treat unspecified crypto_name as crypto 'NULL' */
    if (crypto_name->slen == 0)
	return 0;

    for (i=0; i<cs_cnt; ++i) {
	if (!pj_stricmp2(crypto_name, crypto_suites[i].name))
	    return i;
    }

    return -1;
}


static int srtp_crypto_cmp(const pjmedia_srtp_crypto* c1,
			   const pjmedia_srtp_crypto* c2)
{
    int r;

    r = pj_strcmp(&c1->key, &c2->key);
    if (r != 0)
	return r;

    r = pj_stricmp(&c1->name, &c2->name);
    if (r != 0)
	return r;

    return (c1->flags != c2->flags);
}


static pj_bool_t srtp_crypto_empty(const pjmedia_srtp_crypto* c)
{
    return (c->name.slen==0 || c->key.slen==0);
}


PJ_DEF(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt)
{
    unsigned i;

    pj_assert(opt);

    pj_bzero(opt, sizeof(pjmedia_srtp_setting));
    opt->close_member_tp = PJ_TRUE;
    opt->use = PJMEDIA_SRTP_OPTIONAL;

    /* Copy default crypto-suites, but skip crypto 'NULL' */
    opt->crypto_count = sizeof(crypto_suites)/sizeof(crypto_suites[0]) - 1;
    for (i=0; i<opt->crypto_count; ++i)
	opt->crypto[i].name = pj_str(crypto_suites[i+1].name);
}


/*
 * Create an SRTP media transport.
 */
PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
				       pjmedia_endpt *endpt,
				       pjmedia_transport *tp,
				       const pjmedia_srtp_setting *opt,
				       pjmedia_transport **p_tp)
{
    pj_pool_t *pool;
    transport_srtp *srtp;
    pj_status_t status;
    unsigned i;

    PJ_ASSERT_RETURN(endpt && tp && p_tp, PJ_EINVAL);

    /* Check crypto availability */
    if (opt && opt->crypto_count == 0 && 
	opt->use == PJMEDIA_SRTP_MANDATORY)
	return PJMEDIA_SRTP_ESDPREQCRYPTO;

    /* Check crypto */
    if (opt && opt->use != PJMEDIA_SRTP_DISABLED) {
	for (i=0; i < opt->crypto_count; ++i) {
	    int cs_idx = get_crypto_idx(&opt->crypto[i].name);

	    /* check crypto name */
	    if (cs_idx == -1)
		return PJMEDIA_SRTP_ENOTSUPCRYPTO;

	    /* check key length */
	    if (opt->crypto[i].key.slen && 
		opt->crypto[i].key.slen < 
		(pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)
		return PJMEDIA_SRTP_EINKEYLEN;
	}
    }

    /* Init libsrtp. */
    status = pjmedia_srtp_init_lib(endpt);
    if (status != PJ_SUCCESS)
	return status;

    pool = pjmedia_endpt_create_pool(endpt, "srtp%p", 1000, 1000);
    srtp = PJ_POOL_ZALLOC_T(pool, transport_srtp);

    srtp->pool = pool;
    srtp->session_inited = PJ_FALSE;
    srtp->bypass_srtp = PJ_FALSE;
    srtp->probation_cnt = PROBATION_CNT_INIT;

    if (opt) {
	srtp->setting = *opt;
	if (opt->use == PJMEDIA_SRTP_DISABLED)
	    srtp->setting.crypto_count = 0;

	for (i=0; i < srtp->setting.crypto_count; ++i) {
	    int cs_idx = get_crypto_idx(&opt->crypto[i].name);
	    pj_str_t tmp_key = opt->crypto[i].key;

	    /* re-set crypto */
	    srtp->setting.crypto[i].name = pj_str(crypto_suites[cs_idx].name);
	    /* cut key length */
	    if (tmp_key.slen)
		tmp_key.slen = crypto_suites[cs_idx].cipher_key_len;
	    pj_strdup(pool, &srtp->setting.crypto[i].key, &tmp_key);
	}
    } else {
	pjmedia_srtp_setting_default(&srtp->setting);
    }

    status = pj_lock_create_recursive_mutex(pool, pool->obj_name, &srtp->mutex);
    if (status != PJ_SUCCESS) {
	pj_pool_release(pool);
	return status;
    }

    /* Initialize base pjmedia_transport */
    pj_memcpy(srtp->base.name, pool->obj_name, PJ_MAX_OBJ_NAME);
    if (tp)
	srtp->base.type = tp->type;
    else
	srtp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;
    srtp->base.op = &transport_srtp_op;

    /* Set underlying transport */
    srtp->member_tp = tp;

    /* Initialize peer's SRTP usage mode. */
    srtp->peer_use = srtp->setting.use;

    /* Done */
    *p_tp = &srtp->base;

    return PJ_SUCCESS;
}


/*
 * Initialize and start SRTP session with the given parameters.
 */
PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
			   pjmedia_transport *tp, 
			   const pjmedia_srtp_crypto *tx,
			   const pjmedia_srtp_crypto *rx)
{
    transport_srtp  *srtp = (transport_srtp*) tp;
    srtp_policy_t    tx_;
    srtp_policy_t    rx_;
    err_status_t     err;
    int		     cr_tx_idx = 0;
    int		     au_tx_idx = 0;
    int		     cr_rx_idx = 0;
    int		     au_rx_idx = 0;
    int		     crypto_suites_cnt;
    pj_status_t	     status = PJ_SUCCESS;

    PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL);

    pj_lock_acquire(srtp->mutex);

    if (srtp->session_inited) {
	pjmedia_transport_srtp_stop(tp);
    }

    crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);

    /* Get encryption and authentication method */
    cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name);
    if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)
	cr_tx_idx = 0;
    if (tx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)
	au_tx_idx = 0;

    cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name);
    if (rx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)
	cr_rx_idx = 0;
    if (rx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)
	au_rx_idx = 0;

    /* Check whether the crypto-suite requested is supported */
    if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || 
	au_rx_idx == -1)
    {
	status = PJMEDIA_SRTP_ENOTSUPCRYPTO;
	goto on_return;
    }

    /* If all options points to 'NULL' method, just bypass SRTP */
    if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) {
	srtp->bypass_srtp = PJ_TRUE;
	goto on_return;
    }

    /* Check key length */
    if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len ||
        rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len)
    {
	status = PJMEDIA_SRTP_EINKEYLEN;
	goto on_return;
    }

    /* Init transmit direction */
    pj_bzero(&tx_, sizeof(srtp_policy_t));
    pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen);
    if (cr_tx_idx && au_tx_idx)
	tx_.rtp.sec_serv    = sec_serv_conf_and_auth;
    else if (cr_tx_idx)
	tx_.rtp.sec_serv    = sec_serv_conf;
    else if (au_tx_idx)
	tx_.rtp.sec_serv    = sec_serv_auth;
    else
	tx_.rtp.sec_serv    = sec_serv_none;
    tx_.key		    = (uint8_t*)srtp->tx_key;
    tx_.ssrc.type	    = ssrc_any_outbound;
    tx_.ssrc.value	    = 0;
    tx_.rtp.cipher_type	    = crypto_suites[cr_tx_idx].cipher_type;
    tx_.rtp.cipher_key_len  = crypto_suites[cr_tx_idx].cipher_key_len;
    tx_.rtp.auth_type	    = crypto_suites[au_tx_idx].auth_type;
    tx_.rtp.auth_key_len    = crypto_suites[au_tx_idx].auth_key_len;
    tx_.rtp.auth_tag_len    = crypto_suites[au_tx_idx].srtp_auth_tag_len;
    tx_.rtcp		    = tx_.rtp;
    tx_.rtcp.auth_tag_len   = crypto_suites[au_tx_idx].srtcp_auth_tag_len;
    tx_.next		    = NULL;
    err = srtp_create(&srtp->srtp_tx_ctx, &tx_);
    if (err != err_status_ok) {
	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
	goto on_return;
    }
    srtp->tx_policy = *tx;
    pj_strset(&srtp->tx_policy.key,  srtp->tx_key, tx->key.slen);
    srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name);


    /* Init receive direction */
    pj_bzero(&rx_, sizeof(srtp_policy_t));
    pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen);
    if (cr_rx_idx && au_rx_idx)
	rx_.rtp.sec_serv    = sec_serv_conf_and_auth;
    else if (cr_rx_idx)
	rx_.rtp.sec_serv    = sec_serv_conf;
    else if (au_rx_idx)
	rx_.rtp.sec_serv    = sec_serv_auth;
    else
	rx_.rtp.sec_serv    = sec_serv_none;
    rx_.key		    = (uint8_t*)srtp->rx_key;
    rx_.ssrc.type	    = ssrc_any_inbound;
    rx_.ssrc.value	    = 0;
    rx_.rtp.sec_serv	    = crypto_suites[cr_rx_idx].service;
    rx_.rtp.cipher_type	    = crypto_suites[cr_rx_idx].cipher_type;
    rx_.rtp.cipher_key_len  = crypto_suites[cr_rx_idx].cipher_key_len;
    rx_.rtp.auth_type	    = crypto_suites[au_rx_idx].auth_type;
    rx_.rtp.auth_key_len    = crypto_suites[au_rx_idx].auth_key_len;
    rx_.rtp.auth_tag_len    = crypto_suites[au_rx_idx].srtp_auth_tag_len;
    rx_.rtcp		    = rx_.rtp;
    rx_.rtcp.auth_tag_len   = crypto_suites[au_rx_idx].srtcp_auth_tag_len;
    rx_.next		    = NULL;
    err = srtp_create(&srtp->srtp_rx_ctx, &rx_);
    if (err != err_status_ok) {
	srtp_dealloc(srtp->srtp_tx_ctx);
	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
	goto on_return;
    }
    srtp->rx_policy = *rx;
    pj_strset(&srtp->rx_policy.key,  srtp->rx_key, rx->key.slen);
    srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name);

    /* Declare SRTP session initialized */
    srtp->session_inited = PJ_TRUE;

    /* Logging stuffs */
#if PJ_LOG_MAX_LEVEL >= 5
    {
	char b64[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)];
	int b64_len;

	/* TX crypto and key */
	b64_len = sizeof(b64);
	status = pj_base64_encode((pj_uint8_t*)tx->key.ptr, tx->key.slen,
				  b64, &b64_len);
	if (status != PJ_SUCCESS)
	    b64_len = pj_ansi_sprintf(b64, "--key too long--");
	else
	    b64[b64_len] = '\0';
        
	PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s",
		   srtp->tx_policy.name.ptr, b64));
	if (srtp->tx_policy.flags) {
	    PJ_LOG(5,(srtp->pool->obj_name, "TX: disable%s%s",
		      (cr_tx_idx?"":" enc"),
		      (au_tx_idx?"":" auth")));
	}

	/* RX crypto and key */
	b64_len = sizeof(b64);
	status = pj_base64_encode((pj_uint8_t*)rx->key.ptr, rx->key.slen,
				  b64, &b64_len);
	if (status != PJ_SUCCESS)
	    b64_len = pj_ansi_sprintf(b64, "--key too long--");
	else
	    b64[b64_len] = '\0';

	PJ_LOG(5, (srtp->pool->obj_name, "RX: %s key=%s",
		   srtp->rx_policy.name.ptr, b64));
	if (srtp->rx_policy.flags) {
	    PJ_LOG(5,(srtp->pool->obj_name,"RX: disable%s%s",
		      (cr_rx_idx?"":" enc"),
		      (au_rx_idx?"":" auth")));
	}
    }
#endif

on_return:
    pj_lock_release(srtp->mutex);
    return status;
}

/*
 * Stop SRTP session.
 */
PJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp)
{
    transport_srtp *p_srtp = (transport_srtp*) srtp;
    err_status_t err;

    PJ_ASSERT_RETURN(srtp, PJ_EINVAL);

    pj_lock_acquire(p_srtp->mutex);

    if (!p_srtp->session_inited) {
	pj_lock_release(p_srtp->mutex);
	return PJ_SUCCESS;
    }

    err = srtp_dealloc(p_srtp->srtp_rx_ctx);
    if (err != err_status_ok) {
	PJ_LOG(4, (p_srtp->pool->obj_name, 
		   "Failed to dealloc RX SRTP context: %s",
		   get_libsrtp_errstr(err)));
    }
    err = srtp_dealloc(p_srtp->srtp_tx_ctx);
    if (err != err_status_ok) {
	PJ_LOG(4, (p_srtp->pool->obj_name, 
		   "Failed to dealloc TX SRTP context: %s",
		   get_libsrtp_errstr(err)));
    }

    p_srtp->session_inited = PJ_FALSE;
    pj_bzero(&p_srtp->rx_policy, sizeof(p_srtp->rx_policy));
    pj_bzero(&p_srtp->tx_policy, sizeof(p_srtp->tx_policy));

    pj_lock_release(p_srtp->mutex);

    return PJ_SUCCESS;
}

PJ_DEF(pjmedia_transport *) pjmedia_transport_srtp_get_member(
						pjmedia_transport *tp)
{
    transport_srtp *srtp = (transport_srtp*) tp;

    PJ_ASSERT_RETURN(tp, NULL);

    return srtp->member_tp;
}


static pj_status_t transport_get_info(pjmedia_transport *tp,
				      pjmedia_transport_info *info)
{
    transport_srtp *srtp = (transport_srtp*) tp;
    pjmedia_srtp_info srtp_info;
    int spc_info_idx;

    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);
    PJ_ASSERT_RETURN(info->specific_info_cnt <
		     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);
    PJ_ASSERT_RETURN(sizeof(pjmedia_srtp_info) <=
		     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE, PJ_ENOMEM);

    srtp_info.active = srtp->session_inited;
    srtp_info.rx_policy = srtp->rx_policy;
    srtp_info.tx_policy = srtp->tx_policy;
    srtp_info.use = srtp->setting.use;
    srtp_info.peer_use = srtp->peer_use;

    spc_info_idx = info->specific_info_cnt++;
    info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;
    info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info);
    pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info, 
	      sizeof(srtp_info));

    return pjmedia_transport_get_info(srtp->member_tp, 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))
{
    transport_srtp *srtp = (transport_srtp*) tp;
    pj_status_t status;

    PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);

    /* Save the callbacks */
    pj_lock_acquire(srtp->mutex);
    srtp->rtp_cb = rtp_cb;
    srtp->rtcp_cb = rtcp_cb;
    srtp->user_data = user_data;
    pj_lock_release(srtp->mutex);

    /* Attach itself to transport */
    status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, 
				      rem_rtcp, addr_len, &srtp_rtp_cb,
				      &srtp_rtcp_cb);
    if (status != PJ_SUCCESS) {
	pj_lock_acquire(srtp->mutex);
	srtp->rtp_cb = NULL;
	srtp->rtcp_cb = NULL;
	srtp->user_data = NULL;
	pj_lock_release(srtp->mutex);
	return status;
    }

    return PJ_SUCCESS;
}

static void transport_detach(pjmedia_transport *tp, void *strm)
{
    transport_srtp *srtp = (transport_srtp*) tp;

    PJ_UNUSED_ARG(strm);
    PJ_ASSERT_ON_FAIL(tp, return);

    if (srtp->member_tp) {
	pjmedia_transport_detach(srtp->member_tp, srtp);
    }

    /* Clear up application infos from transport */
    pj_lock_acquire(srtp->mutex);
    srtp->rtp_cb = NULL;
    srtp->rtcp_cb = NULL;
    srtp->user_data = NULL;
    pj_lock_release(srtp->mutex);
}

static pj_status_t transport_send_rtp( pjmedia_transport *tp,
				       const void *pkt,
				       pj_size_t size)
{
    pj_status_t status;
    transport_srtp *srtp = (transport_srtp*) tp;
    int len = (int)size;
    err_status_t err;

    if (srtp->bypass_srtp)
	return pjmedia_transport_send_rtp(srtp->member_tp, pkt, size);

    if (size > sizeof(srtp->rtp_tx_buffer) - 10)
	return PJ_ETOOBIG;

    pj_memcpy(srtp->rtp_tx_buffer, pkt, size);

    pj_lock_acquire(srtp->mutex);
    if (!srtp->session_inited) {
	pj_lock_release(srtp->mutex);
	return PJ_EINVALIDOP;
    }
    err = srtp_protect(srtp->srtp_tx_ctx, srtp->rtp_tx_buffer, &len);
    pj_lock_release(srtp->mutex);

    if (err == err_status_ok) {
	status = pjmedia_transport_send_rtp(srtp->member_tp, 
					    srtp->rtp_tx_buffer, len);
    } else {
	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
    }
    
    return status;
}

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)
{
    pj_status_t status;
    transport_srtp *srtp = (transport_srtp*) tp;
    int len = (int)size;
    err_status_t err;

    if (srtp->bypass_srtp) {
	return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len, 
	                                    pkt, size);
    }

    if (size > sizeof(srtp->rtcp_tx_buffer) - 10)
	return PJ_ETOOBIG;

    pj_memcpy(srtp->rtcp_tx_buffer, pkt, size);

    pj_lock_acquire(srtp->mutex);
    if (!srtp->session_inited) {
	pj_lock_release(srtp->mutex);
	return PJ_EINVALIDOP;
    }
    err = srtp_protect_rtcp(srtp->srtp_tx_ctx, srtp->rtcp_tx_buffer, &len);
    pj_lock_release(srtp->mutex);

    if (err == err_status_ok) {
	status = pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,
					      srtp->rtcp_tx_buffer, len);
    } else {
	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
    }

    return status;
}


static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
					   pjmedia_dir dir,
					   unsigned pct_lost)
{
    transport_srtp *srtp = (transport_srtp *) tp;
    
    PJ_ASSERT_RETURN(tp, PJ_EINVAL);

    return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost);
}

static pj_status_t transport_destroy  (pjmedia_transport *tp)
{
    transport_srtp *srtp = (transport_srtp *) tp;
    pj_status_t status;

    PJ_ASSERT_RETURN(tp, PJ_EINVAL);

    if (srtp->setting.close_member_tp && srtp->member_tp) {
	pjmedia_transport_close(srtp->member_tp);
    }

    status = pjmedia_transport_srtp_stop(tp);

    /* In case mutex is being acquired by other thread */
    pj_lock_acquire(srtp->mutex);
    pj_lock_release(srtp->mutex);

    pj_lock_destroy(srtp->mutex);
    pj_pool_release(srtp->pool);

    return status;
}

/*
 * This callback is called by transport when incoming rtp is received
 */
static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)
{
    transport_srtp *srtp = (transport_srtp *) user_data;
    int len = size;
    err_status_t err;
    void (*cb)(void*, void*, pj_ssize_t) = NULL;
    void *cb_data = NULL;

    if (srtp->bypass_srtp) {
	srtp->rtp_cb(srtp->user_data, pkt, size);
	return;
    }

    if (size < 0) {
	return;
    }

    /* Make sure buffer is 32bit aligned */
    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return );

    if (srtp->probation_cnt > 0)
	--srtp->probation_cnt;

    pj_lock_acquire(srtp->mutex);

    if (!srtp->session_inited) {
	pj_lock_release(srtp->mutex);
	return;
    }
    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
    if (srtp->probation_cnt > 0 && 
	(err == err_status_replay_old || err == err_status_replay_fail)) 
    {
	/* Handle such condition that stream is updated (RTP seq is reinited
	 * & SRTP is restarted), but some old packets are still coming 
	 * so SRTP is learning wrong RTP seq. While the newly inited RTP seq
	 * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect() 
	 * will return err_status_replay_*. Restarting SRTP can resolve this.
	 */
	pjmedia_srtp_crypto tx, rx;
	pj_status_t status;

	tx = srtp->tx_policy;
	rx = srtp->rx_policy;
	status = pjmedia_transport_srtp_start((pjmedia_transport*)srtp,
					      &tx, &rx);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s", 
		      get_libsrtp_errstr(err)));
	} else if (!srtp->bypass_srtp) {
	    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
	}
    }

    if (err != err_status_ok) {
	PJ_LOG(5,(srtp->pool->obj_name, 
		  "Failed to unprotect SRTP, pkt size=%d, err=%s", 
		  size, get_libsrtp_errstr(err)));
    } else {
	cb = srtp->rtp_cb;
	cb_data = srtp->user_data;
    }

    pj_lock_release(srtp->mutex);

    if (cb) {
	(*cb)(cb_data, pkt, len);
    }
}

/*
 * This callback is called by transport when incoming rtcp is received
 */
static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size)
{
    transport_srtp *srtp = (transport_srtp *) user_data;
    int len = size;
    err_status_t err;
    void (*cb)(void*, void*, pj_ssize_t) = NULL;
    void *cb_data = NULL;

    if (srtp->bypass_srtp) {
	srtp->rtcp_cb(srtp->user_data, pkt, size);
	return;
    }

    if (size < 0) {
	return;
    }

    /* Make sure buffer is 32bit aligned */
    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return );

    pj_lock_acquire(srtp->mutex);

    if (!srtp->session_inited) {
	pj_lock_release(srtp->mutex);
	return;
    }
    err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
    if (err != err_status_ok) {
	PJ_LOG(5,(srtp->pool->obj_name, 
		  "Failed to unprotect SRTCP, pkt size=%d, err=%s",
		  size, get_libsrtp_errstr(err)));
    } else {
	cb = srtp->rtcp_cb;
	cb_data = srtp->user_data;
    }

    pj_lock_release(srtp->mutex);

    if (cb) {
	(*cb)(cb_data, pkt, len);
    }
}

/* Generate crypto attribute, including crypto key.
 * If crypto-suite chosen is crypto NULL, just return PJ_SUCCESS,
 * and set buffer_len = 0.
 */
static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
					      char *buffer, int *buffer_len, 
					      pjmedia_srtp_crypto *crypto,
					      int tag)
{
    pj_status_t status;
    int cs_idx = get_crypto_idx(&crypto->name);
    char b64_key[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)+1];
    int b64_key_len = sizeof(b64_key);
    int print_len;

    if (cs_idx == -1)
	return PJMEDIA_SRTP_ENOTSUPCRYPTO;

    /* Crypto-suite NULL. */
    if (cs_idx == 0) {
	*buffer_len = 0;
	return PJ_SUCCESS;
    }

    /* Generate key if not specified. */
    if (crypto->key.slen == 0) {
	pj_bool_t key_ok;
	char key[MAX_KEY_LEN];
	err_status_t err;
	unsigned i;

	PJ_ASSERT_RETURN(MAX_KEY_LEN >= crypto_suites[cs_idx].cipher_key_len,
			 PJ_ETOOSMALL);

	do {
	    key_ok = PJ_TRUE;

	    err = crypto_get_random((unsigned char*)key, 
				     crypto_suites[cs_idx].cipher_key_len);
	    if (err != err_status_ok) {
		PJ_LOG(5,(THIS_FILE, "Failed generating random key: %s",
			  get_libsrtp_errstr(err)));
		return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
	    }
	    for (i=0; i<crypto_suites[cs_idx].cipher_key_len && key_ok; ++i)
		if (key[i] == 0) key_ok = PJ_FALSE;

	} while (!key_ok);
	crypto->key.ptr = (char*)
			  pj_pool_zalloc(pool, 
					 crypto_suites[cs_idx].cipher_key_len);
	pj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len);
	crypto->key.slen = crypto_suites[cs_idx].cipher_key_len;
    }

    if (crypto->key.slen != (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)
	return PJMEDIA_SRTP_EINKEYLEN;

    /* Key transmitted via SDP should be base64 encoded. */
    status = pj_base64_encode((pj_uint8_t*)crypto->key.ptr, crypto->key.slen,
			      b64_key, &b64_key_len);
    if (status != PJ_SUCCESS) {
	PJ_LOG(5,(THIS_FILE, "Failed encoding plain key to base64"));
	return status;
    }

    b64_key[b64_key_len] = '\0';
    
    PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \
		     b64_key_len + 16), PJ_ETOOSMALL);

    /* Print the crypto attribute value. */
    print_len = pj_ansi_snprintf(buffer, *buffer_len, "%d %s inline:%s",
				   tag, 
				   crypto_suites[cs_idx].name,
				   b64_key);
    if (print_len < 1 || print_len >= *buffer_len)
	return PJ_ETOOSMALL;

    *buffer_len = print_len;

    return PJ_SUCCESS;
}

/* Parse crypto attribute line */
static pj_status_t parse_attr_crypto(pj_pool_t *pool,
				     const pjmedia_sdp_attr *attr,
				     pjmedia_srtp_crypto *crypto,
				     int *tag)
{
    pj_str_t input;
    char *token;
    pj_size_t token_len;
    pj_str_t tmp;
    pj_status_t status;
    int itmp;

    pj_bzero(crypto, sizeof(*crypto));
    pj_strdup_with_null(pool, &input, &attr->value);

    /* Tag */
    token = strtok(input.ptr, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));
	return PJMEDIA_SDP_EINATTR;
    }
    token_len = pj_ansi_strlen(token);

    /* Tag must not use leading zeroes. */
    if (token_len > 1 && *token == '0')
	return PJMEDIA_SDP_EINATTR;

    /* Tag must be decimal, i.e: contains only digit '0'-'9'. */
    for (itmp = 0; itmp < token_len; ++itmp)
	if (!pj_isdigit(token[itmp]))
	    return PJMEDIA_SDP_EINATTR;

    /* Get tag value. */
    *tag = atoi(token);

    /* Crypto-suite */
    token = strtok(NULL, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));
	return PJMEDIA_SDP_EINATTR;
    }
    crypto->name = pj_str(token);

    /* Key method */
    token = strtok(NULL, ":");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));
	return PJMEDIA_SDP_EINATTR;
    }
    if (pj_ansi_stricmp(token, "inline")) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!",
	          token));
	return PJMEDIA_SDP_EINATTR;
    }

    /* Key */
    token = strtok(NULL, "| ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));
	return PJMEDIA_SDP_EINATTR;
    }
    tmp = pj_str(token);
    if (PJ_BASE64_TO_BASE256_LEN(tmp.slen) > MAX_KEY_LEN) {
	PJ_LOG(4,(THIS_FILE, "Key too long"));
	return PJMEDIA_SRTP_EINKEYLEN;
    }

    /* Decode key */
    crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);
    itmp = MAX_KEY_LEN;
    status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, 
			      &itmp);
    if (status != PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));
	return status;
    }
    crypto->key.slen = itmp;

    return PJ_SUCCESS;
}

static pj_status_t transport_media_create(pjmedia_transport *tp,
				          pj_pool_t *sdp_pool,
					  unsigned options,
				          const pjmedia_sdp_session *sdp_remote,
					  unsigned media_index)
{
    struct transport_srtp *srtp = (struct transport_srtp*) tp;
    unsigned member_tp_option;

    PJ_ASSERT_RETURN(tp, PJ_EINVAL);
    
    pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
    pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));

    srtp->media_option = options;
    member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;

    srtp->offerer_side = sdp_remote == NULL;

    /* Validations */
    if (srtp->offerer_side) {

	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED)
	    goto BYPASS_SRTP;

    } else {

	pjmedia_sdp_media *m_rem;

	m_rem = sdp_remote->media[media_index];

	/* Nothing to do on inactive media stream */
	if (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))
	    goto BYPASS_SRTP;

	/* Validate remote media transport based on SRTP usage option.
	 */
	switch (srtp->setting.use) {
	    case PJMEDIA_SRTP_DISABLED:
		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
		goto BYPASS_SRTP;
	    case PJMEDIA_SRTP_OPTIONAL:
		break;
	    case PJMEDIA_SRTP_MANDATORY:
		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)
		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
		break;
	}

    }
    goto PROPAGATE_MEDIA_CREATE;

BYPASS_SRTP:
    srtp->bypass_srtp = PJ_TRUE;
    member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;

PROPAGATE_MEDIA_CREATE:
    return pjmedia_transport_media_create(srtp->member_tp, sdp_pool, 
					  member_tp_option, sdp_remote,
					  media_index);
}

static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
					pj_pool_t *sdp_pool,
					pjmedia_sdp_session *sdp_local,
					const pjmedia_sdp_session *sdp_remote,
					unsigned media_index)
{
    struct transport_srtp *srtp = (struct transport_srtp*) tp;
    pjmedia_sdp_media *m_rem, *m_loc;
    enum { MAXLEN = 512 };
    char buffer[MAXLEN];
    int buffer_len;
    pj_status_t status;
    pjmedia_sdp_attr *attr;
    pj_str_t attr_value;
    unsigned i, j;

    PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL);
    
    pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
    pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));

    srtp->offerer_side = sdp_remote == NULL;

    m_rem = sdp_remote ? sdp_remote->media[media_index] : NULL;
    m_loc = sdp_local->media[media_index];

    /* Bypass if media transport is not RTP/AVP or RTP/SAVP */
    if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP)  != 0 && 
	pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0)
	goto BYPASS_SRTP;

    /* If the media is inactive, do nothing. */
    /* No, we still need to process SRTP offer/answer even if the media is
     * marked as inactive, because the transport is still alive in this
     * case (e.g. for keep-alive). See:
     *   http://trac.pjsip.org/repos/ticket/1079
     */
    /*
    if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) || 
	(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))
	goto BYPASS_SRTP;
    */

    /* Check remote media transport & set local media transport 
     * based on SRTP usage option.
     */
    if (srtp->offerer_side) {

	/* Generate transport */
	switch (srtp->setting.use) {
	    case PJMEDIA_SRTP_DISABLED:
		goto BYPASS_SRTP;
	    case PJMEDIA_SRTP_OPTIONAL:
		m_loc->desc.transport = 
				(srtp->peer_use == PJMEDIA_SRTP_MANDATORY)?
				ID_RTP_SAVP : ID_RTP_AVP;
		break;
	    case PJMEDIA_SRTP_MANDATORY:
		m_loc->desc.transport = ID_RTP_SAVP;
		break;
	}

	/* Generate crypto attribute if not yet */
	if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {
	    for (i=0; i<srtp->setting.crypto_count; ++i) {
		/* Offer crypto-suites based on setting. */
		buffer_len = MAXLEN;
		status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,
						    &srtp->setting.crypto[i],
						    i+1);
		if (status != PJ_SUCCESS)
		    return status;

		/* If buffer_len==0, just skip the crypto attribute. */
		if (buffer_len) {
		    pj_strset(&attr_value, buffer, buffer_len);
		    attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr, 
						   &attr_value);
		    m_loc->attr[m_loc->attr_count++] = attr;
		}
	    }
	}

    } else {
	/* Answerer side */

	pj_assert(sdp_remote && m_rem);

	/* Generate transport */
	switch (srtp->setting.use) {
	    case PJMEDIA_SRTP_DISABLED:
		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
		goto BYPASS_SRTP;
	    case PJMEDIA_SRTP_OPTIONAL:
		m_loc->desc.transport = m_rem->desc.transport;
		break;
	    case PJMEDIA_SRTP_MANDATORY:
		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)
		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
		m_loc->desc.transport = ID_RTP_SAVP;
		break;
	}

	/* Generate crypto attribute if not yet */
	if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {

	    pjmedia_srtp_crypto tmp_rx_crypto;
	    pj_bool_t has_crypto_attr = PJ_FALSE;
	    int matched_idx = -1;
	    int chosen_tag = 0;
	    int tags[64]; /* assume no more than 64 crypto attrs in a media */
	    unsigned cr_attr_count = 0;

	    /* Find supported crypto-suite, get the tag, and assign policy_local */
	    for (i=0; i<m_rem->attr_count; ++i) {
		if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)
		    continue;

		has_crypto_attr = PJ_TRUE;

		status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 
					   &tmp_rx_crypto, &tags[cr_attr_count]);
		if (status != PJ_SUCCESS)
		    return status;
    	 
		/* Check duplicated tag */
		for (j=0; j<cr_attr_count; ++j) {
		    if (tags[j] == tags[cr_attr_count]) {
			DEACTIVATE_MEDIA(sdp_pool, m_loc);
			return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG;
		    }
		}

		if (matched_idx == -1) {
		    /* lets see if the crypto-suite offered is supported */
		    for (j=0; j<srtp->setting.crypto_count; ++j)
			if (pj_stricmp(&tmp_rx_crypto.name, 
				       &srtp->setting.crypto[j].name) == 0)
			{
			    int cs_idx = get_crypto_idx(&tmp_rx_crypto.name);

			    /* Force to use test key */
			    /* bad keys for snom: */
			    //char *hex_test_key = "58b29c5c8f42308120ce857e439f2d"
			    //		     "7810a8b10ad0b1446be5470faea496";
			    //char *hex_test_key = "20a26aac7ba062d356ff52b61e3993"
			    //		     "ccb78078f12c64db94b9c294927fd0";
			    //pj_str_t *test_key = &srtp->setting.crypto[j].key;
			    //char  *raw_test_key = pj_pool_zalloc(srtp->pool, 64);
			    //hex_string_to_octet_string(
			    //		raw_test_key,
			    //		hex_test_key,
			    //		strlen(hex_test_key));
			    //pj_strset(test_key, raw_test_key, 
			    //	  crypto_suites[cs_idx].cipher_key_len);
			    /* EO Force to use test key */

			    if (tmp_rx_crypto.key.slen != 
				(int)crypto_suites[cs_idx].cipher_key_len)
				return PJMEDIA_SRTP_EINKEYLEN;

			    srtp->rx_policy_neg = tmp_rx_crypto;
			    chosen_tag = tags[cr_attr_count];
			    matched_idx = j;
    			    break;
			}
		}
		cr_attr_count++;
	    }

	    /* Check crypto negotiation result */
	    switch (srtp->setting.use) {
		case PJMEDIA_SRTP_DISABLED:
		    pj_assert(!"Should never reach here");
		    break;

		case PJMEDIA_SRTP_OPTIONAL:
		    /* bypass SRTP when no crypto-attr and remote uses RTP/AVP */
		    if (!has_crypto_attr && 
			pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
			goto BYPASS_SRTP;
		    /* bypass SRTP when nothing match and remote uses RTP/AVP */
		    else if (matched_idx == -1 && 
			pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
			goto BYPASS_SRTP;
		    break;

		case PJMEDIA_SRTP_MANDATORY:
		    /* Do nothing, intentional */
		    break;
	    }

	    /* No crypto attr */
	    if (!has_crypto_attr) {
		DEACTIVATE_MEDIA(sdp_pool, m_loc);
		return PJMEDIA_SRTP_ESDPREQCRYPTO;
	    }

	    /* No crypto match */
	    if (matched_idx == -1) {
		DEACTIVATE_MEDIA(sdp_pool, m_loc);
		return PJMEDIA_SRTP_ENOTSUPCRYPTO;
	    }

	    /* we have to generate crypto answer, 
	     * with srtp->tx_policy_neg matched the offer
	     * and rem_tag contains matched offer tag.
	     */
	    buffer_len = MAXLEN;
	    status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,
						&srtp->setting.crypto[matched_idx],
						chosen_tag);
	    if (status != PJ_SUCCESS)
		return status;

	    srtp->tx_policy_neg = srtp->setting.crypto[matched_idx];
	    
	    /* If buffer_len==0, just skip the crypto attribute. */
	    if (buffer_len) {
		pj_strset(&attr_value, buffer, buffer_len);
		attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr, 
					       &attr_value);
		m_loc->attr[m_loc->attr_count++] = attr;
	    }

	    /* At this point, we get valid rx_policy_neg & tx_policy_neg. */
	}
	    
    }
    goto PROPAGATE_MEDIA_CREATE;

BYPASS_SRTP:
    /* Do not update this flag here as actually the media session hasn't been
     * updated.
     */
    //srtp->bypass_srtp = PJ_TRUE;

PROPAGATE_MEDIA_CREATE:
    return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool, 
					sdp_local, sdp_remote, 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 *sdp_remote,
				         unsigned media_index)
{
    struct transport_srtp *srtp = (struct transport_srtp*) tp;
    pjmedia_sdp_media *m_rem, *m_loc;
    pj_status_t status;
    unsigned i;

    PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL);

    m_rem = sdp_remote->media[media_index];
    m_loc = sdp_local->media[media_index];

    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
	srtp->peer_use = PJMEDIA_SRTP_MANDATORY;
    else
	srtp->peer_use = PJMEDIA_SRTP_OPTIONAL;

    /* For answerer side, this function will just have to start SRTP */

    /* Check remote media transport & set local media transport 
     * based on SRTP usage option.
     */
    if (srtp->offerer_side) {
	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
	    if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SRTP_ESDPINCRYPTO;
	    }
	    goto BYPASS_SRTP;
	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
	    // Regardless the answer's transport type (RTP/AVP or RTP/SAVP),
	    // the answer must be processed through in optional mode.
	    // Please note that at this point transport type is ensured to be 
	    // RTP/AVP or RTP/SAVP, see transport_media_create()
	    //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
		//DEACTIVATE_MEDIA(pool, m_loc);
		//return PJMEDIA_SDP_EINPROTO;
	    //}
	} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
	    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SDP_EINPROTO;
	    }
	}
    }
    
    if (srtp->offerer_side) {
	/* find supported crypto-suite, get the tag, and assign policy_local */
	pjmedia_srtp_crypto tmp_tx_crypto;
	pj_bool_t has_crypto_attr = PJ_FALSE;
	int rem_tag;

	for (i=0; i<m_rem->attr_count; ++i) {
	    if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)
		continue;

	    /* more than one crypto attribute in media answer */
	    if (has_crypto_attr) {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SRTP_ESDPAMBIGUEANS;
	    }

	    has_crypto_attr = PJ_TRUE;

	    status = parse_attr_crypto(srtp->pool, m_rem->attr[i], 
				       &tmp_tx_crypto, &rem_tag);
	    if (status != PJ_SUCCESS)
		return status;


	    /* our offer tag is always ordered by setting */
	    if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count) {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SRTP_ESDPINCRYPTOTAG;
	    }

	    /* match the crypto name */
	    if (pj_stricmp(&tmp_tx_crypto.name, 
		&srtp->setting.crypto[rem_tag-1].name) != 0)
	    {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SRTP_ECRYPTONOTMATCH;
	    }

	    srtp->tx_policy_neg = srtp->setting.crypto[rem_tag-1];
	    srtp->rx_policy_neg = tmp_tx_crypto;
	}

	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
	    /* should never reach here */
	    goto BYPASS_SRTP;
	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
	    if (!has_crypto_attr)
		goto BYPASS_SRTP;
	} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
	    if (!has_crypto_attr) {
		DEACTIVATE_MEDIA(pool, m_loc);
		return PJMEDIA_SRTP_ESDPREQCRYPTO;
	    }
	}

	/* At this point, we get valid rx_policy_neg & tx_policy_neg. */
    }

    /* Make sure we have the SRTP policies */
    if (srtp_crypto_empty(&srtp->tx_policy_neg) || 
	srtp_crypto_empty(&srtp->rx_policy_neg))
    {
	goto BYPASS_SRTP;
    }

    /* Reset probation counts */
    srtp->probation_cnt = PROBATION_CNT_INIT;

    /* Got policy_local & policy_remote, let's initalize the SRTP */

    /* Ticket #1075: media_start() is called whenever media description
     * gets updated, e.g: call hold, however we should restart SRTP only
     * when the SRTP policy settings are updated.
     */
    if (srtp_crypto_cmp(&srtp->tx_policy_neg, &srtp->tx_policy) ||
	srtp_crypto_cmp(&srtp->rx_policy_neg, &srtp->rx_policy))
    {
	status = pjmedia_transport_srtp_start(tp,
					      &srtp->tx_policy_neg,
					      &srtp->rx_policy_neg);
	if (status != PJ_SUCCESS)
	    return status;
    }

    srtp->bypass_srtp = PJ_FALSE;

    goto PROPAGATE_MEDIA_START;

BYPASS_SRTP:
    srtp->bypass_srtp = PJ_TRUE;
    srtp->peer_use = PJMEDIA_SRTP_DISABLED;
    if (srtp->session_inited) {
	pjmedia_transport_srtp_stop(tp);
    }

PROPAGATE_MEDIA_START:
    return pjmedia_transport_media_start(srtp->member_tp, pool, 
					 sdp_local, sdp_remote,
				         media_index);
}

static pj_status_t transport_media_stop(pjmedia_transport *tp)
{
    struct transport_srtp *srtp = (struct transport_srtp*) tp;
    pj_status_t status;

    PJ_ASSERT_RETURN(tp, PJ_EINVAL);

    status = pjmedia_transport_media_stop(srtp->member_tp);
    if (status != PJ_SUCCESS)
	PJ_LOG(4, (srtp->pool->obj_name, 
		   "SRTP failed stop underlying media transport."));

    return pjmedia_transport_srtp_stop(tp);
}

/* Utility */
PJ_DEF(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,
						       pj_bool_t is_rtp,
						       void *pkt,
						       int *pkt_len)
{
    transport_srtp *srtp = (transport_srtp *)tp;
    err_status_t err;

    if (srtp->bypass_srtp)
	return PJ_SUCCESS;

    PJ_ASSERT_RETURN(tp && pkt && (*pkt_len>0), PJ_EINVAL);
    PJ_ASSERT_RETURN(srtp->session_inited, PJ_EINVALIDOP);

    /* Make sure buffer is 32bit aligned */
    PJ_ASSERT_ON_FAIL( (((pj_ssize_t)pkt) & 0x03)==0, return PJ_EINVAL);

    pj_lock_acquire(srtp->mutex);

    if (!srtp->session_inited) {
	pj_lock_release(srtp->mutex);
	return PJ_EINVALIDOP;
    }

    if (is_rtp)
	err = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len);
    else
	err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, pkt, pkt_len);
    
    if (err != err_status_ok) {
	PJ_LOG(5,(srtp->pool->obj_name, 
		  "Failed to unprotect SRTP, pkt size=%d, err=%s", 
		  *pkt_len, get_libsrtp_errstr(err)));
    }

    pj_lock_release(srtp->mutex);

    return (err==err_status_ok) ? PJ_SUCCESS : PJMEDIA_ERRNO_FROM_LIBSRTP(err);
}

#endif


