--- /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;
+}