/* $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) {
	CPjSSLSocket *self = new (ELeave) CPjSSLSocket();
	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;
    }

private:
    enum ssl_state	 state_;
    pj_sock_t	    	 sock_;
    CSecureSocket  	*securesock_;
    bool	    	 is_connected_;
    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() :
	CActive(0), state_(SSL_STATE_NULL), sock_(PJ_INVALID_SOCKET), 
	securesock_(NULL), 
	is_connected_(false), 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_) {
	    securesock_->Close();
	    delete securesock_;
	    securesock_ = NULL;
	}
	if (sock_ != PJ_INVALID_SOCKET) {
	    delete (CPjSocket*)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;

    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);
    state_ = SSL_STATE_CONNECTING;

    rSock.Connect(rem_addr_, iStatus);
    SetActive();
    
    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();
	    securesock_->Close();
	    
	    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_);
	    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_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;

    pj_ssl_sock_proto	 proto;
    pj_time_val		 timeout;
    unsigned		 ciphers_num;
    pj_ssl_cipher	*ciphers;
    pj_str_t		 servername;
};


/*
 * 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];
        }
        
        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->sock_af = param->sock_af;
    ssock->sock_type = param->sock_type;
    ssock->cb = param->cb;
    ssock->user_data = param->user_data;
    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);

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

    /* 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);
	if (status != PJ_EPENDING) {
	    /* Notify error */
	    (*ssock->cb.on_data_read)(ssock, NULL, 0, status, NULL);
	}
    }
    
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	/* Connection closed or something goes wrong */
	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;
    } else {
	delete ssock->sock;
	ssock->sock = NULL;
    }
    
    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));
    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;
}
