--- 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.