Index: pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_sdes.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_sdes.c	(revision 5749)
+++ pjproject/trunk/pjmedia/src/pjmedia/transport_srtp_sdes.c	(revision 5755)
@@ -278,4 +278,14 @@
     PJ_UNUSED_ARG(sdp_pool);
 
+    /* Verify remote media transport, it has to be RTP/AVP or RTP/SAVP */
+    if (!srtp->offerer_side) {
+	pjmedia_sdp_media *m = sdp_remote->media[media_index];
+	if (pj_stricmp(&m->desc.transport, &ID_RTP_AVP)  != 0 &&
+	    pj_stricmp(&m->desc.transport, &ID_RTP_SAVP) != 0)
+	{
+	    return PJMEDIA_SRTP_ESDPINTRANSPORT;
+	}
+    }
+
     /* Validations */
     if (srtp->offerer_side) {
@@ -284,8 +294,4 @@
 	pjmedia_sdp_media *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))
-	    srtp->bypass_srtp = PJ_TRUE;
-
 	/* Validate remote media transport based on SRTP usage option. */
 	switch (srtp->setting.use) {
@@ -293,5 +299,4 @@
 		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
 		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
-		srtp->bypass_srtp = PJ_TRUE;
 		break;
 	    case PJMEDIA_SRTP_OPTIONAL:
@@ -326,9 +331,12 @@
     m_loc = sdp_local->media[media_index];
 
-    /* Bypass SDES 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)
+    /* Verify media transport, it has to be RTP/AVP or RTP/SAVP */
     {
-	return PJ_SUCCESS;
+	pjmedia_sdp_media *m = sdp_remote? m_rem : m_loc;
+	if (pj_stricmp(&m->desc.transport, &ID_RTP_AVP)  != 0 &&
+	    pj_stricmp(&m->desc.transport, &ID_RTP_SAVP) != 0)
+	{
+	    return PJMEDIA_SRTP_ESDPINTRANSPORT;
+	}
     }
 
@@ -353,5 +361,5 @@
 	switch (srtp->setting.use) {
 	    case PJMEDIA_SRTP_DISABLED:
-		pj_assert(!"Shouldn't reach here");
+		/* Should never reach here */
 		return PJ_SUCCESS;
 	    case PJMEDIA_SRTP_OPTIONAL:
@@ -407,14 +415,13 @@
 	switch (srtp->setting.use) {
 	    case PJMEDIA_SRTP_DISABLED:
+		/* Should never reach here */
 		if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
 		    return PJMEDIA_SRTP_ESDPINTRANSPORT;
 		return PJ_SUCCESS;
 	    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;
 	}
@@ -480,5 +487,5 @@
 	    switch (srtp->setting.use) {
 		case PJMEDIA_SRTP_DISABLED:
-		    pj_assert(!"Should never reach here");
+		    /* Should never reach here */
 		    break;
 
@@ -536,4 +543,7 @@
 	    /* At this point, we get valid rx_policy_neg & tx_policy_neg. */
 	}
+
+	/* Update transport description in local media SDP */
+	m_loc->desc.transport = m_rem->desc.transport;
     }
 
@@ -590,7 +600,19 @@
     pjmedia_srtp_crypto	loc_crypto[PJMEDIA_SRTP_MAX_CRYPTOS];
     int loc_cryto_cnt = PJMEDIA_SRTP_MAX_CRYPTOS;
+    pjmedia_srtp_crypto tmp_tx_crypto;
+    pj_bool_t has_crypto_attr = PJ_FALSE;
+    int rem_tag;
+    int j;
+
 
     m_rem = sdp_remote->media[media_index];
     m_loc = sdp_local->media[media_index];
+
+    /* Verify media transport, it has to be RTP/AVP or RTP/SAVP */
+    if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP)  != 0 &&
+	pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)
+    {
+	return PJMEDIA_SRTP_ESDPINTRANSPORT;
+    }
 
     if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
@@ -599,106 +621,101 @@
 	srtp->peer_use = PJMEDIA_SRTP_OPTIONAL;
 
-    /* For answerer side, this function will just have to start SRTP */
+    /* For answerer side, this function will just have to start SRTP as
+     * SRTP crypto policies have been populated in media_encode_sdp().
+     */
+    if (!srtp->offerer_side)
+	return PJ_SUCCESS;
 
     /* 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;
-	    }
+    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;
+	}
+	return PJ_SUCCESS;
+    } 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 sdes_media_create()
+	//if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
+	    //DEACTIVATE_MEDIA(pool, m_loc);
+	    //return PJMEDIA_SDP_EINPROTO;
+	//}
+	fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt);
+    } 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;
+	}
+	fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt);
+    }
+
+    /* 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;
+
+	/* 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;
+
+
+	/* Tag range check, our tags in the offer must be in the SRTP 
+	 * setting range, so does the remote answer's. The remote answer's 
+	 * tag must not exceed the tag range of the local offer.
+	 */
+	if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count ||
+	    rem_tag > loc_cryto_cnt) 
+	{
+	    DEACTIVATE_MEDIA(pool, m_loc);
+	    return PJMEDIA_SRTP_ESDPINCRYPTOTAG;
+	}
+
+	/* match the crypto name */
+	if (pj_stricmp(&tmp_tx_crypto.name, &loc_crypto[rem_tag-1].name))
+	{
+	    DEACTIVATE_MEDIA(pool, m_loc);
+	    return PJMEDIA_SRTP_ECRYPTONOTMATCH;
+	}
+
+	/* Find the crypto from the setting. */
+	for (j = 0; j < (int)srtp->setting.crypto_count; ++j) {
+	    if (pj_stricmp(&tmp_tx_crypto.name, 
+			   &srtp->setting.crypto[j].name) == 0) 
+	    {
+		srtp->tx_policy_neg = srtp->setting.crypto[j];
+		break;
+	    }		
+	}
+
+	srtp->rx_policy_neg = tmp_tx_crypto;
+    }
+
+    if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
+	/* should never reach here */
+	return PJ_SUCCESS;
+    } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
+	if (!has_crypto_attr)
 	    return PJ_SUCCESS;
-	} 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 sdes_media_create()
-	    //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
-		//DEACTIVATE_MEDIA(pool, m_loc);
-		//return PJMEDIA_SDP_EINPROTO;
-	    //}
-	    fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt);
-	} 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;
-	    }
-	    fill_local_crypto(srtp->pool, m_loc, loc_crypto, &loc_cryto_cnt);
-	}
-    }
-
-    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;
-	int j;
-
-	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;
-
-
-	    /* Tag range check, our tags in the offer must be in the SRTP 
-	     * setting range, so does the remote answer's. The remote answer's 
-	     * tag must not exceed the tag range of the local offer.
-	     */
-	    if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count ||
-		rem_tag > loc_cryto_cnt) 
-	    {
-		DEACTIVATE_MEDIA(pool, m_loc);
-		return PJMEDIA_SRTP_ESDPINCRYPTOTAG;
-	    }
-
-	    /* match the crypto name */
-	    if (pj_stricmp(&tmp_tx_crypto.name, &loc_crypto[rem_tag-1].name))
-	    {
-		DEACTIVATE_MEDIA(pool, m_loc);
-		return PJMEDIA_SRTP_ECRYPTONOTMATCH;
-	    }
-
-	    /* Find the crypto from the setting. */
-	    for (j = 0; j < (int)srtp->setting.crypto_count; ++j) {
-		if (pj_stricmp(&tmp_tx_crypto.name, 
-			       &srtp->setting.crypto[j].name) == 0) 
-		{
-		    srtp->tx_policy_neg = srtp->setting.crypto[j];
-		    break;
-		}		
-	    }
-
-	    srtp->rx_policy_neg = tmp_tx_crypto;
-	}
-
-	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
-	    /* should never reach here */
-	    return PJ_SUCCESS;
-	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
-	    if (!has_crypto_attr)
-		return PJ_SUCCESS;
-	} 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. */
-    }
+    } 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. */
 
     return PJ_SUCCESS;
