Revision: 201031 RCL_3 PDK_3.0.3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 23:28:24 +0300
branchRCL_3
changeset 25 99439b07e980
parent 24 e9b924a62a66
Revision: 201031 Kit: 201035
bluetooth/btextnotifiers/inc/BTExtNotifiers.h
bluetooth/btstack/bluetooth_stack.ini
bluetooth/btstack/common/bt.h
bluetooth/btstack/common/bt_v2.mmp
bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp
bluetooth/btstack/l2cap/l2capSAPSignalHandler.h
bluetooth/btstack/l2cap/l2capSigStates.cpp
bluetooth/btstack/linkmgr/MBtHostControllerEventInternalNotifier.h
bluetooth/btstack/linkmgr/PhysicalLinkHelper.cpp
bluetooth/btstack/linkmgr/PhysicalLinkHelper.h
bluetooth/btstack/linkmgr/encryptionkeyrefreshhelper.cpp
bluetooth/btstack/linkmgr/encryptionkeyrefreshhelper.h
bluetooth/btstack/linkmgr/hcifacade.cpp
bluetooth/btstack/linkmgr/hcifacade.h
bluetooth/btstack/linkmgr/hcifacade_events.cpp
bluetooth/btstack/linkmgr/linkmgr.cpp
bluetooth/btstack/linkmgr/linkmgr.h
bluetooth/btstack/linkmgr/linkutil.h
bluetooth/btstack/linkmgr/physicallinks.cpp
bluetooth/btstack/linkmgr/physicallinks.h
bluetooth/btstack/linkmgr/physicallinksmanager.cpp
bluetooth/btstack/linkmgr/physicallinksmanager.h
bluetooth/btstack/linkmgr/roleswitchhelper.cpp
bluetooth/btstack/linkmgr/roleswitchhelper.h
bluetooth/btstack/rfcomm/rfcommstates.cpp
bthci/hciextensioninterface/tsrc/tproxycorehci/group/bluetooth_stack.ini
--- 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