--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsap/src/BTSapServerState.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,592 @@
+/*
+* Copyright (c) 2004-2006 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:
+* This class is a state machine of BTSap Server
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <e32property.h>
+#include "BTSapDomainPSKeys.h"
+
+#include "BTSapServerState.h"
+#include "BTSapSocketHandler.h"
+#include "BTSapRequestHandler.h"
+#include "BTSapSimCardStatusNotifier.h"
+#include "debug.h"
+
+_LIT(KPhoneTsy, "PhoneTsy") ;
+_LIT(KDefaultPhone, "DefaultPhone");
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::CBTSapStatusObserver()
+//----------------------------------------------------------
+//
+CBTSapStatusObserver::CBTSapStatusObserver(): CActive(CActive::EPriorityStandard)
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::NewL()
+//----------------------------------------------------------
+//
+CBTSapStatusObserver* CBTSapStatusObserver::NewL()
+ {
+ CBTSapStatusObserver* self = new(ELeave) CBTSapStatusObserver();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::ConstructL()
+//----------------------------------------------------------
+//
+void CBTSapStatusObserver::ConstructL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapStatusObserver::ConstructL")));
+
+ User::LeaveIfError(iProperty.Attach( KPSUidBluetoothSapConnectionState,
+ KBTSapConnectionState));
+ }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::~CBTSapStatusObserver
+//----------------------------------------------------------
+//
+CBTSapStatusObserver::~CBTSapStatusObserver()
+ {
+ Cancel();
+ iProperty.Close();
+ }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::StartObservingL()
+//----------------------------------------------------------
+//
+void CBTSapStatusObserver::SubscribeSapStatusL(MSapStatusObserver* aObserver)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapStatusObserver::SubscribeSapStatusL")));
+
+ ASSERT(aObserver);
+
+ iObserver = aObserver;
+
+ iProperty.Subscribe(iStatus);
+ SetActive();
+ }
+
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::DoCancel()
+// ---------------------------------------------------------
+//
+void CBTSapStatusObserver::DoCancel()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapStatusObserver::DoCancel")));
+
+ iProperty.Cancel();
+ }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::RunL()
+// ---------------------------------------------------------
+//
+void CBTSapStatusObserver::RunL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapStatusObserver::RunL")));
+
+ TInt btSapState;
+ TInt err = iStatus.Int();
+
+ iProperty.Subscribe(iStatus);
+ SetActive();
+
+ if (!err)
+ {
+ err = iProperty.Get(btSapState);
+ if (!err)
+ {
+ iObserver->SapStatusChangedL(btSapState);
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::CBTSapServerState()
+// ---------------------------------------------------------
+//
+CBTSapServerState::CBTSapServerState(CBTSapPlugin& aBTSapPlugin)
+ : CActive(CActive::EPriorityStandard),
+ iBTSapPlugin(aBTSapPlugin),
+ iCurrentState(EStateInit),
+ iStatesCreated(EFalse)
+ {
+ CActiveScheduler::Add(this);
+
+ _LIT_SECURITY_POLICY_C2(sapConnectionStateReadAndWritePolicy, ECapabilityLocalServices, ECapabilityReadDeviceData);
+ //_LIT_SECURITY_POLICY_S0(sapConnectionStateWritePolicy, 0x10005950); // BtEngServer SID
+
+ RProperty::Define(KPSUidBluetoothSapConnectionState, KBTSapConnectionState, RProperty::EInt,
+ sapConnectionStateReadAndWritePolicy, sapConnectionStateReadAndWritePolicy);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::~CBTSapServerState()
+// ---------------------------------------------------------
+//
+CBTSapServerState::~CBTSapServerState()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::~CBTSapServerState")));
+ // Make sure we've cancelled.
+ Cancel();
+
+ if (IsSapConnected())
+ {
+ iStateArray[iCurrentState]->NotifySapState(ESapNotConnected);
+ }
+
+ iStateArray.ResetAndDestroy();
+
+ delete iSocketHandler;
+ delete iSimCardStatusNotifier;
+ delete iRequestHandler;
+ delete iStatusObserver;
+
+ iSubscriptionModule.Close();
+ iPhone.Close();
+ iTelServer.UnloadPhoneModule(KPhoneTsy);
+ iTelServer.Close();
+
+ RProperty::Delete(KPSUidBluetoothSapConnectionState, KBTSapConnectionState);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::NewL()
+// ---------------------------------------------------------
+//
+CBTSapServerState* CBTSapServerState::NewL(CBTSapPlugin& aBTSapPlugin)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::NewL")));
+
+ CBTSapServerState* self = new (ELeave) CBTSapServerState(aBTSapPlugin);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::ConstructL()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::ConstructL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::ConstructL")));
+
+ OpenSubscriptionModuleL();
+ iRequestHandler = CBTSapRequestHandler::NewL(*this);
+ iSocketHandler = CBTSapSocketHandler::NewL(*this, *iRequestHandler);
+ iSimCardStatusNotifier = CBTSapSimCardStatusNotifier::NewL(*this);
+ iStatusObserver = CBTSapStatusObserver::NewL();
+
+ TState* state = new (ELeave) TStateInit(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ ChangeState(EStateInit);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::StartL()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::StartL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::StartL")));
+
+ // the order matters
+ TState* state = new (ELeave) TStateNotConnected(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ // The SAP connection is accepted/rejected via a P&S key (KPSUidBluetoothSapConnectionState)
+ // iStatusObserver monitors P&S key changes and calls AcceptSapConnection or
+ // RejectSapConnection accordingly.
+ iStatusObserver->SubscribeSapStatusL(this);
+
+ ChangeState(EStateNotConnected);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::DoCancel()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::DoCancel()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::DoCancel")));
+
+ iStateArray[iCurrentState]->Cancel();
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::ChangeState
+// ---------------------------------------------------------
+void CBTSapServerState:: ChangeState(const TBTSapServerState aNextState)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap] CBTSapServerState:: ChangeState: %d"), aNextState));
+
+ Cancel();
+ iCurrentState = aNextState;
+ iStateArray[iCurrentState]->Enter(iStatus);
+ SetActive();
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::RunL()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::RunL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::RunL: %d >>"), iStatus.Int()));
+
+ TBTSapServerState nextState = iStateArray[iCurrentState]->Complete(iStatus.Int());
+
+ // Enter new state
+ ChangeState(nextState);
+
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap] SM: RunL complete <<")));
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::CurrentState()
+// ---------------------------------------------------------
+TBTSapServerState CBTSapServerState:: CurrentState()
+ {
+ return iCurrentState;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::AcceptSapConnection()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::AcceptSapConnection()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::AcceptSapConnection")));
+
+ return iStateArray[iCurrentState]->AcceptSapConnection();
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::RejectSapConnection()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState:: RejectSapConnection(TBTSapRejectReason aReason)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::RejectSapConnection")));
+
+ return iStateArray[iCurrentState]->RejectSapConnection(aReason);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::DisconnectSapConnection()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::DisconnectSapConnection(TBTSapDisconnectType aType)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::DisconnectSapConnection: %d"), aType));
+ TInt retVal = KErrNotReady;
+
+ if (IsSapConnected())
+ {
+ Cancel(); // Cancel current state
+ retVal = iStateArray[iCurrentState]->DisconnectSapConnection(aType);
+ ChangeState(aType == EDisconnectImmediate ? EStateNotConnected : EStateIdle);
+ }
+
+ return retVal;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::IsSapConnected()
+// ---------------------------------------------------------
+//
+TBool CBTSapServerState::IsSapConnected()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::IsSapConnected")));
+ TBool ret = EFalse;
+ if (iSocketHandler)
+ {
+ ret = iSocketHandler->IsSapConnected();
+ }
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::GetRemoteBTAddress()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::GetRemoteBTAddress(TBTDevAddr& aBTDevAddr)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::GetRemoteBTAddress")));
+
+ return (iSocketHandler != NULL) ? iSocketHandler->GetRemoteBTAddress(aBTDevAddr) : KErrDisconnected;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::SimCardStatusChanged()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::SimCardStatusChanged(TCardStatus aCardStatus)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] SapSimCardStatusChanged: %d"), aCardStatus));
+
+ if (iCurrentState == EStateConnect ||
+ iCurrentState == EStatePowerOn ||
+ iCurrentState == EStateReset)
+ {
+ iStateArray[iCurrentState]->SimCardStatusChanged(aCardStatus);
+ }
+ else
+ {
+ // real indication
+ Cancel();
+ iStateArray[iCurrentState]->SimCardStatusChanged(aCardStatus);
+ ChangeState(EStateIdle);
+ }
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::CreateStatesL()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::CreateStatesL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::CreateStatesL")));
+
+ if (!iStatesCreated)
+ {
+ // Create SAP states. TStateInit and TStateNotConnected have already been created.
+ TState* state = new (ELeave) TStateConnect(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateDisconnect(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateIdle(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateAPDU(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateATR(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStatePowerOff(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStatePowerOn(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateReset(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+
+ state = new (ELeave) TStateCardReaderStatus(*this);
+ CleanupStack::PushL(state);
+ User::LeaveIfError(iStateArray.Append(state));
+ CleanupStack::Pop(state);
+ }
+
+ iStatesCreated = ETrue;
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::ReleaseStatesL()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::ReleaseStatesL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::ReleaseStatesL")));
+ // Delete SAP states, all except TStateInit and TStateNotConnected.
+ for(TInt i = iStateArray.Count() - 1; i >= 2; i--)
+ {
+ delete iStateArray[i];
+ iStateArray[i] = NULL;
+ iStateArray.Remove(i);
+ }
+
+ iStatesCreated = EFalse;
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::DisconnectCompleteL()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::DisconnectCompleteL(TInt aErr)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::DisconnectCompleteL")));
+ iBTSapPlugin.OperationCompletedL(MSapAsyncObserver::EDisconnect, aErr);
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::HandleStateChangeRequest()
+// ---------------------------------------------------------
+//
+TInt CBTSapServerState::HandleStateChangeRequest(TBTSapServerState& aNextState)
+ {
+ return iStateArray[iCurrentState]->ChangeState(aNextState);
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::SendErrorResponse()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::SendErrorResponse()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::SendErrorResponse")));
+
+ // set response: error_response
+ iResponseMessage.SetMsgID(EErrorResponse);
+ iSocketHandler->Send(iResponseMessage.Data());
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::OpenSubscriptionModuleL()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::OpenSubscriptionModuleL()
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::OpenSubscriptionModuleL")));
+
+ User::LeaveIfError(iTelServer.Connect());
+ User::LeaveIfError(iTelServer.LoadPhoneModule(KPhoneTsy)); // Load Custom API Extension
+ User::LeaveIfError(iPhone.Open( iTelServer, KDefaultPhone));
+ User::LeaveIfError(iSubscriptionModule.Open(iPhone));
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::BTSapSocketHandler()
+// ---------------------------------------------------------
+//
+CBTSapSocketHandler& CBTSapServerState::BTSapSocketHandler()
+ {
+ return *iSocketHandler;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::BTSapSimCardStatusNotifier()
+// ---------------------------------------------------------
+//
+CBTSapSimCardStatusNotifier& CBTSapServerState::BTSapSimCardStatusNotifier()
+ {
+ return *iSimCardStatusNotifier;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::SubscriptionModule()
+// ---------------------------------------------------------
+//
+RMmCustomAPI& CBTSapServerState::SubscriptionModule()
+ {
+ return iSubscriptionModule;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::BTSapRequestMessage()
+// ---------------------------------------------------------
+//
+TBTSapMessage& CBTSapServerState::BTSapRequestMessage()
+ {
+ return iRequestMessage;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::BTSapResponseMessage()
+// ---------------------------------------------------------
+//
+TBTSapMessage& CBTSapServerState::BTSapResponseMessage()
+ {
+ return iResponseMessage;
+ }
+
+// ---------------------------------------------------------
+// CBTSapServerState::SapStatusChangedL()
+// ---------------------------------------------------------
+//
+void CBTSapServerState::SapStatusChangedL(TInt aStatus)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTSapServerState::SapStatusChangedL")));
+
+ switch (aStatus)
+ {
+ case EBTSapNotConnected:
+ case EBTSapConnecting:
+ {
+ // no actions
+ break;
+ }
+ case EBTSapConnected:
+ {
+ // Inform observers
+ iBTSapPlugin.ConnectComplete();
+ break;
+ }
+ case EBTSapAccepted:
+ {
+ AcceptSapConnection();
+ break;
+ }
+ case EBTSapRejected:
+ {
+ RejectSapConnection(ERejectGeneralError);
+ break;
+ }
+ default:
+ {
+ // An error or invalid state
+ RejectSapConnection(ERejectGeneralError);
+ break;
+ }
+ }
+ }
+
+
+// End of File