/* $Id$ */
/* 
 * Copyright (C) 2009 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"

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));
    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_;
    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)
{
    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;
    servername_.Set(servername);
    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_);

	    // 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;
    unsigned		 ciphers_num;
    pj_ssl_cipher	*ciphers;
    pj_str_t		 servername;
    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));
    }
}


/*
 * 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);
    
    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] = (pj_ssl_cipher)(ciphers_buf[i*2]*10 + 
					      ciphers_buf[i*2+1]);
        }
        
        delete secure_sock;
    }
    
    if (ciphers_num_ == 0) {
	return PJ_ENOTFOUND;
    }
    
    *cipher_num = PJ_MIN(*cipher_num, ciphers_num_);
    for (i = 0; i < *cipher_num; ++i)
        ciphers[i] = ciphers_[i];
    
    return PJ_SUCCESS;
}

/*
 * 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;
    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];
    }
    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;
	}
    }
}

/*
 * 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 avail_len = st->max_len - st->len;
    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! */
    while (needed_len >= avail_len) {
	pj_symbianos_poll(-1, -1);
	avail_len = st->max_len - st->len;
    }

    /* Ok, make sure the new data will not get wrapped */
    if (st->start + st->len + needed_len > st->buf + st->max_len) {
	/* Align buffer left */
	pj_memmove(st->buf, st->start, st->len);
	st->start = st->buf;
    }
    
    /* 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);
    
    /* Try to connect */
    status = sock->Connect(&connect_cb, ssock, localaddr_, remaddr_,
			   servername_);
    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;
}
