Index: /pjproject/branches/users/nanang/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- /pjproject/branches/users/nanang/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1709)
@@ -121,4 +121,5 @@
     puts  ("SIP Account options:");
     puts  ("  --use-ims           Enable 3GPP/IMS related settings on this account");
+    puts  ("  --use-srtp=N        Use SRTP N= 0: disabled, 1: optional, 2: mandatory");
     puts  ("  --registrar=url     Set the URL of registrar server");
     puts  ("  --id=url            Set the URL of local ID (used in From header)");
@@ -166,5 +167,4 @@
     puts  ("Media Options:");
     puts  ("  --use-ice           Enable ICE (default:no)");
-    puts  ("  --use-srtp          Enable SRTP (default:no)");
     puts  ("  --add-codec=name    Manually add codec (default is to enable all)");
     puts  ("  --dis-codec=name    Disable codec (can be specified multiple times)");
@@ -443,5 +443,5 @@
 	{ "rtp-port",	1, 0, OPT_RTP_PORT},
 	{ "use-ice",    0, 0, OPT_USE_ICE},
-	{ "use-srtp",   0, 0, OPT_USE_SRTP},
+	{ "use-srtp",   1, 0, OPT_USE_SRTP},
 	{ "add-codec",  1, 0, OPT_ADD_CODEC},
 	{ "dis-codec",  1, 0, OPT_DIS_CODEC},
@@ -800,5 +800,10 @@
 
 	case OPT_USE_SRTP:
-	    cfg->media_cfg.enable_srtp = PJ_TRUE;
+	    i = my_atoi(pj_optarg);
+	    if (!pj_isdigit(*pj_optarg) || i > 2) {
+		PJ_LOG(1,(THIS_FILE, "Invalid value for --use-srtp option"));
+		return -1;
+	    }
+	    cur_acc->use_srtp = i;
 	    break;
 
@@ -1115,4 +1120,11 @@
 	pj_ansi_sprintf(line, "--auto-update-nat %i\n",
 			(int)acc_cfg->auto_update_nat);
+	pj_strcat2(result, line);
+    }
+
+    /* SRTP */
+    if (acc_cfg->use_srtp) {
+	pj_ansi_sprintf(line, "--use-srtp %i\n",
+			(int)acc_cfg->use_srtp);
 	pj_strcat2(result, line);
     }
Index: /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua.h	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua.h	(revision 1709)
@@ -1972,4 +1972,27 @@
     pj_str_t	     ka_data;
 
+    /**
+     * Specify whether secure media transport should be used for this account.
+     * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+     * PJMEDIA_SRTP_MANDATORY.
+     *
+     * Default:
+     *	PJMEDIA_SRTP_DISABLED
+     */
+    pjmedia_srtp_use	use_srtp;
+
+    /**
+     * Specify whether SRTP requires secure signaling to be used. This option
+     * is only used when \a use_srtp option above is non-zero.
+     *
+     * Valid values are:
+     *	0: SRTP does not require secure signaling
+     *	1: SRTP requires secure transport such as TLS
+     *	2: SRTP requires secure end-to-end transport (SIPS)
+     *
+     * Default: 0
+     */
+    int		     srtp_secure_signaling;
+
 } pjsua_acc_config;
 
@@ -3769,9 +3792,4 @@
      */
     pj_bool_t		enable_relay;
-
-    /**
-     * Enable SRTP
-     */
-    pj_bool_t		enable_srtp;
 };
 
Index: /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 1709)
@@ -51,5 +51,6 @@
     pjsip_evsub		*xfer_sub;  /**< Xfer server subscription, if this
 					 call was triggered by xfer.	    */
-    pjmedia_transport	*med_tp;    /**< Media transport.		    */
+    pjmedia_transport	*med_tp;    /**< Current media transport.	    */
+    pjmedia_transport	*med_orig;  /**< Original media transport	    */
     pj_timer_entry	 refresh_tm;/**< Timer to send re-INVITE.	    */
     pj_timer_entry	 hangup_tm; /**< Timer to hangup call.		    */
@@ -313,5 +314,6 @@
  */
 pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
-				    pjsip_role_e role);
+				     pjsip_role_e role,
+				     int security_level);
 pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, 
 					   pj_pool_t *pool,
Index: /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_call.c	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_call.c	(revision 1709)
@@ -215,4 +215,42 @@
 #define LATE_SDP    0
 
+static pj_bool_t pj_stristr(const pj_str_t *str, const pj_str_t *substr)
+{
+    int i;
+
+    for (i=0; i<(str->slen-substr->slen); ++i) {
+	pj_str_t s;
+	s.ptr = str->ptr+i;
+	s.slen = substr->slen;
+
+	if (pj_stricmp(&s, substr)==0)
+	    return PJ_TRUE;
+    }
+    return PJ_FALSE;
+}
+
+/* Get signaling secure level.
+ * Return:
+ *  0: if signaling is not secure
+ *  1: if TLS transport is used for immediate hop
+ *  2: if end-to-end signaling is secure.
+ *
+ * NOTE:
+ *  THIS IS WRONG. It should take into account the route-set.
+ */
+static int get_secure_level(const pj_str_t *dst_uri)
+{
+    const pj_str_t tls = pj_str(";transport=tls");
+    const pj_str_t sips = pj_str("sips:");
+
+    PJ_TODO(Fix_get_secure_level);
+
+    if (pj_stristr(dst_uri, &sips))
+	return 2;
+    if (pj_stristr(dst_uri, &tls))
+	return 1;
+    return 0;
+}
+
 /*
  * Make outgoing call to the specified URI using the specified account.
@@ -325,5 +363,6 @@
 
     /* Init media channel */
-    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC);
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC, 
+				      get_secure_level(dest_uri));
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
@@ -482,4 +521,5 @@
     pjsua_call *call;
     int call_id = -1;
+    int secure_level;
     pjmedia_sdp_session *offer, *answer;
     pj_status_t status;
@@ -580,7 +620,38 @@
     }
 
+    /* 
+     * Get which account is most likely to be associated with this incoming
+     * call. We need the account to find which contact URI to put for
+     * the call.
+     */
+    acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
+
+    /* Get signaling security level, only when required by SRTP */
+    if (pjsua_var.acc[acc_id].cfg.srtp_secure_signaling < 2) {
+	secure_level = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport)!=0;
+    } else {
+	char *uri;
+	int uri_len;
+	pj_str_t dst;
+
+	uri = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
+	uri_len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI,
+				  rdata->msg_info.msg->line.req.uri,
+				  uri, PJSIP_MAX_URL_SIZE);
+	if (uri_len < 1) {
+	    pjsua_perror(THIS_FILE, "Error analyzing dst URI", 
+			 PJSIP_EURITOOLONG);
+	    uri_len = 0;
+	}
+
+	dst.ptr = uri;
+	dst.slen = uri_len;
+
+	secure_level = get_secure_level(&dst);
+    }
 
     /* Init media channel */
-    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS);
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 
+				      secure_level);
     if (status != PJ_SUCCESS) {
 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
@@ -618,11 +689,4 @@
     }
 
-    /* 
-     * Get which account is most likely to be associated with this incoming
-     * call. We need the account to find which contact URI to put for
-     * the call.
-     */
-    acc_id = call->acc_id = pjsua_acc_find_for_incoming(rdata);
-
     /* Verify that we can handle the request. */
     options |= PJSIP_INV_SUPPORT_100REL;
@@ -1321,5 +1385,6 @@
 
     /* Init media channel */
-    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC);
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
+				      get_secure_level(&dlg->remote.info_str));
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
@@ -1390,5 +1455,6 @@
 
     /* Init media channel */
-    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC);
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
+				      get_secure_level(&dlg->remote.info_str));
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
@@ -2509,4 +2575,5 @@
 	status = create_inactive_sdp( call, &answer );
     } else {
+	int secure_level;
 
 	PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
@@ -2514,5 +2581,7 @@
 
 	/* Init media channel */
-	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS);
+	secure_level = get_secure_level(&call->inv->dlg->remote.info_str);
+	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS,
+					  secure_level);
 	if (status != PJ_SUCCESS) {
 	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
@@ -2562,4 +2631,5 @@
 	status = create_inactive_sdp( call, offer );
     } else {
+	int secure_level;
 
 	PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer",
@@ -2567,5 +2637,7 @@
 
 	/* Init media channel */
-	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC);
+	secure_level = get_secure_level(&call->inv->dlg->remote.info_str);
+	status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC,
+					  secure_level);
 	if (status != PJ_SUCCESS) {
 	    pjsua_perror(THIS_FILE, "Error initializing media channel", status);
Index: /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1709)
@@ -143,4 +143,6 @@
     cfg->ka_interval = 15;
     cfg->ka_data = pj_str("\r\n");
+    cfg->use_srtp = PJMEDIA_SRTP_DISABLED;
+    cfg->srtp_secure_signaling = 0;
 }
 
Index: /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_media.c	(revision 1708)
+++ /pjproject/branches/users/nanang/pjsip/src/pjsua-lib/pjsua_media.c	(revision 1709)
@@ -536,18 +536,7 @@
 	}
 
-	if (pjsua_var.media_cfg.enable_srtp) {
-	    pjmedia_transport *tp;
-	    unsigned srtp_options = 0;
-
-	    status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,
-						  &skinfo, 0, &tp);
-	    status = pjmedia_transport_srtp_create(pjsua_var.med_endpt, tp,
-						   srtp_options, 
-						   &pjsua_var.calls[i].med_tp);
-	} else {
-	    status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,
-						  &skinfo, 0,
-						  &pjsua_var.calls[i].med_tp);
-	}
+	status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,
+					      &skinfo, 0,
+					      &pjsua_var.calls[i].med_tp);
 	if (status != PJ_SUCCESS) {
 	    pjsua_perror(THIS_FILE, "Unable to create media transport",
@@ -757,35 +746,12 @@
 
 pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
-				     pjsip_role_e role)
+				     pjsip_role_e role,
+				     int security_level)
 {
     pjsua_call *call = &pjsua_var.calls[call_id];
-
-    if (pjsua_var.media_cfg.enable_ice) {
-	pj_ice_sess_role ice_role;
-	pj_status_t status;
-
-	ice_role = (role==PJSIP_ROLE_UAC ? PJ_ICE_SESS_ROLE_CONTROLLING : 
-				           PJ_ICE_SESS_ROLE_CONTROLLED);
-
-	/* Restart ICE */
-	pjmedia_transport_media_stop(call->med_tp);
-
-	status = pjmedia_ice_init_ice(call->med_tp, ice_role, NULL, NULL);
-	if (status != PJ_SUCCESS)
-	    return status;
-    }
-
-    return PJ_SUCCESS;
-}
-
-pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, 
-					   pj_pool_t *pool,
-					   const pjmedia_sdp_session *rem_sdp,
-					   pjmedia_sdp_session **p_sdp)
-{
-    pjmedia_sdp_session *sdp;
-    pjmedia_sock_info skinfo;
-    pjsua_call *call = &pjsua_var.calls[call_id];
-    pj_status_t status;
+    pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
+    pjmedia_srtp_use use_srtp;
+
+    PJ_UNUSED_ARG(role);
 
     /* Return error if media transport has not been created yet
@@ -796,9 +762,54 @@
     }
 
+    /* Stop media transport (for good measure!) */
+    pjmedia_transport_media_stop(call->med_tp);
+    
+    /* See if we need to use SRTP */
+    use_srtp = acc->cfg.use_srtp;
+    if (use_srtp != PJMEDIA_SRTP_DISABLED) {
+	pj_status_t status;
+	pjmedia_transport *srtp;
+
+	if (security_level < acc->cfg.srtp_secure_signaling) {
+	    return PJSIP_ESESSIONINSECURE;
+	}
+
+	/* Create SRTP */
+	status = pjmedia_transport_srtp_create(pjsua_var.med_endpt, 
+					       call->med_tp,
+					       NULL, &srtp);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	/* Set SRTP as current media transport */
+	call->med_tp = srtp;
+    }
+
+    return PJ_SUCCESS;
+}
+
+pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, 
+					   pj_pool_t *pool,
+					   const pjmedia_sdp_session *rem_sdp,
+					   pjmedia_sdp_session **p_sdp)
+{
+    enum { MAX_MEDIA = 1, MEDIA_IDX = 0 };
+    pjmedia_sdp_session *sdp;
+    pjmedia_sock_info skinfo;
+    pjsua_call *call = &pjsua_var.calls[call_id];
+    pj_status_t status;
+
+    /* Return error if media transport has not been created yet
+     * (e.g. application is starting)
+     */
+    if (call->med_tp == NULL) {
+	return PJ_EBUSY;
+    }
+
     /* Get media socket info */
     pjmedia_transport_get_info(call->med_tp, &skinfo);
 
     /* Create SDP */
-    status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, 1,
+    status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, MAX_MEDIA,
 				      &skinfo, &sdp);
     if (status != PJ_SUCCESS)
@@ -829,11 +840,9 @@
     }
 
-    //if (pjsua_var.media_cfg.enable_ice) {
-	//status = pjmedia_transport_media_create(call->med_tp, pool, sdp, NULL);
-	status = pjmedia_transport_media_create(call->med_tp, pool, 
-						sdp, rem_sdp);
-	if (status != PJ_SUCCESS)
-	    goto on_error;
-    //}
+    /* Give the SDP to media transport */
+    status = pjmedia_transport_media_create(call->med_tp, pool, 
+					    sdp, rem_sdp, MEDIA_IDX);
+    if (status != PJ_SUCCESS)
+	goto on_error;
 
     *p_sdp = sdp;
@@ -874,8 +883,10 @@
     stop_media_session(call_id);
 
-    //if (pjsua_var.media_cfg.enable_ice) {
-	pjmedia_transport_media_stop(call->med_tp);
-    //}
-
+    pjmedia_transport_media_stop(call->med_tp);
+
+    if (call->med_tp != call->med_orig) {
+	pjmedia_transport_close(call->med_tp);
+	call->med_tp = call->med_orig;
+    }
     return PJ_SUCCESS;
 }
@@ -962,20 +973,16 @@
 	call->media_dir = PJMEDIA_DIR_NONE;
 
-	/* Shutdown ICE session */
-	//if (pjsua_var.media_cfg.enable_ice) {
-	    pjmedia_transport_media_stop(call->med_tp);
-	//}
+	/* Shutdown transport's session */
+	pjmedia_transport_media_stop(call->med_tp);
 
 	/* No need because we need keepalive? */
 
     } else {
-	/* Start ICE */
-	//if (pjsua_var.media_cfg.enable_ice) {
-	    status = pjmedia_transport_media_start(call->med_tp, 
-						   call->inv->pool,
-						   local_sdp, remote_sdp, 0);
-	    if (status != PJ_SUCCESS)
-		return status;
-	//}
+	/* Start media transport */
+	status = pjmedia_transport_media_start(call->med_tp, 
+					       call->inv->pool,
+					       local_sdp, remote_sdp, 0);
+	if (status != PJ_SUCCESS)
+	    return status;
 
 	/* Override ptime, if this option is specified. */
