Index: /pjproject/branches/users/nanang/pjmedia/src/pjmedia/transport_srtp.c
===================================================================
--- /pjproject/branches/users/nanang/pjmedia/src/pjmedia/transport_srtp.c	(revision 1720)
+++ /pjproject/branches/users/nanang/pjmedia/src/pjmedia/transport_srtp.c	(revision 1721)
@@ -261,7 +261,9 @@
     opt->close_member_tp = PJ_TRUE;
     opt->use = PJMEDIA_SRTP_OPTIONAL;
-    opt->crypto_count = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
+
+    /* 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].name);
+	opt->crypto[i].name = pj_str(crypto_suites[i+1].name);
 }
 
@@ -328,5 +330,6 @@
 	    srtp->setting.crypto[i].name = pj_str(crypto_suites[cs_idx].name);
 	    /* cut key length */
-	    tmp_key.slen = crypto_suites[cs_idx].cipher_key_len;
+	    if (tmp_key.slen)
+		tmp_key.slen = crypto_suites[cs_idx].cipher_key_len;
 	    pj_strdup(pool, &srtp->setting.crypto[i].key, &tmp_key);
 	}
@@ -872,5 +875,5 @@
     enum { MAXLEN = 512 };
     char buffer[MAXLEN];
-    int buffer_len = MAXLEN;
+    int buffer_len;
     pj_status_t status;
     pjmedia_sdp_attr *attr;
@@ -880,5 +883,5 @@
     PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL);
 
-    pj_bzero(&srtp->rx_policy, sizeof(srtp->rx_policy));
+    pj_bzero(&srtp->rx_policy, sizeof(srtp->tx_policy));
     pj_bzero(&srtp->tx_policy, sizeof(srtp->rx_policy));
 
@@ -889,5 +892,5 @@
     if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP)  != 0 && 
 	pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0)
-	goto PROPAGATE_MEDIA_CREATE;
+	goto BYPASS_SRTP;
 
     /* If the media is inactive, do nothing. */
@@ -895,5 +898,5 @@
 	(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))
     {
-	goto PROPAGATE_MEDIA_CREATE;
+	goto BYPASS_SRTP;
     }
 
@@ -905,5 +908,5 @@
     if (srtp->offerer_side) {
 	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
-	    goto PROPAGATE_MEDIA_CREATE;
+	    goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
 	    m_loc->desc.transport = ID_RTP_AVP;
@@ -931,4 +934,5 @@
 	for (i=0; i<srtp->setting.crypto_count; ++i) {
 	    /* Offer crypto-suites based on setting. */
+	    buffer_len = MAXLEN;
 	    status = generate_crypto_attr_value(pool, buffer, &buffer_len,
 						&srtp->setting.crypto[i],
@@ -958,4 +962,5 @@
 		continue;
 
+	    /* SRTP is disabled but there is crypto attr in remote media */
 	    if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
 		DEACTIVATE_MEDIA(pool, m_loc);
@@ -1002,8 +1007,14 @@
 	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
 	    /* At this point, it is ensured remote has no crypto attr */
-	    goto PROPAGATE_MEDIA_CREATE;
+	    goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
-	    if (!has_crypto_attr)
-		goto PROPAGATE_MEDIA_CREATE;;
+	    /* bypass SRTP when no crypto-attr but 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 but remote uses RTP/AVP */
+	    if (!has_match && 
+		pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
+		goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
 	    if (!has_crypto_attr) {
@@ -1023,4 +1034,5 @@
 	 * and rem_tag contains matched offer tag.
 	 */
+	buffer_len = MAXLEN;
 	status = generate_crypto_attr_value(pool, buffer, &buffer_len,
 					    &srtp->tx_policy,
@@ -1040,4 +1052,8 @@
 	 */
     }
+    goto PROPAGATE_MEDIA_CREATE;
+
+BYPASS_SRTP:
+    srtp->bypass_srtp = PJ_TRUE;
 
 PROPAGATE_MEDIA_CREATE:
@@ -1062,22 +1078,9 @@
     PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL);
 
+    if (srtp->bypass_srtp)
+	goto BYPASS_SRTP;
+
     m_rem = sdp_remote->media[media_index];
     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) 
-    {
-	srtp->bypass_srtp = PJ_TRUE;
-	goto PROPAGATE_MEDIA_START;
-    }
-
-    /* If the media is inactive, do nothing. */
-    if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) || 
-	(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))
-    {
-	srtp->bypass_srtp = PJ_TRUE;
-	goto PROPAGATE_MEDIA_START;
-    }
 
     /* For answerer side, this function will just have to start SRTP */
@@ -1092,6 +1095,5 @@
 		return PJMEDIA_SRTP_ESDPINCRYPTO;
 	    }
-	    srtp->bypass_srtp = PJ_TRUE;
-	    goto PROPAGATE_MEDIA_START;
+	    goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
 	    if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
@@ -1151,11 +1153,8 @@
 	if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
 	    /* should never reach here */
-	    srtp->bypass_srtp = PJ_TRUE;
-	    goto PROPAGATE_MEDIA_START;
+	    goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
-	    if (!has_crypto_attr) {
-		srtp->bypass_srtp = PJ_TRUE;
-		goto PROPAGATE_MEDIA_START;
-	    }
+	    if (!has_crypto_attr)
+		goto BYPASS_SRTP;
 	} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
 	    if (!has_crypto_attr) {
@@ -1175,4 +1174,9 @@
 	return status;
 
+    goto PROPAGATE_MEDIA_START;
+
+BYPASS_SRTP:
+    srtp->bypass_srtp = PJ_TRUE;
+
 PROPAGATE_MEDIA_START:
     return pjmedia_transport_media_start(srtp->real_tp, pool, 
@@ -1186,9 +1190,7 @@
     pj_status_t status;
 
-    if (srtp->setting.close_member_tp) {
-	status = pjmedia_transport_media_stop(srtp->real_tp);
-	if (status != PJ_SUCCESS)
-	    PJ_LOG(4, (THIS_FILE, "Failed deinit session."));
-    }
+    status = pjmedia_transport_media_stop(srtp->real_tp);
+    if (status != PJ_SUCCESS)
+	PJ_LOG(4, (THIS_FILE, "SRTP failed stop underlying media transport."));
 
     return pjmedia_transport_srtp_stop(tp);
