--- a/bluetooth/btextnotifiers/inc/BTExtNotifiers.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btextnotifiers/inc/BTExtNotifiers.h Tue Sep 14 23:28:24 2010 +0300
@@ -128,8 +128,8 @@
IMPORT_C TBool UplinkAccessAllowed() const;
IMPORT_C TBool IsValid() const;
- // Non-exported constructor. Allows creation of default NULL instance
- TPanConnection();
+ // Allows creation of default NULL instance
+ IMPORT_C TPanConnection();
private:
TBTDevAddr iRemoteDeviceAddress;
--- a/bluetooth/btstack/bluetooth_stack.ini Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/bluetooth_stack.ini Tue Sep 14 23:28:24 2010 +0300
@@ -19,6 +19,4 @@
[CoreHci]
EcomUid= 0x102736DE
-[lowpowermodeconfiguration]
-overridelpmtimeout_microseconds= 0
--- a/bluetooth/btstack/common/bt.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/common/bt.h Tue Sep 14 23:28:24 2010 +0300
@@ -44,7 +44,6 @@
EPreauthoriseDevice, // used for multiple SAPs operating in one usecase (eg AVRCP and GAVDP);
ESubscribePhysicalLink,
EUnsubscribePhysicalLink,
- EOverrideLPMWithTimeout,
EOverrideLPM,
EUndoOverrideLPM,
ETryToAndThenPreventHostEncryptionKeyRefresh,
--- a/bluetooth/btstack/common/bt_v2.mmp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/common/bt_v2.mmp Tue Sep 14 23:28:24 2010 +0300
@@ -78,6 +78,8 @@
SOURCE hcifacade_events.cpp
SOURCE physicallinks.cpp
SOURCE PhysicalLinkHelper.cpp
+SOURCE roleswitchhelper.cpp
+SOURCE encryptionkeyrefreshhelper.cpp
SOURCE basebandsap.cpp
SOURCE physicallinksmanager.cpp
SOURCE physicallinkmetrics.cpp
--- a/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -813,8 +813,9 @@
{
LOG_FUNC
// The SAP is about to be detached from this signal handler.
- // Ensure no park overrides are active.
+ // Ensure no overrides are active.
UndoOverrideParkMode();
+ UndoOverrideLPM();
// Check if this SH has any unsent commands
// outstanding.
@@ -916,15 +917,26 @@
iSAP->Protocol().ControlPlane().ModifyPhysicalLink(EUndoOverridePark, iSAP->RemoteDev());
}
}
-
-void CL2CapSAPSignalHandler::OverrideLPMWithTimeout()
+
+void CL2CapSAPSignalHandler::OverrideLPM()
{
LOG_FUNC
// Temporarily override all low power modes. A reference to the SAP is required
// to get the remote device address.
if(iSAP)
{
- iSAP->Protocol().ControlPlane().ModifyPhysicalLink(EOverrideLPMWithTimeout, iSAP->RemoteDev());
+ iSAP->Protocol().ControlPlane().ModifyPhysicalLink(EOverrideLPM, iSAP->RemoteDev());
}
}
-
+
+void CL2CapSAPSignalHandler::UndoOverrideLPM()
+ {
+ LOG_FUNC
+ // Remove the temporary override of all low power modes. A reference to the SAP is
+ // required to get the remote device address.
+ if(iSAP)
+ {
+ iSAP->Protocol().ControlPlane().ModifyPhysicalLink(EUndoOverrideLPM, iSAP->RemoteDev());
+ }
+ }
+
--- a/bluetooth/btstack/l2cap/l2capSAPSignalHandler.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.h Tue Sep 14 23:28:24 2010 +0300
@@ -141,7 +141,8 @@
void OverrideParkMode();
void UndoOverrideParkMode();
- void OverrideLPMWithTimeout();
+ void OverrideLPM();
+ void UndoOverrideLPM();
inline TInt SignalHandlerErrorCode() const;
inline MSocketNotify::TOperationBitmasks SignalHandlerErrorAction() const;
--- a/bluetooth/btstack/l2cap/l2capSigStates.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/l2cap/l2capSigStates.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -286,6 +286,8 @@
{
LOG_FUNC
// The SAP has requested a channel be opened.
+ // Override all LPMs to try and avoid signalling timeouts
+ aSignalHandler.OverrideLPM();
TInt err = aSignalHandler.ChannelConfig().UpdateLocalConfigWithEntityCapabilities();
if (err == KErrNone)
@@ -298,9 +300,6 @@
// Update local Port.
aSignalHandler.SetLocalPort(port);
- // Override park to allow the connection to be made.
- aSignalHandler.OverrideParkMode();
-
// Active connection. Send a Connect Request command.
err = aSignalHandler.ConstructConnectionRequest();
if(err == KErrNone)
@@ -330,10 +329,8 @@
// Update local Port.
aSignalHandler.SetLocalPort(port);
- // Override park to allow the connection to be made.
- aSignalHandler.OverrideParkMode();
- // Override all LPMs (if timeout not set to zero)
- aSignalHandler.OverrideLPMWithTimeout();
+ // Override all LPMs to try and avoid signalling timeouts
+ aSignalHandler.OverrideLPM();
// Send a response with a 'pending' result and start security procedure.
err = aSignalHandler.ConstructConnectionResponse(aSignalHandler.GetOutstandingRequestID(),
@@ -384,10 +381,16 @@
aSignalHandler.iOpenChannelRequestAwaitingPeerEntityConfig = EFalse;
- // If Park mode has been overridden during either channel establishment or
- // channel disconnect, remove the override.
- // NB It is safe to call this method multiple times.
+ // Depending where we came from we may have applied either a
+ // park override or an all LPM override. We remove both these
+ // overrides because it's safe to remove an override that
+ // hasn't been applied.
+ // Note that although park is one of the LPMs the different
+ // levels of override are managed separately, so an
+ // UndoOverrideLPM does not remove an explicit park only
+ // override.
aSignalHandler.UndoOverrideParkMode();
+ aSignalHandler.UndoOverrideLPM();
// If the signal handler has left the closed state, it will have been added
// to the SH list in the Muxer. Now that the closed state is being
@@ -1091,8 +1094,16 @@
}
else
{
- // Remove and park override.
+ // Depending where we came from we may have applied either a
+ // park override or an all LPM override. We remove both these
+ // overrides because it's safe to remove an override that
+ // hasn't been applied.
+ // Note that although park is one of the LPMs the different
+ // levels of override are managed separately, so an
+ // UndoOverrideLPM does not remove an explicit park only
+ // override.
aSignalHandler.UndoOverrideParkMode();
+ aSignalHandler.UndoOverrideLPM();
// Cancel the configuration timer.
aSignalHandler.CancelTimer();
@@ -1149,7 +1160,23 @@
void TL2CAPSigStateWaitDisconnect::DisconnectResponse(CL2CapSAPSignalHandler& aSignalHandler) const
{
LOG_FUNC
- aSignalHandler.DrainPendingCommands();
+ // We've got a disconnect response, we're done. Any remaing stuff on the queue
+ // is redundant, so ditch it and close synchronously.
+ aSignalHandler.FlushAllQueues();
+
+ // If an error condition has been recorded forward the error
+ // to the SAP.
+ if(aSignalHandler.SignalHandlerErrorCode() != KErrNone)
+ {
+ Error(aSignalHandler, aSignalHandler.SignalHandlerErrorCode(), aSignalHandler.SignalHandlerErrorAction());
+ }
+ else
+ {
+ // This will delete the signal handler if the SAP has detached.
+ aSignalHandler.SetState(iFactory.GetState(CL2CAPSignalStateFactory::EClosed));
+ aSignalHandler.SignalHandlerDisconnectedCanClose();
+ }
+
}
// "Artificial" state events
@@ -1173,7 +1200,9 @@
void TL2CAPSigStateWaitDisconnect::Enter(CL2CapSAPSignalHandler& aSignalHandler) const
{
LOG_FUNC
- // Override park to allow the disconnect to continue.
+ // Only override park for disconnect. We need to be able
+ // to send the signalling, but we don't care if it takes
+ // ages. No point starting a sniff bun-fight.
aSignalHandler.OverrideParkMode();
// Cancel the configuration timer.
--- a/bluetooth/btstack/linkmgr/MBtHostControllerEventInternalNotifier.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/MBtHostControllerEventInternalNotifier.h Tue Sep 14 23:28:24 2010 +0300
@@ -67,6 +67,8 @@
virtual void RemoteName(THCIErrorCode /*aErr*/, const TBTDevAddr& /*aAddr*/, const TBTDeviceName8& /*aName*/) {};
virtual void SimplePairingComplete(const TBTDevAddr& /*aBDAddr*/, THCIErrorCode /*aErr*/) {};
+
+ virtual void EncryptionKeyRefreshComplete(THCIErrorCode /*aErr*/, THCIConnHandle /*aConnH*/) {};
};
#endif //_MBTHOSTCONTROLEREVENTINTERNALNOTIFIER_H_
--- a/bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp Tue Sep 14 23:28:24 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<TInt> optionBuf;
iBTProxySAP->SAPSetOption(KSolBtLMProxy, EBBRequestPreventAllLowPowerModes, optionBuf);
}
-void CRoleSwitcher::EnableLPM()
- {
- LOG_FUNC
- TPckgBuf<TInt> 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<const TBTBasebandEventNotification*>(aBuf->Ptr());
iBasebandEvent = *event;
iEventReceivedCallBack->CallBack();
}
-
-/*static*/ TInt CRoleSwitcher::EventReceivedCallBack(TAny* aRoleSwitcher)
- {
- LOG_STATIC_FUNC
- CRoleSwitcher* roleSwitcher = static_cast<CRoleSwitcher*>(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<CPhysicalLinkHelper*>(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<CPhysicalLinkHelper*>(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);
- }
+
+
+
+
+
--- a/bluetooth/btstack/linkmgr/PhysicalLinkHelper.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/PhysicalLinkHelper.h Tue Sep 14 23:28:24 2010 +0300
@@ -22,28 +22,25 @@
#include "linkutil.h"
#include <bluetooth/hci/hciutil.h>
-// 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;
-
-NONSHARABLE_CLASS(CRoleSwitcher) : public CTimer, public MSocketNotify
+// 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
{
- friend class TRoleSwitcherState;
- friend class TRSStateDisablingLPM;
- friend class TRSStateDisablingEncryption;
- friend class TRSStateChangingRole;
- friend class TRSStateChangingRoleWithEPR;
- friend class TRSStateEnablingEncryption;
+public:
+ TNotifyEvent(TBTPhysicalLinkStateNotifier aSingleEvent) : iEvent(aSingleEvent) {};
+ TNotifyEvent(TBTPhysicalLinkStateNotifierCombinations aComboEvent) : iEvent(aComboEvent) {};
-public:
+ TInt NotifyEvent() const {return iEvent;};
+private:
+ TInt iEvent;
+ };
- static CRoleSwitcher* NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole);
- ~CRoleSwitcher();
+
+NONSHARABLE_CLASS(CPhysicalLinkHelper) : public CBase, public MSocketNotify
+ {
+public:
+ ~CPhysicalLinkHelper();
// From MSocketNotify
void NewData(TUint aCount);
@@ -61,196 +58,50 @@
void NoBearer(const TDesC8& /*aConnectionInf*/) {};
void Bearer(const TDesC8& /*aConnectionInf*/) {};
- void Start();
- void Finish();
+ virtual void StartHelper() = 0;
+
inline const TBTDevAddr& BDAddr() const;
- inline TBTBasebandRole RequestedRole() const;
- inline TBool IsEncryptionDisabledForRoleSwitch() const;
- TBool IsEPRSupported() const;
- void LogRoleSwitchSuccessful() const;
- TSglQueLink iQLink;
-private:
- CRoleSwitcher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole);
- void ConstructL();
+protected:
+ CPhysicalLinkHelper(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink);
+ void BaseConstructL();
void DisableLPM();
- void DisableEncryption();
- void ChangeRole();
- void EnableEncryption();
- void EnableLPM();
- void CancelIoctl();
- void SaveEncryption();
- // CTimer
- void RunL();
- TInt RunError(TInt aError);
+ void QueueTimer(TTimeIntervalMicroSeconds32 aTimerVal);
+ void RemoveTimer();
+ void NotifyBasebandEvent(TNotifyEvent aEvent);
+ void CancelNotify();
- 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,
- };
+ TBool IsEPRSupported() const;
- TRoleSwitcherState& GetState(TRoleSwitcherStates aState);
- TInt StateIndex(const TRoleSwitcherState* aState) const;
+ virtual void TimerExpired() = 0;
+ virtual void HandleError(TInt aError) = 0;
+ virtual void EventReceived(TBTBasebandEventNotification& aEvent) = 0;
private:
- CRoleSwitcherStateFactory();
- void ConstructL();
- TFixedArray<TRoleSwitcherState*, ERoleSwitcherMaxState> iStates;
+ static TInt EventReceivedCallBack(TAny* aThis);
+ void DoEventReceivedCallBack();
+
+ static TInt TimerExpiredCallBack(TAny* aThis);
+ void DoTimerExpiredCallBack();
+
+protected:
+ CPhysicalLinksManager& iLinkMgr;
+ CPhysicalLink& iLink;
+
+private:
+ // Async Callback to notify baseband event received.
+ CAsyncCallBack* iEventReceivedCallBack;
+ TBTBasebandEventNotification iBasebandEvent;
+ CBTProxySAP* iBTProxySAP;
+
+ TDeltaTimerEntry iTimerEntry;
};
-
-
-//--------------------------------------------------
-// STATES, base
-//--------------------------------------------------
-
-NONSHARABLE_CLASS(TRoleSwitcherState)
- {
-public:
- TRoleSwitcherState(CRoleSwitcherStateFactory& aFactory);
-
- 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:
- 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;
- };
-
-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
+inline const TBTDevAddr& CPhysicalLinkHelper::BDAddr() const
{
return iLink.BDAddr();
}
-inline TBTBasebandRole CRoleSwitcher::RequestedRole() const
- {
- return iRole;
- }
-
-inline TBool CRoleSwitcher::IsEncryptionDisabledForRoleSwitch() const
- {
- return iIsEncryptionDisabledForRoleSwitch;
- }
-
#endif //PHYSICALLINKHELPER_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/encryptionkeyrefreshhelper.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -0,0 +1,311 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <bluetooth/logger.h>
+
+#include "encryptionkeyrefreshhelper.h"
+#include "hcifacade.h"
+#include "linkmgr.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
+#endif
+
+CEncryptionKeyRefresher::CEncryptionKeyRefresher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink)
+ : CPhysicalLinkHelper(aLinkMgr, aLink)
+ {
+ LOG_FUNC
+ }
+
+CEncryptionKeyRefresher* CEncryptionKeyRefresher::NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink)
+ {
+ LOG_STATIC_FUNC
+ CEncryptionKeyRefresher* self = new(ELeave) CEncryptionKeyRefresher(aLinkMgr, aLink);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CEncryptionKeyRefresher::ConstructL()
+ {
+ LOG_FUNC
+
+ BaseConstructL();
+
+ iStateFactory = CEncryptionKeyRefresherStateFactory::NewL();
+ iState = &(iStateFactory->GetState(CEncryptionKeyRefresherStateFactory::EIdle));
+ }
+
+CEncryptionKeyRefresher::~CEncryptionKeyRefresher()
+ {
+ LOG_FUNC
+ }
+
+void CEncryptionKeyRefresher::EncryptionKeyRefreshComplete(TInt aError)
+ {
+ LOG_FUNC
+ iState->EncryptionKeyRefreshComplete(*this, aError);
+ }
+
+void CEncryptionKeyRefresher::TimerExpired()
+ {
+ LOG_FUNC
+ iState->TimerExpired(*this);
+ }
+
+void CEncryptionKeyRefresher::HandleError( TInt aError)
+ {
+ LOG_FUNC
+ iState->Error(*this, aError);
+ }
+
+void CEncryptionKeyRefresher::StartHelper()
+ {
+ LOG_FUNC
+ iState->Start(*this);
+ }
+
+void CEncryptionKeyRefresher::EventReceived(TBTBasebandEventNotification& aEvent)
+ {
+ LOG_FUNC
+ iState->EventReceived(*this, aEvent);
+ }
+
+
+//----------------------------------------------------------------------------------
+// STATE FACTORY
+//----------------------------------------------------------------------------------
+
+CEncryptionKeyRefresherStateFactory* CEncryptionKeyRefresherStateFactory::NewL()
+ {
+ LOG_STATIC_FUNC
+ CEncryptionKeyRefresherStateFactory* ret=new (ELeave) CEncryptionKeyRefresherStateFactory();
+ CleanupStack::PushL(ret);
+ ret->ConstructL();
+ CleanupStack::Pop(ret);
+ return ret;
+ }
+
+void CEncryptionKeyRefresherStateFactory::ConstructL()
+ {
+ LOG_FUNC
+ iStates[EIdle] =new (ELeave) TEkrStateIdle(*this);
+ iStates[EDisablingLPM] =new (ELeave) TEkrStateDisablingLPM(*this);
+ iStates[ERefreshingKey] =new (ELeave) TEkrStateRefreshingKey(*this);
+ }
+
+CEncryptionKeyRefresherStateFactory::CEncryptionKeyRefresherStateFactory()
+ {
+ LOG_FUNC
+ iStates.DeleteAll();
+ }
+
+const TEncryptionKeyRefresherState& CEncryptionKeyRefresherStateFactory::GetState(CEncryptionKeyRefresherStateFactory::TEncryptionKeyRefresherStates aState) const
+ {
+ LOG_FUNC
+ __ASSERT_DEBUG(iStates[aState], Panic(EEncryptionKeyRefresherInvalidState));
+ return *iStates[aState];
+ }
+
+TInt CEncryptionKeyRefresherStateFactory::StateIndex(const TEncryptionKeyRefresherState* aState) const
+ {
+ LOG_FUNC
+ TInt state;
+ for (state = 0; state < EEncryptionKeyRefresherMaxState; state++)
+ {
+ if (iStates[state] == aState)
+ {
+ return state;
+ }
+ }
+
+ return KUnknownState;
+ }
+
+
+//----------------------------------------------------------------------------------
+// STATES
+//----------------------------------------------------------------------------------
+
+TEncryptionKeyRefresherState::TEncryptionKeyRefresherState(CEncryptionKeyRefresherStateFactory& aFactory)
+: iFactory(aFactory)
+ {
+ LOG_FUNC
+ }
+
+void TEncryptionKeyRefresherState::PanicInState(TLinkPanic aPanic) const
+ {
+ LOG_FUNC
+ Panic(aPanic, iFactory.StateIndex(this));
+ }
+
+void TEncryptionKeyRefresherState::ChangeState(CEncryptionKeyRefresher& aContext, CEncryptionKeyRefresherStateFactory::TEncryptionKeyRefresherStates aState) const
+ {
+ LOG_FUNC
+
+ aContext.iState->Exit(aContext);
+
+#ifdef __FLOG_ACTIVE
+ const TEncryptionKeyRefresherState* state=&iFactory.GetState(aState);
+ LOG2(_L("EncryptionKeyRefresher: State %S -> %S"), &aContext.iState->iName, &state->iName);
+#endif //__FLOG_ACTIVE
+ aContext.iState=&iFactory.GetState(aState);
+
+ aContext.iState->Enter(aContext);
+ }
+
+void TEncryptionKeyRefresherState::Enter(CEncryptionKeyRefresher& /*aContext*/) const
+ {
+ LOG_FUNC
+ // do nothing
+ }
+
+void TEncryptionKeyRefresherState::Exit(CEncryptionKeyRefresher& /*aContext*/) const
+ {
+ LOG_FUNC
+ // do nothing
+ }
+
+void TEncryptionKeyRefresherState::Start(CEncryptionKeyRefresher& /*aContext*/) const
+ {
+ LOG_FUNC
+ PanicInState(EEncryptionKeyRefresherStateMachineInvalidEvent);
+ }
+
+void TEncryptionKeyRefresherState::Error(CEncryptionKeyRefresher& aContext, TInt /*aErr*/) const
+ {
+ LOG_FUNC
+ aContext.CancelNotify();
+ aContext.RemoveTimer();
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
+ }
+
+void TEncryptionKeyRefresherState::EventReceived(CEncryptionKeyRefresher& /*aContext*/, TBTBasebandEventNotification& /*aEvent*/) const
+ {
+ LOG_FUNC
+ // do nothing
+ }
+
+void TEncryptionKeyRefresherState::TimerExpired(CEncryptionKeyRefresher& aContext) const
+ {
+ LOG_FUNC
+ aContext.CancelNotify();
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
+ }
+
+void TEncryptionKeyRefresherState::EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& /*aContext*/, TInt /*aError*/) const
+ {
+ LOG_FUNC
+ // do nothing
+ }
+
+//----------------------------------------------------------------------------------
+
+TEkrStateIdle::TEkrStateIdle(CEncryptionKeyRefresherStateFactory& aFactory)
+: TEncryptionKeyRefresherState(aFactory)
+ {
+ LOG_FUNC
+ STATENAME("TEkrStateIdle");
+ }
+
+void TEkrStateIdle::Start(CEncryptionKeyRefresher& aContext) const
+ {
+ LOG_FUNC
+ aContext.QueueTimer(KTimeoutEncryptionKeyRefresh); // watchdog timer
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EDisablingLPM);
+ }
+
+void TEkrStateIdle::Enter(CEncryptionKeyRefresher& aContext) const
+ {
+ LOG_FUNC
+ // async call to delete the helper
+ aContext.iLink.AsyncDeleteKeyRefresher();
+ }
+
+//----------------------------------------------------------------------------------
+
+TEkrStateDisablingLPM::TEkrStateDisablingLPM(CEncryptionKeyRefresherStateFactory& aFactory)
+: TEncryptionKeyRefresherState(aFactory)
+ {
+ LOG_FUNC
+ STATENAME("TEkrStateDisablingLPM");
+ }
+
+void TEkrStateDisablingLPM::Enter(CEncryptionKeyRefresher& aContext) const
+ {
+ LOG_FUNC
+
+ if (aContext.iLink.LinkMode() == EActiveMode)
+ {
+ // Skip straight on to refresh the key
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::ERefreshingKey);
+ }
+ else
+ {
+ aContext.NotifyBasebandEvent(ENotifyActiveMode);
+ }
+
+ // DisableLPM even if link is active to prevent possible LPM requests during key refresh
+ aContext.DisableLPM();
+ }
+
+void TEkrStateDisablingLPM::EventReceived(CEncryptionKeyRefresher& aContext, TBTBasebandEventNotification& aEvent) const
+ {
+ LOG_FUNC
+ if (aEvent.EventType()==ENotifyActiveMode && aEvent.ErrorCode()==KErrNone)
+ {
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::ERefreshingKey);
+ }
+ else
+ {
+ LOG(_L("CEncryptionKeyRefresher failed in DisableLPM"));
+ // If we can't put ourselves into active mode then don't bother with
+ // refresh, it'll probably cause more problems than it would solve
+ // we can quit SM, don't need to rewind
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
+ }
+ }
+
+//----------------------------------------------------------------------------------
+TEkrStateRefreshingKey::TEkrStateRefreshingKey(CEncryptionKeyRefresherStateFactory& aFactory)
+: TEncryptionKeyRefresherState(aFactory)
+ {
+ LOG_FUNC
+ STATENAME("TEkrStateRefreshingKey");
+ }
+
+void TEkrStateRefreshingKey::Enter(CEncryptionKeyRefresher& aContext) const
+ {
+ LOG_FUNC
+
+ TRAPD(err, aContext.iLinkMgr.HCIFacade().RefreshEncryptionKeyL(aContext.iLink.Handle()));
+
+ if(err)
+ {
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
+ }
+ }
+
+void TEkrStateRefreshingKey::EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& aContext, TInt __DEBUG_ONLY(aError)) const
+ {
+ LOG_FUNC
+ LOG1(_L("EncryptionKeyRefresh completed with error %d"), aError);
+
+ // Don't really care what the error is, this is just a best effort service
+ // anyway
+ ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/encryptionkeyrefreshhelper.h Tue Sep 14 23:28:24 2010 +0300
@@ -0,0 +1,169 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef ENCRYPTIONKEYREFRESHHELPER_H
+#define ENCRYPTIONKEYREFRESHHELPER_H
+
+
+#include <bt_sock.h>
+#include <bluetooth/hci/hciutil.h>
+
+#include "debug.h"
+#include "linkutil.h"
+#include "physicallinkhelper.h"
+#include "physicallinks.h"
+
+// watchdog
+const TUint KTimeoutEncryptionKeyRefresh = 3000000; // 3 s;
+
+class TEncryptionKeyRefresherState;
+class CEncryptionKeyRefresherStateFactory;
+NONSHARABLE_CLASS(CEncryptionKeyRefresher) : public CPhysicalLinkHelper
+ {
+ friend class TEncryptionKeyRefresherState;
+ friend class TEkrStateIdle;
+ friend class TEkrStateDisablingLPM;
+ friend class TEkrStateRefreshingKey;
+
+public:
+ static CEncryptionKeyRefresher* NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink);
+ ~CEncryptionKeyRefresher();
+
+ virtual void StartHelper();
+
+ void EncryptionKeyRefreshComplete(TInt aError);
+
+private:
+ CEncryptionKeyRefresher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink);
+ void ConstructL();
+
+ virtual void TimerExpired();
+ virtual void HandleError(TInt aError);
+ virtual void EventReceived(TBTBasebandEventNotification& aEvent);
+
+private:
+ CEncryptionKeyRefresherStateFactory* iStateFactory;
+ const TEncryptionKeyRefresherState* iState;
+ };
+
+//--------------------------------------------------
+// STATE FACTORY
+//--------------------------------------------------
+
+/**
+ Factory for the EncryptionKeyRefresher states
+
+ The states are flyweight classes
+**/
+NONSHARABLE_CLASS(CEncryptionKeyRefresherStateFactory) : public CBase
+ {
+public:
+ static CEncryptionKeyRefresherStateFactory* NewL();
+
+ enum TEncryptionKeyRefresherStates
+ {
+ EIdle,
+ EDisablingLPM,
+ ERefreshingKey,
+ // Note that we don't need a state to enable LPM again
+ // as this will happen implicitly when we close our
+ // proxy SAP.
+ // *** keep next one last ***
+ EEncryptionKeyRefresherMaxState,
+ };
+
+ const TEncryptionKeyRefresherState& GetState(TEncryptionKeyRefresherStates aState) const;
+ TInt StateIndex(const TEncryptionKeyRefresherState* aState) const;
+
+private:
+ CEncryptionKeyRefresherStateFactory();
+ void ConstructL();
+ TFixedArray<TEncryptionKeyRefresherState*, EEncryptionKeyRefresherMaxState> iStates;
+ };
+
+
+
+//--------------------------------------------------
+// STATES, base
+//--------------------------------------------------
+
+NONSHARABLE_CLASS(TEncryptionKeyRefresherState)
+ {
+public:
+ TEncryptionKeyRefresherState(CEncryptionKeyRefresherStateFactory& aFactory);
+
+ virtual void Enter(CEncryptionKeyRefresher& aContext) const;
+ virtual void Exit(CEncryptionKeyRefresher& aContext) const;
+
+ virtual void Start(CEncryptionKeyRefresher& aContext) const;
+ virtual void EventReceived(CEncryptionKeyRefresher& aContext, TBTBasebandEventNotification& aEvent) const;
+ virtual void Error(CEncryptionKeyRefresher& aContext, TInt aErr) const;
+ virtual void TimerExpired(CEncryptionKeyRefresher& aContext) const;
+ virtual void EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& aContext, TInt aError) const;
+
+protected:
+ // Exits old state, sets the new state, and enters it.
+ void ChangeState(CEncryptionKeyRefresher& aContext, CEncryptionKeyRefresherStateFactory::TEncryptionKeyRefresherStates aState) const;
+ void PanicInState(TLinkPanic aPanic) const;
+
+protected:
+ CEncryptionKeyRefresherStateFactory& iFactory;
+#ifdef __FLOG_ACTIVE
+ TBuf<48> iName;
+#endif
+ };
+
+
+//--------------------------------------------------
+// STATES
+//--------------------------------------------------
+
+NONSHARABLE_CLASS(TEkrStateIdle) : public TEncryptionKeyRefresherState
+ {
+public:
+ TEkrStateIdle(CEncryptionKeyRefresherStateFactory& aFactory);
+
+ virtual void Enter(CEncryptionKeyRefresher& aContext) const;
+ virtual void Start(CEncryptionKeyRefresher& aContext) const;
+ };
+
+
+NONSHARABLE_CLASS(TEkrStateDisablingLPM) : public TEncryptionKeyRefresherState
+ {
+public:
+ TEkrStateDisablingLPM(CEncryptionKeyRefresherStateFactory& aFactory);
+
+ virtual void Enter(CEncryptionKeyRefresher& aContext) const;
+ virtual void EventReceived(CEncryptionKeyRefresher& aContext, TBTBasebandEventNotification& aEvent) const;
+ };
+
+NONSHARABLE_CLASS(TEkrStateRefreshingKey) : public TEncryptionKeyRefresherState
+ {
+public:
+ TEkrStateRefreshingKey(CEncryptionKeyRefresherStateFactory& aFactory);
+
+ virtual void Enter(CEncryptionKeyRefresher& aContext) const;
+ virtual void EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& aContext, TInt aError) const;
+ };
+
+
+#ifdef __FLOG_ACTIVE
+#define STATENAME(x) iName=_L(x)
+#else
+#define STATENAME(x)
+#endif
+
+
+#endif /* ENCRYPTIONKEYREFRESHHELPER_H */
--- a/bluetooth/btstack/linkmgr/hcifacade.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/hcifacade.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -175,19 +175,6 @@
iAFHTimer=CAFHTimer::NewL(*this);
- // Read low power mode override timeout from the configuration file
- _LIT(KLPMSection, "lowpowermodeconfiguration");
- _LIT(KLPMTag, "overridelpmtimeout_microseconds");
-
- TUint overrideLPMTimeout = 0;
- TRAP(err, overrideLPMTimeout = iHciUtil->GetValueFromFileL(KLPMSection, KLPMTag));
-
- if (err == KErrNone)
- {
- // LPM override timeout found, pass the value into link manager
- iLinkMgrProtocol.SetOverrideLPMTimeout(overrideLPMTimeout);
- }
-
iLastPowerState = EBTOn;
// used later to ensure that we have enough data to call SetEventMask
--- a/bluetooth/btstack/linkmgr/hcifacade.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/hcifacade.h Tue Sep 14 23:28:24 2010 +0300
@@ -310,6 +310,7 @@
void LinkKeyRequestEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
void LinkKeyNotificationEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
void MaxSlotsChangeEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
+ void EncryptionKeyRefreshCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
// Data event processing functions
void NumberOfCompletedPacketsEvent(THCIEventBase& aEvent);
--- a/bluetooth/btstack/linkmgr/hcifacade_events.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/hcifacade_events.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -80,6 +80,7 @@
#include <bluetooth/hci/vendordebugcompleteevent.h>
#include <bluetooth/hci/writesimplepairingmodecommand.h>
#include <bluetooth/hci/readlocalsupportedcommandscommand.h>
+#include <bluetooth/hci/encryptionkeyrefreshcompleteevent.h>
// Command Complete Events
@@ -1220,6 +1221,14 @@
iLinksMgr->MaxSlotsChange(maxSlotsChangeEvent.ConnectionHandle(), maxSlotsChangeEvent.LMPMaxSlots());
}
+void CHCIFacade::EncryptionKeyRefreshCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
+ {
+ LOG_FUNC
+ const TEncryptionKeyRefreshCompleteEvent& refreshCompleteEvent = TEncryptionKeyRefreshCompleteEvent::Cast(aEvent);
+
+ iLinksMgr->EncryptionKeyRefreshComplete(aEvent.ErrorCode(), refreshCompleteEvent.ConnectionHandle());
+ }
+
// ----------------------------------------------------------------------------
// Data event processing functions
// ----------------------------------------------------------------------------
@@ -1347,6 +1356,10 @@
case EVendorDebugEvent:
VendorDebugEvent(aEvent, aRelatedCommand);
break;
+
+ case EEncryptionKeyRefreshCompleteEvent:
+ EncryptionKeyRefreshCompleteEvent(aEvent, aRelatedCommand);
+ break;
// Inquiry based events.
// By default these should be caused by the inquiry manager and so be returned to it.
@@ -1382,7 +1395,6 @@
case EPageScanModeChangeEvent:
case EPageScanRepetitionModeChangeEvent:
case EUserPasskeyRequestEvent:
- case EEncryptionKeyRefreshCompleteEvent:
LOG1(_L("Warning!! Unhandled Command Event (event code:%d)"), aEvent.EventCode());
break;
--- a/bluetooth/btstack/linkmgr/linkmgr.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/linkmgr.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -800,12 +800,6 @@
}
}
-void CLinkMgrProtocol::SetOverrideLPMTimeout(TUint aOverrideLPMTimeout)
- {
- LOG_FUNC
- iOverrideLPMTimeout =aOverrideLPMTimeout;
- }
-
TInt CLinkMgrProtocol::StartProtocolListening()
{
LOG_FUNC
@@ -1365,9 +1359,6 @@
case EUndoOverridePark:
rerr = con->UndoOverridePark();
break;
- case EOverrideLPMWithTimeout:
- rerr = con->OverrideLPMWithTimeout(iOverrideLPMTimeout);
- break;
case EOverrideLPM:
rerr = con->OverrideLPM();
break;
--- a/bluetooth/btstack/linkmgr/linkmgr.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/linkmgr.h Tue Sep 14 23:28:24 2010 +0300
@@ -182,7 +182,6 @@
void SetLimitedDiscoverableIfChangedL(TBool aOn);
void SetLocalVersion(THCIErrorCode aErr, TBTDevHCIVersion aHCIVersion, TBTDevLMPVersion aLMPVersion);
- void SetOverrideLPMTimeout(TUint aOverrideLPMTimeout);
void SetLocalFeatures(THCIErrorCode aErr, const TBTFeatures& aMask);
void SetLocalCommands(THCIErrorCode aErr, const TBluetoothHciCommands& aMask);
void SetDeviceClassL(TUint32 aCod);
@@ -267,8 +266,6 @@
RPointerArray<CSubscriber> iSubscribers;
- TUint iOverrideLPMTimeout;
-
// protocol state objects
TBool iClosePending; // the protocol is closing
TDeltaTimerEntry iIdleTimerEntry;
--- a/bluetooth/btstack/linkmgr/linkutil.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/linkutil.h Tue Sep 14 23:28:24 2010 +0300
@@ -193,6 +193,8 @@
EBTACLSAPUnexpectedSecurityResult =252,
ELinkMgrFlowControlUnexpectedUpdate =253,
ELinkMgrFlowControlChangeOfMind =254,
+ EEncryptionKeyRefresherInvalidState =255,
+ EEncryptionKeyRefresherStateMachineInvalidEvent = 256,
};
/**
--- a/bluetooth/btstack/linkmgr/physicallinks.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -25,10 +25,11 @@
#include "linkconsts.h"
#include "hcifacade.h"
#include "hostresolver.h"
-#include "PhysicalLinkHelper.h"
+#include "roleswitchhelper.h"
#include "pairingscache.h"
#include "oobdata.h"
#include "pairingserver.h"
+#include "encryptionkeyrefreshhelper.h"
#include <bt_sock.h>
@@ -91,7 +92,6 @@
, iProxySAPs(_FOFF(CBTProxySAP, iQueueLink))
, iOverrideParkRequests(EFalse)
, iOverrideLPMRequests(EFalse)
- , iLPMOverrideTimerQueued(EFalse)
, iConnectionPacketTypeChanged(EFalse)
, iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController())
, iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController())
@@ -119,11 +119,6 @@
iACLLogicalLinks.Close();
RemoveIdleTimer();
- if (iLPMOverrideTimerQueued)
- {
- BTSocketTimer::Remove(iOverrideLPMTimerEntry);
- iLPMOverrideTimerQueued = EFalse;
- }
LOG(_L("sec\tClosing subscribers..."))
@@ -149,9 +144,11 @@
delete iPasskeyEntry;
delete iArbitrationDelay;
delete iRoleSwitchCompleteCallBack;
+ delete iKeyRefreshCompleteCallBack;
delete iEncryptionEnforcer;
DeleteRoleSwitcher();
+ DeleteKeyRefresher();
}
void CPhysicalLink::ConstructL()
@@ -164,9 +161,9 @@
TCallBack cb1(RoleSwitchCompleteCallBack, this);
iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority);
- TCallBack cb2(OverrideLPMTimeoutCallback, this);
- iOverrideLPMTimerEntry.Set(cb2);
-
+ TCallBack cb2(KeyRefreshCompleteCallBack, this);
+ iKeyRefreshCompleteCallBack = new (ELeave)CAsyncCallBack(cb2, EActiveHighPriority);
+
iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController());
}
@@ -237,9 +234,19 @@
}
else
{
- if (iAutoKeyRefreshQue.IsEmpty())
+ // Only refresh the key if no-one is preventing it and we aren't still
+ // refreshing the key from a previous request. Note that although
+ // the previous key refresh may actually have finished if the key
+ // refresher is waiting for async delete we have only just refreshed
+ // the key and there's no point doing it again.
+ if (iAutoKeyRefreshQue.IsEmpty() && !iKeyRefresher)
{
- TRAP_IGNORE(iLinksMan.HCIFacade().RefreshEncryptionKeyL(iHandle));
+ TRAPD(err, iKeyRefresher = CEncryptionKeyRefresher::NewL(iLinksMan, *this));
+ if(!err)
+ {
+ // Kick off the helper state machine
+ iKeyRefresher->StartHelper();
+ }
// If we can't refresh the encryption key, there's not much we can do
}
XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken();
@@ -1364,6 +1371,17 @@
nameChanger->Start(BDAddr(), aName);
}
+void CPhysicalLink::EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH)
+ {
+ LOG_FUNC
+ __CHECK_CONNECTION_HANDLE(aConnH);
+
+ if(iKeyRefresher)
+ {
+ iKeyRefresher->EncryptionKeyRefreshComplete(aErr);
+ }
+ }
+
void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult)
{
LOG_FUNC
@@ -2227,22 +2245,6 @@
iIdleTimerQueued = EFalse;
}
-void CPhysicalLink::QueueLPMOverrideTimer(TInt aTimeout)
-/**
- Queue LPM Override timer entry.
- When this timer expires, it'll call UndoLPMOverride.
-**/
- {
- LOG_FUNC
- __ASSERT_DEBUG(aTimeout!=0, Panic(EBTPhysicalLinksInvalidArgument));
- if (iLPMOverrideTimerQueued)
- {
- BTSocketTimer::Remove(iOverrideLPMTimerEntry);
- }
- BTSocketTimer::Queue(aTimeout, iOverrideLPMTimerEntry);
- iLPMOverrideTimerQueued = ETrue;
- }
-
void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent)
{
LOG_FUNC
@@ -2664,6 +2666,27 @@
iRoleSwitcher = NULL;
}
+void CPhysicalLink::AsyncDeleteKeyRefresher()
+ {
+ LOG_FUNC
+ iKeyRefreshCompleteCallBack->CallBack();
+ }
+
+/*static*/ TInt CPhysicalLink::KeyRefreshCompleteCallBack(TAny* aPhysicalLink)
+ {
+ LOG_STATIC_FUNC
+ CPhysicalLink* physicalLink = static_cast<CPhysicalLink*>(aPhysicalLink);
+ physicalLink->DeleteKeyRefresher();
+ return EFalse;
+ }
+
+void CPhysicalLink::DeleteKeyRefresher()
+ {
+ LOG_FUNC
+ delete iKeyRefresher;
+ iKeyRefresher = NULL;
+ }
+
TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const
/**
If link is encrypted, but role switcher temporarily disabled encryption, returns true.
@@ -2711,20 +2734,6 @@
return Arbitrate();
}
-TInt CPhysicalLink::OverrideLPMWithTimeout(TUint aTimeout)
- {
- LOG_FUNC
- if(aTimeout == 0)
- {
- return KErrNone; //facility not wanted
- }
-
- TInt rerr = OverrideLPM();
- QueueLPMOverrideTimer(aTimeout);
-
- return rerr;
- }
-
TInt CPhysicalLink::OverrideLPM()
/**
A request has come in that requires us to ensure we are not using
@@ -2739,20 +2748,6 @@
return Arbitrate();
}
-/*static*/ TInt CPhysicalLink::OverrideLPMTimeoutCallback(TAny* aCPhysicalLink)
- {
- LOG_STATIC_FUNC
- CPhysicalLink* c = reinterpret_cast<CPhysicalLink*>(aCPhysicalLink);
- TInt err = c->UndoOverrideLPM();
- //we deliberately ignore this return value because we can't do anything to correct the error situation
- if (KErrNone != err)
- {
- LOG2(_L("Physical link: UndoOverrideLPM returned an error %d on the connection 0x%08x"), err, c);
- }
- c->iLPMOverrideTimerQueued = EFalse;
- return KErrNone;
- }
-
TInt CPhysicalLink::UndoOverrideLPM()
/**
A need to ensure we are not in LPM has gone.
--- a/bluetooth/btstack/linkmgr/physicallinks.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/physicallinks.h Tue Sep 14 23:28:24 2010 +0300
@@ -46,6 +46,7 @@
class CRoleSwitcher;
class CBTNumericComparator;
class CBTPasskeyEntry;
+class CEncryptionKeyRefresher;
enum TPhysicalLinkSimplePairingMode
{
@@ -342,7 +343,6 @@
TInt OverridePark();
TInt UndoOverridePark();
- TInt OverrideLPMWithTimeout(TUint aTimeout);
TInt OverrideLPM();
TInt UndoOverrideLPM();
inline TBool IsParked() const;
@@ -375,7 +375,8 @@
virtual void RoleChange(THCIErrorCode aErr, const TBTDevAddr& aAddr, TBTBasebandRole aRole);
virtual void ClockOffset(THCIErrorCode aErr, THCIConnHandle aConnH, TBasebandTime aClockOffset);
virtual void RemoteName(THCIErrorCode aErr, const TBTDevAddr& aAddr, const TBTDeviceName8& aName);
-
+ virtual void EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH);
+
void ConnectionComplete(TInt aResult, const TBTConnect& aConn);
TBool LinkKeyRequestPending();
@@ -412,6 +413,7 @@
TBTLinkMode LinkMode() const;
void AsyncDeleteRoleSwitcher();
+ void AsyncDeleteKeyRefresher();
inline const TLinkPolicy& LinkPolicy() const;
inline const TBTFeatures& RemoteFeatures() const;
@@ -485,7 +487,6 @@
void QueueIdleTimer(TInt aTime);
void RemoveIdleTimer();
- void QueueLPMOverrideTimer(TInt aTimeout);
void NotifyStateChange(TBTBasebandEventNotification & aEvent);
TBool IsPhysicalLinkIdle() const;
@@ -496,6 +497,9 @@
void DeleteRoleSwitcher();
static TInt RoleSwitchCompleteCallBack(TAny* CPhysicalLink);
TInt ManageEncryptionEnforcement(THCIEncryptModeFlag aEnable);
+
+ void DeleteKeyRefresher();
+ static TInt KeyRefreshCompleteCallBack(TAny* CPhysicalLink);
void HandlePrefetch();
void PINCodeRequestReply(const TBTDevAddr& aDevAddr,const TDesC8& aPin);
@@ -552,13 +556,11 @@
TSglQue<CBTProxySAP> iProxySAPs; // the proxies bound to us
TDeltaTimerEntry iIdleTimerEntry;
TBool iIdleTimerQueued;
- TDeltaTimerEntry iOverrideLPMTimerEntry;
TLinkPolicy iLinkPolicy;
TUint16 iPreviousRequestedModeMask;
TBool iOverrideParkRequests; //for maybe temporary unpark
TBool iOverrideLPMRequests; //for maybe temporary force active
- TBool iLPMOverrideTimerQueued;
TBool iConnectionPacketTypeChanged; //for triggering h/w
TBool iPreventLinkKeyUpdateReg; //for case e.g. user has called unpair when there is a paired logical channel
@@ -570,6 +572,8 @@
CArbitrationDelayTimer* iArbitrationDelay; //for lower power modes
CRoleSwitcher* iRoleSwitcher; //class handles role switch, prevents LPM, removes encryption
CAsyncCallBack* iRoleSwitchCompleteCallBack;// Async Callback to delete role swticher class.
+ CEncryptionKeyRefresher* iKeyRefresher; //class handles key refresh
+ CAsyncCallBack* iKeyRefreshCompleteCallBack;// Async Callback to delete key refresher class.
TLowPowModeCmdController iLowPowModeCtrl;
CPhysicalLinkMetrics* iPhysicalLinkMetrics;
--- a/bluetooth/btstack/linkmgr/physicallinksmanager.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/physicallinksmanager.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -23,7 +23,7 @@
#include "ProxySAP.h"
#include <bt_sock.h>
-#include "PhysicalLinkHelper.h"
+#include "roleswitchhelper.h"
#include "hostresolver.h"
#include <bluetooth/hci/writepagetimeoutcommand.h>
@@ -583,6 +583,13 @@
found->MaxSlotsChange(aConnH, aSlots);
}
+void CPhysicalLinksManager::EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH)
+ {
+ CPhysicalLink* found = FindPhysicalLink(aConnH);
+ RETURN_IF_NULL_CONNECTION(found);
+ found->EncryptionKeyRefreshComplete(aErr, aConnH);
+ }
+
void CPhysicalLinksManager::ModeChange(THCIErrorCode aErr, THCIConnHandle aConnH, TBTLinkMode aMode, TBasebandTime aInterval)
{
CPhysicalLink* found = FindPhysicalLink(aConnH);
@@ -996,7 +1003,7 @@
// this the only role request, it's safe to kick off the state machine
// first suspend host resolver
LinkManagerProtocol().InquiryMgr().Suspend();
- aRoleSwitcher.Start();
+ aRoleSwitcher.StartHelper();
}
}
@@ -1016,7 +1023,7 @@
if (startNextRoleSwitcher && !iRoleSwitchersQ.IsEmpty())
{
- iRoleSwitchersQ.First()->Start();
+ iRoleSwitchersQ.First()->StartHelper();
}
else
{
--- a/bluetooth/btstack/linkmgr/physicallinksmanager.h Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/linkmgr/physicallinksmanager.h Tue Sep 14 23:28:24 2010 +0300
@@ -204,6 +204,8 @@
virtual void ClockOffset(THCIErrorCode aErr, THCIConnHandle aConnH, TBasebandTime aClockOffset);
virtual void RemoteName(THCIErrorCode aErr, const TBTDevAddr& aAddr, const TBTDeviceName8& aName);
virtual void SimplePairingComplete(const TBTDevAddr& aBDAddr, THCIErrorCode aErr);
+ virtual void EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH);
+
// events from MBTPairingsCacheObserver
virtual void MbpcoDeferredDecisionResolved(TInt aError);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/roleswitchhelper.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -0,0 +1,518 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#include <bluetooth/logger.h>
+#include "roleswitchhelper.h"
+#include "physicallinksmanager.h"
+#include "AclDataQController.h"
+#include "ProxySAP.h"
+#include "linkmgr.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
+#endif
+
+CRoleSwitcher::CRoleSwitcher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole)
+ : CPhysicalLinkHelper(aLinkMgr, 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()
+ {
+ LOG_FUNC
+
+ BaseConstructL();
+
+ // add ourselves to the list in LinkMgr, LinkMgr will kick off the role change state machine
+ iLinkMgr.AddRoleSwitcher(*this);
+ iAddedToLinkMgr = ETrue;
+ }
+
+CRoleSwitcher::~CRoleSwitcher()
+ {
+ LOG_FUNC
+ if (iAddedToLinkMgr)
+ {
+ iLinkMgr.RemoveRoleSwitcher(*this);
+ }
+ }
+
+void CRoleSwitcher::TimerExpired()
+ {
+ LOG_FUNC
+
+ iState->TimerExpired(*this);
+ }
+
+void CRoleSwitcher::HandleError( TInt aError)
+ {
+ LOG_FUNC
+
+ iState->Error(*this, aError);
+ }
+
+void CRoleSwitcher::DisableEncryption()
+ {
+ LOG_FUNC
+ // data traffic suspended
+ iLinkMgr.LinkManagerProtocol().ACLController().SetParked(iLink.Handle(), ETrue);
+ NotifyBasebandEvent(ENotifyEncryptionChangeOff);
+ 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
+ NotifyBasebandEvent(ENotifyEncryptionChangeOn);
+ iLinkMgr.Encrypt(ETrue, iLink);
+ // data traffic is enabled in IoctlComplete
+ }
+
+void CRoleSwitcher::ChangeRole()
+ {
+ LOG_FUNC
+ NotifyBasebandEvent(ENotifyAnyRole);
+ iLinkMgr.ChangeRole(iRole, iLink);
+ }
+
+void CRoleSwitcher::StartHelper()
+ {
+ LOG_FUNC
+ iState->Start(*this);
+ }
+
+void CRoleSwitcher::SaveEncryption()
+ {
+ LOG_FUNC
+ iIsEncrypted = iLink.Encrypted();
+ }
+
+void CRoleSwitcher::LogRoleSwitchSuccessful(TBTBasebandEventNotification& aEvent) const
+ {
+ LOG_FUNC
+ TInt eventType;
+ eventType = (iRole == EMaster ? ENotifyMaster :ENotifySlave);
+
+ if (aEvent.EventType()==eventType && aEvent.ErrorCode()==KErrNone)
+ {
+ LOG(_L("CRoleSwitcher RoleSwitch OK"));
+ }
+ else
+ {
+ LOG(_L("CRoleSwitcher RoleSwitch failed"));
+ }
+ }
+
+void CRoleSwitcher::EventReceived(TBTBasebandEventNotification& aEvent)
+ {
+ LOG_FUNC
+ iState->EventReceived(*this, aEvent);
+ }
+
+
+//----------------------------------------------------------------------------------
+// STATE FACTORY
+//----------------------------------------------------------------------------------
+
+CRoleSwitcherStateFactory* CRoleSwitcherStateFactory::NewL()
+ {
+ 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);
+ }
+
+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.CancelNotify();
+ aContext.RemoveTimer();
+ ChangeState(aContext, CRoleSwitcherStateFactory::EIdle);
+ }
+
+void TRoleSwitcherState::EventReceived(CRoleSwitcher& /*aContext*/, TBTBasebandEventNotification& /*aEvent*/) 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.QueueTimer(KTimeoutRoleSwitch); // watchdog timer
+ ChangeState(aContext, CRoleSwitcherStateFactory::EDisablingLPM);
+ }
+
+void TRSStateIdle::Enter(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ // async call to delete the helper
+ aContext.iLink.AsyncDeleteRoleSwitcher();
+ }
+
+//----------------------------------------------------------------------------------
+
+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
+ {
+ aContext.NotifyBasebandEvent(ENotifyActiveMode);
+ aContext.DisableLPM();
+ }
+ }
+
+void TRSStateDisablingLPM::EventReceived(CRoleSwitcher& aContext, TBTBasebandEventNotification& aEvent) const
+ {
+ LOG_FUNC
+ if (aEvent.EventType()==ENotifyActiveMode && aEvent.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, TBTBasebandEventNotification& aEvent) const
+ {
+ LOG_FUNC
+ if (aEvent.EventType()==ENotifyEncryptionChangeOff && aEvent.ErrorCode()==KErrNone)
+ {
+ ChangeState(aContext, CRoleSwitcherStateFactory::EChangingRole);
+ }
+ else
+ {
+ LOG(_L("CRoleSwitcher RoleSwitch failed in DisableEncryption"));
+ // before quiting SM , try to enable LPM
+ ChangeState(aContext, CRoleSwitcherStateFactory::EIdle);
+ }
+ }
+
+void TRSStateDisablingEncryption::TimerExpired(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ aContext.CancelNotify();
+ 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, TBTBasebandEventNotification& __DEBUG_ONLY(aEvent)) const
+ {
+ LOG_FUNC
+ aContext.RemoveTimer(); // cancel watchdog timer
+
+ FTRACE(aContext.LogRoleSwitchSuccessful(aEvent));
+
+
+ ChangeState(aContext, CRoleSwitcherStateFactory::EEnablingEncryption);
+ }
+
+void TRSStateChangingRole::TimerExpired(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ aContext.CancelNotify();
+ ChangeState(aContext, CRoleSwitcherStateFactory::EEnablingEncryption);
+ }
+
+//----------------------------------------------------------------------------------
+TRSStateChangingRoleWithEPR::TRSStateChangingRoleWithEPR(CRoleSwitcherStateFactory& aFactory)
+: TRoleSwitcherState(aFactory)
+ {
+ LOG_FUNC
+ STATENAME("TRSStateChangingRoleWithEPR");
+ }
+
+void TRSStateChangingRoleWithEPR::Enter(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ aContext.ChangeRole();
+ }
+
+void TRSStateChangingRoleWithEPR::EventReceived(CRoleSwitcher& aContext, TBTBasebandEventNotification& __DEBUG_ONLY(aEvent)) const
+ {
+ LOG_FUNC
+ aContext.RemoveTimer(); // cancel watchdog timer
+
+ FTRACE(aContext.LogRoleSwitchSuccessful(aEvent));
+
+ ChangeState(aContext, CRoleSwitcherStateFactory::EIdle);
+ }
+
+void TRSStateChangingRoleWithEPR::TimerExpired(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ aContext.CancelNotify();
+ ChangeState(aContext, CRoleSwitcherStateFactory::EIdle);
+ }
+
+//----------------------------------------------------------------------------------
+TRSStateEnablingEncryption::TRSStateEnablingEncryption(CRoleSwitcherStateFactory& aFactory)
+: TRoleSwitcherState(aFactory)
+ {
+ LOG_FUNC
+ STATENAME("TRSStateEnablingEncryption");
+ }
+
+void TRSStateEnablingEncryption::Enter(CRoleSwitcher& aContext) const
+ {
+ LOG_FUNC
+ if (aContext.iIsEncrypted)
+ {
+ aContext.QueueTimer(KTimeoutOneCommand);
+ aContext.EnableEncryption();
+ }
+ else
+ {
+ 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);
+ }
+ }
+
+void TRSStateEnablingEncryption::EventReceived(CRoleSwitcher& aContext, TBTBasebandEventNotification& aEvent) const
+ {
+ LOG_FUNC
+ aContext.RemoveTimer(); // watchdog timer
+ if (aEvent.EventType()==ENotifyEncryptionChangeOn && aEvent.ErrorCode()==KErrNone)
+ {
+ 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.CancelNotify();
+ if (aContext.iLink.Terminate(ERemoteUserEndedConnection) != KErrNone)
+ {
+ LOG(_L("CRoleSwitcher OOM"));
+ }
+ ChangeState(aContext, CRoleSwitcherStateFactory::EIdle);
+ }
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/roleswitchhelper.h Tue Sep 14 23:28:24 2010 +0300
@@ -0,0 +1,230 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef ROLESWITCHHELPER_H
+#define ROLESWITCHHELPER_H
+
+#include <bt_sock.h>
+#include <bluetooth/hci/hciutil.h>
+
+#include "debug.h"
+#include "linkutil.h"
+#include "physicallinkhelper.h"
+#include "physicallinks.h"
+
+// 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;
+
+NONSHARABLE_CLASS(CRoleSwitcher) : public CPhysicalLinkHelper
+ {
+ friend class TRoleSwitcherState;
+ friend class TRSStateIdle;
+ friend class TRSStateDisablingLPM;
+ friend class TRSStateDisablingEncryption;
+ friend class TRSStateChangingRole;
+ friend class TRSStateChangingRoleWithEPR;
+ friend class TRSStateEnablingEncryption;
+
+public:
+ static CRoleSwitcher* NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole);
+ ~CRoleSwitcher();
+
+ virtual void StartHelper();
+
+ inline TBool IsEncryptionDisabledForRoleSwitch() const;
+ inline TBTBasebandRole RequestedRole() const;
+
+ TSglQueLink iQLink;
+
+private:
+ CRoleSwitcher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink, TBTBasebandRole aRole);
+ void ConstructL();
+
+ virtual void TimerExpired();
+ virtual void HandleError(TInt aError);
+ virtual void EventReceived(TBTBasebandEventNotification& aEvent);
+
+ void DisableEncryption();
+ void ChangeRole();
+ void EnableEncryption();
+ void SaveEncryption();
+
+ void LogRoleSwitchSuccessful(TBTBasebandEventNotification& aEvent) const;
+
+ TBool iIsEncrypted;
+ TBool iIsActive; // LinkMode
+ TBool iAddedToLinkMgr;
+ TBTBasebandRole iRole; // Requested role
+ 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,
+ // Note that we don't need a state to enable LPM again
+ // as this will happen implicitly when we close our
+ // proxy SAP.
+ // *** keep next one last ***
+ ERoleSwitcherMaxState,
+ };
+
+ TRoleSwitcherState& GetState(TRoleSwitcherStates aState);
+ TInt StateIndex(const TRoleSwitcherState* aState) const;
+
+private:
+ CRoleSwitcherStateFactory();
+ void ConstructL();
+ TFixedArray<TRoleSwitcherState*, ERoleSwitcherMaxState> iStates;
+ };
+
+
+
+//--------------------------------------------------
+// STATES, base
+//--------------------------------------------------
+
+NONSHARABLE_CLASS(TRoleSwitcherState)
+ {
+public:
+ TRoleSwitcherState(CRoleSwitcherStateFactory& aFactory);
+
+ virtual void Enter(CRoleSwitcher& aContext) const;
+ virtual void Exit(CRoleSwitcher& aContext) const;
+
+ virtual void Start(CRoleSwitcher& aContext) const;
+ virtual void EventReceived(CRoleSwitcher& aContext, TBTBasebandEventNotification& aEvent) 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:
+ 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, TBTBasebandEventNotification& aEvent) const;
+ };
+
+NONSHARABLE_CLASS(TRSStateDisablingEncryption) : public TRoleSwitcherState
+ {
+public:
+ TRSStateDisablingEncryption(CRoleSwitcherStateFactory& aFactory);
+
+ virtual void Enter(CRoleSwitcher& aContext) const;
+ virtual void EventReceived(CRoleSwitcher& aContext, TBTBasebandEventNotification& aEvent) 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, TBTBasebandEventNotification& aEvent) 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, TBTBasebandEventNotification& aEvent) 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, TBTBasebandEventNotification& aEvent) const;
+ virtual void TimerExpired(CRoleSwitcher& aContext) const;
+ };
+
+#ifdef __FLOG_ACTIVE
+#define STATENAME(x) iName=_L(x)
+#else
+#define STATENAME(x)
+#endif
+
+inline TBTBasebandRole CRoleSwitcher::RequestedRole() const
+ {
+ return iRole;
+ }
+
+inline TBool CRoleSwitcher::IsEncryptionDisabledForRoleSwitch() const
+ {
+ return iIsEncryptionDisabledForRoleSwitch;
+ }
+
+#endif /* ROLESWITCHHELPER_H */
--- a/bluetooth/btstack/rfcomm/rfcommstates.cpp Wed Sep 01 12:38:54 2010 +0100
+++ b/bluetooth/btstack/rfcomm/rfcommstates.cpp Tue Sep 14 23:28:24 2010 +0300
@@ -99,7 +99,6 @@
if(aType & MSocketNotify::EErrorFatal)
{
- aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverridePark, aSAP.iRemoteDev);
ChangeState(aSAP, CRfcommStateFactory::EError);
}
return aErr;
@@ -657,6 +656,16 @@
don't want to get any more notifications from the mux
**/
{
+ // Depending where we came from we may have applied either a
+ // park override or an all LPM override. We remove both these
+ // overrides because it's safe to remove an override that
+ // hasn't been applied.
+ // Note that although park is one of the LPMs the different
+ // levels of override are managed separately, so an
+ // UndoOverrideLPM does not remove an explicit park only
+ // override.
+ aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverridePark, aSAP.iRemoteDev);
+ aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverrideLPM, aSAP.iRemoteDev);
aSAP.DeregisterCodService(); // See if there is a Service to remove for CodMan
@@ -694,13 +703,23 @@
}
aSAP.iNewDataToNotify=0;
aSAP.iDataBuffer.Reset();
+
+ // Depending where we came from we may have applied either a
+ // park override or an all LPM override. We remove both these
+ // overrides because it's safe to remove an override that
+ // hasn't been applied.
+ // Note that although park is one of the LPMs the different
+ // levels of override are managed separately, so an
+ // UndoOverrideLPM does not remove an explicit park only
+ // override.
aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverridePark, aSAP.iRemoteDev);
+ aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverrideLPM, aSAP.iRemoteDev);
+
if(aSAP.iMux)
{
aSAP.iMux->DetachSAP(aSAP);
}
aSAP.DeregisterCodService(); // See if there is a Service to remove for CodMan
-
}
void TRfcommStateClosed::Error(CRfcommSAP& /*aSAP*/, TInt /*aErr*/,
@@ -731,7 +750,11 @@
}
aSAP.RegisterCodService(); // See if there is a Service set for CodMan
-
+
+ // Override LPM while we do some sigalling to ensure it can complete in
+ // a timely fashion.
+ aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EOverrideLPM, aSAP.iRemoteDev);
+
// First get a Mux.
ChangeState(aSAP, CRfcommStateFactory::EWaitForMux);
}
@@ -1313,7 +1336,7 @@
newSAP->iRemoteDev=aMux.RemoteBTAddr();
// Must come after registering the remote address with the new SAP because we will need
// the remote address to find a link in LinkMgrProtocol to override LPM on
- newSAP->iProtocol.ControlPlane().ModifyPhysicalLink(EOverrideLPMWithTimeout, newSAP->iRemoteDev);
+ newSAP->iProtocol.ControlPlane().ModifyPhysicalLink(EOverrideLPM, newSAP->iRemoteDev);
newSAP->iUserDefinedMTU=aSAP.iUserDefinedMTU; // We take our cues as
// regards max MTU from
// the listening SAP.
@@ -1738,7 +1761,17 @@
return;
}
+ // Depending where we came from we may have applied either a
+ // park override or an all LPM override. We remove both these
+ // overrides because it's safe to remove an override that
+ // hasn't been applied.
+ // Note that although park is one of the LPMs the different
+ // levels of override are managed separately, so an
+ // UndoOverrideLPM does not remove an explicit park only
+ // override.
aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverridePark, aSAP.iRemoteDev);
+ aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EUndoOverrideLPM, aSAP.iRemoteDev);
+
aSAP.iSocket->ConnectComplete();
aSAP.CTS(EFalse); // So that we block should anyone try to write
// anything through this SAP before we get MSC
@@ -1779,6 +1812,9 @@
Shutdown the open channel gracefully
**/
{
+ // Only override park for disconnect. We need to be able
+ // to send the signalling, but we don't care if it takes
+ // ages. No point starting a sniff bun-fight.
aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EOverridePark, aSAP.iRemoteDev);
aSAP.iClosePending=ETrue;
ChangeState(aSAP, CRfcommStateFactory::EDisconnect);
@@ -1796,6 +1832,10 @@
// the queued DISC frame does not get deleted when the SAP gets
// removed from the muxer
__ASSERT_DEBUG(aSAP.iMux!=NULL,PanicInState(ERfcommNullMux));
+
+ // Only override park for disconnect. We need to be able
+ // to send the signalling, but we don't care if it takes
+ // ages. No point starting a sniff bun-fight.
aSAP.iProtocol.ControlPlane().ModifyPhysicalLink(EOverridePark, aSAP.iRemoteDev);
aSAP.iMux->SendDISC(aSAP.DLCI()); // Disassociated from the SAP
ChangeState(aSAP, CRfcommStateFactory::EClosed);
--- a/bthci/hciextensioninterface/tsrc/tproxycorehci/group/bluetooth_stack.ini Wed Sep 01 12:38:54 2010 +0100
+++ b/bthci/hciextensioninterface/tsrc/tproxycorehci/group/bluetooth_stack.ini Tue Sep 14 23:28:24 2010 +0300
@@ -18,6 +18,3 @@
[CoreHci]
EcomUid= 0x10286A7B
-
-[lowpowermodeconfiguration]
-overridelpmtimeout_microseconds= 0
\ No newline at end of file