Index: pjsip/include/pjsip/sip_transport_tls.h
===================================================================
--- pjsip/include/pjsip/sip_transport_tls.h	(revision 3220)
+++ pjsip/include/pjsip/sip_transport_tls.h	(working copy)
@@ -26,6 +26,7 @@
  */
 
 #include <pjsip/sip_transport.h>
+#include <pj/pool.h>
 #include <pj/ssl_sock.h>
 #include <pj/string.h>
 #include <pj/sock_qos.h>
@@ -106,20 +107,19 @@
     int		method;
 
     /**
-     * TLS cipher list string in OpenSSL format. If empty, then default
-     * cipher list of the backend will be used.
+     * Number of ciphers contained in the specified cipher preference. 
+     * If this is set to zero, then default cipher list of the backend 
+     * will be used.
+     *
+     * Default: 0 (zero).
      */
-    pj_str_t	ciphers;
+    unsigned ciphers_num;
 
     /**
-     * Optionally specify the server name instance to be contacted when
-     * making outgoing TLS connection. This setting is useful when the
-     * server is hosting multiple domains for the same TLS listening
-     * socket.
-     *
-     * Default: empty.
+     * Ciphers and order preference. The #pj_ssl_cipher_get_availables()
+     * can be used to check the available ciphers supported by backend.
      */
-    pj_str_t	server_name;
+    pj_ssl_cipher *ciphers;
 
     /**
      * Specifies TLS transport behavior on the server TLS certificate 
@@ -246,7 +246,13 @@
     pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file);
     pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
     pj_strdup_with_null(pool, &dst->password, &src->password);
-    pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers);
+    if (src->ciphers_num) {
+	unsigned i;
+	dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,
+						       sizeof(pj_ssl_cipher));
+	for (i=0; i<src->ciphers_num; ++i)
+	    dst->ciphers[i] = src->ciphers[i];
+    }
 }
 
 
Index: pjsip/src/pjsip/sip_transport_tls.c
===================================================================
--- pjsip/src/pjsip/sip_transport_tls.c	(revision 3220)
+++ pjsip/src/pjsip/sip_transport_tls.c	(working copy)
@@ -293,6 +293,8 @@
 	ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;
     if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
 	ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+    ssock_param.ciphers = listener->tls_setting.ciphers;
     ssock_param.qos_type = listener->tls_setting.qos_type;
     ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
     pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,
@@ -862,7 +864,6 @@
     ssock_param.cb.on_data_sent = &on_data_sent;
     ssock_param.async_cnt = 1;
     ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);
-    PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type);
     ssock_param.server_name = remote_name;
     ssock_param.timeout = listener->tls_setting.timeout;
     ssock_param.user_data = NULL; /* pending, must be set later */
@@ -872,6 +873,8 @@
 	ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;
     if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
 	ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+    ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+    ssock_param.ciphers = listener->tls_setting.ciphers;
     ssock_param.qos_type = listener->tls_setting.qos_type;
     ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
     pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,
Index: pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- pjsip-apps/src/pjsua/pjsua_app.c	(revision 3220)
+++ pjsip-apps/src/pjsua/pjsua_app.c	(working copy)
@@ -234,6 +234,8 @@
     puts  ("                      May be specified multiple times");
     puts  ("  --stun-srv=FORMAT   Set STUN server host or domain. This option may be");
     puts  ("                      specified more than once. FORMAT is hostdom[:PORT]");
+
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
     puts  ("");
     puts  ("TLS Options:");
     puts  ("  --use-tls           Enable TLS transport (default=no)");
@@ -244,7 +246,9 @@
     puts  ("  --tls-verify-server Verify server's certificate (default=no)");
     puts  ("  --tls-verify-client Verify client's certificate (default=no)");
     puts  ("  --tls-neg-timeout   Specify TLS negotiation timeout (default=no)");
-    puts  ("  --tls-srv-name      Specify TLS server name for multi-hosting server (optional)");
+    puts  ("  --tls-cipher        Specify prefered TLS cipher (optional).");
+    puts  ("                      May be specified multiple times");
+#endif
 
     puts  ("");
     puts  ("Media Options:");
@@ -509,9 +513,11 @@
 	   OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, 
 	   OPT_DURATION, OPT_NO_TCP, OPT_NO_UDP, OPT_THREAD_CNT,
 	   OPT_NOREFERSUB, OPT_ACCEPT_REDIRECT,
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
 	   OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE,
 	   OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT,
-	   OPT_TLS_NEG_TIMEOUT, OPT_TLS_SRV_NAME,
+	   OPT_TLS_NEG_TIMEOUT, OPT_TLS_CIPHER,
+#endif
 	   OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV,
 	   OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, OPT_JB_MAX_SIZE,
 	   OPT_STDOUT_REFRESH, OPT_STDOUT_REFRESH_TEXT, OPT_IPV6, OPT_QOS,
@@ -610,6 +616,7 @@
 	{ "max-calls",	1, 0, OPT_MAX_CALLS},
 	{ "duration",	1, 0, OPT_DURATION},
 	{ "thread-cnt",	1, 0, OPT_THREAD_CNT},
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
 	{ "use-tls",	0, 0, OPT_USE_TLS}, 
 	{ "tls-ca-file",1, 0, OPT_TLS_CA_FILE},
 	{ "tls-cert-file",1,0, OPT_TLS_CERT_FILE}, 
@@ -618,7 +625,8 @@
 	{ "tls-verify-server", 0, 0, OPT_TLS_VERIFY_SERVER},
 	{ "tls-verify-client", 0, 0, OPT_TLS_VERIFY_CLIENT},
 	{ "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT},
-	{ "tls-srv-name", 1, 0, OPT_TLS_SRV_NAME},
+	{ "tls-cipher", 1, 0, OPT_TLS_CIPHER},
+#endif
 	{ "capture-dev",    1, 0, OPT_CAPTURE_DEV},
 	{ "playback-dev",   1, 0, OPT_PLAYBACK_DEV},
 	{ "capture-lat",    1, 0, OPT_CAPTURE_LAT},
@@ -1274,28 +1282,17 @@
 	    }
 	    break;
 
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
 	case OPT_USE_TLS:
 	    cfg->use_tls = PJ_TRUE;
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
 	case OPT_TLS_CA_FILE:
 	    cfg->udp_cfg.tls_setting.ca_list_file = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
 	case OPT_TLS_CERT_FILE:
 	    cfg->udp_cfg.tls_setting.cert_file = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 	    
 	case OPT_TLS_PRIV_FILE:
@@ -1304,10 +1301,6 @@
 
 	case OPT_TLS_PASSWORD:
 	    cfg->udp_cfg.tls_setting.password = pj_str(pj_optarg);
-#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0
-	    PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured"));
-	    return -1;
-#endif
 	    break;
 
 	case OPT_TLS_VERIFY_SERVER:
@@ -1323,9 +1316,35 @@
 	    cfg->udp_cfg.tls_setting.timeout.sec = atoi(pj_optarg);
 	    break;
 
-	case OPT_TLS_SRV_NAME:
-	    cfg->udp_cfg.tls_setting.server_name = pj_str(pj_optarg);
+	case OPT_TLS_CIPHER:
+	    {
+		pj_ssl_cipher cipher;
+
+		cipher = pj_ssl_cipher_id(pj_optarg);
+		if (cipher != PJ_TLS_CIPHER_UNKNOWN) {
+		    static pj_ssl_cipher tls_ciphers[128];
+		    static unsigned tls_ciphers_num = 0;
+
+		    tls_ciphers[tls_ciphers_num++] = cipher;
+		    cfg->udp_cfg.tls_setting.ciphers_num = tls_ciphers_num;
+		    cfg->udp_cfg.tls_setting.ciphers = tls_ciphers;
+		} else {
+		    /* The cipher is not supported */
+		    pj_ssl_cipher ciphers[128];
+		    unsigned j, ciphers_cnt;
+
+		    ciphers_cnt = PJ_ARRAY_SIZE(ciphers);
+		    pj_ssl_cipher_get_availables(ciphers, &ciphers_cnt);
+		    PJ_LOG(1,(THIS_FILE, "Cipher \"%s\" is not supported by "
+					 "TLS/SSL backend.", pj_optarg));
+		    puts("Supported TLS/SSL ciphers:");
+		    for (j=0; j<ciphers_cnt; ++j)
+			printf("- %s\n", pj_ssl_cipher_name(ciphers[j]));
+		    return -1;
+		}
+	    }
 	    break;
+#endif
 
 	case OPT_CAPTURE_DEV:
 	    cfg->capture_dev = atoi(pj_optarg);
@@ -1742,6 +1761,7 @@
 	pj_strcat2(&cfg, line);
     }
 
+#if defined(PJSIP_HAS_TLS_TRANSPORT) && (PJSIP_HAS_TLS_TRANSPORT != 0)
     /* TLS */
     if (config->use_tls)
 	pj_strcat2(&cfg, "--use-tls\n");
@@ -1771,13 +1791,6 @@
 	pj_strcat2(&cfg, line);
     }
 
-    if (config->udp_cfg.tls_setting.server_name.slen) {
-	pj_ansi_sprintf(line, "--tls-srv-name %.*s\n",
-			(int)config->udp_cfg.tls_setting.server_name.slen, 
-			config->udp_cfg.tls_setting.server_name.ptr);
-	pj_strcat2(&cfg, line);
-    }
-
     if (config->udp_cfg.tls_setting.verify_server)
 	pj_strcat2(&cfg, "--tls-verify-server\n");
 
@@ -1790,6 +1803,13 @@
 	pj_strcat2(&cfg, line);
     }
 
+    for (i=0; i<config->udp_cfg.tls_setting.ciphers_num; ++i) {
+	pj_ansi_sprintf(line, "--tls-cipher %s\n",
+			pj_ssl_cipher_name(config->udp_cfg.tls_setting.ciphers[i]));
+	pj_strcat2(&cfg, line);
+    }
+#endif
+
     pj_strcat2(&cfg, "\n#\n# Media settings:\n#\n");
 
     /* SRTP */
@@ -2907,29 +2927,38 @@
 	const char *verif_msgs[32];
 	unsigned verif_msg_cnt;
 
-	/* Dump server TLS certificate */
-	pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, "  ",
-			      buf, sizeof(buf));
-	PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf));
+	/* Dump server TLS cipher */
+	PJ_LOG(4,(THIS_FILE, "TLS cipher used: %s",
+		  pj_ssl_cipher_name(ssl_sock_info->cipher)));
 
-	/* Dump server TLS certificate verification result */
-	verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
-	pj_ssl_cert_get_verify_status_strings(ssl_sock_info->verify_status,
-					      verif_msgs, &verif_msg_cnt);
-	PJ_LOG(3,(THIS_FILE, "TLS cert verification result of %s : %s",
-			     host_port,
-			     (verif_msg_cnt == 1? verif_msgs[0]:"")));
-	if (verif_msg_cnt > 1) {
-	    unsigned i;
-	    for (i = 0; i < verif_msg_cnt; ++i)
-		PJ_LOG(3,(THIS_FILE, "- %s", verif_msgs[i]));
-	}
+	/* Dump server TLS certificate and the verification result, if any */
+	if (ssl_sock_info->remote_cert_info &&
+	    ssl_sock_info->remote_cert_info->subject.info.slen)
+	{
+	    /* Dump server TLS certificate */
+	    pj_ssl_cert_info_dump(ssl_sock_info->remote_cert_info, "  ",
+				  buf, sizeof(buf));
+	    PJ_LOG(4,(THIS_FILE, "TLS cert info of %s:\n%s", host_port, buf));
 
-	if (ssl_sock_info->verify_status &&
-	    !app_config.udp_cfg.tls_setting.verify_server) 
-	{
-	    PJ_LOG(3,(THIS_FILE, "PJSUA is configured to ignore TLS cert "
-				 "verification errors"));
+	    /* Dump server TLS certificate verification result */
+	    verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
+	    pj_ssl_cert_get_verify_status_strings(ssl_sock_info->verify_status,
+						  verif_msgs, &verif_msg_cnt);
+	    PJ_LOG(3,(THIS_FILE, "TLS cert verification result of %s : %s",
+				 host_port,
+				 (verif_msg_cnt == 1? verif_msgs[0]:"")));
+	    if (verif_msg_cnt > 1) {
+		unsigned i;
+		for (i = 0; i < verif_msg_cnt; ++i)
+		    PJ_LOG(3,(THIS_FILE, "- %s", verif_msgs[i]));
+	    }
+
+	    if (ssl_sock_info->verify_status &&
+		!app_config.udp_cfg.tls_setting.verify_server) 
+	    {
+		PJ_LOG(3,(THIS_FILE, "PJSUA is configured to ignore TLS cert "
+				     "verification errors"));
+	    }
 	}
     }
 
Index: pjlib/include/pj/ssl_sock.h
===================================================================
--- pjlib/include/pj/ssl_sock.h	(revision 3220)
+++ pjlib/include/pj/ssl_sock.h	(working copy)
@@ -246,6 +246,9 @@
     /* NULL */
     PJ_TLS_NULL_WITH_NULL_NULL               	= 0x00000000,
 
+    /* UNKNOWN */
+    PJ_TLS_CIPHER_UNKNOWN              		= 0xFFFFFFFF,
+
     /* TLS/SSLv3 */
     PJ_TLS_RSA_WITH_NULL_MD5                 	= 0x00000001,
     PJ_TLS_RSA_WITH_NULL_SHA                 	= 0x00000002,
@@ -336,12 +339,45 @@
  *
  * @param cipher	The cipher.
  *
- * @return		The cipher name or NULL if cipher is not recognized.
+ * @return		The cipher name or NULL if cipher is not recognized/
+ *			supported.
  */
 PJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher);
 
 
 /**
+ * Get cipher ID from cipher name string.
+ *
+ * @param cipher_name	The cipher name string.
+ *
+ * @return		The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher
+ *			name string is not recognized/supported.
+ */
+PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name);
+
+
+/**
+ * Internal function to resolve the generic/standard cipher name.
+ *
+ * @param cipher	The cipher.
+ *
+ * @return		The cipher name or NULL if cipher is not recognized.
+ */
+const char* pj_ssl_cipher_generic_name(pj_ssl_cipher cipher);
+
+
+/**
+ * Internal function to resolve generic/standard cipher ID.
+ *
+ * @param cipher_name	The cipher name string.
+ *
+ * @return		The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher
+ *			name string is not recognized.
+ */
+pj_ssl_cipher pj_ssl_cipher_generic_id(const char *cipher_name);
+
+
+/**
  * This structure contains the callbacks to be called by the secure socket.
  */
 typedef struct pj_ssl_sock_cb
Index: pjlib/src/pj/ssl_sock_ossl.c
===================================================================
--- pjlib/src/pj/ssl_sock_ossl.c	(revision 3225)
+++ pjlib/src/pj/ssl_sock_ossl.c	(working copy)
@@ -270,8 +270,11 @@
 static int openssl_reg_strerr;
 
 /* OpenSSL available ciphers */
-static pj_ssl_cipher openssl_ciphers[100];
 static unsigned openssl_cipher_num;
+static struct openssl_ciphers_t {
+    pj_ssl_cipher    id;
+    const char	    *name;
+} openssl_ciphers[100];
 
 /* OpenSSL application data index */
 static int sslsock_idx;
@@ -330,10 +333,14 @@
 
 	for (i = 0; i < n; ++i) {
 	    SSL_CIPHER *c;
+	    const char *name;
 	    c = sk_SSL_CIPHER_value(sk_cipher,i);
-	    openssl_ciphers[i] = (pj_ssl_cipher)
-				 (pj_uint32_t)c->id & 0x00FFFFFF;
-	    //printf("%3u: %08x=%s\n", i+1, c->id, SSL_CIPHER_get_name(c));
+	    openssl_ciphers[i].id = (pj_ssl_cipher)
+				    (pj_uint32_t)c->id & 0x00FFFFFF;
+	    name = pj_ssl_cipher_generic_name(openssl_ciphers[i].id);
+	    if (name == NULL)
+		name = SSL_CIPHER_get_name(c);
+	    openssl_ciphers[i].name = name;
 	}
 
 	SSL_free(ssl);
@@ -1705,18 +1712,58 @@
 	shutdown_openssl();
     }
 
-    if (openssl_cipher_num == 0)
+    if (openssl_cipher_num == 0) {
+	*cipher_num = 0;
 	return PJ_ENOTFOUND;
+    }
 
     *cipher_num = PJ_MIN(*cipher_num, openssl_cipher_num);
 
     for (i = 0; i < *cipher_num; ++i)
-	ciphers[i] = openssl_ciphers[i];
+	ciphers[i] = openssl_ciphers[i].id;
 
     return PJ_SUCCESS;
 }
 
 
+/* Get cipher name string */
+PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
+{
+    unsigned i;
+
+    if (openssl_cipher_num == 0) {
+	init_openssl();
+	shutdown_openssl();
+    }
+
+    for (i = 0; i < openssl_cipher_num; ++i) {
+	if (cipher == openssl_ciphers[i].id)
+	    return openssl_ciphers[i].name;
+    }
+
+    return NULL;
+}
+
+
+/* Get cipher from cipher name string. */
+PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name)
+{
+    unsigned i;
+
+    if (openssl_cipher_num == 0) {
+	init_openssl();
+	shutdown_openssl();
+    }
+
+    for (i = 0; i < openssl_cipher_num; ++i) {
+	if (pj_ansi_stricmp(cipher_name, openssl_ciphers[i].name)==0)
+	    return openssl_ciphers[i].id;
+    }
+
+    return PJ_TLS_CIPHER_UNKNOWN;
+}
+
+
 /*
  * Create SSL socket instance. 
  */
Index: pjlib/src/pj/ssl_sock_symbian.cpp
===================================================================
--- pjlib/src/pj/ssl_sock_symbian.cpp	(revision 3220)
+++ pjlib/src/pj/ssl_sock_symbian.cpp	(working copy)
@@ -115,7 +115,8 @@
 
     int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr, 
 		const TInetAddr &rem_addr, 
-		const TDesC8 &servername = TPtrC8(NULL,0));
+		const TDesC8 &servername = TPtrC8(NULL,0),
+		const TDesC8 &ciphers = TPtrC8(NULL,0));
     int Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, TUint flags);
     int SendSync(const TDesC8 &aDesc, TUint flags);
 
@@ -146,6 +147,7 @@
     TBuf<32> 	    	 ssl_proto_;
     TInetAddr       	 rem_addr_;
     TPtrC8		 servername_;
+    TPtrC8		 ciphers_;
     TInetAddr       	 local_addr_;
     TSockXfrLength 	 sent_len_;
 
@@ -186,7 +188,8 @@
 int CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key, 
 			  const TInetAddr &local_addr, 
 			  const TInetAddr &rem_addr,
-			  const TDesC8 &servername)
+			  const TDesC8 &servername,
+			  const TDesC8 &ciphers)
 {
     pj_status_t status;
     
@@ -213,7 +216,11 @@
     cb_ = cb;
     key_ = key;
     rem_addr_ = rem_addr;
+    
+    /* Note: the following members only keep the pointer, not the data */
     servername_.Set(servername);
+    ciphers_.Set(ciphers);
+
     rSock.Connect(rem_addr_, iStatus);
     SetActive();
     state_ = SSL_STATE_CONNECTING;
@@ -318,6 +325,8 @@
 	    if (servername_.Length() > 0)
 		securesock_->SetOpt(KSoSSLDomainName, KSolInetSSL,
 				    servername_);
+	    if (ciphers_.Length() > 0)
+		securesock_->SetAvailableCipherSuites(ciphers_);
 
 	    // FlushSessionCache() seems to also fire signals to all 
 	    // completed AOs (something like CActiveScheduler::RunIfReady())
@@ -441,9 +450,8 @@
 
     pj_ssl_sock_proto	 proto;
     pj_time_val		 timeout;
-    unsigned		 ciphers_num;
-    pj_ssl_cipher	*ciphers;
     pj_str_t		 servername;
+    pj_str_t		 ciphers;
     pj_ssl_cert_info	 remote_cert_info;
 };
 
@@ -579,15 +587,20 @@
 }
 
 
+/* Available ciphers */
+static unsigned ciphers_num_ = 0;
+static struct ciphers_t
+{
+    pj_ssl_cipher    id;
+    const char	    *name;
+} ciphers_[64];
+
 /*
  * Get cipher list supported by SSL/TLS backend.
  */
 PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables (pj_ssl_cipher ciphers[],
 					          unsigned *cipher_num)
 {
-    /* Available ciphers */
-    static pj_ssl_cipher ciphers_[64];
-    static unsigned ciphers_num_ = 0;
     unsigned i;
 
     PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);
@@ -605,25 +618,69 @@
             ciphers_num_ = ciphers_buf.Length() / 2;
             if (ciphers_num_ > PJ_ARRAY_SIZE(ciphers_))
         	ciphers_num_ = PJ_ARRAY_SIZE(ciphers_);
-            for (i = 0; i < ciphers_num_; ++i)
-                ciphers_[i] = (pj_ssl_cipher)(ciphers_buf[i*2]*10 + 
-					      ciphers_buf[i*2+1]);
+            for (i = 0; i < ciphers_num_; ++i) {
+                ciphers_[i].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 + 
+					         ciphers_buf[i*2+1]);
+		ciphers_[i].name = pj_ssl_cipher_generic_name(ciphers_[i].id);
+	    }
         }
         
         delete secure_sock;
     }
     
     if (ciphers_num_ == 0) {
+	*cipher_num = 0;
 	return PJ_ENOTFOUND;
     }
     
     *cipher_num = PJ_MIN(*cipher_num, ciphers_num_);
     for (i = 0; i < *cipher_num; ++i)
-        ciphers[i] = ciphers_[i];
+        ciphers[i] = ciphers_[i].id;
     
     return PJ_SUCCESS;
 }
 
+
+/* Get cipher name string */
+PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
+{
+    unsigned i;
+
+    if (ciphers_num_ == 0) {
+	pj_ssl_cipher c[1];
+	i = 0;
+	pj_ssl_cipher_get_availables(c, &i);
+    }
+	
+    for (i = 0; i < ciphers_num_; ++i) {
+	if (cipher == ciphers_[i].id)
+	    return ciphers_[i].name;
+    }
+
+    return NULL;
+}
+
+
+/* Get cipher ID from cipher name string. */
+PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name)
+{
+    unsigned i;
+
+    if (ciphers_num_ == 0) {
+	pj_ssl_cipher c[1];
+	i = 0;
+	pj_ssl_cipher_get_availables(c, &i);
+    }
+
+    for (i = 0; i < ciphers_num_; ++i) {
+	if (pj_ansi_stricmp(cipher_name, ciphers_[i].name)==0)
+	    return ciphers_[i].id;
+    }
+
+    return PJ_TLS_CIPHER_UNKNOWN;
+}
+
+
 /*
  * Create SSL socket instance. 
  */
@@ -652,14 +709,15 @@
     ssock->cb = param->cb;
     ssock->user_data = param->user_data;
     ssock->timeout = param->timeout;
-    ssock->ciphers_num = param->ciphers_num;
     if (param->ciphers_num > 0) {
-	unsigned i;
-	ssock->ciphers = (pj_ssl_cipher*)
-			 pj_pool_calloc(pool, param->ciphers_num, 
-					sizeof(pj_ssl_cipher));
-	for (i = 0; i < param->ciphers_num; ++i)
-	    ssock->ciphers[i] = param->ciphers[i];
+	/* Cipher list in Symbian is represented as array of two-octets. */
+	ssock->ciphers.slen = param->ciphers_num*2;
+	ssock->ciphers.ptr  = (char*)pj_pool_alloc(pool, ssock->ciphers.slen);
+	pj_uint8_t *c = (pj_uint8_t*)ssock->ciphers.ptr;
+	for (unsigned i = 0; i < param->ciphers_num; ++i) {
+	    *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF00) >> 8;
+	    *c++ = (pj_uint8_t)(param->ciphers[i] & 0xFF);
+	}
     }
     pj_strdup_with_null(pool, &ssock->servername, &param->server_name);
 
@@ -782,7 +840,7 @@
 	/* Cipher suite */
 	TBuf8<4> cipher;
 	if (ssock->sock->GetCipher(cipher) == KErrNone) {
-	    info->cipher = (pj_ssl_cipher)cipher[1]; 
+	    info->cipher = (pj_ssl_cipher)(cipher[0]*10+cipher[1]); 
 	}
 
 	/* Remote address */
@@ -1252,9 +1310,13 @@
     TPtrC8 servername_((TUint8*)ssock->servername.ptr, 
 		       ssock->servername.slen);
     
+    /* Convert cipher list to Symbian descriptor */
+    TPtrC8 ciphers_((TUint8*)ssock->ciphers.ptr, 
+		    ssock->ciphers.slen);
+    
     /* Try to connect */
     status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_,
-			   servername_);
+			   servername_, ciphers_);
     if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 	delete sock;
 	return status;
Index: pjlib/src/pj/ssl_sock_common.c
===================================================================
--- pjlib/src/pj/ssl_sock_common.c	(revision 3220)
+++ pjlib/src/pj/ssl_sock_common.c	(working copy)
@@ -129,8 +129,8 @@
 }
 
 
-/* Get cipher name string */
-PJ_DEF(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher)
+/* Get generic/standard cipher name string */
+const char* pj_ssl_cipher_generic_name(pj_ssl_cipher cipher)
 {
     unsigned i, n;
 
@@ -144,8 +144,21 @@
 }
 
 
+/* Get generic/standard cipher ID from cipher name string. */
+pj_ssl_cipher pj_ssl_cipher_generic_id(const char *cipher_name)
+{
+    unsigned i, n;
 
+    n = PJ_ARRAY_SIZE(cipher_names);
+    for (i = 0; i < n; ++i) {
+	if (pj_ansi_stricmp(cipher_name, cipher_names[i].name)==0)
+	    return cipher_names[i].cipher;
+    }
 
+    return PJ_TLS_CIPHER_UNKNOWN;
+}
+
+
 PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
 						pj_uint32_t verify_status, 
 						const char *error_strings[],
Index: pjsip-apps/src/symbian_ua/ua.cpp
===================================================================
--- pjsip-apps/src/symbian_ua/ua.cpp	(revision 3220)
+++ pjsip-apps/src/symbian_ua/ua.cpp	(working copy)
@@ -58,9 +58,6 @@
 #define ENABLE_SIP_TCP	0 // experimental
 #define ENABLE_SIP_TLS	0 // experimental
 
-#define TLS_SRV_NAME	"pjsip.org"	// TLS servername (required for
-					// TLS transport)
-
 //
 // Configure nameserver if DNS SRV is to be used with both SIP
 // or STUN (for STUN see other settings below)
