diff -r a1b8f5cc021e -r 0bcc0c74cec9 bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp --- a/bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp Fri Sep 17 08:36:02 2010 +0300 +++ b/bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp Mon Oct 04 02:11:29 2010 +0300 @@ -22,60 +22,37 @@ #include "ProxySAP.h" #include "linkmgr.h" + #ifdef __FLOG_ACTIVE _LIT8(KLogComponent, LOG_COMPONENT_LINKMGR); #endif -CRoleSwitcher::CRoleSwitcher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole) - : CTimer(CActive::EPriorityStandard) - , iLinkMgr(aLinkMgr) +CPhysicalLinkHelper::CPhysicalLinkHelper(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink) + : iLinkMgr(aLinkMgr) , iLink(aLink) - , iRole(aRole) - , iIsEncryptionDisabledForRoleSwitch(EFalse) { LOG_FUNC - iState = &iLinkMgr.RoleSwitcherStateFactory().GetState(CRoleSwitcherStateFactory::EIdle); - } - -CRoleSwitcher* CRoleSwitcher::NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole) - { - LOG_STATIC_FUNC - CRoleSwitcher* self = new(ELeave) CRoleSwitcher(aLinkMgr, aLink, aRole); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; } -void CRoleSwitcher::ConstructL() +void CPhysicalLinkHelper::BaseConstructL() { LOG_FUNC // create Proxy telling it the possible PHY iBTProxySAP = CBTProxySAP::NewL(iLinkMgr, &iLink); iBTProxySAP->SetNotify(this); - - TCallBack cb(EventReceivedCallBack, this); - iEventReceivedCallBack = new (ELeave)CAsyncCallBack(cb, EActiveHighPriority); - - CTimer::ConstructL(); - CActiveScheduler::Add(this); - - // add ourselves to the list in LinkMgr, LinkMgr will kick off the role change state machine - iLinkMgr.AddRoleSwitcher(*this); - iAddedToLinkMgr = ETrue; + + TCallBack ecb(EventReceivedCallBack, this); + iEventReceivedCallBack = new (ELeave)CAsyncCallBack(ecb, EActiveHighPriority); } -CRoleSwitcher::~CRoleSwitcher() +CPhysicalLinkHelper::~CPhysicalLinkHelper() { LOG_FUNC - if (iAddedToLinkMgr) - { - iLinkMgr.RemoveRoleSwitcher(*this); - } - - Cancel(); // watchdog timer + + RemoveTimer(); delete iBTProxySAP; + if (iEventReceivedCallBack) { iEventReceivedCallBack->Cancel(); @@ -83,158 +60,14 @@ } } -void CRoleSwitcher::DisableLPM() +void CPhysicalLinkHelper::DisableLPM() { LOG_FUNC TPckgBuf optionBuf; iBTProxySAP->SAPSetOption(KSolBtLMProxy, EBBRequestPreventAllLowPowerModes, optionBuf); } -void CRoleSwitcher::EnableLPM() - { - LOG_FUNC - TPckgBuf optionBuf; - iBTProxySAP->SAPSetOption(KSolBtLMProxy, EBBRequestAllowAllLowPowerModes, optionBuf); - } - -void CRoleSwitcher::DisableEncryption() - { - LOG_FUNC - // data traffic suspended - iLinkMgr.LinkManagerProtocol().ACLController().SetParked(iLink.Handle(), ETrue); - TBTBasebandEvent event(ENotifyEncryptionChangeOff); - iBTProxySAP->Ioctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &event); - iLinkMgr.Encrypt(EFalse, iLink); - - // set flag here, it's too late when we receive the event as AccessReqester - // might receive the baseband notification earlier then the flag is set! - iIsEncryptionDisabledForRoleSwitch = ETrue; - } - -void CRoleSwitcher::EnableEncryption() - { - LOG_FUNC - TBTBasebandEvent event(ENotifyEncryptionChangeOn); - iBTProxySAP->Ioctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &event); - iLinkMgr.Encrypt(ETrue, iLink); - // data traffic is enabled in IoctlComplete - } - -void CRoleSwitcher::ChangeRole() - { - LOG_FUNC - TBTBasebandEvent event(ENotifyAnyRole); - iBTProxySAP->Ioctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &event); - iLinkMgr.ChangeRole(iRole, iLink); - } - -void CRoleSwitcher::CancelIoctl() - { - LOG_FUNC - iBTProxySAP->CancelIoctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl); - } - -// Timer -void CRoleSwitcher::RunL() - { - LOG_FUNC - iState->TimerExpired(*this); - } - -TInt CRoleSwitcher::RunError(TInt aError) - { - LOG_FUNC - iState->Error(*this, aError); - return KErrNone; - } - -// From MSocketNotify -void CRoleSwitcher::NewData(TUint /*aCount*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::CanSend() - { - LOG_FUNC - - } - -void CRoleSwitcher::ConnectComplete() - { - LOG_FUNC - - } - -void CRoleSwitcher::ConnectComplete(const TDesC8& /*aConnectData*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::ConnectComplete(CServProviderBase& /*aSSP*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::ConnectComplete(CServProviderBase& /*aSSP*/,const TDesC8& /*aConnectData*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::CanClose(TDelete /*aDelete*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::CanClose(const TDesC8& /*aDisconnectData*/,TDelete /*aDelete*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::Error(TInt /*aError*/,TUint /*aOperationMask*/) - { - LOG_FUNC - - } - -void CRoleSwitcher::Disconnect(void) - { - LOG_FUNC - iState->Error(*this, KErrDisconnected); - } - -void CRoleSwitcher::Disconnect(TDesC8& /*aDisconnectData*/) - { - LOG_FUNC - iState->Error(*this, KErrDisconnected); - } - -void CRoleSwitcher::Start() - { - LOG_FUNC - iState->Start(*this); - } - -void CRoleSwitcher::Finish() - { - LOG_FUNC - // async call to delete this class - iLink.AsyncDeleteRoleSwitcher(); - } - -void CRoleSwitcher::SaveEncryption() - { - LOG_FUNC - iIsEncrypted = iLink.Encrypted(); - } - -TBool CRoleSwitcher::IsEPRSupported() const +TBool CPhysicalLinkHelper::IsEPRSupported() const { LOG_FUNC // For Lisbon (Bluetooth 2.1), if EPR is supported both locally and remotely, @@ -243,418 +76,144 @@ return iLink.IsEncryptionPauseResumeSupported(); } -void CRoleSwitcher::LogRoleSwitchSuccessful() const +void CPhysicalLinkHelper::NotifyBasebandEvent(TNotifyEvent aEvent) + { + LOG_FUNC + TBTBasebandEvent event(aEvent.NotifyEvent()); + iBTProxySAP->Ioctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &event); + } + +void CPhysicalLinkHelper::CancelNotify() + { + LOG_FUNC + iBTProxySAP->CancelIoctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl); + } + +void CPhysicalLinkHelper::QueueTimer(TTimeIntervalMicroSeconds32 aTimerVal) + { + LOG_FUNC + + TCallBack cb(TimerExpiredCallBack, this); + iTimerEntry.Set(cb); + BTSocketTimer::Queue(aTimerVal, iTimerEntry); + } + + +void CPhysicalLinkHelper::RemoveTimer() + { + LOG_FUNC + + BTSocketTimer::Remove(iTimerEntry); + } + +// From MSocketNotify +void CPhysicalLinkHelper::NewData(TUint /*aCount*/) + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::CanSend() + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::ConnectComplete() { LOG_FUNC - TInt eventType; - eventType = (iRole == EMaster ? ENotifyMaster :ENotifySlave); + + } + +void CPhysicalLinkHelper::ConnectComplete(const TDesC8& /*aConnectData*/) + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::ConnectComplete(CServProviderBase& /*aSSP*/) + { + LOG_FUNC - if (iBasebandEvent.EventType()==eventType && - iBasebandEvent.ErrorCode()==KErrNone) - { - LOG(_L("CRoleSwitcher RoleSwitch OK")); - } - else - { - LOG(_L("CRoleSwitcher RoleSwitch failed")); - } + } + +void CPhysicalLinkHelper::ConnectComplete(CServProviderBase& /*aSSP*/,const TDesC8& /*aConnectData*/) + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::CanClose(TDelete /*aDelete*/) + { + LOG_FUNC + } -void CRoleSwitcher::IoctlComplete(TDesC8 *aBuf) +void CPhysicalLinkHelper::CanClose(const TDesC8& /*aDisconnectData*/,TDelete /*aDelete*/) + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::Error(TInt /*aError*/,TUint /*aOperationMask*/) + { + LOG_FUNC + + } + +void CPhysicalLinkHelper::Disconnect(void) + { + LOG_FUNC + Error(KErrDisconnected); + } + +void CPhysicalLinkHelper::Disconnect(TDesC8& /*aDisconnectData*/) + { + LOG_FUNC + Error(KErrDisconnected); + } + +void CPhysicalLinkHelper::IoctlComplete(TDesC8 *aBuf) { LOG_FUNC const TBTBasebandEventNotification* event = reinterpret_cast(aBuf->Ptr()); iBasebandEvent = *event; iEventReceivedCallBack->CallBack(); } - -/*static*/ TInt CRoleSwitcher::EventReceivedCallBack(TAny* aRoleSwitcher) - { - LOG_STATIC_FUNC - CRoleSwitcher* roleSwitcher = static_cast(aRoleSwitcher); - roleSwitcher->iState->EventReceived(*roleSwitcher); - return EFalse; - } - -//---------------------------------------------------------------------------------- -// STATE FACTORY -//---------------------------------------------------------------------------------- - -CRoleSwitcherStateFactory* CRoleSwitcherStateFactory::NewL() +/*static*/ TInt CPhysicalLinkHelper::EventReceivedCallBack(TAny* aThis) { LOG_STATIC_FUNC - CRoleSwitcherStateFactory* ret=new (ELeave) CRoleSwitcherStateFactory(); - CleanupStack::PushL(ret); - ret->ConstructL(); - CleanupStack::Pop(ret); - return ret; - } - -void CRoleSwitcherStateFactory::ConstructL() - { - LOG_FUNC - iStates[EIdle] =new (ELeave) TRSStateIdle(*this); - iStates[EDisablingLPM] =new (ELeave) TRSStateDisablingLPM(*this); - iStates[EDisablingEncryption] =new (ELeave) TRSStateDisablingEncryption(*this); - iStates[EChangingRole] =new (ELeave) TRSStateChangingRole(*this); - iStates[EChangingRoleWithEPR] =new (ELeave) TRSStateChangingRoleWithEPR(*this); - iStates[EEnablingEncryption] =new (ELeave) TRSStateEnablingEncryption(*this); - } - -CRoleSwitcherStateFactory::CRoleSwitcherStateFactory() - { - LOG_FUNC - iStates.DeleteAll(); - } - -TRoleSwitcherState& CRoleSwitcherStateFactory::GetState(CRoleSwitcherStateFactory::TRoleSwitcherStates aState) - { - LOG_FUNC - __ASSERT_DEBUG(iStates[aState], Panic(ERoleSwitcherInvalidState)); - return *iStates[aState]; - } - -TInt CRoleSwitcherStateFactory::StateIndex(const TRoleSwitcherState* aState) const - { - LOG_FUNC - TInt state; - for (state = 0; state < ERoleSwitcherMaxState; state++) - { - if (iStates[state] == aState) - { - return state; - } - } - - return KUnknownState; - } - - -//---------------------------------------------------------------------------------- -// STATES -//---------------------------------------------------------------------------------- - -TRoleSwitcherState::TRoleSwitcherState(CRoleSwitcherStateFactory& aFactory) -: iFactory(aFactory) - { - LOG_FUNC - } - -void TRoleSwitcherState::PanicInState(TLinkPanic aPanic) const - { - LOG_FUNC - Panic(aPanic, iFactory.StateIndex(this)); - } - -void TRoleSwitcherState::ChangeState(CRoleSwitcher& aContext, CRoleSwitcherStateFactory::TRoleSwitcherStates aState) const - { - LOG_FUNC - - aContext.iState->Exit(aContext); - -#ifdef __FLOG_ACTIVE - TRoleSwitcherState* state=&iFactory.GetState(aState); - LOG2(_L("RoleSwitcher: State %S -> %S"), &aContext.iState->iName, &state->iName); -#endif //__FLOG_ACTIVE - aContext.iState=&iFactory.GetState(aState); - - aContext.iState->Enter(aContext); + CPhysicalLinkHelper* helper = static_cast(aThis); + helper->DoEventReceivedCallBack(); + return EFalse; } -void TRoleSwitcherState::Enter(CRoleSwitcher& /*aContext*/) const - { - LOG_FUNC - // do nothing - } - -void TRoleSwitcherState::Exit(CRoleSwitcher& /*aContext*/) const - { - LOG_FUNC - // do nothing - } - -void TRoleSwitcherState::Start(CRoleSwitcher& /*aContext*/) const - { - LOG_FUNC - PanicInState(ERoleSwitcherStateMachineInvalidEvent); - } - -void TRoleSwitcherState::Error(CRoleSwitcher& aContext, TInt /*aErr*/) const - { - LOG_FUNC - aContext.CancelIoctl(); - aContext.Cancel(); - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - -void TRoleSwitcherState::EventReceived(CRoleSwitcher& /*aContext*/) const - { - LOG_FUNC - // do nothing - } - -void TRoleSwitcherState::TimerExpired(CRoleSwitcher& aContext) const - { - LOG_FUNC - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - -//---------------------------------------------------------------------------------- - -TRSStateIdle::TRSStateIdle(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) - { - LOG_FUNC - STATENAME("TRSStateIdle"); - } - -void TRSStateIdle::Start(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.After(KTimeoutRoleSwitch); // watchdog timer - ChangeState(aContext, CRoleSwitcherStateFactory::EDisablingLPM); - } - -void TRSStateIdle::Enter(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.Finish(); - } - -//---------------------------------------------------------------------------------- - -TRSStateDisablingLPM::TRSStateDisablingLPM(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) - { - LOG_FUNC - STATENAME("TRSStateDisablingLPM"); - } - -void TRSStateDisablingLPM::Enter(CRoleSwitcher& aContext) const - { - LOG_FUNC - // DisableLPM even if link is active to prevent possible LPM requests during encryption disabling - - if (aContext.iLink.LinkMode() == EActiveMode) - { - aContext.DisableLPM(); - if (aContext.IsEPRSupported()) - { - ChangeState(aContext, CRoleSwitcherStateFactory::EChangingRoleWithEPR); - } - else - { - ChangeState(aContext, CRoleSwitcherStateFactory::EDisablingEncryption); - } - // don't wait for notification - } - else - { - TBTBasebandEvent event(ENotifyActiveMode); - aContext.iBTProxySAP->Ioctl(KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &event); - aContext.DisableLPM(); - } - } - -void TRSStateDisablingLPM::EventReceived(CRoleSwitcher& aContext) const +void CPhysicalLinkHelper::DoEventReceivedCallBack() { LOG_FUNC - if (aContext.iBasebandEvent.EventType()==ENotifyActiveMode && - aContext.iBasebandEvent.ErrorCode()==KErrNone) - { - if (aContext.IsEPRSupported()) - { - ChangeState(aContext, CRoleSwitcherStateFactory::EChangingRoleWithEPR); - } - else - { - ChangeState(aContext, CRoleSwitcherStateFactory::EDisablingEncryption); - } - } - else - { - LOG(_L("CRoleSwitcher RoleSwitch failed in DisableLPM")); - // we can quit SM, don't need to rewind - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - } - -//---------------------------------------------------------------------------------- -TRSStateDisablingEncryption::TRSStateDisablingEncryption(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) - { - LOG_FUNC - STATENAME("TRSStateDisablingEncryption"); - } - -void TRSStateDisablingEncryption::Enter(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.SaveEncryption(); - if (aContext.iIsEncrypted) - { - aContext.DisableEncryption(); - } - else - { - ChangeState(aContext, CRoleSwitcherStateFactory::EChangingRole); - } - } - -void TRSStateDisablingEncryption::EventReceived(CRoleSwitcher& aContext) const - { - LOG_FUNC - if (aContext.iBasebandEvent.EventType()==ENotifyEncryptionChangeOff && - aContext.iBasebandEvent.ErrorCode()==KErrNone) - { - ChangeState(aContext, CRoleSwitcherStateFactory::EChangingRole); - } - else - { - LOG(_L("CRoleSwitcher RoleSwitch failed in DisableEncryption")); - // before quiting SM , try to enable LPM - aContext.EnableLPM(); - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - } - -void TRSStateDisablingEncryption::TimerExpired(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.CancelIoctl(); - ChangeState(aContext, CRoleSwitcherStateFactory::EEnablingEncryption); - } - -//---------------------------------------------------------------------------------- -TRSStateChangingRole::TRSStateChangingRole(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) - { - LOG_FUNC - STATENAME("TRSStateChangingRole"); - } - -void TRSStateChangingRole::Enter(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.ChangeRole(); - } - -void TRSStateChangingRole::EventReceived(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.Cancel(); // cancel watchdog timer - - FTRACE(aContext.LogRoleSwitchSuccessful()); - - - ChangeState(aContext, CRoleSwitcherStateFactory::EEnablingEncryption); - } - -void TRSStateChangingRole::TimerExpired(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.CancelIoctl(); - ChangeState(aContext, CRoleSwitcherStateFactory::EEnablingEncryption); + EventReceived(iBasebandEvent); } -//---------------------------------------------------------------------------------- -TRSStateChangingRoleWithEPR::TRSStateChangingRoleWithEPR(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) +/*static*/ TInt CPhysicalLinkHelper::TimerExpiredCallBack(TAny* aThis) { - LOG_FUNC - STATENAME("TRSStateChangingRoleWithEPR"); - } - -void TRSStateChangingRoleWithEPR::Enter(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.ChangeRole(); + LOG_STATIC_FUNC + CPhysicalLinkHelper* helper = static_cast(aThis); + helper->DoTimerExpiredCallBack(); + return EFalse; } -void TRSStateChangingRoleWithEPR::EventReceived(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.Cancel(); // cancel watchdog timer - - FTRACE(aContext.LogRoleSwitchSuccessful()); - - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - -void TRSStateChangingRoleWithEPR::TimerExpired(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.CancelIoctl(); - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - -//---------------------------------------------------------------------------------- -TRSStateEnablingEncryption::TRSStateEnablingEncryption(CRoleSwitcherStateFactory& aFactory) -: TRoleSwitcherState(aFactory) - { - LOG_FUNC - STATENAME("TRSStateEnablingEncryption"); - } - -void TRSStateEnablingEncryption::Enter(CRoleSwitcher& aContext) const +void CPhysicalLinkHelper::DoTimerExpiredCallBack() { LOG_FUNC - if (aContext.iIsEncrypted) - { - aContext.After(KTimeoutOneCommand); - aContext.EnableEncryption(); - } - else - { - aContext.EnableLPM(); - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - } - -void TRSStateEnablingEncryption::Exit(CRoleSwitcher& aContext) const - { - LOG_FUNC - if (aContext.iIsEncrypted) - { - // enable data traffic - aContext.iLinkMgr.LinkManagerProtocol().ACLController().SetParked(aContext.iLink.Handle(), EFalse); - } + TimerExpired(); } -void TRSStateEnablingEncryption::EventReceived(CRoleSwitcher& aContext) const - { - LOG_FUNC - aContext.Cancel(); // watchdog timer - if (aContext.iBasebandEvent.EventType()==ENotifyEncryptionChangeOn && - aContext.iBasebandEvent.ErrorCode()==KErrNone) - { - aContext.EnableLPM(); - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - aContext.iIsEncryptionDisabledForRoleSwitch = EFalse; - } - else - { - LOG(_L("CRoleSwitcher SetEncryption failed, disconnect link")); - if (aContext.iLink.Terminate(ERemoteUserEndedConnection) != KErrNone) - { - LOG(_L("CRoleSwitcher OOM")); - } - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } - } - -void TRSStateEnablingEncryption::TimerExpired(CRoleSwitcher& aContext) const - { - LOG_FUNC - LOG(_L("CRoleSwitcher Timeout in EncryptionEnable, disconnect")); - aContext.CancelIoctl(); - if (aContext.iLink.Terminate(ERemoteUserEndedConnection) != KErrNone) - { - LOG(_L("CRoleSwitcher OOM")); - } - ChangeState(aContext, CRoleSwitcherStateFactory::EIdle); - } + + + + +