Revision: 201018 RCL_3 PDK_3.0.0
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 25 May 2010 13:54:55 +0300
branchRCL_3
changeset 17 32ba20339036
parent 16 9f17f914e828
child 18 1f10b9300be6
Revision: 201018 Kit: 2010121
bluetooth/btstack/eirman/eirmanager.cpp
bluetooth/btstack/eirman/eirmanager.h
bluetooth/btstack/eirman/eirmanserver.cpp
bluetooth/btstack/eirman/eirmanserver.h
bluetooth/btstack/eirman/eirmansession.cpp
bluetooth/btstack/eirman/eirmansession.h
bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp
bluetooth/btstack/l2cap/l2capSAPSignalHandler.h
bluetooth/btstack/l2cap/l2capSigStates.cpp
bluetooth/btstack/l2cap/l2capSigStates.h
bluetooth/btstack/l2cap/l2util.h
bluetooth/btstack/linkmgr/ACLSAP.cpp
bluetooth/btstack/linkmgr/ProxySAP.cpp
bluetooth/btstack/linkmgr/ProxySAP.h
bluetooth/btstack/linkmgr/eirpublisherlocalname.cpp
bluetooth/btstack/linkmgr/eirpublisherlocalname.h
bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.cpp
bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.h
bluetooth/btstack/linkmgr/linkmgr.cpp
bluetooth/btstack/linkmgr/linkmgr.h
bluetooth/btstack/linkmgr/physicallinks.cpp
bluetooth/btstack/linkmgr/physicallinks.h
bluetooth/btstack/rfcomm/rfcommmuxchannel.cpp
bluetooth/btstack/rfcomm/rfcommmuxchannel.h
bluetooth/btstack/rfcomm/rfcommmuxchannel.inl
bluetooth/btstack/rfcomm/rfcommmuxer.cpp
bluetoothmgmt/bluetoothclientlib/inc/bt_sock.h
bt_plat/bluetooth_audio_adaptation_api/inc/btaudiostreaminputbase.h
--- a/bluetooth/btstack/eirman/eirmanager.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanager.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -169,7 +169,7 @@
 		}
 	}
 
-TInt CEirManager::SetData(TEirTag aTag, TDesC8& aData, TEirDataMode aEirDataMode)
+TInt CEirManager::SetData(TEirTag aTag, const TDesC8& aData, TEirDataMode aEirDataMode)
 	{
 	LOG_FUNC
 	LOG1(_L("CEirManager::SetData tag = %d"), aTag);
--- a/bluetooth/btstack/eirman/eirmanager.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanager.h	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -89,7 +89,7 @@
 
 	TInt RegisterTag(TEirTag aTag, MEirManagerNotifiee& aNotifiee);
 	void DeregisterTag(TEirTag aTag);
-	TInt SetData(TEirTag aTag, TDesC8& aData, TEirDataMode aEirDataMode);
+	TInt SetData(TEirTag aTag, const TDesC8& aData, TEirDataMode aEirDataMode);
 	
 	// from MHCICommandQueueClient
 	void MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
--- a/bluetooth/btstack/eirman/eirmanserver.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanserver.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -58,9 +58,11 @@
 	: CPolicyServer(CActive::EPriorityStandard, KEirManServerPolicy)
 	, iCommandQueue(aCommandQueue)
 	, iLinkMgrProtocol(aLinkMgrProtocol)
-	, iSessionCount(0)
+	, iInternalSessionCount(0)
+	, iExternalSessionCount(0)
 	, iIsFeaturesReady(EFalse)
 	, iIsEirSupported(EFalse)
+	, iSessions(_FOFF(CEirManSession, iLink))
 	{
 	LOG_FUNC
 	}
@@ -93,28 +95,63 @@
 	
 	CEirManServer* ncThis = const_cast<CEirManServer*>(this);
 	
-	CEirManSession* sess = CEirManSession::NewL(*ncThis);
+	CEirManExternalSession* sess = CEirManExternalSession::NewL(*ncThis);
 	LOG1(_L("\tsess = 0x%08x"), sess);
 	return sess;
 	}
 
-void CEirManServer::AddSession()
+CEirManInternalSession* CEirManServer::NewInternalSessionL(MEirInternalSessionNotifier& aParent)
+	{
+	LOG_FUNC
+	// Server will refuse to create any more session if we have found out eir isn't supported.
+	if(iIsFeaturesReady && !iIsEirSupported)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	CEirManInternalSession* sess = CEirManInternalSession::NewL(*this, aParent);
+	return sess;
+	}
+
+void CEirManServer::AddSession(CEirManSession& aSession, TBool aInternalSession)
 	{
 	LOG_FUNC
-	if(iSessionCount++ == 0)
+	
+	iSessions.AddLast(aSession);
+	
+	if (aInternalSession)
 		{
-		// While we have clients we need to make sure that the protocol remains alive.
-		iLinkMgrProtocol.LocalOpen();
+		if(iInternalSessionCount++ == 0)
+			{
+			// While we have clients we need to make sure that the protocol remains alive.
+			iLinkMgrProtocol.LocalOpen();
+			}
+		}
+	else
+		{
+		if(iExternalSessionCount++ == 0)
+			{
+			// While we have clients we need to make sure that the protocol remains alive.
+			iLinkMgrProtocol.Open();
+			}
 		}
 	}
 
-void CEirManServer::DropSession()
+void CEirManServer::DropSession(TBool aInternalSession)
 	{
 	LOG_FUNC
-	if(--iSessionCount == 0)
+	if (aInternalSession)
 		{
-		// There are no long 
-		iLinkMgrProtocol.LocalClose();
+		if(--iInternalSessionCount == 0)
+			{
+			iLinkMgrProtocol.LocalClose();
+			}
+		}
+	else
+		{
+		if(--iExternalSessionCount == 0)
+			{
+			iLinkMgrProtocol.Close();
+			}		
 		}
 	}
 
@@ -126,8 +163,10 @@
 		TRAPD(err, iEirManager = CEirManager::NewL(iCommandQueue, iLinkMgrProtocol));
 		iIsFeaturesReady = ETrue;
 		
-		iSessionIter.SetToFirst();
-		CSession2* sessionPtr;
+		TDblQueIter<CEirManSession> sessionIter(iSessions);
+		
+		sessionIter.SetToFirst();
+		CEirManSession* sessionPtr;
 		if(iLinkMgrProtocol.IsExtendedInquiryResponseSupportedLocally() && err == KErrNone)
 			{
 			iIsEirSupported = ETrue;
@@ -137,10 +176,9 @@
 			err = ((err != KErrNone) ? KErrNoMemory : KErrNotSupported);
 			}
 		
-		while((sessionPtr = iSessionIter++) != NULL)
+		while((sessionPtr = sessionIter++) != NULL)
 			{
-			CEirManSession* eirSession = static_cast<CEirManSession*>(sessionPtr);
-			eirSession->NotifyEirFeatureState(err);
+			sessionPtr->NotifyEirFeatureState(err);
 			}
 		}
 	}
--- a/bluetooth/btstack/eirman/eirmanserver.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanserver.h	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -24,9 +24,11 @@
 #include <e32base.h>
 
 class CEirManSession;
+class CEirManInternalSession;
 class CEirManager;
 class MHCICommandQueue;
 class CLinkMgrProtocol;
+class MEirInternalSessionNotifier;
 
 enum TEirFeatureState
 	{
@@ -44,10 +46,12 @@
 	static CEirManServer* NewL(MHCICommandQueue& aCommandQueue, CLinkMgrProtocol& aLinkMgrProtocol);
 	~CEirManServer();
 	
+	CEirManInternalSession* NewInternalSessionL(MEirInternalSessionNotifier& aParent);
+	
 	inline CEirManager& EirManager() const;
 	
-	void AddSession();
-	void DropSession();
+	void AddSession(CEirManSession& aSession, TBool aInternalSession);
+	void DropSession(TBool aInternalSession);
 	void NotifyFeaturesReady();
 	TEirFeatureState EirFeatureState();
 
@@ -65,9 +69,11 @@
 	CLinkMgrProtocol& 	iLinkMgrProtocol;
 	//owned
 	CEirManager* 		iEirManager;
-	TInt				iSessionCount;
+	TInt				iInternalSessionCount;
+	TInt				iExternalSessionCount;
 	TBool				iIsFeaturesReady;
 	TBool				iIsEirSupported;
+	TDblQue<CEirManSession> iSessions;
 	};
 #include "eirmanserver.inl"
 
--- a/bluetooth/btstack/eirman/eirmansession.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmansession.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -32,19 +32,21 @@
 _LIT8(KLogComponent, LOG_COMPONENT_EIRMANAGER);
 #endif
 
-CEirManSession* CEirManSession::NewL(CEirManServer& aServer)
+CEirManSession* CEirManSession::NewL(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession)
 	{
 	LOG_STATIC_FUNC
-	CEirManSession* self = new(ELeave) CEirManSession(aServer);
+	CEirManSession* self = new(ELeave) CEirManSession(aServer, aParent, aInternalSession);
 	CleanupStack::PushL(self);
 	self->ConstructL();
 	CleanupStack::Pop(self);
 	return self;
 	}
 
-CEirManSession::CEirManSession(CEirManServer& aServer)
+CEirManSession::CEirManSession(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession)
 	: iEirManServer(aServer)
+	, iParent(aParent)
 	, iEirTag(EEirTagRESERVED)
+	, iInternalSession(aInternalSession)
 	{
 	LOG_FUNC
 	}
@@ -52,7 +54,7 @@
 void CEirManSession::ConstructL()
 	{
 	LOG_FUNC
-	iEirManServer.AddSession();
+	iEirManServer.AddSession(*this, iInternalSession);
 	}
 
 CEirManSession::~CEirManSession()
@@ -60,15 +62,154 @@
 	LOG_FUNC
 	// deregister any registered tag that may be registered
 	DeregisterTag();
+	iLink.Deque();
+	iEirManServer.DropSession(iInternalSession);
+	}
+
+void CEirManSession::RegisterTag(TEirTag aTag)
+	{
+	LOG_FUNC
+
+	LOG1(_L("CEirManSession::RegisterTag tag = %d"), aTag);
+
+	if(!(aTag >= EEirTagName && aTag < EEirTagRESERVED))
+		{
+		iParent.MesnRegisterComplete(KErrArgument);
+		}
+	else if(iEirTag != EEirTagRESERVED)
+		{
+		LOG1(_L("CEirManSession::RegisterTag ERROR, Tag in use: %d"), iEirTag);
+		iParent.MesnRegisterComplete(KErrInUse);
+		}
+	else
+		{
+		// Register this tag for callbacks
+		if(iEirManServer.EirFeatureState() == EEirFeatureReady)
+			{
+			// Eir is supported
+			TInt result = iEirManServer.EirManager().RegisterTag(aTag, *this);
+			if(result == KErrNone)
+				{
+				iEirTag = aTag;
+				}
+			iParent.MesnRegisterComplete(result);
+			}
+		else if(iEirManServer.EirFeatureState() == EEirFeaturePending)
+			{
+			// We don't know if eir is supported or not at this moment
+			iRegisterPending = ETrue;
+			iPendingEirTag = aTag;
+			}
+		else
+			{
+			// Eir is not supported
+			iParent.MesnRegisterComplete(KErrNotSupported);
+			}
+		}
+	}
+
+void CEirManSession::DeregisterTag()
+	{
+	LOG_FUNC
+	LOG1(_L("CEirManSession::DeregisterTag tag = %d"), iEirTag);
+	
+	if(iEirTag != EEirTagRESERVED)
+		{
+		// Deregister this tag for callbacks 
+		iEirManServer.EirManager().DeregisterTag(iEirTag);
+		iEirTag = EEirTagRESERVED;
+		}
+	}
+
+// Eir Server has tried to register tag
+void CEirManSession::NotifyEirFeatureState(TInt aResult)
+	{
+	LOG1(_L("Eir Server has been notified feature ready, result: %d"), aResult);
+	if(aResult == KErrNone && iRegisterPending)
+		{
+		__ASSERT_DEBUG(iEirManServer.EirFeatureState() == EEirFeatureReady, EIR_SESSION_PANIC(EEirSessionEirFeatureNotSupported));
+		TInt result = iEirManServer.EirManager().RegisterTag(iPendingEirTag, *this);
+		if(result == KErrNone)
+			{
+			iEirTag = iPendingEirTag;
+			}
+		iRegisterPending = EFalse;
+		iParent.MesnRegisterComplete(result);
+		}
+	else if(iRegisterPending)
+		{
+		iRegisterPending = EFalse;
+		iParent.MesnRegisterComplete(aResult);
+		}
+	}
+
+
+TInt CEirManSession::NewData(TInt aRequiredLength)
+	{
+	LOG_FUNC
+	return iEirManServer.EirManager().NewData(iEirTag, aRequiredLength);
+	}
+
+
+TInt CEirManSession::SetData(const TDesC8& aData, TEirDataMode aMode)
+	{
+	LOG_FUNC
+	return iEirManServer.EirManager().SetData(iEirTag, aData, aMode);
+	}
+
+// Callback from the EIR Manager
+void CEirManSession::MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag)
+	{
+	LOG_FUNC
+	LOG2(_L("CEirManSession::MemnEirBlockAvailable Tag: %d space: %d"), aTag, aSpaceForTag);
+
+	// Silently discard callbacks not containing our EIR Tag
+	if(aTag != iEirTag)
+		{
+		__ASSERT_DEBUG(EFalse, EIR_SESSION_PANIC(EEirSessionInvalidEirTag));
+		LOG3(_L("CEirManSession::MemnEirBlockAvailable early return: aTag: %d iEirTag: %d space: %d"), aTag, iEirTag, aSpaceForTag);
+		return;
+		}
+
+	iParent.MesnSpaceAvailable(aSpaceForTag);
+
+	}
+
+TEirTag CEirManSession::EirTag() const
+	{
+	return iEirTag;
+	}
+
+CEirManExternalSession* CEirManExternalSession::NewL(CEirManServer& aServer)
+	{
+	CEirManExternalSession* self = new(ELeave) CEirManExternalSession();
+	CleanupStack::PushL(self);
+	self->ConstructL(aServer);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CEirManExternalSession::CEirManExternalSession()
+	{
+	
+	}
+
+void CEirManExternalSession::ConstructL(CEirManServer& aServer)
+	{
+	iSession = CEirManSession::NewL(aServer, *this, EFalse);
+	}
+
+CEirManExternalSession::~CEirManExternalSession()
+	{
 	if(!iDataAvailableListenerMessage.IsNull())
 		{
 		// complete any outstanding messages.
 		iDataAvailableListenerMessage.Complete(KErrCancel);
 		}
-	iEirManServer.DropSession();
+	delete iSession;
 	}
 
-void CEirManSession::ServiceL(const RMessage2& aMessage)
+void CEirManExternalSession::ServiceL(const RMessage2& aMessage)
 	{
 	LOG_FUNC
 	LOG1(_L("CEirManSession::ServiceL aMessage.Function() = %d"), aMessage.Function());
@@ -109,83 +250,28 @@
 		}
 	}
 
-void CEirManSession::RegisterTag(const RMessage2& aMessage)
+void CEirManExternalSession::RegisterTag(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-
 	TEirTag tag = static_cast<TEirTag>(aMessage.Int0());
 	LOG1(_L("CEirManSession::RegisterTag tag = %d"), tag);
 
-	if(!(tag >= EEirTagName && tag < EEirTagRESERVED))
-		{
-		__ASSERT_ALWAYS(EFalse, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
-		}
-	else if(iEirTag != EEirTagRESERVED)
-		{
-		LOG1(_L("CEirManSession::RegisterTag ERROR, Tag in use: %d"), iEirTag);
-		aMessage.Complete(KErrInUse);
-		}
-	else
-		{
-		// Register this tag for callbacks
-		if(iEirManServer.EirFeatureState() == EEirFeatureReady)
-			{
-			// Eir is supported
-			TInt result = iEirManServer.EirManager().RegisterTag(tag, *this);
-			if(result == KErrNone)
-				{
-				iEirTag = tag;
-				}
-			aMessage.Complete(result);
-			}
-		else if(iEirManServer.EirFeatureState() == EEirFeaturePending)
-			{
-			// We don't know if eir is supported or not at this moment
-			iPendingEirTag = tag;
-			iRegisterMessage = aMessage;
-			}
-		else
-			{
-			// Eir is not supported
-			aMessage.Complete(KErrNotSupported);
-			}
-		}
+	iRegisterMessage = aMessage;
+	
+	iSession->RegisterTag(tag);
+
 	}
 
-void CEirManSession::DeregisterTag()
+void CEirManExternalSession::MesnRegisterComplete(TInt aResult)
 	{
-	LOG_FUNC
-	LOG1(_L("CEirManSession::DeregisterTag tag = %d"), iEirTag);
-	
-	if(iEirTag != EEirTagRESERVED)
+	if (aResult == KErrArgument)
 		{
-		// Deregister this tag for callbacks 
-		iEirManServer.EirManager().DeregisterTag(iEirTag);
-		iEirTag = EEirTagRESERVED;
+		__ASSERT_ALWAYS(EFalse, iRegisterMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 		}
+	iRegisterMessage.Complete(aResult);
 	}
 
-// Eir Server has tried to register tag
-void CEirManSession::NotifyEirFeatureState(TInt aResult)
-	{
-	LOG1(_L("Eir Server has been notified feature ready, result: %d"), aResult);
-	if(aResult == KErrNone && !iRegisterMessage.IsNull())
-		{
-		__ASSERT_DEBUG(iEirManServer.EirFeatureState() == EEirFeatureReady, EIR_SESSION_PANIC(EEirSessionEirFeatureNotSupported));
-		TInt result = iEirManServer.EirManager().RegisterTag(iPendingEirTag, *this);
-		if(result == KErrNone)
-			{
-			iEirTag = iPendingEirTag;
-			}
-		iRegisterMessage.Complete(result);
-		}
-	else if(!iRegisterMessage.IsNull())
-		{
-		iRegisterMessage.Complete(aResult);
-		}
-	}
-
-TInt CEirManSession::RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete)
+TInt CEirManExternalSession::RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete)
 	{
 	LOG_FUNC
 
@@ -211,16 +297,16 @@
 	return KErrNone;
 	}
 	
-TInt CEirManSession::NewData(const RMessage2& aMessage)
+TInt CEirManExternalSession::NewData(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-	__ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
+	__ASSERT_ALWAYS(iSession->EirTag() != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 	TInt requiredLength = static_cast<TInt>(aMessage.Int0());
 
-	return iEirManServer.EirManager().NewData(iEirTag, requiredLength);
+	return iSession->NewData(requiredLength);
 	}
 
-TInt CEirManSession::CancelSpaceAvailableListener()
+TInt CEirManExternalSession::CancelSpaceAvailableListener()
 	{
 	LOG_FUNC
 
@@ -234,12 +320,12 @@
 	return KErrNone;
 	}
 
-TInt CEirManSession::SetData(const RMessage2& aMessage)
+TInt CEirManExternalSession::SetData(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-	__ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
+	__ASSERT_ALWAYS(iSession->EirTag() != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 	TEirDataMode eirDataMode = static_cast<TEirDataMode>(aMessage.Int1());
-	LOG2(_L("Tag: %d EirDataMode: %d"), iEirTag, eirDataMode);
+	LOG1(_L("EirDataMode: %d"),  eirDataMode);
 
 	// No need to allocate memory with an expensive malloc() call (via HBuf8::NewL or whatever), 
 	// since the EIR contents fit in the stack, and the EIR Manager will cache the data anyway
@@ -248,25 +334,13 @@
 	
 	if(err == KErrNone)
 		{
-		err = iEirManServer.EirManager().SetData(iEirTag, data, eirDataMode);
+		err = iSession->SetData(data, eirDataMode);
 		}
 	return err;
 	}
 
-// Callback from the EIR Manager
-void CEirManSession::MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag)
+void CEirManExternalSession::MesnSpaceAvailable(TUint aSpaceForTag)
 	{
-	LOG_FUNC
-	LOG2(_L("CEirManSession::MemnEirBlockAvailable Tag: %d space: %d"), aTag, aSpaceForTag);
-
-	// Silently discard callbacks not containing our EIR Tag
-	if(aTag != iEirTag)
-		{
-		__ASSERT_DEBUG(EFalse, EIR_SESSION_PANIC(EEirSessionInvalidEirTag));
-		LOG3(_L("CEirManSession::MemnEirBlockAvailable early return: aTag: %d iEirTag: %d space: %d"), aTag, iEirTag, aSpaceForTag);
-		return;
-		}
-
 	if(iDataAvailableListenerMessage.Handle())
 		{
 		LOG(_L("Listener outstanding, completing request"));
@@ -282,14 +356,92 @@
 		}
 	}
 
-void CEirManSession::CompleteSpaceAvailableRequest(TUint aBytesAvailable)
+void CEirManExternalSession::CompleteSpaceAvailableRequest(TUint aBytesAvailable)
 	{
 	LOG_FUNC
 	LOG1(_L("CEirManSession::CompleteSpaceAvailableRequest bytes: %d"), aBytesAvailable);
 	// Offer the space to the client
-	TPckg<TUint32> pckg(aBytesAvailable);
+	TPckgC<TUint32> pckg(aBytesAvailable);
 
 	TInt err = iDataAvailableListenerMessage.Write(0, pckg);
 	iDataAvailableListenerMessage.Complete(err);
 	}
 
+CEirManInternalSession* CEirManInternalSession::NewL(CEirManServer& aServer, MEirInternalSessionNotifier& aParent)
+	{
+	LOG_STATIC_FUNC
+	CEirManInternalSession* self = new(ELeave) CEirManInternalSession(aParent);
+	CleanupStack::PushL(self);
+	self->ConstructL(aServer);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CEirManInternalSession::CEirManInternalSession(MEirInternalSessionNotifier& aParent)
+	: iParent(aParent)
+	{
+	
+	}
+
+void CEirManInternalSession::ConstructL(CEirManServer& aServer)
+	{
+	iSession = CEirManSession::NewL(aServer, *this, ETrue);
+	iSetDataCb = new (ELeave) CAsyncCallBack(CActive::EPriorityHigh);
+	TCallBack cb(&SetDataCb, this);
+	iSetDataCb->Set(cb);
+	}
+
+CEirManInternalSession::~CEirManInternalSession()
+	{
+	delete iSetDataCb;
+	delete iSession;
+	}
+	
+void CEirManInternalSession::RegisterTag(TEirTag aTag)
+	{
+	iSession->RegisterTag(aTag);
+	}
+
+void CEirManInternalSession::SetData(const TDesC8& aData, TEirDataMode aMode)
+	{
+	delete iPendingData;
+	iPendingData = NULL;
+	iSetDataCb->Cancel();
+	iPendingData = aData.Alloc();
+	iPendingMode = aMode;
+	if (iPendingData)
+		{
+		iSetDataCb->CallBack();
+		}
+	}
+
+TInt CEirManInternalSession::SetDataCb(TAny* aThis)
+	{
+	static_cast<CEirManInternalSession*>(aThis)->DoSetData();
+	return KErrNone;
+	}
+
+void CEirManInternalSession::DoSetData()
+	{
+	TInt err = iSession->SetData(*iPendingData, iPendingMode);
+	if (err != KErrNone)
+		{
+		iParent.MeisnSetDataError(err);
+		}
+	}
+
+TInt CEirManInternalSession::NewData(TInt aRequiredLength)
+	{
+	return iSession->NewData(aRequiredLength);
+	}
+
+
+void CEirManInternalSession::MesnRegisterComplete(TInt aResult)
+	{
+	iParent.MeisnRegisterComplete(aResult);
+	}
+
+void CEirManInternalSession::MesnSpaceAvailable(TUint aSpaceForTag)
+	{
+	iParent.MeisnSpaceAvailable(aSpaceForTag - KEirLengthTagLength);
+	}
--- a/bluetooth/btstack/eirman/eirmansession.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmansession.h	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -27,41 +27,115 @@
 #include "eirmanager.h"
 
 class CEirManServer;
+class CEirManInternalSession;
 
-NONSHARABLE_CLASS(CEirManSession) : public CSession2, public MEirManagerNotifiee
+NONSHARABLE_CLASS(MEirSessionNotifier)
+	{
+public:
+	virtual void MesnRegisterComplete(TInt aResult) = 0;
+	virtual void MesnSpaceAvailable(TUint aSpaceForTag) = 0;
+	};
+
+NONSHARABLE_CLASS(MEirInternalSessionNotifier)
+	{
+public:
+	virtual void MeisnRegisterComplete(TInt aResult) = 0;
+	virtual void MeisnSpaceAvailable(TUint aSpaceForTag) = 0;
+	virtual void MeisnSetDataError(TInt aError) = 0;
+	};
+
+NONSHARABLE_CLASS(CEirManSession) : public CBase, public MEirManagerNotifiee
 	{
 public:
-	static CEirManSession* NewL(CEirManServer& aServer);
+	static CEirManSession* NewL(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession);
 	~CEirManSession();
 	void NotifyEirFeatureState(TInt aResult);
+	
+	void RegisterTag(TEirTag aTag);
+	TInt SetData(const TDesC8& aData, TEirDataMode aMode);
+	TInt NewData(TInt aRequiredLength);
+	TEirTag EirTag() const;
+
 private:
-	CEirManSession(CEirManServer& aServer);
+	CEirManSession(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession);
 	void ConstructL();
+	void DeregisterTag();
 
-	// ServiceL handlers
+private: // from MEirManagerNotifiee
+	virtual void MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag);
+
+public:
+	TDblQueLink	iLink;
+	
+private:
+	CEirManServer& 		iEirManServer; // unowned
+	MEirSessionNotifier& iParent;
+	TEirTag 			iEirTag;
+	TEirTag				iPendingEirTag;
+	TBool				iRegisterPending;
+	TBool				iInternalSession;
+	};
+
+NONSHARABLE_CLASS(CEirManExternalSession): public CSession2, public MEirSessionNotifier
+	{
+public:
+	static CEirManExternalSession* NewL(CEirManServer& aServer);
+	~CEirManExternalSession();
+	
+private:
+	void ConstructL(CEirManServer& aServer);
+	CEirManExternalSession();
 	void RegisterTag(const RMessage2& aMessage);
 	TInt RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete);
 	TInt CancelSpaceAvailableListener();
+	TInt NewData(const RMessage2& aMessage);
 	TInt SetData(const RMessage2& aMessage);
-	TInt NewData(const RMessage2& aMessage);
-	
+
+private:
 	void CompleteSpaceAvailableRequest(TUint aBytesAvailable);
-	void DeregisterTag();
 
 private: // CSession2 virtuals
 	virtual void ServiceL(const RMessage2& aMessage);
 
-private: // from MEirManagerNotifiee
-	virtual void MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag);
-
 private:
-	CEirManServer& 		iEirManServer; // unowned
-	TEirTag 			iEirTag;
-	TEirTag				iPendingEirTag;
-	TUint 				iLastSpaceOffered;
-	TBool 				iSpaceAvailableListenerOutstanding;
+	virtual void MesnRegisterComplete(TInt aResult);
+	virtual void MesnSpaceAvailable(TUint aSpaceForTag);
+	
+private:
 	RMessage2			iRegisterMessage;
 	RMessage2			iDataAvailableListenerMessage;
+	TUint 				iLastSpaceOffered;
+
+	CEirManSession* iSession;
+	};
+
+NONSHARABLE_CLASS(CEirManInternalSession) : public CBase, public MEirSessionNotifier
+	{
+public:
+	static CEirManInternalSession* NewL(CEirManServer& aServer, MEirInternalSessionNotifier& aParent);
+	~CEirManInternalSession();
+	
+	void RegisterTag(TEirTag aTag);
+	void SetData(const TDesC8& aData, TEirDataMode aMode);
+	TInt NewData(TInt aRequiredLength);
+	
+private:
+	CEirManInternalSession(MEirInternalSessionNotifier& aParent);
+	void ConstructL(CEirManServer& aServer);
+
+	static TInt SetDataCb(TAny* aThis);
+	void DoSetData();
+	
+private: // from MEirManagerNotifiee
+	virtual void MesnRegisterComplete(TInt aResult);
+	virtual void MesnSpaceAvailable(TUint aSpaceForTag);
+	
+private:
+	CEirManSession* iSession;
+	MEirInternalSessionNotifier& iParent;
+	CAsyncCallBack* iSetDataCb;
+	HBufC8* iPendingData;
+	TEirDataMode iPendingMode;
 	};
 
 #endif // _EIRMANSESSION_H
--- a/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp	Tue May 25 13:54:55 2010 +0300
@@ -631,32 +631,44 @@
  		// SAP state machine requested that we open the channel before we could do it.
  		// We can do it now.
  		iOpenChannelRequestAwaitingPeerEntityConfig = EFalse;
- 		iSigState->OpenChannelRequest(*this);
+ 		iSigState->OpenChannel(*this);
  		}
  	}
 
 TBool CL2CapSAPSignalHandler::DelayConfigRequest()
 	{
 	LOG_FUNC
-	iAwaitingConfigRequestDelayTimer = iSAPSignalHandlerTimerState==EConfigRequestDelayTimer;
+	// The whole delaying of sending of ConfigRequest is basically a workaround for
+	// certain broken carkits from a certain Swedish manufacturer at a certain stretch
+	// of time.
+	// The defect was: the carkits advertised their capability to do RTM in Extended
+	// Feature Mask, but when sent a ConfigRequest with RTM they would just panic
+	// (ie. they really only did Basic mode). 
+	// So the workaround is to delay the sending of our Config Request such that
+	// we receive the carkit's request first - we have an optimization which will
+	// downgrade our requested channel mode to Basic if the remote requests it before
+	// we've sent out our ConfigReq. This way we send Basic mode in our ConfigReq
+	// and the carkit is happy.
+	return iSAPSignalHandlerTimerState==EConfigRequestDelayTimer;
+	}
 
-	return iAwaitingConfigRequestDelayTimer; //true if we are delaying
-	}
-				
 void CL2CapSAPSignalHandler::ConfigRequestDelayTimerExpiry()	
  	{
  	LOG_FUNC
- 	if(iAwaitingConfigRequestDelayTimer)
+ 	// Now that ConfigReq delay timer have expired we can start the proper configuration timer.
+ 	StartConfigurationTimer();
+
+ 	if (!iAwaitConfigureChannelRequest)
  		{
- 		iAwaitingConfigRequestDelayTimer = EFalse;
-		ConfigureChannelRequest();
+		ConfigureChannel();
  		}
+ 	// [else]: we're in an active open scenario and SAP hasn't yet issued a ConfigureChannelRequest.
  	}
 
 void CL2CapSAPSignalHandler::CloseChannelRequest()
 	{
 	LOG_FUNC
-	iSigState->CloseChannelRequest(*this);
+	iSigState->CloseChannel(*this);
 	}
 
 void CL2CapSAPSignalHandler::OpenChannelRequest()
@@ -667,7 +679,7 @@
 
 	if (IsPeerInfoDefined())
 		{
-		iSigState->OpenChannelRequest(*this);
+		iSigState->OpenChannel(*this);
 		}
 	else
 		{
@@ -686,7 +698,12 @@
 void CL2CapSAPSignalHandler::ConfigureChannelRequest()
 	{
 	LOG_FUNC
-	iSigState->ConfigureChannelRequest(*this);
+	iAwaitConfigureChannelRequest = EFalse;
+
+	if (iSAPSignalHandlerTimerState != EConfigRequestDelayTimer)
+		{
+		ConfigureChannel();
+		}
 	}
 
 void CL2CapSAPSignalHandler::PendingCommandsDrained()
@@ -707,34 +724,31 @@
 void CL2CapSAPSignalHandler::StartConfigurationTimer()
 	{
 	LOG_FUNC
-	switch(iSAPSignalHandlerTimerState)
-		{
-		case EConfigurationTimer:
-		case EConfigRequestDelayTimer:
-			// The timer is already running. Cancel it and start it again.
-			BTSocketTimer::Remove(iSAPSignalHandlerTimerEntry);
-			iSAPSignalHandlerTimerState = ETimerIdle;
-			break;
-					
-		case ETimerIdle:
-		default:
-			// No timer running, nothing needs to be done.
-			break;
-		};
+	__ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle,
+				   Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning));
+
+	TCallBack cb(TimerExpired, this);
+	iSAPSignalHandlerTimerEntry.Set(cb);
+	BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, 
+	                     iSAPSignalHandlerTimerEntry);
+	iSAPSignalHandlerTimerState = EConfigurationTimer;
+	}
 
-	if(iSAPSignalHandlerTimerState == ETimerIdle)
-		{
-		TCallBack cb(TimerExpired, this);
-		iSAPSignalHandlerTimerEntry.Set(cb);
-		BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, 
-		                     iSAPSignalHandlerTimerEntry);
-		iSAPSignalHandlerTimerState = EConfigRequestDelayTimer;
-		}
+void CL2CapSAPSignalHandler::StartConfigRequestDelayTimer()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iSAPSignalHandlerTimerState == ETimerIdle,
+				   Panic(EL2CapAttemptToStartConfigTimerWhenItIsRunning));
+
+	TCallBack cb(TimerExpired, this);
+	iSAPSignalHandlerTimerEntry.Set(cb);
+	BTSocketTimer::Queue(KL2ConfigRequestDelayTimout, 
+						 iSAPSignalHandlerTimerEntry);
+	iSAPSignalHandlerTimerState = EConfigRequestDelayTimer;
 	}
-	
+
 void CL2CapSAPSignalHandler::CancelTimer()
 	{
-
 	LOG_FUNC
 	if(iSAPSignalHandlerTimerState != ETimerIdle)
 		{
@@ -751,18 +765,14 @@
 		case ETimerIdle:
 			Panic(EL2CAPSSHTimerExpiredWhileInIdleState);
 			break;
-			
+	
 		case EConfigRequestDelayTimer:
 			{
-			TCallBack cb(TimerExpired, this);
-			iSAPSignalHandlerTimerEntry.Set(cb);
-			BTSocketTimer::Queue(KL2ConfigWatchdogTimeout * KL2ProtocolSecondTimerMultiplier, 
-			                     iSAPSignalHandlerTimerEntry);
-			iSAPSignalHandlerTimerState = EConfigurationTimer;
+			iSAPSignalHandlerTimerState = ETimerIdle;
 			ConfigRequestDelayTimerExpiry();
 			}
 			break;
-			
+
 		case EConfigurationTimer:
 			iSAPSignalHandlerTimerState = ETimerIdle;
 			iSigState->ConfigurationTimerExpiry(*this);
--- a/bluetooth/btstack/l2cap/l2capSAPSignalHandler.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.h	Tue May 25 13:54:55 2010 +0300
@@ -128,6 +128,7 @@
 	static TInt TimerExpired(TAny* aSAPSignalHandler);
 
 	void StartConfigurationTimer();
+	void StartConfigRequestDelayTimer();
 	void CancelTimer();
 
 	void DetachFromMux();
@@ -136,14 +137,16 @@
 	TInt SendEchoRequest(const TDes8* aData);
 	void EchoResponseReceived(const TDesC8* aData);
 
+	inline void ConfigureChannel();
+
 	void OverrideParkMode();
 	void UndoOverrideParkMode();
 	void OverrideLPMWithTimeout();
+
 	inline TInt SignalHandlerErrorCode() const;
 	inline MSocketNotify::TOperationBitmasks SignalHandlerErrorAction() const;
 	inline void SetSignalHandlerErrorCode(TInt aError);
 	inline void SetSignalHandlerErrorAction(MSocketNotify::TOperationBitmasks aAction);
-
 private:
 	CL2CapSAPSignalHandler(CL2CAPConnectionSAP& aSAP);
 	void ConstructL();
@@ -187,9 +190,14 @@
 	// OpenChannelRequest, so OpenChannelRequest is delayed until Information Response comes
 	// through.
 	TBool iOpenChannelRequestAwaitingPeerEntityConfig;
-	// The SAP is ready to send a config request
-	// Flag to indicate that we are delaying sending this config request
-	TBool iAwaitingConfigRequestDelayTimer;
+	// A ConfigureChannelRequest from the SAP is only expected in an active open scenario.
+	// On passive open we kick the configuration ourselves.
+	TBool iAwaitConfigureChannelRequest;
+
+	friend class TL2CAPSigStateClosed;
+	friend class TL2CAPSigStateWaitConnectRsp;
+	friend class TL2CAPSigStateWaitConnect;
+	friend class TL2CAPSigStateConfigBase;
 	};
 
 inline TUint8 CL2CapSAPSignalHandler::GetOutstandingRequestID()
@@ -230,7 +238,7 @@
 	{
 	return iRemotePort;
 	}
-	
+
 inline const TBTDevAddr& CL2CapSAPSignalHandler::RemoteBTAddress() const
 	{
 	return iSAP->RemoteDev();
@@ -280,5 +288,10 @@
 	{
 	iSignalHandlerErrorAction = aAction;
 	}
-	
+
+inline void CL2CapSAPSignalHandler::ConfigureChannel()
+	{
+	iSigState->ConfigureChannel(*this);
+	}
+
 #endif
--- a/bluetooth/btstack/l2cap/l2capSigStates.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSigStates.cpp	Tue May 25 13:54:55 2010 +0300
@@ -49,7 +49,7 @@
 	}
 
 // Events from the SAP
-void TL2CAPSigState::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigState::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// This is a standard action for most states.
@@ -62,7 +62,7 @@
 	aSignalHandler.SAP()->ChannelClosed();
 	}
 
-void TL2CAPSigState::OpenChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const	
+void TL2CAPSigState::OpenChannel(CL2CapSAPSignalHandler& /*aSignalHandler*/) const	
 	{
 	LOG_FUNC
 	PanicInState(EL2CAPUnexpectedSAPEvent);
@@ -74,7 +74,7 @@
 	PanicInState(EL2CAPUnexpectedSAPEvent);
 	}
 
-void TL2CAPSigState::ConfigureChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const	
+void TL2CAPSigState::ConfigureChannel(CL2CapSAPSignalHandler& /*aSignalHandler*/) const	
 	{
 	LOG_FUNC
 	PanicInState(EL2CAPUnexpectedSAPEvent);
@@ -282,7 +282,7 @@
 	LOG_FUNC
 	}
 
-void TL2CAPSigStateClosed::OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateClosed::OpenChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// The SAP has requested a channel be opened.
@@ -353,7 +353,7 @@
 	}
 
 
-void TL2CAPSigStateClosed::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateClosed::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// Detach from the Mux.  Inform the SAP that disconnection is complete.
@@ -382,6 +382,8 @@
 	// Cancel the configuration timer.
 	aSignalHandler.CancelTimer();
 
+	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.
@@ -446,7 +448,7 @@
 	}
 
 // Events from the Mux
-void TL2CAPSigStateWaitConnectRsp::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateWaitConnectRsp::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{	
 	// Disconnect the channel.	
 	HandleSAPDisconnect(aSignalHandler);
@@ -457,6 +459,7 @@
 	LOG_FUNC
 	//set the remote CID to 0
 	aSignalHandler.SetRemotePort(TL2CAPPort(0));
+	aSignalHandler.iAwaitConfigureChannelRequest = ETrue;
 	}
 
 /****************************************************************************/
@@ -469,7 +472,7 @@
 	}
 	
 // Events from the SAP
-void TL2CAPSigStateWaitConnect::OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateWaitConnect::OpenChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 
@@ -489,7 +492,7 @@
 				// We should never get in here! The timer, which allows the delay
 				// should have been started on entry to the state "WaitConfig". 
 				{
-				aSignalHandler.ConfigureChannelRequest();
+				aSignalHandler.ConfigureChannel();
 				}
 			}
 		} // Success Response
@@ -516,7 +519,7 @@
 	}
 
 // Events from the Mux
-void TL2CAPSigStateWaitConnect::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateWaitConnect::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 
@@ -567,6 +570,12 @@
 	HandleDisconnectRequest(aSignalHandler, aId);
 	}
 
+void TL2CAPSigStateWaitConnect::Enter(CL2CapSAPSignalHandler& aSignalHandler) const
+	{
+	LOG_FUNC
+	aSignalHandler.iAwaitConfigureChannelRequest = EFalse;
+	}
+
 
 /**************************************************************************/
 // Implementation of TL2CAPSigStateConfigBase
@@ -606,7 +615,7 @@
 	}      							 	
 
 // Events from the SAP
-void TL2CAPSigStateConfigBase::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateConfigBase::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// Disconnect the channel.
@@ -624,7 +633,7 @@
 void TL2CAPSigStateConfigBase::ConfigurationTimerExpiry(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
-	CloseChannelRequest(aSignalHandler);
+	CloseChannel(aSignalHandler);
 	}
 	
 // Common handling of Config Request and Response commands.
@@ -669,13 +678,29 @@
 							case EConfigSuccess:
 								// Move to next state.
 								aSignalHandler.SetState(iFactory.GetState(aConfigSuccessState));
+
+								if (!configRequestSent && !aSignalHandler.iAwaitConfigureChannelRequest)
+									{
+									// The delay timer is there so that we don't send a
+									// Config Req before receiving one from the remote
+									// (as a workaround for some broken carkits, see 
+									// DelayConfigRequest()). Since we've just received a
+									// ConfigReq from the remote, we can stop the delay
+									// timer and send our request if this is passive open
+                                    // or remotely-initiated reconfiguration.
+									// If it's an active open scenario then we need to wait
+									// for security access request to get completed.
+									aSignalHandler.CancelTimer();
+									aSignalHandler.StartConfigurationTimer();
+									aSignalHandler.ConfigureChannel();
+									}
 								break;
-	
+
 							case EConfigUnacceptableParams:
 							case EConfigRejected:
 								// Stay in current state.
 								break;
-	
+
 							case EConfigUnknownOption: // impossible on this path
 							default:
 								__ASSERT_DEBUG(EFalse, PanicInState(EL2CAPInvalidConfigResponseCodeGenerated));
@@ -836,7 +861,7 @@
 	}
 
 // Events from the SAP
-void TL2CAPSigStateWaitConfig::ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateWaitConfig::ConfigureChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// Local config can now be initiated.  The local config requirements must
@@ -851,7 +876,7 @@
 		if(err == KErrNone)
 			{
 			aSignalHandler.SetState(iFactory.GetState(CL2CAPSignalStateFactory::EWaitConfigReqRsp));
-			}						
+			}
 		else
 			{
 			Error(aSignalHandler, KErrCouldNotConnect, MSocketNotify::EErrorAllOperations);
@@ -859,7 +884,7 @@
 		}
 	// Else wait until the delay timer expires.
 	}
-	
+
 // L2CAP commands received from the peer.
 void TL2CAPSigStateWaitConfig::ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
 								  			 HConfigureRequest* aConfigRequest) const
@@ -868,12 +893,14 @@
 	// Call the config base class helper method to process this command.
 	TL2CAPSigStateConfigBase::ConfigRequest(aSignalHandler, aConfigRequest, CL2CAPSignalStateFactory::EWaitSendConfig);
 	}
-		
+
 // Change of state events
 void TL2CAPSigStateWaitConfig::Enter(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
-	aSignalHandler.StartConfigurationTimer();
+	// First start the ConfigReq sending delay timer (see DelayConfigRequest() for why).
+	// It's short lived, we'll start the proper L2CAP config timer when it expires.
+	aSignalHandler.StartConfigRequestDelayTimer();
 	}
 
 /**************************************************************************/
@@ -890,7 +917,7 @@
 	}
 	
 // Events from the SAP
-void TL2CAPSigStateWaitSendConfig::ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateWaitSendConfig::ConfigureChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// Local config can now be initiated.  The local config requirements must
@@ -1005,9 +1032,6 @@
 	// should not be sent until it completes.
 	aSignalHandler.ReconfiguringChannel();
 	static_cast<void>(aSignalHandler.HandleConfigureRequest(aConfigRequest));
-
-	// Start local reconfiguration.
-	aSignalHandler.ConfigureChannelRequest();
 	}
 
 TInt TL2CAPSigStateOpen::UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const
@@ -1019,14 +1043,14 @@
 		{
 		aSignalHandler.ReconfiguringChannel();
 		aSignalHandler.SetState(iFactory.GetState(CL2CAPSignalStateFactory::EWaitConfig));
-		aSignalHandler.ConfigureChannelRequest();
+		aSignalHandler.ConfigureChannel();
 		rerr = KErrL2CAPConfigPending;
 		}
 	return rerr;
 	}
 
 
-void TL2CAPSigStateOpen::CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const
+void TL2CAPSigStateOpen::CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const
 	{
 	LOG_FUNC
 	// Disconnect the channel.
@@ -1060,16 +1084,16 @@
 		LOG(_L("CL2CapSigStateOpen::Enter doing reconfig"));
 		// now get reconfiguring
 		aSignalHandler.SetState(iFactory.GetState(CL2CAPSignalStateFactory::EWaitConfig));
-		aSignalHandler.ConfigureChannelRequest();
+		aSignalHandler.ConfigureChannel();
 		}
 	else
 		{
 		// Remove and park override.
 		aSignalHandler.UndoOverrideParkMode();
-		
+
 		// Cancel the configuration timer.
 		aSignalHandler.CancelTimer();
-		
+
 		// Inform the SAP that the channel is now configured and ready to use.
 		aSignalHandler.SAP()->ChannelConfigured(aSignalHandler.ChannelConfig(),
 		                                        aSignalHandler.Mux(),
@@ -1153,7 +1177,7 @@
 	aSignalHandler.CancelTimer();
 	}
 
-void TL2CAPSigStateWaitDisconnect::CloseChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const
+void TL2CAPSigStateWaitDisconnect::CloseChannel(CL2CapSAPSignalHandler& /*aSignalHandler*/) const
 	{
 	LOG_FUNC
 	// Already disconnecting.
@@ -1201,7 +1225,7 @@
 	// Could well be in this state - just drop.
 	}
 
-void TL2CAPSigStateWaitDisconnect::ConfigureChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const
+void TL2CAPSigStateWaitDisconnect::ConfigureChannel(CL2CapSAPSignalHandler& /*aSignalHandler*/) const
 	{
 	LOG_FUNC
 	// This may be called if an Information Request times out
--- a/bluetooth/btstack/l2cap/l2capSigStates.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSigStates.h	Tue May 25 13:54:55 2010 +0300
@@ -78,10 +78,10 @@
 	TL2CAPSigState(const CL2CAPSignalStateFactory& aFactory);
 	
 	// Events from the SAP
-	virtual void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
-	virtual void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void OpenChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	virtual void ConnectRequestReceived(CL2CapSAPSignalHandler& aSignalHandler) const;
-	virtual void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void ConfigureChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	virtual TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
 
 	virtual TInt GetNegotiatedChannelMode(const CL2CapSAPSignalHandler& aSignalHandler, TL2CapChannelMode& aMode) const;
@@ -142,9 +142,9 @@
 	TL2CAPSigStateClosed(const CL2CAPSignalStateFactory& aFactory);
 
 	// Events from the SAP
-	void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void OpenChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	void ConnectRequestReceived(CL2CapSAPSignalHandler& aSignalHandler) const;
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 
 	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
 					   HConfigureRequest* aConfigRequest) const;
@@ -165,7 +165,7 @@
 	TL2CAPSigStateWaitConnectRsp(const CL2CAPSignalStateFactory& aFactory);
 
 	// Events from the SAP
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 
 	// L2CAP commands received from the peer.
 	void ConnectResponse(CL2CapSAPSignalHandler& aSignalHandler,
@@ -183,15 +183,16 @@
 	TL2CAPSigStateWaitConnect(const CL2CAPSignalStateFactory& aFactory);	
 
 	// Events from the SAP
-	void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void OpenChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	
 	// L2CAP commands received from the peer.
 	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
 
 	// Change of state state events
 	void PendingCommandsDrained(CL2CapSAPSignalHandler& aSignalHandler) const;
-	
+
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
 	};
 	
 NONSHARABLE_CLASS(TL2CAPSigStateConfigBase) : public TL2CAPSigState
@@ -212,7 +213,7 @@
 	           MSocketNotify::TOperationBitmasks aErrorAction) const;
 
 	// Events from the SAP
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
 
 	// Timer Events
@@ -238,7 +239,7 @@
 	TL2CAPSigStateWaitConfig(const CL2CAPSignalStateFactory& aFactory);	
 
 	// Events from the SAP
-	void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void ConfigureChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 
 	// L2CAP commands received from the peer.
 	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
@@ -259,7 +260,7 @@
 	TL2CAPSigStateWaitSendConfig(const CL2CAPSignalStateFactory& aFactory);	
 
 	// Events from the SAP
-	void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void ConfigureChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	};
 
 NONSHARABLE_CLASS(TL2CAPSigStateWaitConfigReqRsp) : public TL2CAPSigStateConfigBase
@@ -317,7 +318,7 @@
 	TL2CAPSigStateOpen(const CL2CAPSignalStateFactory& aFactory);	
 
 	// Events from the SAP
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 
 	// L2CAP commands received from the peer.
 	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
@@ -343,7 +344,7 @@
 	TL2CAPSigStateWaitDisconnect(const CL2CAPSignalStateFactory& aFactory);	
 
 	// Events from the SAP
-	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannel(CL2CapSAPSignalHandler& aSignalHandler) const;
 	TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
 
 	// State changes from the Mux
@@ -360,7 +361,7 @@
 
 	void ConfigResponse(CL2CapSAPSignalHandler& /*aSignalHandler*/,
  	                	HConfigureResponse* /*aConfigResponse*/) const;
-	void ConfigureChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const;
+	void ConfigureChannel(CL2CapSAPSignalHandler& /*aSignalHandler*/) const;
 	};
 
 #endif
--- a/bluetooth/btstack/l2cap/l2util.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2util.h	Tue May 25 13:54:55 2010 +0300
@@ -172,7 +172,8 @@
 	EL2CAPNullOwnerSupplied = 148,
 	EL2CAPTryingToStealOwnedPdu = 149,
 	EL2CapConstructingPositiveConfigResponseWithUnresolvedOptionStatus = 200,
-	EL2CapReferencingUnackedIFrameWhenNoRetransmissionGoing = 274, 
+	EL2CapReferencingUnackedIFrameWhenNoRetransmissionGoing = 274,
+	EL2CapAttemptToStartConfigTimerWhenItIsRunning = 275,
 	};
 
 /**
--- a/bluetooth/btstack/linkmgr/ACLSAP.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ACLSAP.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1089,13 +1089,7 @@
 		CPhysicalLink* physicalLink = &iLinksMan.NewPhysicalLinkL(iRemoteDev);
 		// physicalLink is owned by the physical links manager.
 		User::LeaveIfError(BindLink(EACLLink, *physicalLink));
-		TInt err = iPhysicalLink->Connect();
-		if(err != KErrNone)
-			{
-			// If we failed to connect then we should roll back the attachment
-			ClearPhysicalLink();
-			User::Leave(err);
-			}
+		iPhysicalLink->Connect();
 		}
 	}
 
--- a/bluetooth/btstack/linkmgr/ProxySAP.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ProxySAP.cpp	Tue May 25 13:54:55 2010 +0300
@@ -552,7 +552,7 @@
 					}
 				else
 					{
-					iRequestedActiveMode = option ? ETrue : EFalse;
+					iRequestedActiveMode = option;
 					if(iRequestedActiveMode)
 						{
 						localPriority = ETrue;
--- a/bluetooth/btstack/linkmgr/ProxySAP.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ProxySAP.h	Tue May 25 13:54:55 2010 +0300
@@ -80,6 +80,7 @@
 public:
 	static CBTProxySAP* NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink*);
 	static CBTProxySAP* NewL(CPhysicalLinksManager& aConnectionMan, CPhysicalLink*);
+	~CBTProxySAP();
 
 // from SAP - the proxy will not do all of these
 	virtual void Start();
@@ -122,8 +123,7 @@
 
 	void Error(TInt aError);
 	void Disconnect();
-
-	~CBTProxySAP();
+	
 public:
 	TSglQueLink			iQueueLink;	
 	TBTDblQueLink		iPLMLink;	
--- a/bluetooth/btstack/linkmgr/eirpublisherlocalname.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublisherlocalname.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -15,9 +15,10 @@
 
 #include "eirpublisherlocalname.h"
 #include "linkutil.h"
-#include <bluetooth/eirpublisherbase.h>
 #include <bluetooth/logger.h>
 
+#include "eirmanserver.h"
+
 #ifdef __FLOG_ACTIVE
 _LIT8(KLogComponent, LOG_COMPONENT_EIRMANAGER);
 #endif
@@ -29,18 +30,17 @@
 /**
 Provides functionality to publish Local Name to EIR.
 **/
-CEirPublisherLocalName* CEirPublisherLocalName::NewL()
+CEirPublisherLocalName* CEirPublisherLocalName::NewL(CEirManServer& aServer)
 	{
 	LOG_STATIC_FUNC
 	CEirPublisherLocalName* self = new (ELeave) CEirPublisherLocalName();
 	CleanupStack::PushL(self);
-	self->ConstructL();
+	self->ConstructL(aServer);
 	CleanupStack::Pop();
 	return self;
 	}
 
 CEirPublisherLocalName::CEirPublisherLocalName()
-:	CEirPublisherBase(EEirTagName)
 	{
 	LOG_FUNC
 	}
@@ -49,26 +49,49 @@
 	{
 	LOG_FUNC
 	delete iPublishBuf;
+	delete iSession;
 	}
 	
-void CEirPublisherLocalName::ConstructL()
+void CEirPublisherLocalName::ConstructL(CEirManServer& aServer)
 	{
 	LOG_FUNC
-	CEirPublisherBase::ConstructL();
+	iSession = aServer.NewInternalSessionL(*this);
+	iSession->RegisterTag(EEirTagName);
 	}
+
+void CEirPublisherLocalName::MeisnRegisterComplete(TInt aResult)
+	{
+	if (aResult == KErrNone)
+		{
+		iTagRegistered = ETrue;
+		if (iLocalName.Length() > 0)
+			{
+			iSession->NewData(iLocalName.Length());
+			}
+		}
+	}
+
+void CEirPublisherLocalName::MeisnSetDataError(TInt /* aError */)
+	{
 	
+	}
+
+
 void CEirPublisherLocalName::UpdateName(const TDesC8& aName)
 	{
 	LOG_FUNC
 	// Check aName isn't longer than 248 characters
 	__ASSERT_DEBUG(aName.Length() <= 248, Panic(EEIRPublisherUpdateNameTooLong));
 	iLocalName = aName;
-	iPublisher->PublishData(aName.Size());
+	if (iTagRegistered)
+		{
+		iSession->NewData(iLocalName.Size());
+		}
 	}
 	
 
 // From MEirPublisherNotifier
-void CEirPublisherLocalName::MepnSpaceAvailable(TUint aBytesAvailable)
+void CEirPublisherLocalName::MeisnSpaceAvailable(TUint aBytesAvailable)
 	{
 	LOG_FUNC
 	// Delete memory from last time this was called
@@ -84,7 +107,7 @@
 		iPublishBuf = iLocalName.Left(avail).Alloc();
 		if(iPublishBuf)
 			{
-			iPublisher->SetData(*iPublishBuf, EEirDataPartial);
+			iSession->SetData(*iPublishBuf, EEirDataPartial);
 			}
 		}
 	else
@@ -94,17 +117,14 @@
 		iPublishBuf = iLocalName.Alloc();
 		if(iPublishBuf)
 			{
-			iPublisher->SetData(*iPublishBuf, EEirDataComplete);
+			iSession->SetData(*iPublishBuf, EEirDataComplete);
 			}
 		}
 	// Final case to handle if OOM occurs.
 	if(!iPublishBuf)
 		{
-		iPublisher->SetData(KNullDesC8(), EEirDataPartial);
+		iSession->SetData(KNullDesC8(), EEirDataPartial);
 		}
 	}
-	
-void CEirPublisherLocalName::MepnSetDataError(TInt /*aResult*/)
-	{
-	LOG_FUNC
-	}
+
+
--- a/bluetooth/btstack/linkmgr/eirpublisherlocalname.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublisherlocalname.h	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -17,8 +17,10 @@
 #define EIRPUBLISHERLOCALNAME_H
 
 #include <e32base.h>
-#include <bluetooth/eirpublisherbase.h>
 #include <bluetooth/hci/hciconsts.h>
+#include "eirmansession.h"
+
+class CEirManServer;
 
 //**********************************
 // CEirPublisherLocalName
@@ -26,24 +28,27 @@
 /**
 Provides functionality to publish 16 bit UUIDs to EIR.
 **/
-NONSHARABLE_CLASS(CEirPublisherLocalName) : public CEirPublisherBase
+NONSHARABLE_CLASS(CEirPublisherLocalName): public CBase, public MEirInternalSessionNotifier
 	{
 public:
-	static CEirPublisherLocalName* NewL();
+	static CEirPublisherLocalName* NewL(CEirManServer& aServer);
 	~CEirPublisherLocalName();
 	void UpdateName(const TDesC8& aName);
 
 private:
 	CEirPublisherLocalName();
-	void ConstructL();
+	void ConstructL(CEirManServer& aServer);
 
-	// From MEirPublisherNotifier
-	virtual void MepnSpaceAvailable(TUint aBytesAvailable);
-	virtual void MepnSetDataError(TInt aResult);
+	// From MEirInternalSessionNotifier
+	virtual void MeisnSpaceAvailable(TUint aBytesAvailable);
+	virtual void MeisnRegisterComplete(TInt aResult);
+	virtual void MeisnSetDataError(TInt aError);
 
 private:
 	TBuf8<KHCILocalDeviceNameMaxLength> iLocalName;
 	HBufC8* iPublishBuf;
+	CEirManInternalSession* iSession;
+	TBool		iTagRegistered;
 	};
 	
 #endif	// EIRPUBLISHERLOCALNAME_H
--- a/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -14,7 +14,7 @@
 //
 
 #include "eirpublishertxpowerlevel.h"
-#include <bluetooth/eirpublisherbase.h>
+#include "eirmanserver.h"
 
 //**********************************
 // CEirPublisherTxPowerLevel
@@ -22,53 +22,71 @@
 /**
 Provides functionality to publish transmission power level to EIR.
 **/
-CEirPublisherTxPowerLevel* CEirPublisherTxPowerLevel::NewL()
+CEirPublisherTxPowerLevel* CEirPublisherTxPowerLevel::NewL(CEirManServer& aServer)
 	{
 	CEirPublisherTxPowerLevel* self = new (ELeave) CEirPublisherTxPowerLevel();
 	CleanupStack::PushL(self);
-	self->ConstructL();
+	self->ConstructL(aServer);
 	CleanupStack::Pop();
 	return self;
 	}
 
 CEirPublisherTxPowerLevel::CEirPublisherTxPowerLevel()
-:	CEirPublisherBase(EEirTagTxPowerLevel)
 	{
 	}
 
-void CEirPublisherTxPowerLevel::ConstructL()
+void CEirPublisherTxPowerLevel::ConstructL(CEirManServer& aServer)
 	{
-	CEirPublisherBase::ConstructL();
+	iSession = aServer.NewInternalSessionL(*this);
+	iSession->RegisterTag(EEirTagTxPowerLevel);
 	}
 
 CEirPublisherTxPowerLevel::~CEirPublisherTxPowerLevel()
 	{
+	delete iSession;
+	}
+
+void CEirPublisherTxPowerLevel::MeisnRegisterComplete(TInt aResult)
+	{
+	if (aResult == KErrNone)
+		{
+		iTagRegistered = ETrue;
+		if (iTxPowerLevelPublished)
+			{
+			iSession->NewData(KSizeOfTxPowerLevelData);
+			}
+		}
 	}
 
 void CEirPublisherTxPowerLevel::UpdateTxPowerLevel(TInt8 aTxPowerLevel)
 	{
 	iTxPowerLevel = aTxPowerLevel;
-	iPublisher->PublishData(KSizeOfTxPowerLevelData);
+	iTxPowerLevelPublished = ETrue;
+	if (iTagRegistered)
+		{
+		iSession->NewData(KSizeOfTxPowerLevelData);
+		}
 	}
 	
 // From MEirPublisherNotifier
-void CEirPublisherTxPowerLevel::MepnSpaceAvailable(TUint aBytesAvailable)
+void CEirPublisherTxPowerLevel::MeisnSpaceAvailable(TUint aBytesAvailable)
 	{
 	if (aBytesAvailable >= KSizeOfTxPowerLevelData)
 		{
 		// only publish TxPowerLevel if enough space
 		iPublishBuf.Zero();
 		iPublishBuf.Append(iTxPowerLevel);
-		iPublisher->SetData(iPublishBuf, EEirDataComplete);
+		iSession->SetData(iPublishBuf, EEirDataComplete);
 		}
 	else
 		{
 		// Otherwise publish zero length string
 		iPublishBuf.Zero();
-		iPublisher->SetData(iPublishBuf, EEirDataPartial);
+		iSession->SetData(iPublishBuf, EEirDataPartial);
 		}
 	}
 
-void CEirPublisherTxPowerLevel::MepnSetDataError(TInt /*aResult*/)
+void CEirPublisherTxPowerLevel::MeisnSetDataError(TInt /* aError */)
 	{
+	
 	}
--- a/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.h	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -18,7 +18,9 @@
 #define EIRPUBLISHERTXPOWERLEVEL_H
 
 #include <e32base.h>
-#include <bluetooth/eirpublisherbase.h>
+#include "eirmansession.h"
+
+class CEirManServer;
 
 #define KSizeOfTxPowerLevelData 1
 
@@ -28,24 +30,28 @@
 /**
 Provides functionality to publish TxPowerLevel to EIR.
 **/
-NONSHARABLE_CLASS(CEirPublisherTxPowerLevel) : public CEirPublisherBase
+NONSHARABLE_CLASS(CEirPublisherTxPowerLevel) : public CBase, public MEirInternalSessionNotifier
 	{
 public:
-	static CEirPublisherTxPowerLevel* NewL();
+	static CEirPublisherTxPowerLevel* NewL(CEirManServer& aServer);
 	~CEirPublisherTxPowerLevel();
 	void UpdateTxPowerLevel(TInt8 aTxPowerLevel);
 
 private:
 	CEirPublisherTxPowerLevel();
-	void ConstructL();
+	void ConstructL(CEirManServer& aServer);
 	
-	// From MEirPublisherNotifier
-	virtual void MepnSpaceAvailable(TUint aBytesAvailable);
-	virtual void MepnSetDataError(TInt aResult);
-
+	// From MEirInternalSessionNotifier
+	virtual void MeisnSpaceAvailable(TUint aBytesAvailable);
+	virtual void MeisnRegisterComplete(TInt aResult);
+	virtual void MeisnSetDataError(TInt aError);
+	
 private:
 	TInt8 iTxPowerLevel;
 	TBuf8<KSizeOfTxPowerLevelData> iPublishBuf;
+	CEirManInternalSession* iSession;
+	TBool iTxPowerLevelPublished;
+	TBool		iTagRegistered;
 	};
 	
 #endif	//EIRPUBLISHERTXPOWERLEVEL_H
--- a/bluetooth/btstack/linkmgr/linkmgr.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmgr.cpp	Tue May 25 13:54:55 2010 +0300
@@ -652,8 +652,8 @@
 void CLinkMgrProtocol::ExternalOpenInit()
 	{
 	LOG_FUNC
-	TRAP_IGNORE(iLocalNamePublisher = CEirPublisherLocalName::NewL());
-	TRAP_IGNORE(iTxPowerLevelPublisher = CEirPublisherTxPowerLevel::NewL());
+	TRAP_IGNORE(iLocalNamePublisher = CEirPublisherLocalName::NewL(*iEirManServer));
+	TRAP_IGNORE(iTxPowerLevelPublisher = CEirPublisherTxPowerLevel::NewL(*iEirManServer));
 	if(iLocalNamePublisher)
 		{
 		// Publish the initial name.
--- a/bluetooth/btstack/linkmgr/linkmgr.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmgr.h	Tue May 25 13:54:55 2010 +0300
@@ -128,14 +128,17 @@
 	
 	void Error(TInt anError,CProtocolBase* aSourceProtocol=NULL);
 
+public: // from CProtocolBase
+	// Ref Counting
+	void Close();
+	void Open();
+	
 private: // From CProtocolBase
 	// Factories
 	CHostResolvProvdBase* NewHostResolverL();
 	CServProviderBase* NewSAPL(TUint aSockType);
 	
 	// Ref Counting
-	void Close();
-	void Open();
 	void CloseNow();
 
 	// Others
--- a/bluetooth/btstack/linkmgr/physicallinks.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp	Tue May 25 13:54:55 2010 +0300
@@ -927,7 +927,12 @@
 void CPhysicalLink::ConnectionComplete(THCIErrorCode aErr, const TBTConnect& aConn)
 	{
 	LOG_FUNC
-	if (aErr == KErrNone)
+	ConnectionComplete(CHciUtil::SymbianErrorCode(aErr), aConn);
+	}
+
+void CPhysicalLink::ConnectionComplete(TInt aResult, const TBTConnect& aConn)
+	{
+	if (aResult == KErrNone)
 		{
 		if(aConn.iLinkType == ESCOLink && !iSyncLogicalLink)
 			{
@@ -936,12 +941,9 @@
 			//a remote device to respond to a connection request.
 			iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
 
-			if(aErr==EOK) // if error, aConn.iConnH will refer to the ACL link used to initialise the SCO link, so dont disconnect that
-				{
-				//The baseband might actually have established a SCO link, so send a Disconnect.
-				//If no SCO link exists the command will fail gracefully.
-				TRAP_IGNORE(iLinksMan.HCIFacade().DisconnectL(aConn.iConnH, ERemoteUserEndedConnection));
-				}
+			//The baseband might actually have established a SCO link, so send a Disconnect.
+			//If no SCO link exists the command will fail gracefully.
+			TRAP_IGNORE(iLinksMan.HCIFacade().DisconnectL(aConn.iConnH, ERemoteUserEndedConnection));
 
 			return;
 			}
@@ -989,7 +991,7 @@
 			if (aConn.iEncryptMode)
 				{
 				// pretend there's been an encryption event
-				EncryptionChange(aErr, aConn.iConnH, aConn.iEncryptMode);
+				EncryptionChange(EOK, aConn.iConnH, aConn.iEncryptMode);
 				}
 			}
 
@@ -1061,13 +1063,13 @@
 			}
 
 		iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
-		NotifyLogicalLinkError(aConn.iLinkType, CHciUtil::SymbianErrorCode(aErr));
+		NotifyLogicalLinkError(aConn.iLinkType, aResult);
 		if (aConn.iLinkType == EACLLink)
 			{
 			// BT 1.2 says that as the ACL Link goes up and down, so does the physical link
 			// so if the ACL Link has gone, so has this
 			// for SCO we remain in place.
-			TBTBasebandEventNotification event(ENotifyPhysicalLinkError, CHciUtil::SymbianErrorCode(aErr));
+			TBTBasebandEventNotification event(ENotifyPhysicalLinkError, aResult);
 			NotifyStateChange(event);
 			delete this;
 			}
@@ -1700,73 +1702,60 @@
 	{
 	LOG_FUNC
 	if (!IsConnected())
+		{
+		LOG(_L8("Physical link not connected, no arbitration executed"));
 		return KErrDisconnected;
-
-	if ( aImmediately )
-		{
-		iArbitrationDelay->Cancel();
-		return DoArbitrate(aLocalPriority);		
 		}
-	else if (iArbitrationDelay->IsActive())
-		{
-		return KErrNone;
-		}
-	else
-		{
-		iArbitrationDelay->Start(aLocalPriority);
-		return KErrNone;
-		}
+	// The arbitration delay object will decide how much delay
+	return iArbitrationDelay->Start(aImmediately, aLocalPriority);
 	}
 
 TInt CPhysicalLink::DoArbitrate(TBool aLocalPriority)
 	{
+	LOG_FUNC
 	if (!IsConnected())
 		{
+		LOG(_L8("Physical link not connected, no arbitration executed"));
 		return KErrDisconnected;
 		}
 
 	//start arbitrate process with what our local controller supports
 	TUint8 allowedModesMask = EHoldMode | EParkMode | ESniffMode; // local features sorted out later
-	TBool roleSwitchAllowed = EFalse;
-
- 	if (iLinksMan.LinkManagerProtocol().IsRoleSwitchSupportedLocally() && iLinksMan.RoleSwitchAllowed())
- 		{
- 		roleSwitchAllowed = ETrue;
- 		}
-
+	TBool roleSwitchAllowed = iLinksMan.LinkManagerProtocol().IsRoleSwitchSupportedLocally() && iLinksMan.RoleSwitchAllowed();
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - Prior to proxies"), allowedModesMask, roleSwitchAllowed);
+	
 	// ask proxies what they want from the PHY
- 	TUint8 requestedModeMask = 0;
- 	TUint8 requestedMode = 0;
- 	TBool activeModeIsRequested = EFalse;
+	TUint16 requestedModeMask = 0; // mask of current LPM requests from proxy's
+	static const TUint16 KExplicitActiveMode = 0x0100; // special bit for explicit active mode requests
+	
 	TSglQueIter<CBTProxySAP> iter(iProxySAPs);
 	while (iter)
 		{
 		CBTProxySAP* proxy = iter++;
 
- 		requestedMode = proxy->GetRequestedModes();
- 		requestedModeMask |= requestedMode;
-
-		if (requestedMode == EActiveMode && proxy->RequestedActiveMode())
- 			{
- 			// An Active Mode request will override all other local low power mode requests
- 			// but continue to collect the requirement from the other proxies..
- 			activeModeIsRequested = ETrue;
- 			}
-
-		allowedModesMask &= proxy->GetAllowedModes();
-		roleSwitchAllowed &= proxy->IsRoleSwitchAllowed();
+		TUint8 requestedMode = proxy->GetRequestedModes();
+		requestedModeMask |= requestedMode;
+
+		TBool explicitActiveModeRequest = proxy->RequestedActiveMode();
+		if (requestedMode == EActiveMode && explicitActiveModeRequest)
+			{
+			requestedModeMask |= KExplicitActiveMode;
+			}
+
+		TUint8 allowedModes = proxy->GetAllowedModes();
+		allowedModesMask &= allowedModes;
+		
+		TBool roleSwitchAllowedByProxy = proxy->IsRoleSwitchAllowed();
+		roleSwitchAllowed = roleSwitchAllowed && roleSwitchAllowedByProxy;
+		
+		LOG4(_L8("Arbitration: Proxy(0x%08x) - requested mode = 0x%04x, link policy (LPM:0x%02x, Role:0x%x)"), proxy, requestedMode, allowedModes, roleSwitchAllowedByProxy);
 		}
-
- 	if (activeModeIsRequested)
- 		{
- 		// Any Active Mode request will override all other low power mode requests,
- 		// so overwrite the requestedModeMask but keep allowedModesMask and roleSwitchAllowed
- 		// as specified by all the local proxies
- 		requestedModeMask = EActiveMode;
- 		}
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - after proxies"), allowedModesMask, roleSwitchAllowed);
 
 	// clear out modes not supported by local Controller
+	// Future improvement - what about modes supported by the remote device?
 	allowedModesMask &= iLinksMan.LinkManagerProtocol().ModesSupportedLocally();
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - only supported modes"), allowedModesMask, roleSwitchAllowed);
 
 	if(iOverrideParkRequests)
 		{
@@ -1774,13 +1763,11 @@
 		// The only way to guarantee this is to disallow PARK via the link policy settings.
 		allowedModesMask &= ~EParkMode;
 		}
-
-	if(allowedModesMask != iLinkPolicy.LowPowerModePolicy()
-		|| roleSwitchAllowed != iLinkPolicy.IsSwitchAllowed())
-		{
-		// Controller policy for the connection needs updating
-		SetModesAllowed(allowedModesMask, roleSwitchAllowed);
-		}
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - overrides applied"), allowedModesMask, roleSwitchAllowed);
+
+	// Controller policy for the connection may need updating
+	SetModesAllowed(allowedModesMask, roleSwitchAllowed);
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - submitted"), allowedModesMask, roleSwitchAllowed);
 
 	//If OverrideLPM flag is set, we do not disable LP modes via the link policy settings
 	//This is done because OverrideLPM should not prevent remotes putting us into an LPM
@@ -1790,9 +1777,11 @@
 		// We need to ensure the physical link is in active mode.
 		allowedModesMask = EActiveMode;
 		}
-
-	TUint8 modeChangeMask = static_cast<TUint8>(requestedModeMask & allowedModesMask);
-	TUint8 modeCompareMask = 0;
+	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - post setting overrides applied"), allowedModesMask, roleSwitchAllowed);
+
+	TUint16 modeChangeMask = requestedModeMask & (static_cast<TUint16>(allowedModesMask)|KExplicitActiveMode);
+	TUint16 modeCompareMask = 0;
+	LOG2(_L8("Arbitration: mode change mask = 0x%04x, local priority = 0x%x"), modeChangeMask, aLocalPriority);
 
 	if(aLocalPriority)
 		{
@@ -1809,57 +1798,89 @@
 		// modeCompareMask should start only having zero bits where
 		// requestedModeMask has a zero bit and iPreviousRequestedModeMask does not
 		// i.e. a mode is newly no longer requested.
-		modeCompareMask = requestedModeMask | ~iPreviousRequestedModeMask;
+		modeCompareMask = ~((requestedModeMask ^ iPreviousRequestedModeMask) & iPreviousRequestedModeMask);
 
 		// Remove bits from modeCompareMask that are not in allowedModesMask
 		// We cannot stay in a power mode that we do not allow.
-		modeCompareMask &= allowedModesMask;
+		modeCompareMask &= (static_cast<TUint16>(allowedModesMask)|KExplicitActiveMode);
 		}
+	LOG1(_L8("Arbitration: Comparison mask = 0x%04x"), modeCompareMask);
 
 	iPreviousRequestedModeMask = requestedModeMask; // Update previous requested to current value.
 
-	TUint8 currentModeMask = static_cast<TUint8>(iLinkState.LinkMode());
+	// get the current mode.
+	TBTLinkMode currentMode = iLinkState.LinkMode();
+	TUint16 currentModeMask = static_cast<TUint16>(currentMode);
+	if(currentModeMask == EActiveMode)
+		{
+		// if in active mode then could have been because of an explicit active mode request
+		currentModeMask |= KExplicitActiveMode;
+		}
+	LOG1(_L8("Arbitration: Current mode mask = 0x%04x"), currentModeMask);
+	
 	if(modeCompareMask & currentModeMask)
 		{
+		LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask);
 		// The current state is the same as the permitted required role(s).
 		return KErrNone;
 		}
-
-	if(modeChangeMask == EActiveMode && currentModeMask != EActiveMode)
+	
+	TBTLinkMode nextMode = EActiveMode;
+	// Determine which LPM we should be in (if any)
+	if(modeChangeMask & KExplicitActiveMode)
 		{
-		// The current low power mode should be exited.
-		return RequestActive();
+		nextMode = EActiveMode;
 		}
-
-	if(modeChangeMask != EActiveMode)
+	else if(modeChangeMask & EHoldMode)
+		{
+		nextMode = EHoldMode;
+		}
+	else if(modeChangeMask & ESniffMode)
 		{
-		if(currentModeMask != EActiveMode)
+		nextMode = ESniffMode;
+		}
+	else if(modeChangeMask & EParkMode)
+		{
+		nextMode = EParkMode;
+		}
+	LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, nextMode);
+	
+	if(nextMode != currentMode)
+		{
+		if(currentMode != EActiveMode)
 			{
-			// The system is currently in a low power mode.  Exit this before
-			// entering the new mode.
-			TInt rerr = RequestActive();
-			if(rerr != KErrNone)
+			LOG(_L8("Arbitration: Exiting existing LPM mode..."));
+			TInt err = RequestActive();
+			if(err != KErrNone)
 				{
-				return rerr;
+				return err;
 				}
 			}
-
-		if(modeChangeMask & EHoldMode)
+		if(nextMode == EHoldMode)
 			{
+			LOG(_L8("Arbitration: Entering Hold mode..."));
 			return RequestHold();
 			}
-		if(modeChangeMask & ESniffMode)
+		else if(nextMode == ESniffMode)
 			{
+			LOG(_L8("Arbitration: Entering Sniff mode..."));
 			return RequestSniff();
 			}
-		if(modeChangeMask & EParkMode)
+		else if(nextMode == EParkMode)
 			{
+			LOG(_L8("Arbitration: Entering Park mode..."));
 			return RequestPark();
 			}
+		else if(nextMode == EActiveMode)
+			{
+			LOG(_L8("Arbitration: Staying in Active mode..."));
+			return KErrNone;
+			}
+		// Shouldn't reach here, we have a strange mode
+		DEBUG_PANIC_LINENUM;
 		}
 
-	// This point in the code is reached if the Link Policy settings are
-	// changed but the mode is not.	 Return OK error code.
+	LOG(_L8("Arbitration: Already in correct LPM, not doing anything"));
 	return KErrNone;
 	}
 
@@ -1880,10 +1901,10 @@
 void CPhysicalLink::StartArbitrationTimer() const
 	{
 	LOG_FUNC
-	iArbitrationDelay->Start();
+	iArbitrationDelay->Restart();
 	}
 
-TInt CPhysicalLink::Connect(TBasebandPageTimePolicy aPolicy)
+void CPhysicalLink::Connect(TBasebandPageTimePolicy aPolicy)
 	{
 	LOG_FUNC
 	// assume that we will be master until told otherwise
@@ -1902,16 +1923,20 @@
 	// optimise paging (as a best-effort attempt).
 	TBasebandTime pagetimeout = CalculatePageTimeout(aPolicy, psrm, clockOffset & KHCIClockOffsetValidBit);
 	iLinksMan.TryToChangePageTimeout(pagetimeout);
+	
+	// Set state in anticipation of the connection
+	iLinkState.SetLinkState(TBTBasebandLinkState::ELinkPending);
+	iLinksMan.Baseband().UpdateModel(iDevice.Address(), pkt, EACLLink);
+	iLinkState.SetLinkRole(EMaster);
 
 	TRAPD(ret, iLinksMan.HCIFacade().ConnectL(iDevice.Address(), pkt, psrm, psm, clockOffset, allowRoleSwitch));
-	if(ret==KErrNone)
+	if(ret != KErrNone) // a physical link is in charge of it's own destiny.
 		{
-		iLinkState.SetLinkState(TBTBasebandLinkState::ELinkPending);
-		iLinksMan.Baseband().UpdateModel(iDevice.Address(), pkt, EACLLink);
-		iLinkState.SetLinkRole(EMaster);
+		TBTConnect conn;
+		conn.iBdaddr = BDAddr();
+		conn.iLinkType = EACLLink;
+		ConnectionComplete(ret, conn);
 		}
-
-	return ret;
 	}
 
 TInt CPhysicalLink::SCOConnect()
@@ -2264,7 +2289,7 @@
 		(aEvent.EventType() & ENotifyHoldMode)) &&
 		(aEvent.ErrorCode() == KErrNone))
 		{
-		iArbitrationDelay->Start();
+		iArbitrationDelay->Restart();
 		}
 	}
 
@@ -3378,17 +3403,18 @@
 // CArbitrationDelayTimer
 
 CArbitrationDelayTimer::CArbitrationDelayTimer(CPhysicalLink* aParent)
-	:CTimer(CActive::EPriorityStandard),
-	iParent(aParent)
+	: CTimer(CActive::EPriorityStandard)
+	, iParent(aParent)
 	{
 	LOG_FUNC
+	ASSERT_DEBUG(iParent);
+	CActiveScheduler::Add(this);
 	}
 
 void CArbitrationDelayTimer::ConstructL()
 	{
 	LOG_FUNC
 	CTimer::ConstructL();
-	CActiveScheduler::Add(this);
 	}
 
 CArbitrationDelayTimer* CArbitrationDelayTimer::NewL(CPhysicalLink* aParent)
@@ -3401,16 +3427,46 @@
 	return self;
 	}
 
-void CArbitrationDelayTimer::Start(TBool aLocalPriority)
+TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority)
 	{
 	LOG_FUNC
 	// Work out what the local priority will be now
-	TBool localPriority = iLocalPriority || aLocalPriority;
-	Cancel(); // cancel current timer (will also reset priority so ...
-	iLocalPriority = localPriority; // set the new priority)
+	iLocalPriority = iLocalPriority || aLocalPriority;
+	LOG1(_L8("Arbitraion: Local Priority now %d"), iLocalPriority);
+	if(aImmediate)
+		{
+		LOG(_L8("Arbitraion: Immediate Arbitration Requested..."));
+		CancelButPreserveLocalPriority();
+		return DoArbitrate();
+		}
+	else if(!IsActive())
+		{
+		LOG(_L8("Arbitraion: Arbitration requested, will execute after delay timer..."));
+		After(KBTArbitrationDelay);
+		}
+	else // timer is already on its way
+		{
+		LOG(_L8("Arbitraion: Arbitration delay timer still pending..."));
+		}
+	return KErrNone;
+	}
+
+void CArbitrationDelayTimer::Restart()
+	{
+	LOG_FUNC
+	LOG(_L8("Arbitraion: Arbitration timer restarted..."));
+	CancelButPreserveLocalPriority();
 	After(KBTArbitrationDelay);
 	}
 
+void CArbitrationDelayTimer::CancelButPreserveLocalPriority()
+	{
+	LOG_FUNC
+	TBool localPriority = iLocalPriority;
+	Cancel();
+	iLocalPriority = localPriority;
+	}
+
 
 void CArbitrationDelayTimer::RunL()
 /**
@@ -3418,10 +3474,16 @@
 **/
 	{
 	LOG_FUNC
-	if (iParent)
-		{
-		iParent->DoArbitrate(iLocalPriority);
-		}
+	LOG(_L8("Arbitraion: Delayed Arbitration executing..."));
+	static_cast<void>(DoArbitrate()); // ignore the error (always has been...)
+	}
+
+TInt CArbitrationDelayTimer::DoArbitrate()
+	{
+	LOG_FUNC
+	TBool localPriority = iLocalPriority;
+	iLocalPriority = EFalse;
+	return iParent->DoArbitrate(localPriority);
 	}
 
 void CArbitrationDelayTimer::DoCancel()
--- a/bluetooth/btstack/linkmgr/physicallinks.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.h	Tue May 25 13:54:55 2010 +0300
@@ -70,17 +70,20 @@
 	{
 public:
 	static CArbitrationDelayTimer* NewL(CPhysicalLink* aParent);
-    void Start(TBool aLocalPriority=EFalse);
-	
+	TInt Start(TBool aImmediate, TBool aLocalPriority);
+	void Restart();
+
 private:
 	CArbitrationDelayTimer(CPhysicalLink* aParent);
 	void ConstructL();
 	void RunL();
-    void DoCancel();
-    
+	void DoCancel();
+	TInt DoArbitrate();
+	void CancelButPreserveLocalPriority();
+
 private:
-	CPhysicalLink* 	iParent;
-    TBool iLocalPriority;	
+	CPhysicalLink* iParent;
+	TBool iLocalPriority;
 	};
 
 
@@ -296,15 +299,14 @@
 	inline TBTBasebandRole Role() const;
 	void SetDeviceNamePending(TBool aBool);
 	TInt GetOption(TUint aLevel,TUint aName,TDes8& aOption) const;
-	TInt Connect(TBasebandPageTimePolicy aPolicy=EPagingNormal);
+	void Connect(TBasebandPageTimePolicy aPolicy=EPagingNormal);
 	TInt SCOConnect();
 	TInt SCOConnect(const TUint16 aUserHVPacketTypes);
 	TInt SynchronousConnect(TUint aTransmitBandwidth, TUint aReceiveBandwidth,
 		TUint16 aMaxLatency, TUint16 aVoiceSettings,
 		TUint8 aRetransmissionEffort, const TBTSyncPacketTypes aUserPacketTypes);
-	TInt PassiveOpen();
-    TInt Arbitrate(TBool aImmediately=EFalse, TBool aLocalPriority=EFalse); 
-    TInt DoArbitrate(TBool aLocalPriority);
+	TInt Arbitrate(TBool aImmediately=EFalse, TBool aLocalPriority=EFalse); 
+	TInt DoArbitrate(TBool aLocalPriority);
 	void SetPassKey(const TDesC8& aPassKey);
 	const TBTPinCode& PassKey() const;		
 
@@ -374,6 +376,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);
+	
+	void ConnectionComplete(TInt aResult, const TBTConnect& aConn);
 
 	TBool LinkKeyRequestPending();
 	void SetAuthenticationPending(TUint8 aFlag);
@@ -553,7 +557,7 @@
 	TDeltaTimerEntry			iOverrideLPMTimerEntry;
 
 	TLinkPolicy					iLinkPolicy;
-	TUint8 						iPreviousRequestedModeMask;
+	TUint16						iPreviousRequestedModeMask;
 	TBool						iOverrideParkRequests; //for maybe temporary unpark
 	TBool						iOverrideLPMRequests; //for maybe temporary force active
 	TBool						iLPMOverrideTimerQueued;
--- a/bluetooth/btstack/rfcomm/rfcommmuxchannel.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.cpp	Tue May 25 13:54:55 2010 +0300
@@ -210,6 +210,11 @@
 	{
 	return EFalse;
 	}
+	
+TBool TMuxChannelState::IsErrored(CRfcommMuxChannel& /*aContext*/)
+	{
+	return EFalse;
+	}	
 
 void TMuxChannelState::UA(CRfcommMuxChannel& /*aContext*/)
 	/**
@@ -463,6 +468,11 @@
 	return EFalse;
 	}
 
+TBool TMuxChannelStateError::IsErrored(CRfcommMuxChannel& /*aContext*/)
+	{
+	return ETrue;
+	}
+
 /*
   Connected.  Super state for several states
 */
--- a/bluetooth/btstack/rfcomm/rfcommmuxchannel.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.h	Tue May 25 13:54:55 2010 +0300
@@ -89,6 +89,7 @@
 	void Open();
 	void Close();
 	TBool IsOpen();
+	TBool IsErrored();
 	TInt MaxDataSize();
 
 	// Rfcomm events
@@ -142,6 +143,7 @@
 	virtual void Open(CRfcommMuxChannel& aContext);
 	virtual void Close(CRfcommMuxChannel& aContext);
 	virtual TBool IsOpen(CRfcommMuxChannel& aContext);
+	virtual TBool IsErrored(CRfcommMuxChannel& aContext);
 	virtual void UA(CRfcommMuxChannel& aContext);
 	virtual void DISC(CRfcommMuxChannel& aContext);
 	virtual void DM(CRfcommMuxChannel& aContext);
@@ -221,6 +223,7 @@
 	void Open(CRfcommMuxChannel& aContext);
 	void Close(CRfcommMuxChannel& aContext);
 	TBool CanAttachSAP();
+	TBool IsErrored(CRfcommMuxChannel& aContext);
 	};
 
 /**
--- a/bluetooth/btstack/rfcomm/rfcommmuxchannel.inl	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.inl	Tue May 25 13:54:55 2010 +0300
@@ -28,6 +28,11 @@
 	return iState->IsOpen(*this);
 	}
 
+inline TBool CRfcommMuxChannel::IsErrored()
+	{
+	return iState->IsErrored(*this);
+	}
+
 inline TInt CRfcommMuxChannel::MaxDataSize()
 	{
 	return iMaxDataSize;
--- a/bluetooth/btstack/rfcomm/rfcommmuxer.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxer.cpp	Tue May 25 13:54:55 2010 +0300
@@ -209,9 +209,17 @@
 	DequeIdleTimer();
 	iSAPs.AddFirst(aSAP);
 	if(iMuxChannel->IsOpen())
+		{
 		aSAP.MuxUp();
+		}
+	else if (iMuxChannel->IsErrored())
+		{
+		aSAP.Error(KErrRfcommMuxChannelErrored, CRfcommSAP::EErrorFatal);
+		}
 	else
+		{
 		iMuxChannel->Open();  // Eventually calls back
+		}
 	}
 
 void CRfcommMuxer::DetachSAP(CRfcommSAP& aSAP)
--- a/bluetoothmgmt/bluetoothclientlib/inc/bt_sock.h	Tue May 11 17:15:36 2010 +0300
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bt_sock.h	Tue May 25 13:54:55 2010 +0300
@@ -615,6 +615,7 @@
 const static TInt KErrRfcommParameterNegotiationFailure = KRFErrorBase-7;	/*!< RFCOMM parameter negotiation failure error code. */
 const static TInt KErrRfcommNotListening = KRFErrorBase-8;					/*!< RFCOMM not listening error code. */
 const static TInt KErrRfcommNoMoreServerChannels = KRFErrorBase-9;			/*!< RFCOMM no more server channels available error code. */
+const static TInt KErrRfcommMuxChannelErrored = KRFErrorBase-10;			/*!< RFCOMM Mux channel errored */
 
 //RFCOMMIoctls
 
--- a/bt_plat/bluetooth_audio_adaptation_api/inc/btaudiostreaminputbase.h	Tue May 11 17:15:36 2010 +0300
+++ b/bt_plat/bluetooth_audio_adaptation_api/inc/btaudiostreaminputbase.h	Tue May 25 13:54:55 2010 +0300
@@ -21,7 +21,7 @@
 
 #include <e32base.h>
 #include <e32std.h>
-#include <mmf/common/MmfUtilities.h> 
+#include <mmf/common/mmfutilities.h> 
 
 /**
  *  Observer interface for receiving the audio data buffers.