bluetoothengine/bteng/src/btengsrvstate.cpp
changeset 0 f63038272f30
child 8 0707dd69d236
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bteng/src/btengsrvstate.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 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:  Bluetooth Engine server state machine class implementation.
+*
+*/
+
+
+
+#include <ecom/ecomresolverparams.h>
+
+#include "btengsrvstate.h"
+#include "btengserver.h"
+#include "btengsrvpluginmgr.h"
+#include "debug.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ default constructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvState::CBTEngSrvState( CBTEngServer* aServer )
+:   iState( EInit ),
+    iOperation( ESrvOpIdle ),
+    iServer( aServer )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd-phase constructor
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvState::ConstructL()
+    {
+    TRACE_FUNC_ENTRY
+    // Create the active object handling asynchronous state transitions.
+    // The state transitions need to be done fast, as it can be initiated 
+    // through user interaction (i.e. the user is waiting).
+    const TCallBack cb(&ChangeStateCb, this);
+    iAsyncCallback = new(ELeave) CAsyncCallBack(cb, CActive::EPriorityHigh);
+    TRACE_FUNC_EXIT
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvState* CBTEngSrvState::NewL( CBTEngServer* aServer )
+    {
+    CBTEngSrvState* self = new( ELeave ) CBTEngSrvState( aServer );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvState::~CBTEngSrvState()
+    {
+    delete iAsyncCallback;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns the current state machine operation.
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvState::TBTEngSrvOperation CBTEngSrvState::CurrentOperation()
+    {
+    return iOperation;
+    }
+
+
+// ---------------------------------------------------------------------------
+// ?implementation_description
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvState::StartStateMachineL( TBool aState )
+    {
+    TRACE_FUNC_ENTRY
+    if( aState )
+        {
+        // Power on; starting state is initializing the stack
+        iState = EInitBTStack;
+        iOperation = EPowerOn;
+        }
+    else
+        {
+        // Power off, starting state is to disconnect the plug-ins
+        iState = EDisconnectPlugins;
+        iOperation = EPowerOff;
+        iServer->UpdateCenRepPowerKeyL( EBTPowerOff );
+        iServer->SetUiIndicatorsL();
+        }
+    ChangeState();
+    }
+
+
+// ---------------------------------------------------------------------------
+// ?implementation_description
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvState::ChangeState()
+    {
+    TRACE_FUNC_ENTRY
+    if(!iAsyncCallback->IsActive())
+        {
+        iAsyncCallback->CallBack();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ?implementation_description
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngSrvState::ChangeStateCb(TAny* aThis)
+    {
+    TRAPD(err, static_cast<CBTEngSrvState*>(aThis)->RequestCompletedL());
+    if(err != KErrNone)
+        {
+        static_cast<CBTEngSrvState*>(aThis)->HandleError(err);
+        }
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// ?implementation_description
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvState::RequestCompletedL()
+    {
+    switch( iState )
+        {
+        case EInitBTStack:
+            {
+            iState = ELoadDIService;
+            iServer->InitBTStackL();
+            }
+            break;
+        case ELoadDIService:
+            {
+            iState = ELoadPlugins;
+            iServer->ManageDIServiceL( ETrue );
+            }
+            break;
+        case ELoadPlugins:
+            {
+            iState = ELoadNextPlugin;
+            TEComResolverParams params;
+            iServer->iPluginMgr->LoadProfilePluginsL( params );
+            }
+            break;
+        case ELoadNextPlugin:
+            {
+                // Only change the state when all plug-ins are loaded
+            if( iServer->iPluginMgr->LoadPluginL() <= 0 )
+                {
+                iState = EIdle;
+                }
+            }
+            break;
+        case EStopBTStack:
+            {
+            iState = EWaitingForPowerOff;
+            iServer->StopBTStackL();
+            }
+            break;
+        case EUnloadDIService:
+            {
+            iState = EStopBTStack;
+            iServer->ManageDIServiceL( EFalse );
+            }
+            break;
+        case EUnloadPlugins:
+            {
+            iState = EUnloadDIService;
+            iServer->iPluginMgr->UnloadProfilePlugins();
+            }
+            break;
+        case EDisconnectPlugins:
+            {
+            iState = EUnloadPlugins;
+            // This is the starting state; the disconnect command has 
+            // already been sent. Just one more loop to give more time
+            // for disconnecting.
+            }
+            break;
+        case EWaitingForPowerOff:
+            {
+            // Disconnecting all connections completed and 
+            // called us back; we are done.
+            iState = EIdle;
+            }   // Fall through
+        case EIdle:
+            {
+            if( iOperation == EPowerOn )
+                {
+                iServer->UpdateCenRepPowerKeyL( EBTPowerOn );
+                iServer->SetUiIndicatorsL();
+                }
+            iOperation = ESrvOpIdle;
+            iServer->CheckIdle();
+            }
+        case EInit:
+        default:
+            break;
+        }
+    // In state EWaitingForPowerOff, we change the state 
+    // through a callback in the server.
+    if( iOperation != ESrvOpIdle && iState != EWaitingForPowerOff )
+        {
+        ChangeState();
+        }
+    TRACE_FUNC_EXIT
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// Handles a leave in RunL/RequestCompletedL.
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvState::HandleError(TInt aError)
+    {
+    TRACE_FUNC_ARG( ( _L( "error: %d" ), aError ) )
+    
+    (void) aError;
+    // All critical operations are done in turning power on; all other
+    // operations are recoverable i.e. we can do without loading/unloading
+    // of services. So simply change the state to handle next state change.
+    ChangeState();
+    }