diff -r 000000000000 -r 3e07fef1e154 testexecfw/statsrv/device/source/statapi/src/stat_tcpip.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/statsrv/device/source/statapi/src/stat_tcpip.cpp Mon Mar 08 15:03:44 2010 +0800 @@ -0,0 +1,370 @@ +/* +* Copyright (c) 2005-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: +* +*/ + + + +/******************************************************************************** + * + * System Includes + * + *******************************************************************************/ +#include +#include + +/******************************************************************************** + * + * Local Includes + * + *******************************************************************************/ +#include "assert.h" +#include "ntoh.h" +#include "stat_tcpip.h" +#include "../../../../common/inc/SerialPacketSize.h" + +/******************************************************************************** + * + * Macro functions + * + ********************************************************************************/ + +/******************************************************************************** + * + * CStatTransportTCPIP -- Constructor + * + *******************************************************************************/ +CStatTransportTCPIP *CStatTransportTCPIP::NewL( void ) +{ + CStatTransportTCPIP *self = new (ELeave) CStatTransportTCPIP(); + CleanupStack::PushL(self); + self->ConstructL( ); + CleanupStack::Pop(); + return self; +} + +CStatTransportTCPIP::CStatTransportTCPIP() : CActive(EPriorityStandard) +{ +} + +void CStatTransportTCPIP::ConstructL( void ) +{ + // add this to active scheduler + CActiveScheduler::Add(this); + + // initialise all params + + iBufferPtr = NULL; + iTransport = NULL; + iTransportStatus = EIdle; + iRWStatus = ENoRW; + + iMaxPacketSize = KMaxTCPIPPacketSize; + + iBuffer = HBufC8::New( iMaxPacketSize ); + +} + +CStatTransportTCPIP::~CStatTransportTCPIP() +{ + // this will call cancel and remove the active object -- this will call cancel + Deque(); + + // cleanup the sockets + switch( iTransportStatus ) { + + case EIdle: + case EInitialised: + case EDisconnected: + case EError: + break; + + case EConnected: + iDataSocket.Shutdown( RSocket::EImmediate, iStatus ); + /* fall through */ + + case EConnecting: + iDataSocket.Close(); + iListenSocket.Shutdown( RSocket::EImmediate, iStatus ); + iListenSocket.Close(); + iSocketServ.Close(); + break; + + case EDisconnectingData: + case EDisconnectingListen: + ; + break; + } + + if( iBuffer ) + { + delete iBuffer; + iBuffer = NULL; + } + + if( iBufferPtr ) + { + delete iBufferPtr; + iBufferPtr = NULL; + } +} + +/******************************************************************************** + * + * CStatTransportTCPIP -- MStatApiTransport + * + *******************************************************************************/ +TInt CStatTransportTCPIP::InitialiseL( MNotifyStatTransport *aTransport ) +{ + // save the transport interface + iTransport = aTransport; + + // everything here is done in connect + iTransportStatus = EInitialised; + return KSTErrSuccess; +} + +TInt CStatTransportTCPIP::Release( void ) +{ + // release has nothing to do + asserte( (iTransportStatus == EDisconnected) || (iTransportStatus == EInitialised) ); + iTransportStatus = EIdle; + return KSTErrSuccess; +} + +TInt CStatTransportTCPIP::ConnectL( TDesC* /*aRemoteHost*/ ) +{ + // make sure we are in the correct state + asserte( iTransportStatus == EInitialised ); + + // connect to the socket server, create a socket, bind, listen, accept + User::LeaveIfError( iSocketServ.Connect() ); + User::LeaveIfError( iListenSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp) ); + User::LeaveIfError( iListenSocket.SetLocalPort( KLittleStatPort) ); + User::LeaveIfError( iListenSocket.Listen(KLittleStatListenQueue) ); + + // create a blank socket which is used as the data socket + User::LeaveIfError( iDataSocket.Open(iSocketServ) ); + + // everything should now be set up, we just wait for a stat connection + asserte( !IsActive() ); + iListenSocket.Accept( iDataSocket, iStatus ); + SetActive(); + iTransportStatus = EConnecting; + + // tell the client to wait for an asynchronous response + return KSTErrAsynchronous; +} + +TInt CStatTransportTCPIP::Disconnect( void ) +{ + // must be connected + asserte( (iTransportStatus == EInitialised) || + (iTransportStatus == EConnected) || + (iTransportStatus == EConnecting) || + (iTransportStatus == EDisconnectingData) || + (iTransportStatus == EDisconnectingListen) ); + + // cancel any pending ops + Cancel(); + + // clean up the sockets depending on the state + switch( iTransportStatus ) { + + case EConnected: + iDataSocket.Shutdown( RSocket::ENormal, iStatus ); + SetActive(); + iTransportStatus = EDisconnectingData; + return KSTErrAsynchronous; + + case EConnecting: + case EDisconnectingData: + iDataSocket.Close(); + iListenSocket.Shutdown( RSocket::ENormal, iStatus ); + SetActive(); + iTransportStatus = EDisconnectingListen; + return KSTErrAsynchronous; + + case EInitialised: + case EDisconnectingListen: + // initialised may mean that ConnectL threw an error -- so close the resources + iDataSocket.Close(); + iListenSocket.Close(); + iSocketServ.Close(); + return KSTErrSuccess; + + default: + ; + } + return KSTErrSuccess; +} + +TInt CStatTransportTCPIP::RequestSend( TDesC8 *aData, const TUint /*aDataLength*/ ) +{ + + // make sure the state is correct + asserte( iTransportStatus == EConnected ); + asserte( iRWStatus == ENoRW ); + iRWStatus = EWritePending; + + iDataSocket.Write( *aData, iStatus ); + SetActive(); + + // tell the caller to wait for an asynchronous response + return KSTErrAsynchronous; + + +} + +TInt CStatTransportTCPIP::RequestReceive( TUint aByteCount ) +{ + + // ensure that there are no reads in progress + asserte( iTransportStatus == EConnected ); + asserte( !IsActive() ); + asserte( iRWStatus == ENoRW ); + iRWStatus = EReadPending; + + asserte( aByteCount <= static_cast(iMaxPacketSize) ); + asserte( !IsActive() ); + + if(!iBufferPtr) + { + iBufferPtr = new TPtr8(const_cast(iBuffer->Ptr( )),aByteCount); + } + else + if(iBufferPtr->MaxLength()!=aByteCount) + { + delete iBufferPtr; + iBufferPtr = new TPtr8(const_cast(iBuffer->Ptr( )),aByteCount); + } + + iDataSocket.Read( *iBufferPtr, iStatus ); + SetActive(); + + // return to the caller + return KSTErrAsynchronous; + +} + +TText8 *CStatTransportTCPIP::Error( void ) +{ + return NULL; +} + +TInt CStatTransportTCPIP::GetPacketSize() +{ + // The packet size is configured when we initialise the port. + return iMaxPacketSize; +} + +/******************************************************************************** + * + * CStatTransportTCPIP -- Active Object + * + *******************************************************************************/ +void CStatTransportTCPIP::RunL( void ) +{ + // if there was an error during connectiong then tell the engine this + if( (iTransportStatus == EConnecting) && (iStatus != KErrNone) ) { + iTransport->HandleError( KSTErrConnectFailure, (void*)iStatus.Int() ); + return; + } + + //reconnect without restarting STAT + if(iStatus != KErrNone) + { + //if no error due to end of socket connection + if(iStatus != KErrDisconnected && iStatus != KErrEof) + { + _LIT(KFormat,"Error during TCPIP: %d\n"); + TBuf<50> lBuf; + lBuf.Format(KFormat,iStatus.Int()); + iTransport->HandleInfo(&lBuf); + } + + // close and reopen the socket + iDataSocket.Close(); + iDataSocket.Open(iSocketServ); + + // wait for a new connection + iTransportStatus = EConnecting; + iRWStatus = ENoRW; + iListenSocket.Accept( iDataSocket, iStatus ); + SetActive(); + return; + } + + // handle connection response + if( iTransportStatus == EConnecting ) { + asserte( iStatus == KErrNone ); + iTransportStatus = EConnected; + iTransport->HandleConnect( KErrNone ); + return; + } + + // handle shutdown data socket + if( iTransportStatus == EDisconnectingData ) { + iDataSocket.Close(); + iListenSocket.Shutdown( RSocket::ENormal, iStatus ); + SetActive(); + iTransportStatus = EDisconnectingListen; + return; + } + + // handle shutdown listen + if( iTransportStatus == EDisconnectingListen ) { + iListenSocket.Close(); + iTransportStatus = EDisconnected; + iSocketServ.Close(); + iTransport->HandleDisconnect( KErrNone ); + return; + } + + // if we are writing then notify of the write + if( iRWStatus == EWritePending ) { + iRWStatus = ENoRW; + iTransport->HandleSend( KErrNone ); + return; + } + + // if we are reading then notify of the read + if( iRWStatus == EReadPending ) { + iRWStatus = ENoRW; + iTransport->HandleReceive( KErrNone, iBufferPtr, iBufferPtr->Length( ) ); + return; + } +} + +void CStatTransportTCPIP::DoCancel( void ) +{ + if( iTransportStatus == EConnecting ) + { + iListenSocket.CancelAccept(); + } + + if( iRWStatus == EReadPending ) + { + iDataSocket.CancelRead(); + } + + if( iRWStatus == EWritePending ) + { + iDataSocket.CancelWrite(); + } + + iRWStatus = ENoRW; +} +