/* $Id$ */
/* 
 * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
 *
 * 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 <pj/ssl_sock.h>
#include <pj/compat/socket.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/math.h>
#include <pj/pool.h>
#include <pj/sock.h>
#include <pj/string.h>

#include "os_symbian.h"
#include <securesocket.h>
#include <x509cert.h>
#include <e32des8.h>

#define THIS_FILE "ssl_sock_symbian.cpp"


/* Cipher name structure */
typedef struct cipher_name_t {
    pj_ssl_cipher    cipher;
    const char	    *name;
} cipher_name_t;

/* Cipher name constants */
static cipher_name_t cipher_names[] =
{
    {PJ_TLS_NULL_WITH_NULL_NULL,               "NULL"},

    /* TLS/SSLv3 */
    {PJ_TLS_RSA_WITH_NULL_MD5,                 "TLS_RSA_WITH_NULL_MD5"},
    {PJ_TLS_RSA_WITH_NULL_SHA,                 "TLS_RSA_WITH_NULL_SHA"},
    {PJ_TLS_RSA_WITH_NULL_SHA256,              "TLS_RSA_WITH_NULL_SHA256"},
    {PJ_TLS_RSA_WITH_RC4_128_MD5,              "TLS_RSA_WITH_RC4_128_MD5"},
    {PJ_TLS_RSA_WITH_RC4_128_SHA,              "TLS_RSA_WITH_RC4_128_SHA"},
    {PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA,         "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA,          "TLS_RSA_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA,          "TLS_RSA_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_RSA_WITH_AES_128_CBC_SHA256,       "TLS_RSA_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_RSA_WITH_AES_256_CBC_SHA256,       "TLS_RSA_WITH_AES_256_CBC_SHA256"},
    {PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,      "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,      "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,     "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,     "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA,       "TLS_DH_DSS_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA,       "TLS_DH_RSA_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,      "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA,       "TLS_DH_DSS_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA,       "TLS_DH_RSA_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,      "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,    "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,    "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,   "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,   "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,    "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"},
    {PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,    "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"},
    {PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,   "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"},
    {PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,   "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
    {PJ_TLS_DH_anon_WITH_RC4_128_MD5,          "TLS_DH_anon_WITH_RC4_128_MD5"},
    {PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,     "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"},
    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA,      "TLS_DH_anon_WITH_AES_128_CBC_SHA"},
    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA,      "TLS_DH_anon_WITH_AES_256_CBC_SHA"},
    {PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256,   "TLS_DH_anon_WITH_AES_128_CBC_SHA256"},
    {PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256,   "TLS_DH_anon_WITH_AES_256_CBC_SHA256"},

    /* TLS (deprecated) */
    {PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5,        "TLS_RSA_EXPORT_WITH_RC4_40_MD5"},
    {PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,    "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"},
    {PJ_TLS_RSA_WITH_IDEA_CBC_SHA,             "TLS_RSA_WITH_IDEA_CBC_SHA"},
    {PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,     "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_RSA_WITH_DES_CBC_SHA,              "TLS_RSA_WITH_DES_CBC_SHA"},
    {PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,  "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_DH_DSS_WITH_DES_CBC_SHA,           "TLS_DH_DSS_WITH_DES_CBC_SHA"},
    {PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,  "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_DH_RSA_WITH_DES_CBC_SHA,           "TLS_DH_RSA_WITH_DES_CBC_SHA"},
    {PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA,          "TLS_DHE_DSS_WITH_DES_CBC_SHA"},
    {PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA,          "TLS_DHE_RSA_WITH_DES_CBC_SHA"},
    {PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,    "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"},
    {PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"},
    {PJ_TLS_DH_anon_WITH_DES_CBC_SHA,          "TLS_DH_anon_WITH_DES_CBC_SHA"},

    /* SSLv3 */
    {PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA,        "SSL_FORTEZZA_KEA_WITH_NULL_SHA"},
    {PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA,"SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"},
    {PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA,     "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"},

    /* SSLv2 */
    {PJ_SSL_CK_RC4_128_WITH_MD5,               "SSL_CK_RC4_128_WITH_MD5"},
    {PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5,      "SSL_CK_RC4_128_EXPORT40_WITH_MD5"},
    {PJ_SSL_CK_RC2_128_CBC_WITH_MD5,           "SSL_CK_RC2_128_CBC_WITH_MD5"},
    {PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,  "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5"},
    {PJ_SSL_CK_IDEA_128_CBC_WITH_MD5,          "SSL_CK_IDEA_128_CBC_WITH_MD5"},
    {PJ_SSL_CK_DES_64_CBC_WITH_MD5,            "SSL_CK_DES_64_CBC_WITH_MD5"},
    {PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5,      "SSL_CK_DES_192_EDE3_CBC_WITH_MD5"}
};


/* Get cipher name string */
static const char* get_cipher_name(pj_ssl_cipher cipher)
{
    unsigned i, n;

    n = PJ_ARRAY_SIZE(cipher_names);
    for (i = 0; i < n; ++i) {
       if (cipher == cipher_names[i].cipher)
           return cipher_names[i].name;
    }

    return "CIPHER_UNKNOWN";
}

typedef void (*CPjSSLSocket_cb)(int err, void *key);

class CPjSSLSocketReader : public CActive
{
public:
    static CPjSSLSocketReader *NewL(CSecureSocket &sock) 
    {
	CPjSSLSocketReader *self = new (ELeave) 
				   CPjSSLSocketReader(sock);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
    }

    ~CPjSSLSocketReader() {
	Cancel();
    }

    /* Asynchronous read from the socket. */
    int Read(CPjSSLSocket_cb cb, void *key, TPtr8 &data, TUint flags)
    {
	PJ_ASSERT_RETURN(!IsActive(), PJ_EBUSY);
	
	cb_ = cb;
	key_ = key;
	sock_.RecvOneOrMore(data, iStatus, len_received_);
	SetActive();
	
	return PJ_EPENDING;
    }

private:
    CSecureSocket  	&sock_;
    CPjSSLSocket_cb	 cb_;
    void		*key_;
    TSockXfrLength  	 len_received_; /* not really useful? */

    void DoCancel() {
	sock_.CancelAll();
    }
    
    void RunL() {
	(*cb_)(iStatus.Int(), key_);
    }

    CPjSSLSocketReader(CSecureSocket &sock) : 
	CActive(0), sock_(sock), cb_(NULL), key_(NULL) 
    {}
    
    void ConstructL() {
	CActiveScheduler::Add(this);
    }
};

class CPjSSLSocket : public CActive
{
public:
    enum ssl_state {
	SSL_STATE_NULL,
	SSL_STATE_CONNECTING,
	SSL_STATE_HANDSHAKING,
	SSL_STATE_ESTABLISHED
    };
    
    static CPjSSLSocket *NewL(const TDesC8 &ssl_proto,
			      pj_qos_type qos_type,
			      const pj_qos_params &qos_params) 
    {
	CPjSSLSocket *self = new (ELeave) CPjSSLSocket(qos_type, qos_params);
	CleanupStack::PushL(self);
	self->ConstructL(ssl_proto);
	CleanupStack::Pop(self);
	return self;
    }

    ~CPjSSLSocket() {
	Cancel();
	CleanupSubObjects();
    }

    int Connect(CPjSSLSocket_cb cb, void *key, const TInetAddr &local_addr, 
		const TInetAddr &rem_addr, 
		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);

    CPjSSLSocketReader* GetReader();
    enum ssl_state GetState() const { return state_; }
    const TInetAddr* GetLocalAddr() const { return &local_addr_; }
    int GetCipher(TDes8 &cipher) const {
	if (securesock_)
	    return securesock_->CurrentCipherSuite(cipher);
	return KErrNotFound;
    }
    const CX509Certificate *GetPeerCert() {
	if (securesock_)
	    return securesock_->ServerCert();
	return NULL;
    }

private:
    enum ssl_state	 state_;
    pj_sock_t	    	 sock_;
    CSecureSocket  	*securesock_;
    bool	    	 is_connected_;
    
    pj_qos_type 	 qos_type_;
    pj_qos_params 	 qos_params_;
    			      
    CPjSSLSocketReader  *reader_;
    TBuf<32> 	    	 ssl_proto_;
    TInetAddr       	 rem_addr_;
    TPtrC8		 servername_;
    TPtrC8		 ciphers_;
    TInetAddr       	 local_addr_;
    TSockXfrLength 	 sent_len_;

    CPjSSLSocket_cb 	 cb_;
    void 	   	*key_;
    
    void DoCancel();
    void RunL();

    CPjSSLSocket(pj_qos_type qos_type, const pj_qos_params &qos_params) :
	CActive(0), state_(SSL_STATE_NULL), sock_(PJ_INVALID_SOCKET), 
	securesock_(NULL), is_connected_(false),
	qos_type_(qos_type), qos_params_(qos_params),
	reader_(NULL), 	cb_(NULL), key_(NULL)
    {}
    
    void ConstructL(const TDesC8 &ssl_proto) {
	ssl_proto_.Copy(ssl_proto);
	CActiveScheduler::Add(this);
    }

    void CleanupSubObjects() {
	delete reader_;
	reader_ = NULL;
	if (securesock_) {
	    if (state_ == SSL_STATE_ESTABLISHED)
		securesock_->Close();
	    delete securesock_;
	    securesock_ = NULL;
	}
	if (sock_ != PJ_INVALID_SOCKET) {
	    pj_sock_close(sock_);
	    sock_ = PJ_INVALID_SOCKET;
	}	    
    }
};

int CPjSSLSocket::Connect(CPjSSLSocket_cb cb, void *key, 
			  const TInetAddr &local_addr, 
			  const TInetAddr &rem_addr,
			  const TDesC8 &servername,
			  const TDesC8 &ciphers)
{
    pj_status_t status;
    
    PJ_ASSERT_RETURN(state_ == SSL_STATE_NULL, PJ_EINVALIDOP);
    
    status = pj_sock_socket(rem_addr.Family(), pj_SOCK_STREAM(), 0, &sock_);
    if (status != PJ_SUCCESS)
	return status;

    // Apply QoS
    status = pj_sock_apply_qos2(sock_, qos_type_, &qos_params_, 
    				2,  THIS_FILE, NULL);
    
    RSocket &rSock = ((CPjSocket*)sock_)->Socket();

    local_addr_ = local_addr;
    
    if (!local_addr_.IsUnspecified()) {
	TInt err = rSock.Bind(local_addr_);
	if (err != KErrNone)
	    return PJ_RETURN_OS_ERROR(err);
    }
    
    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;
    
    rSock.LocalName(local_addr_);

    return PJ_EPENDING;
}

int CPjSSLSocket::Send(CPjSSLSocket_cb cb, void *key, const TDesC8 &aDesc, 
		       TUint flags)
{
    PJ_UNUSED_ARG(flags);

    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
    
    if (IsActive())
	return PJ_EBUSY;
    
    cb_ = cb;
    key_ = key;
    
    securesock_->Send(aDesc, iStatus, sent_len_);
    SetActive();
    
    return PJ_EPENDING;
}

int CPjSSLSocket::SendSync(const TDesC8 &aDesc, TUint flags)
{
    PJ_UNUSED_ARG(flags);

    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, PJ_EINVALIDOP);
    
    TRequestStatus reqStatus;
    securesock_->Send(aDesc, reqStatus, sent_len_);
    User::WaitForRequest(reqStatus);
    
    return PJ_RETURN_OS_ERROR(reqStatus.Int());
}

CPjSSLSocketReader* CPjSSLSocket::GetReader()
{
    PJ_ASSERT_RETURN(state_ == SSL_STATE_ESTABLISHED, NULL);
    
    if (reader_)
	return reader_;
    
    TRAPD(err,	reader_ = CPjSSLSocketReader::NewL(*securesock_));
    if (err != KErrNone)
	return NULL;
    
    return reader_;
}

void CPjSSLSocket::DoCancel()
{
    /* Operation to be cancelled depends on current state */
    switch (state_) {
    case SSL_STATE_CONNECTING:
	{
	    RSocket &rSock = ((CPjSocket*)sock_)->Socket();

	    rSock.CancelConnect();
	    CleanupSubObjects();
	    state_ = SSL_STATE_NULL;
	}
	break;
    case SSL_STATE_HANDSHAKING:
	{
	    securesock_->CancelHandshake();
	    CleanupSubObjects();
	    state_ = SSL_STATE_NULL;
	}
	break;
    case SSL_STATE_ESTABLISHED:
	securesock_->CancelSend();
	break;
    default:
	break;
    }
}

void CPjSSLSocket::RunL()
{
    switch (state_) {
    case SSL_STATE_CONNECTING:
	if (iStatus != KErrNone) {
	    CleanupSubObjects();
	    state_ = SSL_STATE_NULL;
	    /* Dispatch connect failure notification */
	    if (cb_) (*cb_)(iStatus.Int(), key_);
	} else {
	    RSocket &rSock = ((CPjSocket*)sock_)->Socket();

	    /* Get local addr */
	    rSock.LocalName(local_addr_);
	    
	    /* Prepare and start handshake */
	    securesock_ = CSecureSocket::NewL(rSock, ssl_proto_);
	    securesock_->SetDialogMode(EDialogModeAttended);
	    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())
	    // which may cause problem, e.g: we've experienced that when 
	    // SSL timeout is set to 1s, the SSL timeout timer fires up
	    // at this point and securesock_ instance gets deleted here!
	    // So be careful using this. And we don't think we need it here.
	    //securesock_->FlushSessionCache();

	    securesock_->StartClientHandshake(iStatus);
	    SetActive();
	    state_ = SSL_STATE_HANDSHAKING;
	}
	break;
    case SSL_STATE_HANDSHAKING:
	if (iStatus == KErrNone) {
	    state_ = SSL_STATE_ESTABLISHED;
	} else {
	    state_ = SSL_STATE_NULL;
	    CleanupSubObjects();
	}
	/* Dispatch connect status notification */
	if (cb_) (*cb_)(iStatus.Int(), key_);
	break;
    case SSL_STATE_ESTABLISHED:
	/* Dispatch data sent notification */
	if (cb_) (*cb_)(iStatus.Int(), key_);
	break;
    default:
	pj_assert(0);
	break;
    }
}

typedef void (*CPjTimer_cb)(void *user_data);

class CPjTimer : public CActive 
{
public:
    CPjTimer(const pj_time_val *delay, CPjTimer_cb cb, void *user_data) : 
	CActive(0), cb_(cb), user_data_(user_data)
    {
	CActiveScheduler::Add(this);

	rtimer_.CreateLocal();
	pj_int32_t interval = PJ_TIME_VAL_MSEC(*delay) * 1000;
	if (interval < 0) {
	    interval = 0;
	}
	rtimer_.After(iStatus, interval);
	SetActive();
    }
    
    ~CPjTimer() { Cancel(); }
    
private:	
    RTimer		 rtimer_;
    CPjTimer_cb		 cb_;
    void		*user_data_;
    
    void RunL() { if (cb_) (*cb_)(user_data_); }
    void DoCancel() { rtimer_.Cancel(); }
};

/*
 * Structure of recv/read state.
 */
typedef struct read_state_t {
    TPtr8		*read_buf;
    TPtr8		*orig_buf;
    pj_uint32_t		 flags;    
} read_state_t;

/*
 * Structure of send/write data.
 */
typedef struct write_data_t {
    pj_size_t 	 	 len;
    pj_ioqueue_op_key_t	*key;
    pj_size_t 	 	 data_len;
    char		 data[1];
} write_data_t;

/*
 * Structure of send/write state.
 */
typedef struct write_state_t {
    char		*buf;
    pj_size_t		 max_len;    
    char		*start;
    pj_size_t		 len;
    write_data_t	*current_data;
    TPtrC8		 send_ptr;
} write_state_t;

/*
 * Secure socket structure definition.
 */
struct pj_ssl_sock_t
{
    pj_pool_t		*pool;
    pj_ssl_sock_cb	 cb;
    void		*user_data;
    
    pj_bool_t		 established;
    write_state_t	 write_state;
    read_state_t	 read_state;
    CPjTimer		*connect_timer;

    CPjSSLSocket   	*sock;
    int			 sock_af;
    int			 sock_type;
    pj_sockaddr		 local_addr;
    pj_sockaddr		 rem_addr;

    /* QoS settings */
    pj_qos_type		 qos_type;
    pj_qos_params	 qos_params;
    pj_bool_t		 qos_ignore_error;


    pj_ssl_sock_proto	 proto;
    pj_time_val		 timeout;
    pj_str_t		 servername;
    pj_str_t		 ciphers;
    pj_ssl_cert_info	 remote_cert_info;
};


static pj_str_t get_cert_name(char *buf, unsigned buf_len,
                              const CX500DistinguishedName &name)
{
    TInt i;
    TUint8 *p;
    TInt l = buf_len;
    
    p = (TUint8*)buf;
    for(i = 0; i < name.Count(); ++i) {
	const CX520AttributeTypeAndValue &attr = name.Element(i);

	/* Print element separator */
	*p++ = '/';
	if (0 == --l) break;

	/* Print the type. */
	TPtr8 type(p, l);
	type.Copy(attr.Type());
	p += type.Length();
	l -= type.Length();
	if (0 >= --l) break;

	/* Print equal sign */
	*p++ = '=';
	if (0 == --l) break;
	
	/* Print the value. Let's just get the raw data here */
	TPtr8 value(p, l);
	value.Copy(attr.EncodedValue().Mid(2));
	p += value.Length();
	l -= value.Length();
	if (0 >= --l) break;
    }
    
    pj_str_t src;
    pj_strset(&src, buf, buf_len - l);
    
    return src;
}
                            
/* Get certificate info from CX509Certificate.
 */
static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci,
                          const CX509Certificate *x)
{
    enum { tmp_buf_len = 512 };
    char *tmp_buf;
    unsigned len;
    
    pj_assert(pool && ci && x);
    
    /* Init */
    tmp_buf = new char[tmp_buf_len];
    pj_bzero(ci, sizeof(*ci));
    
    /* Version */
    ci->version = x->Version();
    
    /* Serial number */
    len = x->SerialNumber().Length();
    if (len > sizeof(ci->serial_no)) 
	len = sizeof(ci->serial_no);
    pj_memcpy(ci->serial_no + sizeof(ci->serial_no) - len, 
              x->SerialNumber().Ptr(), len);
    
    /* Subject */
    {
	HBufC *subject = NULL;
	TRAPD(err, subject = x->SubjectL());
	if (err == KErrNone) {
	    TPtr16 ptr16(subject->Des());
	    len = ptr16.Length();
	    TPtr8 ptr8((TUint8*)pj_pool_alloc(pool, len), len);
	    ptr8.Copy(ptr16);
	    pj_strset(&ci->subject.cn, (char*)ptr8.Ptr(), ptr8.Length());
	}
	pj_str_t tmp = get_cert_name(tmp_buf, tmp_buf_len,
				     x->SubjectName());
	pj_strdup(pool, &ci->subject.info, &tmp);
    }

    /* Issuer */
    {
	HBufC *issuer = NULL;
	TRAPD(err, issuer = x->IssuerL());
	if (err == KErrNone) {
	    TPtr16 ptr16(issuer->Des());
	    len = ptr16.Length();
	    TPtr8 ptr8((TUint8*)pj_pool_alloc(pool, len), len);
	    ptr8.Copy(ptr16);
	    pj_strset(&ci->issuer.cn, (char*)ptr8.Ptr(), ptr8.Length());
	}
	pj_str_t tmp = get_cert_name(tmp_buf, tmp_buf_len,
				     x->IssuerName());
	pj_strdup(pool, &ci->issuer.info, &tmp);
    }
    
    /* Validity */
    const CValidityPeriod &valid_period = x->ValidityPeriod();
    TTime base_time(TDateTime(1970, EJanuary, 0, 0, 0, 0, 0));
    TTimeIntervalSeconds tmp_sec;
    valid_period.Start().SecondsFrom(base_time, tmp_sec);
    ci->validity.start.sec = tmp_sec.Int(); 
    valid_period.Finish().SecondsFrom(base_time, tmp_sec);
    ci->validity.end.sec = tmp_sec.Int();
    
    /* Deinit */
    delete [] tmp_buf;
}


/* Update certificates info. This function should be called after handshake
 * or renegotiation successfully completed.
 */
static void update_certs_info(pj_ssl_sock_t *ssock)
{
    const CX509Certificate *x;

    pj_assert(ssock && ssock->sock &&
              ssock->sock->GetState() == CPjSSLSocket::SSL_STATE_ESTABLISHED);
        
    /* Active remote certificate */
    x = ssock->sock->GetPeerCert();
    if (x) {
	get_cert_info(ssock->pool, &ssock->remote_cert_info, x);
    } else {
	pj_bzero(&ssock->remote_cert_info, sizeof(pj_ssl_cert_info));
    }
}


/* 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)
{
    unsigned i;

    PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL);
    
    if (ciphers_num_ == 0) {
        RSocket sock;
        CSecureSocket *secure_sock;
        TPtrC16 proto(_L16("TLS1.0"));

        secure_sock = CSecureSocket::NewL(sock, proto);
        if (secure_sock) {
            TBuf8<128> ciphers_buf(0);
            secure_sock->AvailableCipherSuites(ciphers_buf);
            
            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].id = (pj_ssl_cipher)(ciphers_buf[i*2]*10 + 
					         ciphers_buf[i*2+1]);
		ciphers_[i].name = get_cipher_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].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;
}


/* Check if the specified cipher is supported by SSL/TLS backend. */
PJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(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 PJ_TRUE;
    }

    return PJ_FALSE;
}


/*
 * Create SSL socket instance. 
 */
PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
					const pj_ssl_sock_param *param,
					pj_ssl_sock_t **p_ssock)
{
    pj_ssl_sock_t *ssock;

    PJ_ASSERT_RETURN(param->async_cnt == 1, PJ_EINVAL);
    PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);

    /* Allocate secure socket */
    ssock = PJ_POOL_ZALLOC_T(pool, pj_ssl_sock_t);
    
    /* Allocate write buffer */
    ssock->write_state.buf = (char*)pj_pool_alloc(pool, 
						  param->send_buffer_size);
    ssock->write_state.max_len = param->send_buffer_size;
    ssock->write_state.start = ssock->write_state.buf;
    
    /* Init secure socket */
    ssock->pool = pool;
    ssock->sock_af = param->sock_af;
    ssock->sock_type = param->sock_type;
    ssock->cb = param->cb;
    ssock->user_data = param->user_data;
    ssock->timeout = param->timeout;
    if (param->ciphers_num > 0) {
	/* 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);

    ssock->qos_type = param->qos_type;
    ssock->qos_ignore_error = param->qos_ignore_error;
    pj_memcpy(&ssock->qos_params, &param->qos_params,
	      sizeof(param->qos_params));

    /* Finally */
    *p_ssock = ssock;

    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool,
                                        	const pj_str_t *CA_file,
                                        	const pj_str_t *cert_file,
                                        	const pj_str_t *privkey_file,
                                        	const pj_str_t *privkey_pass,
                                        	pj_ssl_cert_t **p_cert)
{
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(CA_file);
    PJ_UNUSED_ARG(cert_file);
    PJ_UNUSED_ARG(privkey_file);
    PJ_UNUSED_ARG(privkey_pass);
    PJ_UNUSED_ARG(p_cert);
    return PJ_ENOTSUP;
}

/*
 * Set SSL socket credential.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
					    pj_ssl_sock_t *ssock,
					    pj_pool_t *pool,
					    const pj_ssl_cert_t *cert)
{
    PJ_UNUSED_ARG(ssock);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(cert);
    return PJ_ENOTSUP;
}

/*
 * Close the SSL socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
{
    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
    
    delete ssock->connect_timer;
    ssock->connect_timer = NULL;
    
    delete ssock->sock;
    ssock->sock = NULL;

    delete ssock->read_state.read_buf;
    delete ssock->read_state.orig_buf;
    ssock->read_state.read_buf = NULL;
    ssock->read_state.orig_buf = NULL;
    
    return PJ_SUCCESS;
}


/*
 * Associate arbitrary data with the SSL socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_set_user_data (pj_ssl_sock_t *ssock,
					       void *user_data)
{
    PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
    
    ssock->user_data = user_data;
    
    return PJ_SUCCESS;
}
					       

/*
 * Retrieve the user data previously associated with this SSL
 * socket.
 */
PJ_DEF(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock)
{
    PJ_ASSERT_RETURN(ssock, NULL);
    
    return ssock->user_data;
}


/*
 * Retrieve the local address and port used by specified SSL socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock,
					  pj_ssl_sock_info *info)
{
    PJ_ASSERT_RETURN(ssock && info, PJ_EINVAL);
    
    pj_bzero(info, sizeof(*info));
    
    info->established = ssock->established;
    
    /* Local address */
    if (ssock->sock) {
	const TInetAddr* local_addr_ = ssock->sock->GetLocalAddr();
	int addrlen = sizeof(pj_sockaddr);
	pj_status_t status;
	
	status = PjSymbianOS::Addr2pj(*local_addr_, info->local_addr, &addrlen);
	if (status != PJ_SUCCESS)
	    return status;
    } else {
	pj_sockaddr_cp(&info->local_addr, &ssock->local_addr);
    }

    if (info->established) {
	/* Cipher suite */
	TBuf8<4> cipher;
	if (ssock->sock->GetCipher(cipher) == KErrNone) {
	    info->cipher = (pj_ssl_cipher)cipher[1]; 
	}

	/* Remote address */
        pj_sockaddr_cp((pj_sockaddr_t*)&info->remote_addr, 
    		       (pj_sockaddr_t*)&ssock->rem_addr);
        
        /* Certificates info */
        info->remote_cert_info = &ssock->remote_cert_info;
    }

    /* Protocol */
    info->proto = ssock->proto;
    
    return PJ_SUCCESS;
}


/*
 * Starts read operation on this SSL socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_read (pj_ssl_sock_t *ssock,
					    pj_pool_t *pool,
					    unsigned buff_size,
					    pj_uint32_t flags)
{
    PJ_ASSERT_RETURN(ssock && pool && buff_size, PJ_EINVAL);
    PJ_ASSERT_RETURN(ssock->established, PJ_EINVALIDOP);

    /* Reading is already started */
    if (ssock->read_state.orig_buf) {
	return PJ_SUCCESS;
    }

    void *readbuf[1];
    readbuf[0] = pj_pool_alloc(pool, buff_size);
    return pj_ssl_sock_start_read2(ssock, pool, buff_size, readbuf, flags);
}

static void read_cb(int err, void *key)
{
    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;
    pj_status_t status;

    status = (err == KErrNone)? PJ_SUCCESS : PJ_RETURN_OS_ERROR(err);

    /* Check connection status */
    if (err == KErrEof || !PjSymbianOS::Instance()->IsConnectionUp() ||
	!ssock->established) 
    {
	status = PJ_EEOF;
    }
    
    /* Notify data arrival */
    if (ssock->cb.on_data_read) {
	pj_size_t remainder = 0;
	char *data = (char*)ssock->read_state.orig_buf->Ptr();
	pj_size_t data_len = ssock->read_state.read_buf->Length() + 
			     ssock->read_state.read_buf->Ptr() -
			     ssock->read_state.orig_buf->Ptr();
	
	if (data_len > 0) {
	    /* Notify received data */
	    pj_bool_t ret = (*ssock->cb.on_data_read)(ssock, data, data_len, 
						      status, &remainder);
	    if (!ret) {
		/* We've been destroyed */
		return;
	    }
	    
	    /* Calculate available data for next READ operation */
	    if (remainder > 0) {
		pj_size_t data_maxlen = ssock->read_state.orig_buf->MaxLength();
		
		/* There is some data left unconsumed by application, we give
		 * smaller buffer for next READ operation.
		 */
		ssock->read_state.read_buf->Set((TUint8*)data+remainder, 0, 
					        data_maxlen - remainder);
	    } else {
		/* Give all buffer for next READ operation. 
		 */
		ssock->read_state.read_buf->Set(*ssock->read_state.orig_buf);
	    }
	}
    }

    if (status == PJ_SUCCESS) {
	/* Perform the "next" READ operation */
	CPjSSLSocketReader *reader = ssock->sock->GetReader(); 
	ssock->read_state.read_buf->SetLength(0);
	status = reader->Read(&read_cb, ssock, *ssock->read_state.read_buf, 
			      ssock->read_state.flags);
    }
    
    /* Connection closed or something goes wrong */
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	/* Notify error */
	if (ssock->cb.on_data_read) {
	    pj_bool_t ret = (*ssock->cb.on_data_read)(ssock, NULL, 0, 
						      status, NULL);
	    if (!ret) {
		/* We've been destroyed */
		return;
	    }
	}
	
	delete ssock->read_state.read_buf;
	delete ssock->read_state.orig_buf;
	ssock->read_state.read_buf = NULL;
	ssock->read_state.orig_buf = NULL;
	ssock->established = PJ_FALSE;
    }
}

/*
 * Same as #pj_ssl_sock_start_read(), except that the application
 * supplies the buffers for the read operation so that the acive socket
 * does not have to allocate the buffers.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_read2 (pj_ssl_sock_t *ssock,
					     pj_pool_t *pool,
					     unsigned buff_size,
					     void *readbuf[],
					     pj_uint32_t flags)
{
    PJ_ASSERT_RETURN(ssock && buff_size && readbuf, PJ_EINVAL);
    PJ_ASSERT_RETURN(ssock->established, PJ_EINVALIDOP);
    
    /* Return failure if access point is marked as down by app. */
    PJ_SYMBIAN_CHECK_CONNECTION();
    
    /* Reading is already started */
    if (ssock->read_state.orig_buf) {
	return PJ_SUCCESS;
    }
    
    PJ_UNUSED_ARG(pool);

    /* Get reader instance */
    CPjSSLSocketReader *reader = ssock->sock->GetReader();
    if (!reader)
	return PJ_ENOMEM;
    
    /* We manage two buffer pointers here:
     * 1. orig_buf keeps the orginal buffer address (and its max length).
     * 2. read_buf provides buffer for READ operation, mind that there may be
     *    some remainder data left by application.
     */
    ssock->read_state.read_buf = new TPtr8((TUint8*)readbuf[0], 0, buff_size);
    ssock->read_state.orig_buf = new TPtr8((TUint8*)readbuf[0], 0, buff_size);
    ssock->read_state.flags = flags;
    
    pj_status_t status;
    status = reader->Read(&read_cb, ssock, *ssock->read_state.read_buf, 
			  ssock->read_state.flags);
    
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	delete ssock->read_state.read_buf;
	delete ssock->read_state.orig_buf;
	ssock->read_state.read_buf = NULL;
	ssock->read_state.orig_buf = NULL;
	
	return status;
    }
    
    return PJ_SUCCESS;
}

/*
 * Same as pj_ssl_sock_start_read(), except that this function is used
 * only for datagram sockets, and it will trigger \a on_data_recvfrom()
 * callback instead.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom (pj_ssl_sock_t *ssock,
						pj_pool_t *pool,
						unsigned buff_size,
						pj_uint32_t flags)
{
    PJ_UNUSED_ARG(ssock);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(buff_size);
    PJ_UNUSED_ARG(flags);
    return PJ_ENOTSUP;
}

/*
 * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() 
 * operation takes the buffer from the argument rather than creating
 * new ones.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom2 (pj_ssl_sock_t *ssock,
						 pj_pool_t *pool,
						 unsigned buff_size,
						 void *readbuf[],
						 pj_uint32_t flags)
{
    PJ_UNUSED_ARG(ssock);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(buff_size);
    PJ_UNUSED_ARG(readbuf);
    PJ_UNUSED_ARG(flags);
    return PJ_ENOTSUP;
}

static void send_cb(int err, void *key)
{
    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;
    write_state_t *st = &ssock->write_state;

    /* Check connection status */
    if (err != KErrNone || !PjSymbianOS::Instance()->IsConnectionUp() ||
	!ssock->established) 
    {
	ssock->established = PJ_FALSE;
	return;
    }

    /* Remove sent data from buffer */
    st->start += st->current_data->len;
    st->len -= st->current_data->len;

    /* Reset current outstanding send */
    st->current_data = NULL;

    /* Let's check if there is pending data to send */
    if (st->len) {
	write_data_t *wdata = (write_data_t*)st->start;
	pj_status_t status;
	
	st->send_ptr.Set((TUint8*)wdata->data, (TInt)wdata->data_len);
	st->current_data = wdata;
	status = ssock->sock->Send(&send_cb, ssock, st->send_ptr, 0);
	if (status != PJ_EPENDING) {
	    ssock->established = PJ_FALSE;
	    st->len = 0;
	    return;
	}
    } else {
        /* Buffer empty, reset the start position */
        st->start = st->buf;
    }
}

/*
 * Send data using the socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_send (pj_ssl_sock_t *ssock,
				      pj_ioqueue_op_key_t *send_key,
				      const void *data,
				      pj_ssize_t *size,
				      unsigned flags)
{
    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(ssock && data && size, PJ_EINVAL);
    PJ_ASSERT_RETURN(ssock->write_state.max_len == 0 || 
		     ssock->write_state.max_len >= (pj_size_t)*size, 
		     PJ_ETOOSMALL);
    
    /* Check connection status */
    if (!PjSymbianOS::Instance()->IsConnectionUp() || !ssock->established) 
    {
	ssock->established = PJ_FALSE;
	return PJ_ECANCELLED;
    }

    write_state_t *st = &ssock->write_state;
    
    /* Synchronous mode */
    if (st->max_len == 0) {
	st->send_ptr.Set((TUint8*)data, (TInt)*size);
	return ssock->sock->SendSync(st->send_ptr, flags);
    }

    /* CSecureSocket only allows one outstanding send operation, so
     * we use buffering mechanism to allow application to perform send 
     * operations at any time.
     */
    
    pj_size_t needed_len = *size + sizeof(write_data_t) - 1;
    
    /* Align needed_len to be multiplication of 4 */
    needed_len = ((needed_len + 3) >> 2) << 2; 

    /* Block until there is buffer slot available and contiguous! */
    while (st->start + st->len + needed_len > st->buf + st->max_len) {
	pj_symbianos_poll(-1, -1);
    }

    /* Push back the send data into the buffer */
    write_data_t *wdata = (write_data_t*)(st->start + st->len);
    
    wdata->len = needed_len;
    wdata->key = send_key;
    wdata->data_len = (pj_size_t)*size;
    pj_memcpy(wdata->data, data, *size);
    st->len += needed_len;

    /* If no outstanding send, send it */
    if (st->current_data == NULL) {
	pj_status_t status;
	    
	wdata = (write_data_t*)st->start;
	st->current_data = wdata;
	st->send_ptr.Set((TUint8*)wdata->data, (TInt)wdata->data_len);
	status = ssock->sock->Send(&send_cb, ssock, st->send_ptr, flags);
	
	if (status != PJ_EPENDING) {
	    *size = -status;
	    return status;
	}
    }
    
    return PJ_SUCCESS;
}

/*
 * Send datagram using the socket.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_sendto (pj_ssl_sock_t *ssock,
					pj_ioqueue_op_key_t *send_key,
					const void *data,
					pj_ssize_t *size,
					unsigned flags,
					const pj_sockaddr_t *addr,
					int addr_len)
{
    PJ_UNUSED_ARG(ssock);
    PJ_UNUSED_ARG(send_key);
    PJ_UNUSED_ARG(data);
    PJ_UNUSED_ARG(size);
    PJ_UNUSED_ARG(flags);
    PJ_UNUSED_ARG(addr);
    PJ_UNUSED_ARG(addr_len);
    return PJ_ENOTSUP;
}

/*
 * Starts asynchronous socket accept() operations on this SSL socket. 
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
					      pj_pool_t *pool,
					      const pj_sockaddr_t *local_addr,
					      int addr_len)
{
    PJ_UNUSED_ARG(ssock);
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(local_addr);
    PJ_UNUSED_ARG(addr_len);
    
    return PJ_ENOTSUP;
}

static void connect_cb(int err, void *key)
{
    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)key;
    pj_status_t status;
    
    if (ssock->connect_timer) {
	delete ssock->connect_timer;
	ssock->connect_timer = NULL;
    }

    status = (err == KErrNone)? PJ_SUCCESS : PJ_RETURN_OS_ERROR(err);
    if (status == PJ_SUCCESS) {
	ssock->established = PJ_TRUE;
	update_certs_info(ssock);
    } else {
	delete ssock->sock;
	ssock->sock = NULL;
	if (err == KErrTimedOut) status = PJ_ETIMEDOUT;
    }
    
    if (ssock->cb.on_connect_complete) {
	pj_bool_t ret = (*ssock->cb.on_connect_complete)(ssock, status);
	if (!ret) {
	    /* We've been destroyed */
	    return;
	}
    }
}

static void connect_timer_cb(void *key)
{
    connect_cb(KErrTimedOut, key);
}

/*
 * Starts asynchronous socket connect() operation and SSL/TLS handshaking 
 * for this socket. Once the connection is done (either successfully or not),
 * the \a on_connect_complete() callback will be called.
 */
PJ_DEF(pj_status_t) pj_ssl_sock_start_connect (pj_ssl_sock_t *ssock,
					       pj_pool_t *pool,
					       const pj_sockaddr_t *localaddr,
					       const pj_sockaddr_t *remaddr,
					       int addr_len)
{
    CPjSSLSocket *sock = NULL;
    pj_status_t status;
    
    PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len,
		     PJ_EINVAL);

    /* Check connection status */
    PJ_SYMBIAN_CHECK_CONNECTION();
    
    if (ssock->sock != NULL) {
	CPjSSLSocket::ssl_state state = ssock->sock->GetState();
	switch (state) {
	case CPjSSLSocket::SSL_STATE_ESTABLISHED:
	    return PJ_SUCCESS;
	default:
	    return PJ_EPENDING;
	}
    }

    /* Set SSL protocol */
    TPtrC8 proto;
    
    if (ssock->proto == PJ_SSL_SOCK_PROTO_DEFAULT)
	ssock->proto = PJ_SSL_SOCK_PROTO_TLS1;

    /* CSecureSocket only support TLS1.0 and SSL3.0 */
    switch(ssock->proto) {
    case PJ_SSL_SOCK_PROTO_TLS1:
	proto.Set((const TUint8*)"TLS1.0", 6);
	break;
    case PJ_SSL_SOCK_PROTO_SSL3:
	proto.Set((const TUint8*)"SSL3.0", 6);
	break;
    default:
	return PJ_ENOTSUP;
    }

    /* Prepare addresses */
    TInetAddr localaddr_, remaddr_;
    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)localaddr, addr_len, 
				  localaddr_);
    if (status != PJ_SUCCESS)
	return status;
    
    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)remaddr, addr_len,
				  remaddr_);
    if (status != PJ_SUCCESS)
	return status;

    pj_sockaddr_cp((pj_sockaddr_t*)&ssock->rem_addr, remaddr);

    /* Init SSL engine */
    TRAPD(err, sock = CPjSSLSocket::NewL(proto, ssock->qos_type, 
				         ssock->qos_params));
    if (err != KErrNone)
	return PJ_ENOMEM;
    
    if (ssock->timeout.sec != 0 || ssock->timeout.msec != 0) {
	ssock->connect_timer = new CPjTimer(&ssock->timeout, 
					    &connect_timer_cb, ssock);
    }
    
    /* Convert server name to Symbian descriptor */
    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_, ciphers_);
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	delete sock;
	return status;
    }

    ssock->sock = sock;
    return status;
}


PJ_DEF(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock)
{
    PJ_UNUSED_ARG(ssock);
    return PJ_ENOTSUP;
}
