--- /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 <es_sock.h>
+#include <in_sock.h>
+
+/********************************************************************************
+ *
+ * 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<TUint>(iMaxPacketSize) );
+ asserte( !IsActive() );
+
+ if(!iBufferPtr)
+ {
+ iBufferPtr = new TPtr8(const_cast<unsigned char*>(iBuffer->Ptr( )),aByteCount);
+ }
+ else
+ if(iBufferPtr->MaxLength()!=aByteCount)
+ {
+ delete iBufferPtr;
+ iBufferPtr = new TPtr8(const_cast<unsigned char*>(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;
+}
+