email/imap4mtm/imaptransporthandler/src/csocket.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/imap4mtm/imaptransporthandler/src/csocket.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,253 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "csocket.h"
+#include "csecuresocketcontroller.h"
+#include "mcommsinfoprovider.h"
+#include "imappaniccodes.h"
+
+// Flags to pass to protocol in RecvOneOrMore call for socket
+const TInt KDefaultFlags = 0;
+
+/**
+The factory constructor.
+
+@param		aCommsInfoProvider	The comms info provider object.
+@param		aSocketType			The type of the socket.
+@return		A pointer to a fully constructed object.
+*/
+CSocket* CSocket::NewL(MCommsInfoProvider& aCommsInfoProvider, TSocketType aSocketType)
+	{
+	CSocket* self = new (ELeave) CSocket(aCommsInfoProvider);
+	CleanupStack::PushL(self);
+	self->ConstructL(aSocketType);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+Destructor.
+*/
+CSocket::~CSocket()
+	{
+	// Close socket and notify the socket status observer
+	if( iSecureSocketController )
+		{
+		delete iSecureSocketController;
+		}
+	else
+		{
+		iSocket.Close();
+		}
+	}
+
+/**
+Constructor.
+
+@param	aCommsInfoProvider	The comms info provider object.
+*/
+CSocket::CSocket(MCommsInfoProvider& aCommsInfoProvider)
+	: iCommsInfoProvider(aCommsInfoProvider)
+	{
+	}
+
+/**
+Second phase constructor.
+
+@param		aSocketType	The type of the socket.
+*/
+void CSocket::ConstructL(TSocketType aSocketType)
+	{
+	switch( aSocketType )
+		{
+	case EProtocolSocket:
+		{
+		// Open a protocol socket
+		User::LeaveIfError(iSocket.Open(
+									iCommsInfoProvider.SocketServer(),
+									iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
+									iCommsInfoProvider.ProtocolDescription().iSockType, 
+									iCommsInfoProvider.ProtocolDescription().iProtocol,
+									iCommsInfoProvider.Connection()
+									));
+		} break;
+	case EBlankSocket:
+		{
+		// Open a blank socket
+		User::LeaveIfError(iSocket.Open(iCommsInfoProvider.SocketServer()));
+		} break;
+	default:
+		{
+		User::Invariant();
+		} break;
+		}
+	}
+
+/**
+Start asynchronous connect service. The address contains the IP address and
+port with which a tcp connection should be established with. The request 
+status is completed either when a connection has been established or an error
+has occurred - this is reflected in the value of the request status.
+
+@param	aAddr	The IP address and port of the remote host.
+@param	aStatus	The request status that is completed when the connect 
+		service completes.
+*/
+void CSocket::Connect(TInetAddr& aAddr, TRequestStatus& aStatus)
+	{
+	iSocket.Connect(aAddr, aStatus);
+	}
+
+/**
+Cancel the connect service.
+*/
+void CSocket::CancelConnect()
+	{
+	iSocket.CancelConnect();
+	}
+
+/**
+Receive data from socket asynchronously. Any data received by the socket is 
+placed in the buffer supplied by aBuffer. The request status is completed 
+either when data has been received or an error has occurred - this is 
+reflected in the value of the request status.
+
+@param		aBuffer	The buffer where any received data is placed.	
+@param		aStatus	The request status that is completed when the receive 
+					service completes.
+*/
+void CSocket::RecvOneOrMore(TDes8& aBuffer, TRequestStatus& aStatus)
+	{
+	if( iSecureSocketController )
+		{
+		// aFlags not used for secure sockets
+		iSecureSocketController->RecvOneOrMore(aBuffer, aStatus, iBytesReceived);
+		}
+	else
+		{
+		iSocket.RecvOneOrMore(aBuffer, KDefaultFlags, aStatus, iBytesReceived);
+		}
+	}
+
+/**
+Cancel the receive service.
+*/
+void CSocket::CancelRecv()
+	{
+	if( iSecureSocketController )
+		{
+		iSecureSocketController->CancelRecv();
+		}
+	else
+		{
+		iSocket.CancelRecv();
+		}
+	}
+
+/**
+Send data to the socket asynchronously. The data in the supplied buffer is 
+sent to the socket. The request status is completed either when data has 
+been sent or an error has occurred - this is reflected in the value of the
+request status.
+
+@param		aBuffer	The buffer containing the data to be sent.
+@param		aStatus	The request status that is completed when the send 
+					service completes.
+*/
+void CSocket::Send(const TDesC8& aBuffer, TRequestStatus& aStatus)
+	{
+	if( iSecureSocketController )
+		{
+		iSecureSocketController->Send(aBuffer, aStatus);
+		}
+	else
+		{
+		iSocket.Write(aBuffer, aStatus);
+		}
+	}
+
+/**
+Cancel the send service.
+*/
+void CSocket::CancelSend()
+	{
+	if( iSecureSocketController )
+		{
+		iSecureSocketController->CancelSend();
+		}
+	else
+		{
+		iSocket.CancelWrite();
+		}
+	}
+
+/**
+Get the remote host name. The IP address and port of the remote host is set
+in the output argument.
+
+@param	aAddr	The output argument where the IP address and port of the
+				remote host is placed.
+*/
+void CSocket::RemoteName(TInetAddr& aAddr)
+	{
+	iSocket.RemoteName(aAddr);
+	}
+
+/**
+Get the local socket name. The IP address and port of the local socket is 
+set in the output argument.
+
+@param	aAddr	The output argument where the IP address and port of the
+				local socket is placed.
+*/
+void CSocket::LocalName(TInetAddr& aAddr)
+	{
+	iSocket.LocalName(aAddr);
+	}
+
+/**
+Upgrade the socket connection to a secure connection.
+
+@param	aStatus		The request status.
+@param	aSSLDomainName SSL domain name.
+*/
+void CSocket::UpgradeToSecureL(TRequestStatus& aStatus, const TDesC8& aSSLDomainName)
+	{
+	// Check that the socket is already a secure one.
+	if( iSecureSocketController )
+		{
+		// The socket connection is already secure, simply complete the request
+		aStatus=KRequestPending;
+		TRequestStatus* pStat = &aStatus;
+		User::RequestComplete(pStat, KErrNone);
+		}
+	else
+		{
+		// Create the secure socket controller and start the secure handshake
+		iSecureSocketController = CSecureSocketController::NewL(iSocket, iCommsInfoProvider);
+		iSecureSocketController->StartSecureHandshakeL(aStatus, aSSLDomainName);
+		}
+	}
+
+/**
+Cancel the upgrade to a secure socket.
+*/
+void CSocket::CancelUpgradeToSecure()
+	{
+	if( iSecureSocketController )
+		{
+		iSecureSocketController->CancelHandshake();
+		}
+	}