diff -r 10183c6d2913 -r 015fa7494bd2 bluetooth/btstack/linkmgr/PhysicalLinkHelper.h --- a/bluetooth/btstack/linkmgr/PhysicalLinkHelper.h Wed Sep 15 13:27:26 2010 +0300 +++ b/bluetooth/btstack/linkmgr/PhysicalLinkHelper.h Wed Oct 13 15:48:34 2010 +0300 @@ -22,25 +22,28 @@ #include "linkutil.h" #include -// A struct to allow both single event and combination events to be passed for requesting -// notification. This effectively moves the cast to a TInt to below the API rather than -// being required by the client. -struct TNotifyEvent - { -public: - TNotifyEvent(TBTPhysicalLinkStateNotifier aSingleEvent) : iEvent(aSingleEvent) {}; - TNotifyEvent(TBTPhysicalLinkStateNotifierCombinations aComboEvent) : iEvent(aComboEvent) {}; +// watchdog for first half of the SM including: +// DisablingLPM, DisablingEncryption, RoleSwitch +const TUint KTimeoutRoleSwitch = 3000000; // 3 s; + +// watchdog for EnablingEncryption +const TUint KTimeoutOneCommand = 2000000; // 2 s; + +class TRoleSwitcherState; - TInt NotifyEvent() const {return iEvent;}; -private: - TInt iEvent; - }; +NONSHARABLE_CLASS(CRoleSwitcher) : public CTimer, public MSocketNotify + { + friend class TRoleSwitcherState; + friend class TRSStateDisablingLPM; + friend class TRSStateDisablingEncryption; + friend class TRSStateChangingRole; + friend class TRSStateChangingRoleWithEPR; + friend class TRSStateEnablingEncryption; +public: -NONSHARABLE_CLASS(CPhysicalLinkHelper) : public CBase, public MSocketNotify - { -public: - ~CPhysicalLinkHelper(); + static CRoleSwitcher* NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole); + ~CRoleSwitcher(); // From MSocketNotify void NewData(TUint aCount); @@ -58,50 +61,196 @@ void NoBearer(const TDesC8& /*aConnectionInf*/) {}; void Bearer(const TDesC8& /*aConnectionInf*/) {}; - virtual void StartHelper() = 0; - + void Start(); + void Finish(); inline const TBTDevAddr& BDAddr() const; + inline TBTBasebandRole RequestedRole() const; + inline TBool IsEncryptionDisabledForRoleSwitch() const; + TBool IsEPRSupported() const; + void LogRoleSwitchSuccessful() const; + TSglQueLink iQLink; -protected: - CPhysicalLinkHelper(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink); - void BaseConstructL(); +private: + CRoleSwitcher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole); + void ConstructL(); void DisableLPM(); + void DisableEncryption(); + void ChangeRole(); + void EnableEncryption(); + void EnableLPM(); + void CancelIoctl(); - void QueueTimer(TTimeIntervalMicroSeconds32 aTimerVal); - void RemoveTimer(); - void NotifyBasebandEvent(TNotifyEvent aEvent); - void CancelNotify(); + void SaveEncryption(); + // CTimer + void RunL(); + TInt RunError(TInt aError); - TBool IsEPRSupported() const; + static TInt EventReceivedCallBack(TAny* aRoleSwitcher); + // Async Callback to notify baseband event received. + CAsyncCallBack* iEventReceivedCallBack; + TBTBasebandEventNotification iBasebandEvent; + TBool iIsEncrypted; + TBool iIsActive; // LinkMode + TBool iAddedToLinkMgr; + CPhysicalLinksManager& iLinkMgr; + CPhysicalLink& iLink; + TBTBasebandRole iRole; // Requested role + CBTProxySAP* iBTProxySAP; + TRoleSwitcherState* iState; + TBool iIsEncryptionDisabledForRoleSwitch; + }; + +//-------------------------------------------------- +// STATE FACTORY +//-------------------------------------------------- + +/** + Factory for the RoleSwitcher states + + The states are flyweight classes +**/ +NONSHARABLE_CLASS(CRoleSwitcherStateFactory) : public CBase + { +public: + static CRoleSwitcherStateFactory* NewL(); + + enum TRoleSwitcherStates + { + EIdle, + EDisablingLPM, + EDisablingEncryption, + EChangingRole, + EChangingRoleWithEPR, + EEnablingEncryption, + // *** keep next one last *** + ERoleSwitcherMaxState, + }; - virtual void TimerExpired() = 0; - virtual void HandleError(TInt aError) = 0; - virtual void EventReceived(TBTBasebandEventNotification& aEvent) = 0; + TRoleSwitcherState& GetState(TRoleSwitcherStates aState); + TInt StateIndex(const TRoleSwitcherState* aState) const; private: - static TInt EventReceivedCallBack(TAny* aThis); - void DoEventReceivedCallBack(); + CRoleSwitcherStateFactory(); + void ConstructL(); + TFixedArray iStates; + }; + + + +//-------------------------------------------------- +// STATES, base +//-------------------------------------------------- + +NONSHARABLE_CLASS(TRoleSwitcherState) + { +public: + TRoleSwitcherState(CRoleSwitcherStateFactory& aFactory); - static TInt TimerExpiredCallBack(TAny* aThis); - void DoTimerExpiredCallBack(); + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void Exit(CRoleSwitcher& aContext) const; + + virtual void Start(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; + virtual void Error(CRoleSwitcher& aContext, TInt aErr) const; + virtual void TimerExpired(CRoleSwitcher& aContext) const; + +protected: + // Exits old state, sets the new state, and enters it. + void ChangeState(CRoleSwitcher& aContext, CRoleSwitcherStateFactory::TRoleSwitcherStates aState) const; + void PanicInState(TLinkPanic aPanic) const; protected: - CPhysicalLinksManager& iLinkMgr; - CPhysicalLink& iLink; - -private: - // Async Callback to notify baseband event received. - CAsyncCallBack* iEventReceivedCallBack; - TBTBasebandEventNotification iBasebandEvent; - CBTProxySAP* iBTProxySAP; - - TDeltaTimerEntry iTimerEntry; + CRoleSwitcherStateFactory& iFactory; +#ifdef __FLOG_ACTIVE + TBuf<48> iName; +#endif + }; + + +//-------------------------------------------------- +// STATES +//-------------------------------------------------- + +NONSHARABLE_CLASS(TRSStateIdle) : public TRoleSwitcherState + { +public: + TRSStateIdle(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void Start(CRoleSwitcher& aContext) const; + }; + + +NONSHARABLE_CLASS(TRSStateDisablingLPM) : public TRoleSwitcherState + { +public: + TRSStateDisablingLPM(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; }; -inline const TBTDevAddr& CPhysicalLinkHelper::BDAddr() const +NONSHARABLE_CLASS(TRSStateDisablingEncryption) : public TRoleSwitcherState + { +public: + TRSStateDisablingEncryption(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; + virtual void TimerExpired(CRoleSwitcher& aContext) const; + }; + +NONSHARABLE_CLASS(TRSStateChangingRole) : public TRoleSwitcherState + { +public: + TRSStateChangingRole(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; + virtual void TimerExpired(CRoleSwitcher& aContext) const; + }; + +NONSHARABLE_CLASS(TRSStateChangingRoleWithEPR) : public TRoleSwitcherState + { +public: + TRSStateChangingRoleWithEPR(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; + virtual void TimerExpired(CRoleSwitcher& aContext) const; + }; + +NONSHARABLE_CLASS(TRSStateEnablingEncryption) : public TRoleSwitcherState + { +public: + TRSStateEnablingEncryption(CRoleSwitcherStateFactory& aFactory); + + virtual void Enter(CRoleSwitcher& aContext) const; + virtual void Exit(CRoleSwitcher& aContext) const; + virtual void EventReceived(CRoleSwitcher& aContext) const; + virtual void TimerExpired(CRoleSwitcher& aContext) const; + }; + +#ifdef __FLOG_ACTIVE +#define STATENAME(x) iName=_L(x) +#else +#define STATENAME(x) +#endif + +inline const TBTDevAddr& CRoleSwitcher::BDAddr() const { return iLink.BDAddr(); } +inline TBTBasebandRole CRoleSwitcher::RequestedRole() const + { + return iRole; + } + +inline TBool CRoleSwitcher::IsEncryptionDisabledForRoleSwitch() const + { + return iIsEncryptionDisabledForRoleSwitch; + } + #endif //PHYSICALLINKHELPER_H_