diff -r 000000000000 -r f63038272f30 bluetoothengine/btsap/src/BTSapServerState.cpp --- /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 +#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