testexecfw/statsrv/device/source/statapi/src/stat_controller.cpp
changeset 0 3e07fef1e154
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecfw/statsrv/device/source/statapi/src/stat_controller.cpp	Mon Mar 08 15:03:44 2010 +0800
@@ -0,0 +1,349 @@
+/*
+* 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
+ *
+ *************************************************************************/
+
+/*************************************************************************
+ *
+ * Local Includes
+ *
+ *************************************************************************/
+#include "assert.h"
+#include "stat.h"
+#include "stat_interfaces.h"
+#include "stat_controller.h"
+#include "stat_engine.h"
+
+
+/*************************************************************************
+ *
+ * Definitions
+ *
+ *************************************************************************/
+
+/*************************************************************************
+ *
+ * CStatController - Construction
+ *
+ *************************************************************************/
+CStatController *CStatController::NewL()
+{
+    CStatController *self = new (ELeave) CStatController();
+    CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+    return self;
+}
+
+CStatController::CStatController() : CActive(EPriorityHigh), iFs( NULL ), iMsg( NULL )
+{
+}
+
+void CStatController::ConstructL( void ) 
+{
+	// add me to the active scheduler
+	CActiveScheduler::Add(this); 
+
+	// params
+	iEngine = NULL;
+	iSessionStatus = EIdle;
+	iTransport = NULL;
+	iUI = NULL;
+	iConnectedSuccessfully = EFalse;
+	iUserInitiatedExitRequest = EFalse;
+	iFs =	NULL;
+	iMsg = NULL;
+
+	// wait for notifications
+	iStatus = KRequestPending;
+	SetActive();
+}
+
+CStatController::~CStatController()
+{
+	// clear notification -- deque (and CActive destructor) will fail otherwise
+	Notify( KErrCancel );
+	Deque();
+
+	// make sure the session is closed
+	asserte( iSessionStatus == EIdle );
+	asserte( iEngine == NULL );
+	asserte( iTransport == NULL );
+}
+
+/*************************************************************************
+ *
+ * CStatController - public interface
+ *
+ *************************************************************************/
+TInt CStatController::StartSession( TStatConnectType aConnectType, TDesC *aConnectParams, MNotifyUI *aUI, RFs *const aSession, MNotifyLogMessage *const aMsg )
+{
+	TInt exp =	KErrNone;
+
+	iFs =	aSession;
+	iMsg =	aMsg;
+
+    if(!aConnectParams) {
+        return -1;
+    }
+
+	// this is the notification sink for this session
+	iUI = aUI;
+	iConnectType = aConnectType;
+	asserte( aConnectParams->Length() <= KAddressTextLimit );
+    iConnectParams.Copy( *aConnectParams );
+		
+	// create the engine with a callback interface to the controller, create the 
+	// appropriate transport, and start the engine
+	iConnectedSuccessfully = EFalse;
+	TRAP( exp, (iEngine = CStatEngine::NewL(this, iFs, iMsg)) );
+	if( exp != KErrNone ) {
+		return -1;
+	}
+
+	// if the start transport leaves then its because it failed to create an object. This
+	// is either because the network or transport creation failed left. If it was the
+	// transport then the network may still have memory allocated.
+	TRAP( exp, (iTransport = StartTransportL(iConnectType)) );
+	if( exp != KErrNone ) {
+		if( iSerialNetwork != NULL ) {
+			delete iSerialNetwork;
+		}
+		return -1;
+	}
+
+	iEngine->StartEngine( iTransport, iConnectType, &iConnectParams );
+
+	// this controller only supports one session which always has ID = 1
+	return 1;
+}
+
+TInt CStatController::StopSession( TInt aSessionId )
+{
+	// make sure this is a valid, active, session
+	if( (aSessionId != 1) || (iSessionStatus == EIdle) )
+	{
+		// If the session is valid and idle then it is not
+		// initialised and connected correctly.
+		// Call Notify to cancel the outstanding asynchronous events
+		// we are registered for.
+		// This fixes a problem that appears when the engine fails to
+		// start correctly (due to COM port failures for example) and
+		// caused the CActiveScheduler never to stop as this object
+		// never received a callback when it needs one to remove
+		// itself from the active state.
+		// If the CActiveScheduler does not shut down then the
+		// program never exits and blocks.
+		Notify( KErrNone );
+		//
+		return KErrBadHandle;
+	}
+
+	iMsg->Msg( _L("CONTROLLER: Stopping session.") );
+
+	// tell the engine to stop and then wait for an asynchronous response
+	iUserInitiatedExitRequest = ETrue;
+	iEngine->StopEngine();
+	return KErrNone;
+}
+
+TInt CStatController::SessionStatus( TInt aSessionId )
+{
+	if( aSessionId != 1 )
+		return KErrBadHandle;
+	return iSessionStatus;
+}
+
+void CStatController::SetStatus( TCommStatus aNewStatus )
+{
+	iSessionStatus = aNewStatus;
+	if( iUI != NULL )
+		iUI->HandleStatusChange( 1, iSessionStatus );
+	if( aNewStatus == EConnected ) 
+		iConnectedSuccessfully = ETrue;
+}
+
+/*************************************************************************
+ *
+ * CStatController - MNotifyStatController
+ *
+ *************************************************************************/
+void CStatController::HandleStatusChange( TCommStatus aNewStatus )
+{
+	// If the engine has gone idle then everything is done and we can kill
+	// everything off. But, this function was called by the engine, so we
+	// can't kill it here -- send self an event to clean things up.
+	if( aNewStatus == EIdle ) {
+		Notify( KErrNone );
+		return;
+	}
+	
+	// update the status
+	SetStatus( aNewStatus );
+}
+
+// The engine deals with the transports in the face of errors itself, and the 
+// interaction with the engine is really handled via HandleStatusChange. This
+// function is mainly here to be able to pass information up from the transport
+// and the engine to the UI / user
+void CStatController::HandleError( TInt aError, void *aErrorData )
+{
+	if( iUI != NULL ) 
+		iUI->HandleError( aError, aErrorData );
+}
+
+// Info is for end-user consumption only and is sent directly to the UI.
+void CStatController::HandleInfo( const TDesC *aInfo )
+{
+	if( iUI != NULL )
+		iUI->HandleInfo( aInfo );
+}
+
+/*************************************************************************
+ *
+ * CStatController - CActive
+ *
+ *************************************************************************/
+void CStatController::RunL()
+{
+	// delete the engine and the transport
+	delete iEngine;
+	iEngine = NULL;
+	KillTransport();
+
+	// now change the status to idle
+	SetStatus( EIdle );
+
+	// wait again
+	iStatus = KRequestPending;
+	SetActive();
+
+	// But if this wasn't a user requested exit -- and the last connection
+	// did connect successfully, then restart. Otherwise clear the flags.
+	if( (iConnectedSuccessfully) && (!iUserInitiatedExitRequest) ) {
+		iConnectedSuccessfully = EFalse;
+		iEngine = CStatEngine::NewL( this, iFs, iMsg );
+		iTransport = StartTransportL( iConnectType );
+		iEngine->StartEngine( iTransport, iConnectType, &iConnectParams );
+	} else {
+		iUserInitiatedExitRequest = EFalse;
+		iConnectedSuccessfully = EFalse;
+	}
+}		
+
+void CStatController::DoCancel()
+{
+}
+
+void CStatController::Notify( TInt aErrorStatus )
+{
+	TRequestStatus *pstatus;
+	pstatus = &iStatus;
+	TRequestStatus *&rstatus = pstatus;
+	User::RequestComplete( rstatus, aErrorStatus );
+}
+
+/*************************************************************************
+ *
+ * CStatController - Private
+ *
+ *************************************************************************/
+MStatApiTransport *CStatController::StartTransportL( TStatConnectType aConnectType )
+{
+	switch( aConnectType ) {
+
+#ifndef LIGHT_MODE
+	case ETCPIP:
+		iTcpipTransport = CStatTransportTCPIP::NewL( );
+		iPacketisationTransport = CStatTransportPacketisation::NewL( iEngine, iTcpipTransport, iTcpipTransport->GetPacketSize() );
+		return iPacketisationTransport;
+
+	case EInfrared:
+		iSerialNetwork = CStatApiSerial::NewL( _L("IrCOMM") );
+		iPacketisationTransport = CStatTransportPacketisation::NewL( iEngine, iSerialNetwork, iSerialNetwork->GetPacketSize() );
+		return iPacketisationTransport;
+
+	case EBluetooth:
+		iBluetoothTransport = CStatTransportBT::NewL();
+		iPacketisationTransport = CStatTransportPacketisation::NewL( iEngine, iBluetoothTransport, iBluetoothTransport->GetPacketSize() );
+		return iPacketisationTransport;
+	
+	case EUsb:
+		iUsbNetwork = CStatApiUsb::NewL();
+		iPacketisationTransport = CStatTransportPacketisation::NewL( iEngine, iUsbNetwork, iUsbNetwork->GetPacketSize() );
+		return iPacketisationTransport;
+
+		
+		
+#endif // ifndef LIGHT_MODE
+
+	case ESerial:
+		iSerialNetwork = CStatApiSerial::NewL( _L("ECUART") );
+		iPacketisationTransport = CStatTransportPacketisation::NewL( iEngine, iSerialNetwork, iSerialNetwork->GetPacketSize() );
+		return iPacketisationTransport;
+
+	default:
+		;
+	}
+	return NULL;
+}
+
+void CStatController::KillTransport()
+{
+	switch( iConnectType ) {
+
+#ifndef LIGHT_MODE
+	case ETCPIP:
+		delete iTcpipTransport;
+		delete iPacketisationTransport;
+		iPacketisationTransport = NULL;
+		iTcpipTransport = NULL;
+		break;
+
+	case EBluetooth:
+		delete iBluetoothTransport;
+		delete iPacketisationTransport;
+		iBluetoothTransport = NULL;
+		iPacketisationTransport = NULL;
+		break;
+
+	case EInfrared:
+		delete iSerialNetwork;
+		delete iPacketisationTransport;
+		iSerialNetwork = NULL;
+		iPacketisationTransport = NULL;
+		break;
+#endif // ifndef LIGHT_MODE
+
+	case ESerial:
+		delete iSerialNetwork;
+		delete iPacketisationTransport;
+		iSerialNetwork = NULL;
+		iPacketisationTransport = NULL;
+		break;
+
+	default:
+		;
+	}
+	iTransport = NULL;	
+}