--- 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 <bluetooth/hci/hciutil.h>
-// 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<TRoleSwitcherState*, ERoleSwitcherMaxState> 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_