// 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 socketconst 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 andport with which a tcp connection should be established with. The request status is completed either when a connection has been established or an errorhas 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 therequest 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 setin 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(); } }