--- a/bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2001-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"
@@ -19,6 +19,7 @@
#include <btextnotifiersconsts.h>
#include <bttypes.h>
#include <btdevice.h>
+#include <bluetooth/hci/hcitypes.h>
/**
@publishedPartner
--- a/bluetooth/btstack/common/bt_v2.mmp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/common/bt_v2.mmp Tue Jul 06 15:33:04 2010 +0300
@@ -69,6 +69,7 @@
SOURCE Subscribers.cpp
SOURCE btcommands.cpp
SOURCE AclDataQ.cpp
+SOURCE hostmbufpool.cpp
SOURCE AclDataQController.cpp
SOURCE bredrcontrollerconfiguration.cpp
@@ -231,6 +232,7 @@
MACRO CONNECTION_PREEMPTS_INQUIRY
//MACRO KEEP_L2CAP_DEBUG_STATISTICS
MACRO BT_LINKMGR_V2
+MACRO HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
OPTION cw -strict on -w pedantic,unused,hidevirtual,padding,ptrintconv
--- a/bluetooth/btstack/eirman/eirmanager.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanager.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanager.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanserver.cpp Tue Jul 06 15:33:04 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);
}
}
}
@@ -171,42 +209,46 @@
_LIT_SECURITY_POLICY_S0(KSDPSecurityPolicy, KSDPServerID);
_LIT_SECURITY_POLICY_S0(KStackSecurityPolicy, KStackID);
_LIT_SECURITY_POLICY_C1(KVendorSpecificDataSecurityPolicy, ECapabilityWriteDeviceData);
- if(function == EEirManRegisterTag)
+ _LIT_SECURITY_POLICY_C1(KEirCommonSecurityPolicy, ECapabilityLocalServices);
+
+ if(KEirCommonSecurityPolicy.CheckPolicy(aMsg))
{
- tag = static_cast<TEirTag>(aMsg.Int0());
- switch(tag)
+ if(function == EEirManRegisterTag)
{
- case EEirTagName:
- case EEirTagTxPowerLevel:
- /** These must have come from the stack **/
- if(KStackSecurityPolicy.CheckPolicy(aMsg))
- {
- result = EPass;
- }
- break;
- case EEirTagSdpUuid16:
- case EEirTagSdpUuid32:
- case EEirTagSdpUuid128:
- /** These must have come from SDP server **/
- if(KSDPSecurityPolicy.CheckPolicy(aMsg))
- {
- result = EPass;
- }
- break;
- case EEirTagManufacturerSpecific:
- /** To do this you must have write device data **/
- if(KVendorSpecificDataSecurityPolicy.CheckPolicy(aMsg))
- {
- result = EPass;
- }
- break;
-
- case EEirTagFlags:
- /** At present no implementation of Flags is supported.
- So we are rejecting this until an implementation is provided. **/
- default: //unknown or reserved tag, reject
- //no need to do anything
- break;
+ tag = static_cast<TEirTag>(aMsg.Int0());
+ switch(tag)
+ {
+ case EEirTagName:
+ case EEirTagTxPowerLevel:
+ /** These must have come from the stack **/
+ if(KStackSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+ case EEirTagSdpUuid16:
+ case EEirTagSdpUuid32:
+ case EEirTagSdpUuid128:
+ /** These must have come from SDP server **/
+ if(KSDPSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+ case EEirTagManufacturerSpecific:
+ /** To do this you must have write device data **/
+ if(KVendorSpecificDataSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+ case EEirTagFlags:
+ /** At present no implementation of Flags is supported.
+ So we are rejecting this until an implementation is provided. **/
+ default: //unknown or reserved tag, reject
+ //no need to do anything
+ break;
+ }
}
}
//Anything not covered by the above is invalid so do nothing and let it fail
--- a/bluetooth/btstack/eirman/eirmanserver.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanserver.h Tue Jul 06 15:33:04 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/eirmanserversecuritypolicy.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmanserversecuritypolicy.h Tue Jul 06 15:33:04 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,7 +58,7 @@
/** Main policy */
const CPolicyServer::TPolicy KEirManServerPolicy =
{
- CPolicyServer::EAlwaysPass , /** Specifies all connect attempts should pass */
+ KPolicyCapabilityCheck , /** Connect attempts are only successful if the caller has ECapabilityLocalServices */
KEirManServerRangeCount,
KEirManServerRanges,
KEirManServerElementsIndex,
--- a/bluetooth/btstack/eirman/eirmansession.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmansession.cpp Tue Jul 06 15:33:04 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,70 +62,24 @@
LOG_FUNC
// deregister any registered tag that may be registered
DeregisterTag();
- if(!iDataAvailableListenerMessage.IsNull())
- {
- // complete any outstanding messages.
- iDataAvailableListenerMessage.Complete(KErrCancel);
- }
- iEirManServer.DropSession();
+ iLink.Deque();
+ iEirManServer.DropSession(iInternalSession);
}
-void CEirManSession::ServiceL(const RMessage2& aMessage)
- {
- LOG_FUNC
- LOG1(_L("CEirManSession::ServiceL aMessage.Function() = %d"), aMessage.Function());
- TBool complete = ETrue;
- TInt ret = KErrNone;
-
- switch (aMessage.Function())
- {
- case EEirManRegisterTag:
- complete = EFalse; // always async.
- RegisterTag(aMessage);
- break;
-
- case EEirManSpaceAvailableNotification:
- ret = RegisterSpaceAvailableListener(aMessage, complete);
- break;
-
- case EEirManCancelSpaceAvailableNotification:
- ret = CancelSpaceAvailableListener();
- break;
-
- case EEirManSetData:
- ret = SetData(aMessage);
- break;
-
- case EEirManNewData:
- ret = NewData(aMessage);
- break;
-
- default:
- aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidIPC);
- break;
- }
-
- if (complete)
- {
- aMessage.Complete(ret);
- }
- }
-
-void CEirManSession::RegisterTag(const RMessage2& aMessage)
+void CEirManSession::RegisterTag(TEirTag aTag)
{
LOG_FUNC
- TEirTag tag = static_cast<TEirTag>(aMessage.Int0());
- LOG1(_L("CEirManSession::RegisterTag tag = %d"), tag);
+ LOG1(_L("CEirManSession::RegisterTag tag = %d"), aTag);
- if(!(tag >= EEirTagName && tag < EEirTagRESERVED))
+ if(!(aTag >= EEirTagName && aTag < EEirTagRESERVED))
{
- __ASSERT_ALWAYS(EFalse, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
+ iParent.MesnRegisterComplete(KErrArgument);
}
else if(iEirTag != EEirTagRESERVED)
{
LOG1(_L("CEirManSession::RegisterTag ERROR, Tag in use: %d"), iEirTag);
- aMessage.Complete(KErrInUse);
+ iParent.MesnRegisterComplete(KErrInUse);
}
else
{
@@ -131,23 +87,23 @@
if(iEirManServer.EirFeatureState() == EEirFeatureReady)
{
// Eir is supported
- TInt result = iEirManServer.EirManager().RegisterTag(tag, *this);
+ TInt result = iEirManServer.EirManager().RegisterTag(aTag, *this);
if(result == KErrNone)
{
- iEirTag = tag;
+ iEirTag = aTag;
}
- aMessage.Complete(result);
+ iParent.MesnRegisterComplete(result);
}
else if(iEirManServer.EirFeatureState() == EEirFeaturePending)
{
// We don't know if eir is supported or not at this moment
- iPendingEirTag = tag;
- iRegisterMessage = aMessage;
+ iRegisterPending = ETrue;
+ iPendingEirTag = aTag;
}
else
{
// Eir is not supported
- aMessage.Complete(KErrNotSupported);
+ iParent.MesnRegisterComplete(KErrNotSupported);
}
}
}
@@ -169,7 +125,7 @@
void CEirManSession::NotifyEirFeatureState(TInt aResult)
{
LOG1(_L("Eir Server has been notified feature ready, result: %d"), aResult);
- if(aResult == KErrNone && !iRegisterMessage.IsNull())
+ if(aResult == KErrNone && iRegisterPending)
{
__ASSERT_DEBUG(iEirManServer.EirFeatureState() == EEirFeatureReady, EIR_SESSION_PANIC(EEirSessionEirFeatureNotSupported));
TInt result = iEirManServer.EirManager().RegisterTag(iPendingEirTag, *this);
@@ -177,80 +133,28 @@
{
iEirTag = iPendingEirTag;
}
- iRegisterMessage.Complete(result);
+ iRegisterPending = EFalse;
+ iParent.MesnRegisterComplete(result);
}
- else if(!iRegisterMessage.IsNull())
+ else if(iRegisterPending)
{
- iRegisterMessage.Complete(aResult);
+ iRegisterPending = EFalse;
+ iParent.MesnRegisterComplete(aResult);
}
}
-TInt CEirManSession::RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete)
- {
- LOG_FUNC
- if(iDataAvailableListenerMessage.Handle())
- {
- LOG(_L("CEirManSession:::RegisterSpaceAvailableListener ERROR IN USE"));
- return KErrInUse;
- }
-
- iDataAvailableListenerMessage = aMessage;
-
- aComplete = EFalse;
-
- if(iLastSpaceOffered != 0)
- {
- LOG(_L("cached space present, completing immediately"));
- CompleteSpaceAvailableRequest(iLastSpaceOffered);
- iLastSpaceOffered = 0;
- return KErrNone;
- }
-
- LOG(_L("waiting for callback..."));
- return KErrNone;
- }
-
-TInt CEirManSession::NewData(const RMessage2& aMessage)
+TInt CEirManSession::NewData(TInt aRequiredLength)
{
LOG_FUNC
- __ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
- TInt requiredLength = static_cast<TInt>(aMessage.Int0());
-
- return iEirManServer.EirManager().NewData(iEirTag, requiredLength);
+ return iEirManServer.EirManager().NewData(iEirTag, aRequiredLength);
}
-TInt CEirManSession::CancelSpaceAvailableListener()
+
+TInt CEirManSession::SetData(const TDesC8& aData, TEirDataMode aMode)
{
LOG_FUNC
-
- if(!iDataAvailableListenerMessage.Handle())
- {
- return KErrNotFound;
- }
-
- iDataAvailableListenerMessage.Complete(KErrCancel);
-
- return KErrNone;
- }
-
-TInt CEirManSession::SetData(const RMessage2& aMessage)
- {
- LOG_FUNC
- __ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
- TEirDataMode eirDataMode = static_cast<TEirDataMode>(aMessage.Int1());
- LOG2(_L("Tag: %d EirDataMode: %d"), iEirTag, 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
- TBuf8<KHCIExtendedInquiryResponseMaxLength> data;
- TInt err = aMessage.Read(0, data);
-
- if(err == KErrNone)
- {
- err = iEirManServer.EirManager().SetData(iEirTag, data, eirDataMode);
- }
- return err;
+ return iEirManServer.EirManager().SetData(iEirTag, aData, aMode);
}
// Callback from the EIR Manager
@@ -267,6 +171,181 @@
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);
+ }
+ delete iSession;
+ }
+/*
+ * Each of the individual methods is responsible for completing the message.
+ * All 'leaves' are processed in CSession2::ServiceError() resulting in message completion
+ * with the appropriate error code.
+ * RegisterTagL() and RegisterSpaceAvailableListenerL() store aMessage parameter for the future use
+ * when the callbacks are called.
+ */
+void CEirManExternalSession::ServiceL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+ LOG1(_L("CEirManSession::ServiceL aMessage.Function() = %d"), aMessage.Function());
+
+ switch (aMessage.Function())
+ {
+ case EEirManRegisterTag:
+ RegisterTagL(aMessage);
+ break;
+
+ case EEirManSpaceAvailableNotification:
+ RegisterSpaceAvailableListenerL(aMessage);
+ break;
+
+ case EEirManCancelSpaceAvailableNotification:
+ CancelSpaceAvailableListenerL(aMessage);
+ break;
+
+ case EEirManSetData:
+ SetDataL(aMessage);
+ break;
+
+ case EEirManNewData:
+ NewDataL(aMessage);
+ break;
+
+ default:
+ aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidIPC);
+ break;
+ }
+ }
+
+void CEirManExternalSession::RegisterTagL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+ TEirTag tag = static_cast<TEirTag>(aMessage.Int0());
+ LOG1(_L("CEirManSession::RegisterTag tag = %d"), tag);
+
+ iRegisterMessage = aMessage;
+
+ iSession->RegisterTag(tag);
+ }
+
+void CEirManExternalSession::MesnRegisterComplete(TInt aResult)
+ {
+ if (aResult == KErrArgument)
+ {
+ iRegisterMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag);
+ }
+ else
+ {
+ iRegisterMessage.Complete(aResult);
+ }
+ }
+
+void CEirManExternalSession::RegisterSpaceAvailableListenerL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+
+ if(iDataAvailableListenerMessage.Handle())
+ {
+ LOG(_L("CEirManSession:::RegisterSpaceAvailableListener ERROR IN USE"));
+ LEAVEL(KErrInUse);
+ }
+
+ iDataAvailableListenerMessage = aMessage;
+
+ if(iLastSpaceOffered != 0)
+ {
+ LOG(_L("cached space present, completing immediately"));
+ CompleteSpaceAvailableRequest(iLastSpaceOffered);
+ iLastSpaceOffered = 0;
+ return;
+ }
+
+ LOG(_L("waiting for callback..."));
+ }
+
+void CEirManExternalSession::NewDataL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+
+ if (iSession->EirTag() == EEirTagRESERVED)
+ {
+ aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag);
+ return;
+ }
+
+ TInt requiredLength = static_cast<TInt>(aMessage.Int0());
+
+ LEAVEIFERRORL(iSession->NewData(requiredLength));
+ aMessage.Complete(KErrNone);
+ }
+
+void CEirManExternalSession::CancelSpaceAvailableListenerL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+
+ if(!iDataAvailableListenerMessage.Handle())
+ {
+ LEAVEL(KErrNotFound);
+ }
+
+ iDataAvailableListenerMessage.Complete(KErrCancel);
+ aMessage.Complete(KErrNone);
+ }
+
+void CEirManExternalSession::SetDataL(const RMessage2& aMessage)
+ {
+ LOG_FUNC
+ if (iSession->EirTag() == EEirTagRESERVED)
+ {
+ aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag);
+ return;
+ }
+
+ TEirDataMode eirDataMode = static_cast<TEirDataMode>(aMessage.Int1());
+ 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
+ TBuf8<KHCIExtendedInquiryResponseMaxLength> data;
+ LEAVEIFERRORL(aMessage.Read(0, data));
+
+ LEAVEIFERRORL(iSession->SetData(data, eirDataMode));
+ aMessage.Complete(KErrNone);
+ }
+
+void CEirManExternalSession::MesnSpaceAvailable(TUint aSpaceForTag)
+ {
if(iDataAvailableListenerMessage.Handle())
{
LOG(_L("Listener outstanding, completing request"));
@@ -282,14 +361,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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmansession.h Tue Jul 06 15:33:04 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:
- static CEirManSession* NewL(CEirManServer& aServer);
+ 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, 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();
+
+private: // from MEirManagerNotifiee
+ virtual void MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag);
- // ServiceL handlers
- void RegisterTag(const RMessage2& aMessage);
- TInt RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete);
- TInt CancelSpaceAvailableListener();
- TInt SetData(const RMessage2& aMessage);
- TInt NewData(const RMessage2& aMessage);
+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 RegisterTagL(const RMessage2& aMessage);
+ void RegisterSpaceAvailableListenerL(const RMessage2& aMessage);
+ void CancelSpaceAvailableListenerL(const RMessage2& aMessage);
+ void NewDataL(const RMessage2& aMessage);
+ void SetDataL(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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSAPSignalHandler.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSigStates.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2capSigStates.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/l2cap/l2util.h Tue Jul 06 15:33:04 2010 +0300
@@ -172,7 +172,8 @@
EL2CAPNullOwnerSupplied = 148,
EL2CAPTryingToStealOwnedPdu = 149,
EL2CapConstructingPositiveConfigResponseWithUnresolvedOptionStatus = 200,
- EL2CapReferencingUnackedIFrameWhenNoRetransmissionGoing = 274,
+ EL2CapReferencingUnackedIFrameWhenNoRetransmissionGoing = 274,
+ EL2CapAttemptToStartConfigTimerWhenItIsRunning = 275,
};
/**
--- a/bluetooth/btstack/linkmgr/ACLSAP.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ACLSAP.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -19,6 +19,7 @@
#include <bluetooth/logger.h>
#include <bt_sock.h>
#include <bluetooth/hci/aclpacketconsts.h>
+#include <bluetooth/hci/hciconsts.h>
#include "ACLSAP.h"
#include "physicallinks.h"
@@ -1089,13 +1090,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();
}
}
@@ -1333,53 +1328,34 @@
iState->Shutdown(*this, aOption);
}
-
void CACLLink::NotifyDataToSocket(TUint8 aFlag, const TDesC8& aData)
{
LOG_FUNC
- const TUint8 KFlagHeaderSize =1;
/*
The design of the protocol specification for L2CAP
means that both we and L2CAP need to know the flag parameter
for now we just signal one datagram (*could* signal two - one for flag: but that's just as grubby)
*/
+ RMBufChain aclData;
- // make a new chain consisting of Flag(1st octet) followed by Data.
- RMBufChain aclData;
- #ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- THCIConnHandle connH=iHandle;
- aclData = const_cast<CHCIFacade&>(iLinksMan.HCIFacade()).TakeInboundACLDataBufferFromPool(connH);
- aclData.CopyIn(aData,KFlagHeaderSize);
- aclData.TrimEnd(aData.Length()+KFlagHeaderSize); //return the reserved MBufs we didn't need
- //to the global pool
- #else
- TRAPD(err, aclData.CreateL(aData, KFlagHeaderSize));
-
+ CACLDataQController& aclQctrl = iProtocol.ACLController();
+ THCIConnHandle connH = iHandle;
+ TRAPD(err, aclData = aclQctrl.PopulateInboundBufferL(connH, aFlag, aData));
if (err)
{
- //Since HC->H flow control is off, and we have run out of MBufs
- //there is nothing we can do here but drop or disconnect the link
- //due to limited resources. We drop.
+ // We have run out of MBufs, there is nothing we can do here but
+ // 1) drop the received packet, or
+ // 2) disconnect the link
+ // We drop the packet to be multi-profile "friendly"
+ LOG1(_L8("*** ERROR: Dropping ACL Data!!! (error = %d) ***"), err);
return;
}
- #endif
-
- aclData.First()->Ptr()[0] = aFlag; // aData is already in the chain
-
-
+
// slap onto the RMBufPacketQ
iInboundBuffer.Append(aclData); // transfers
-
- #ifndef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- if (!err)
- {
- #endif
- iSocket->NewData(1); // datagrams: could async notify - or get l2cap to drain async
- #ifndef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- }
- #endif
+ iSocket->NewData(1); // datagrams: could async notify - or get l2cap to drain async
}
--- a/bluetooth/btstack/linkmgr/AclDataQController.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/AclDataQController.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -20,10 +20,14 @@
//
#include <bluetooth/logger.h>
+#include <bluetooth/hci/hciconsts.h>
#include "AclDataQController.h"
#include "linkmgr.h"
#include "AclDataQ.h"
#include "hcifacade.h"
+#include "hostmbufpool.h"
+#include "linkflowcontrol.h"
+#include "linkconsts.h"
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
@@ -50,8 +54,6 @@
CleanupStack::PushL(self);
self->ConstructL(aProtocol, aBufSize, aFrameOverhead, aNumBufs);
CleanupStack::Pop(self);
-
- LOG1(_L("CACLDataQController::NewL self = 0x%08x"), self);
return self;
}
@@ -67,7 +69,11 @@
CACLDataQController::~CACLDataQController()
{
LOG_FUNC
-
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ delete iMBufPool;
+#endif
+
delete iDataQ;
iAclConns.Reset();
iAclConns.Close();
@@ -81,6 +87,7 @@
LOG_FUNC
iDataQ = CAclDataQ::NewL(aProtocol, aNumBufs, aBufSize, aFrameOverhead);
+
#ifdef PROXY_COMMUNICATES
LOG(_L("\tPROXY_COMMUNICATES defined- reserving slots for broadcast channel"));
@@ -88,6 +95,11 @@
// Reserve BC one now
User::LeaveIfError(ACLLogicalLinkUp(KHCIBroadcastHandle, EFalse));
#endif
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ LOG(_L8("\tHOSTCONTROLLER_TO_HOST_FLOW_CONTROL defined- creating buffer pool"));
+ iMBufPool = CHostMBufPool::NewL(aProtocol.HCIFacade().CommandQController());
+#endif
}
void CACLDataQController::InitialDataCredits(TUint16 aCredits)
@@ -427,6 +439,15 @@
LOG1(_L("CACLDataQController::ACLLogicalLinkDown aConnH = %d"),
aConnH);
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ if(iMBufPool)
+ {
+ iMBufPool->InvalidateByConnH(aConnH);
+ // the packet completions should probably move to the iAclConns model
+ // to clean up this code.
+ }
+#endif // HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+
TInt connection = FindConnection(aConnH);
if ( connection == KErrNotFound )
@@ -620,5 +641,44 @@
return rerr;
}
+RMBufChain CACLDataQController::PopulateInboundBufferL(THCIConnHandle aConnH, TUint8 aFlag, const TDesC8& aData)
+ {
+ LOG_FUNC
+ // make a new chain consisting of Flag(1st octet) followed by Data.
+ RMBufChain aclData;
+ static const TInt KFlagHeaderOffset = 0;
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ // Check what flow control mode is in operation
+ TFlowControlMode flowControl = iLinkMuxer.FlowControlMode();
+ TBool ctrlerToHost = (flowControl == ETwoWayFlowControlEnabled) || (flowControl == EFlowControlFromHostControllerOnly);
+ if(ctrlerToHost)
+ {
+ __ASSERT_DEBUG(iMBufPool, Panic(ELinkMgrFlowControlChangeOfMind));
+ aclData = iMBufPool->TakeBufferL(aConnH);
+ aclData.CopyIn(aData, KLinkMgrIncomingBufferHeaderSize);
+ // return the reserved MBufs we didn't need to the global pool
+ aclData.TrimEnd(aData.Length() + KLinkMgrIncomingBufferHeaderSize);
+ }
+ else
+#endif // HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ {
+ aclData.CreateL(aData, KLinkMgrIncomingBufferHeaderSize);
+ }
+
+ aclData.First()->Ptr()[KFlagHeaderOffset] = aFlag;
+
+ return aclData;
+ }
+
+void CACLDataQController::NoExplicitInboundPoolNeeded()
+ {
+ LOG_FUNC
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ delete iMBufPool;
+ iMBufPool = NULL;
+#endif // HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ }
+
//
// End of file
--- a/bluetooth/btstack/linkmgr/AclDataQController.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/AclDataQController.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2001-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,6 +18,7 @@
#include <e32base.h>
#include <bttypes.h>
+#include <es_mbuf.h>
class CAclDataQ;
struct TDataQConnectionInfo;
@@ -25,6 +26,7 @@
class CLinkMgrProtocol;
class CLinkMuxer;
class CHCIFacade;
+class CHostMBufPool;
/**
Controller of the ACL data Q and of the pending packet list.
@@ -43,6 +45,7 @@
~CACLDataQController();
public:
+ // Outbound aspects
void InitialDataCredits(TUint16 aCredits);
void AddItem(CACLDataItem& aACLFrame);
TBool IssueNextACLDataFragment();
@@ -57,6 +60,11 @@
void ACLLogicalLinkDown(THCIConnHandle aConnH);
void SetParked(THCIConnHandle aConnH, TBool aParked);
void CompletedPackets(THCIConnHandle aConnH, TUint16 aNo);
+
+ // Inbound buffer related aspects
+ RMBufChain PopulateInboundBufferL(THCIConnHandle aConnH, TUint8 aFlag, const TDesC8& aData);
+ void NoExplicitInboundPoolNeeded();
+
private:
CACLDataQController(CHCIFacade& aHCIFacade, CLinkMuxer& aMuxer);
@@ -84,6 +92,10 @@
TUint iIndexOfLastSendingConn;
TUint16 iNumControllerBufs;
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ CHostMBufPool* iMBufPool;
+#endif
private: // unowned
CLinkMuxer& iLinkMuxer;
--- a/bluetooth/btstack/linkmgr/ProxySAP.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ProxySAP.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -26,6 +26,7 @@
#include "linkmgr.h"
#include <bluetooth/hci/aclpacketconsts.h>
+#include <bluetooth/hci/hciconsts.h>
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
@@ -552,7 +553,7 @@
}
else
{
- iRequestedActiveMode = option ? ETrue : EFalse;
+ iRequestedActiveMode = option;
if(iRequestedActiveMode)
{
localPriority = ETrue;
--- a/bluetooth/btstack/linkmgr/ProxySAP.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ProxySAP.h Tue Jul 06 15:33:04 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/Subscribers.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/Subscribers.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -18,6 +18,7 @@
#include <bt_subscribe.h>
#include <bt_sock.h>
#include <utf.h>
+#include <bluetooth/hci/hciconsts.h>
#include "Subscribers.h"
#include "linkmgr.h"
#include "physicallinksmanager.h"
--- a/bluetooth/btstack/linkmgr/SyncSap.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/SyncSap.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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,6 +17,7 @@
#include <bluetooth/logger.h>
#include <bt_sock.h>
+#include <bluetooth/hci/hciconsts.h>
#include "SCOSAP.h"
#include "physicallinksmanager.h"
#include "physicallinks.h"
--- a/bluetooth/btstack/linkmgr/basebandsap.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/basebandsap.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -16,6 +16,7 @@
//
#include <bluetooth/logger.h>
+#include <bluetooth/hci/hciconsts.h>
#include "basebandsap.h"
#include "physicallinksmanager.h"
#include "physicallinks.h"
--- a/bluetooth/btstack/linkmgr/eirpublisherlocalname.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublisherlocalname.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublisherlocalname.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/eirpublishertxpowerlevel.h Tue Jul 06 15:33:04 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/hcifacade.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -35,10 +35,11 @@
#include <bluetooth/hcicommandqitem.h>
#include <bluetooth/hcicmdqcontroller.h>
+#include <bluetooth/hci/hciopcodes.h>
+
#include <bluetooth/hci/controllerinitialisationinterface.h>
#include <bluetooth/hci/hcidataframer.h>
#include <bluetooth/hci/readlocalsupportedfeaturescommand.h>
-#include <bluetooth/hci/hostbuffersizecommand.h>
#include <bluetooth/hci/resetcommand.h>
#include <bluetooth/hci/readbdaddrcommand.h>
#include <bluetooth/hci/readlocalversioninfocommand.h>
@@ -192,10 +193,6 @@
// used later to ensure that we have enough data to call SetEventMask
iReadLocalSupportedFeaturesComplete = EFalse;
iReadLocalVersionComplete = EFalse;
-
-#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- iMBufPool = CHostMBufPool::NewL(*this);
-#endif
}
void CHCIFacade::SetLinkMuxer(CLinkMuxer& aLinkMuxer)
@@ -319,9 +316,6 @@
{
LOG_FUNC
delete iAFHTimer;
- #ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- delete iMBufPool;
- #endif
delete iCoreHciPlugin;
@@ -430,9 +424,12 @@
iLinkMgrProtocol.LinkMuxer().ChannelsClosed(KHCITransportAllChannels);
iLinkMgrProtocol.Error(KErrHardwareNotAvailable);
// Reset UI
+ //
iLinkMgrProtocol.SetUIConnecting(EFalse);
iLinkMgrProtocol.SetUINumPhysicalLinks(0);
- // The h/w CoD has been reset, so we need to clear our persistent value, to reflect this
+ // The h/w has been (or will be) reset, so we need to clear our locally cached data
+ //
+ iLinkMgrProtocol.LinkMuxer().ResetFlowControlMode();
iLinkMgrProtocol.ClearPendingLocalDeviceSettingsCod();
// Removes any pending AFH Channel Classification command
@@ -529,58 +526,39 @@
*/
{
LOG_FUNC
+
switch (aMode)
{
- case ENoFlowControl:
- {
-#ifndef _DEBUG
- Panic(ELinkMgrBadFlowControlSetInReleaseBuild);
-#endif
- break;
- }
- case EFlowControlToHostControllerOnly:
- {
- // the host will not tell the Controller about its buffers
-
- User::LeaveIfError(
- SendInitialisationCommand(CReadBufferSizeCommand::NewL()));
- break;
- }
- case EFlowControlFromHostControllerOnly:
- {
-#ifdef _DEBUG
- CHCICommandBase *command = CHostBufferSizeCommand::NewL(KLinkMgrIncomingBufferSize,
- KStackSCOBuffersSize, KStackACLBuffersNum,
- KStackSCOBuffersNum);
-
- User::LeaveIfError(SendInitialisationCommand(command));
-
- command = CSetControllerToHostFlowControlCommand::NewL(ETrue);
-
- User::LeaveIfError(SendInitialisationCommand(command));
-
-#else
- Panic(ELinkMgrBadFlowControlSetInReleaseBuild);
-#endif
- break;
- }
- case ETwoWayFlowControlEnabled:
- {
- CHCICommandBase *command = CHostBufferSizeCommand::NewL(KLinkMgrIncomingBufferSize,
- KStackSCOBuffersSize, KStackACLBuffersNum,
- KStackSCOBuffersNum);
-
- User::LeaveIfError(SendInitialisationCommand(command));
-
- command = CSetControllerToHostFlowControlCommand::NewL(ETrue);
-
- User::LeaveIfError(SendInitialisationCommand(command));
-
- break;
- }
- default:
- Panic(ELinkMgrNoSuchFlowControlMode);
- break;
+ case ENoFlowControl:
+ case EFlowControlToHostControllerOnly:
+ case EFlowControlFromHostControllerOnly:
+ case ETwoWayFlowControlEnabled:
+ // a valid argument has been provided
+ break;
+ default:
+ Panic(ELinkMgrNoSuchFlowControlMode);
+ break;
+ }
+
+ TBool ctrlerToHostFlowControl = (aMode == ETwoWayFlowControlEnabled) || (aMode == EFlowControlFromHostControllerOnly);
+ TBool hostToCtrlerFlowControl = (aMode == ETwoWayFlowControlEnabled) || (aMode == EFlowControlToHostControllerOnly);
+
+ if(hostToCtrlerFlowControl)
+ {
+ LEAVEIFERRORL(SendInitialisationCommand(CReadBufferSizeCommand::NewL()));
+ }
+
+ if(ctrlerToHostFlowControl)
+ {
+ static const TUint8 KControllerToHostFlowControlAclOnSyncOff = 0x01;
+ CHCICommandBase* command =
+ CSetControllerToHostFlowControlCommand::NewL(KControllerToHostFlowControlAclOnSyncOff);
+ LEAVEIFERRORL(SendInitialisationCommand(command));
+ // When this command successfully completes then host buffer size command will be issued.
+ }
+ else
+ {
+ iLinkMuxer->RecordHostControllerToHostFlowControl(EFalse);
}
}
@@ -639,14 +617,6 @@
return 0;
}
-#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
-RMBufChain CHCIFacade::TakeInboundACLDataBufferFromPool(const THCIConnHandle& aForConnHandle)
- {
- LOG_FUNC
- return iMBufPool->TakeBuffer(aForConnHandle);
- }
-#endif
-
// MControllerInitialisationObserver
void CHCIFacade::McioPreResetCommandComplete(TInt aError)
{
@@ -1098,177 +1068,3 @@
return KErrNone;
}
-#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
-
-CHostMBufPool* CHostMBufPool::NewL(CHCIFacade& aHCIFacade)
- {
- LOG_FUNC
- CHostMBufPool* self = new (ELeave) CHostMBufPool(aHCIFacade);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-void CHostMBufPool::DeletePool(TSglQue<TPoolBuffer>& aQueue)
- {
- LOG_FUNC
- TPoolBuffer* tmpItem = NULL;
- TSglQueIter<TPoolBuffer> iter(aQueue);
- while(iter)
- {
- tmpItem=iter++;
- aQueue.Remove(*tmpItem);
- delete tmpItem;
- }
- }
-
-CHostMBufPool::~CHostMBufPool()
- {
- LOG_FUNC
- Cancel();
- DeletePool(iBufferPool);
- DeletePool(iWaitingAllocPool);
- }
-
-CHostMBufPool::CHostMBufPool(CHCIFacade& aHCIFacade) :
- CActive(0),iHCIFacade(aHCIFacade),iBufferPool(_FOFF(TPoolBuffer,iLink)),
- iWaitingAllocPool(_FOFF(TPoolBuffer,iLink)),iCurrAckHandle(KErrNotFound),iCurrCompletedPackets(0)
- {
- LOG_FUNC
- }
-
-void CHostMBufPool::ConstructL()
-/**
-2nd phase constructor for the Host MBuf Pool.
-
-This method will attempt to reserve enough MBufs from the global pool
-for bluetooth use.
-@leave KErrNoMemory If the required number of MBufs couldn't be reserved
-*/
- {
- LOG_FUNC
- LOG2(_L("CHostMBufPool: now reserving %d size %d MBufChains"),KStackACLBuffersNum,KLinkMgrIncomingBufferSize);
-
- for (TInt i=0;i<=KStackACLBuffersNum-1;i++)
- {
- TPoolBuffer* thisBuffer = new (ELeave) TPoolBuffer();
- CleanupStack::PushL(thisBuffer);
- thisBuffer->iCurrentHandle=KErrNotFound; //we assert on this later
- thisBuffer->iMBufChain.AllocL(KLinkMgrIncomingBufferSize);
- iBufferPool.AddFirst(*thisBuffer);
- CleanupStack::Pop(thisBuffer);
- }
-
- CActiveScheduler::Add(this);
- }
-
-void CHostMBufPool::DoCancel()
- {
- LOG_FUNC
- iMBufRequester.Cancel();
- }
-
-RMBufChain CHostMBufPool::TakeBuffer(const THCIConnHandle& aConnHandle)
-/**
-Takes a buffer from the pool and schedules an asynchronous allocation
-of the next buffer. Only when that allocation has succeeded will the host
-controller be signalled with a host_number_of_completed_packets. Hence,
-if we cannot allocate a buffer from the global MBuf pool, the host controller
-will be flowed off and no data will be lost.
-*/
- {
- LOG_FUNC
- TPoolBuffer* ready = iBufferPool.First();
- iBufferPool.Remove(*ready);
- __ASSERT_DEBUG(!ready->iMBufChain.IsEmpty(),Panic(ELinkMgrHostControllerHasOverflowedHost));
- __ASSERT_DEBUG(ready->iCurrentHandle==KErrNotFound,Panic(ELinkMgrHostControllerHasOverflowedHost));
- ready->iCurrentHandle = aConnHandle;
-
- RMBufChain retChain;
- retChain.Assign(ready->iMBufChain);
-
- if (IsActive())
- {
- //This buffer will be reclaimed from the global pool
- //after the one(s) we're currently trying to reclaim
- LOG(_L("CHostMBufPool: TakeBuffer, buffer taken while alloc outstanding: queued alloc"));
- iWaitingAllocPool.AddLast(*ready);
- }
- else
- {
- LOG(_L("CHostMBufPool: TakeBuffer, buffer taken"));
- iBufferPool.AddLast(*ready); //NB the Controller cannot use this
- //buffer until it is alloced as it will
- //be flowed off.
- iMBufRequester.Alloc(ready->iMBufChain,KLinkMgrIncomingBufferSize,iStatus);
- SetActive();
- }
-
- return retChain;
- }
-
-void CHostMBufPool::RunL()
- {
- LOG_FUNC
- if (iStatus.Int()!=KErrNone)
- {
- LOG1(_L("Error! CHostMBufPool:: RunL %d"),iStatus.Int());
- __DEBUGGER();
- }
- else
- {
- TPoolBuffer* justAllocd = iBufferPool.Last();
-
-
- if (iCurrAckHandle==KErrNotFound)
- {
- //This is the first completion we have ever seen
- iCurrAckHandle=justAllocd->iCurrentHandle;
- }
-
- TBool ackNow=((justAllocd->iCurrentHandle!=iCurrAckHandle));
-
- if (!ackNow)
- {
- iCurrCompletedPackets++;
- LOG2(_L("CHostMBufPool: CompletedPackets++ for conn: %d [->%d]"),justAllocd->iCurrentHandle,iCurrCompletedPackets);
-
- if (iCurrCompletedPackets>=KStackACLBuffersTideMarkNum)
- {
- ackNow=ETrue;
- }
- }
-
- if (ackNow)
- {
- TInt err=KErrNone;
-
- if (iCurrCompletedPackets>0)
- {
- LOG2(_L("CHostMBufPool: Sending HostNumberOfCompletedPackets for conn: %d [%d completed]"),iCurrAckHandle,iCurrCompletedPackets);
- //Acknowledge the completed packets
- TRAP(err, iHCIFacade.HostNumberOfCompletedPacketsL(iCurrAckHandle,iCurrCompletedPackets));
- //if this failed we probably couldn't alloc the memory for the command frame,
- //the HC is still flowed off.
- __ASSERT_DEBUG(err==KErrNone,Panic(ELinkMgrCouldNotSendHostNumberOfCompletedPackets));
- }
-
- iCurrCompletedPackets= (justAllocd->iCurrentHandle!=iCurrAckHandle) ? 1:0;
- iCurrAckHandle=justAllocd->iCurrentHandle;
- }
-
- justAllocd->iCurrentHandle=KErrNotFound;
-
- if (!iWaitingAllocPool.IsEmpty())
- {
- TPoolBuffer* needsAlloc = iWaitingAllocPool.First();
- iBufferPool.AddLast(*needsAlloc);
- iWaitingAllocPool.Remove(*needsAlloc);
- iMBufRequester.Alloc(needsAlloc->iMBufChain,KLinkMgrIncomingBufferSize,iStatus);
- SetActive();
- }
- }
- }
-
-#endif
--- a/bluetooth/btstack/linkmgr/hcifacade.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -93,43 +93,7 @@
private:
};
-#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
-NONSHARABLE_CLASS(CHostMBufPool) : public CActive
- {
- NONSHARABLE_CLASS(TPoolBuffer)
- {
- public:
- RMBufChain iMBufChain;
- TInt iCurrentHandle; //NB THCIConnHandle is TUint16,
- //we use -1 to indicate no handle
- TSglQueLink iLink;
- };
-public:
- static CHostMBufPool* NewL(CHCIFacade& aHCIFacade);
- ~CHostMBufPool();
- RMBufChain TakeBuffer(const THCIConnHandle& aConnHandle);
-private:
- CHostMBufPool(CHCIFacade& aHCIFacade);
- void ConstructL();
- void RunL();
- void DoCancel();
-
- void DeletePool(TSglQue<TPoolBuffer>& aPool);
-
-private:
- CHCIFacade& iHCIFacade;
- CAsyncCallBack* iBufferFreeCallback;
-
- TSglQue<TPoolBuffer> iBufferPool;
- TSglQue<TPoolBuffer> iWaitingAllocPool;
-
- TInt iCurrAckHandle;
- TUint iCurrCompletedPackets;
-
- RMBufAsyncRequest iMBufRequester;
- };
-
-#endif //HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+
NONSHARABLE_CLASS(CAFHTimer) : public CTimer
{
@@ -226,7 +190,6 @@
void AcceptConnectionRequestL(const TBTDevAddr& aAddr, TUint8 aRole);
void RejectConnectionRequestL(const TBTConnect& aConnect, THCIErrorCode aReason);
- void HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aFrags);
void WriteLinkPolicySettingsL(THCIConnHandle aConnH, TUint16 aSettings);
void FlushL(THCIConnHandle aConnH);
void SetEventMaskL(const THCIEventMask& aEventMask);
@@ -318,9 +281,6 @@
TUint16 ReadACLReportingInterval() const;
TUint16 ReadACLFramingOverhead() const;
- #ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- RMBufChain TakeInboundACLDataBufferFromPool(const THCIConnHandle& aForConnHandle);
- #endif
void ReadDeviceClassL();
private:
TInt SendInitialisationCommand(CHCICommandBase* aCommand);
@@ -364,6 +324,7 @@
void WriteCurrentIACLAPOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void WriteClassOfDeviceOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void SetControllerToHostFlowControlOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
+ void HostBufferSizeOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void WriteScanEnableOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void SetAFHHostChannelClassificationOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void WriteAFHChannelAssessmentModeOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
@@ -375,6 +336,8 @@
void SetEventMaskOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
void ReadInquiryResponseTransmitPowerLevelOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
+ void WriteSimplePairingModeOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand);
+
// Functions
CHCIFacade(CLinkMgrProtocol& aProtocol);
void ConstructL();
@@ -443,10 +406,6 @@
THCITransportChannel iHCTLState; // memorize the status of the free channels
TBTPowerState iLastPowerState;
-
- #ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
- CHostMBufPool* iMBufPool;
- #endif
// This array contains outstanding command Op Codes. The array is
// not defined using THCIOpcode as the template type because RArray
--- a/bluetooth/btstack/linkmgr/hcifacade_commands.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade_commands.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -42,7 +42,6 @@
#include <bluetooth/hci/rejectsynchronousconnectionrequestcommand.h>
#include <bluetooth/hci/disconnectcommand.h>
#include <bluetooth/hci/writelinkpolicysettingscommand.h>
-#include <bluetooth/hci/hostnumberofcompletedpacketscommand.h>
#include <bluetooth/hci/acceptconnectionrequestcommand.h>
#include <bluetooth/hci/rejectconnectionrequestcommand.h>
#include <bluetooth/hci/readremoteversioninfocommand.h>
@@ -186,24 +185,6 @@
iCmdController->MhcqAddCommandL(cmd, *this);
}
-void CHCIFacade::HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aFrags)
- {
- RArray<THCIConnectionHandle> connHandles;
- connHandles.AppendL(aConnH);
- CleanupClosePushL(connHandles);
-
- RArray<THCINumOfCompletedPackets> numPackets;
- numPackets.AppendL(aFrags);
- CleanupClosePushL(numPackets);
-
- CHostNumberOfCompletedPacketsCommand* cmd = CHostNumberOfCompletedPacketsCommand::NewL(1, connHandles, numPackets);
- // ownership of arrays has been taken by cmd
- CleanupStack::Pop(2, &connHandles); // &numPackets, &connHandles
-
- // Ownership of cmd transfered even if MhcqAddCommandL leaves
- iCmdController->MhcqAddCommandL(cmd, *this);
- }
-
void CHCIFacade::AcceptConnectionRequestL(const TBTDevAddr& aAddr, TUint8 aRole)
{
CAcceptConnectionRequestCommand* cmd = CAcceptConnectionRequestCommand::NewL(aAddr, aRole);
--- a/bluetooth/btstack/linkmgr/hcifacade_events.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade_events.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -100,6 +100,7 @@
#include <bluetooth/hci/readremoteextendedfeaturescommand.h>
#include <bluetooth/hci/readinquiryresponsetransmitpowerlevelcommand.h>
+#include <bluetooth/hci/hostbuffersizecommand.h>
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_HCI_FACADE);
@@ -215,8 +216,47 @@
void CHCIFacade::SetControllerToHostFlowControlOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
{
LOG_FUNC
- LOG(_L("HCIFacade: SetControllerToHostFlowControl Command Complete Event"));
- iLinkMuxer->RecordHostControllerToHostFlowControl(aHciErr == EOK ? ETrue:EFalse);
+ LOG1(_L8("HCIFacade: SetControllerToHostFlowControl Command Complete Event (result = 0x%02x)"), aHciErr);
+ if(aHciErr == EOK)
+ {
+ // flow control mode set - so provide the host buffer settings
+ CHCICommandBase* command = NULL;
+ TRAPD(err, command = CHostBufferSizeCommand::NewL(KStackACLBuffersSize, KStackSCOBuffersSize,
+ KStackACLBuffersNum, KStackSCOBuffersNum));
+ if(err == KErrNone)
+ {
+ err = SendInitialisationCommand(command);
+ }
+ if(err != KErrNone)
+ {
+ // unfortunately at this stage we are stuck since we need to inform
+ // the controller of our buffers. We've failed to initialise.
+ LOG1(_L8("Failed to send HostBufferSize command(%d) - initialisation failed"), err);
+ iInitialisationError = ETrue;
+ }
+ }
+ else // we'll drop back to no flow control to the host
+ {
+ iLinkMuxer->RecordHostControllerToHostFlowControl(EFalse);
+ }
+ }
+
+void CHCIFacade::HostBufferSizeOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
+ {
+ LOG_FUNC
+ LOG1(_L8("HCIFacade: HostBufferSizeOpcode Command Complete Event (result = 0x%02x)"), aHciErr);
+ if(aHciErr == EOK)
+ {
+ // all set-up for controller to host flow-control
+ iLinkMuxer->RecordHostControllerToHostFlowControl(ETrue);
+ }
+ else
+ {
+ // If we've failed to perform this command then the stack is stuck
+ // half initialised to perform controller to host flow control.
+ LOG(_L8("Failed to set the host buffer size in controller - initialisation failed"));
+ iInitialisationError = ETrue;
+ }
}
void CHCIFacade::WriteScanEnableOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
@@ -351,9 +391,16 @@
if(iLinkMgrProtocol.IsSecureSimplePairingSupportedLocally())
{
CWriteSimplePairingModeCommand* cmd = NULL;
- TRAP_IGNORE(cmd = CWriteSimplePairingModeCommand::NewL(ESimplePairingEnabled));
- static_cast<void>(SendInitialisationCommand(cmd));
- iLinksMgr->SecMan().SetLocalSimplePairingMode(ETrue); //probably unnecessary
+ TRAPD(err, cmd = CWriteSimplePairingModeCommand::NewL(ESimplePairingEnabled));
+ if(err == KErrNone)
+ {
+ err = SendInitialisationCommand(cmd);
+ }
+ if(err != KErrNone)
+ {
+ LOG(_L("HCIFacade: ReadLocalSupportedFeaturesOpcode Error"));
+ iInitialisationError = ETrue;
+ }
}
else
{
@@ -363,6 +410,7 @@
else
{
iLinkMgrProtocol.SetLocalFeatures(aHciErr, TBTFeatures(0));
+ iLinksMgr->SecMan().SetLocalSimplePairingMode(EFalse); // for want of a better solution
}
iReadLocalSupportedFeaturesComplete = ETrue;
@@ -566,6 +614,10 @@
SetControllerToHostFlowControlOpcode(aHciErr, aEvent, aRelatedCommand);
break;
+ case KHostBufferSizeOpcode:
+ HostBufferSizeOpcode(aHciErr, aEvent, aRelatedCommand);
+ break;
+
case KWriteScanEnableOpcode:
WriteScanEnableOpcode(aHciErr, aEvent, aRelatedCommand);
break;
@@ -622,8 +674,13 @@
__ASSERT_DEBUG(EFalse, Panic(EHCIUnmatchedInquiryEvent));
break;
+ case KWriteSimplePairingModeOpcode:
+ {
+ WriteSimplePairingModeOpcode(aHciErr, aEvent, aRelatedCommand);
+ break;
+ }
+
// Security related events that are sent from the facade.
- case KWriteSimplePairingModeOpcode:
case KReadLocalOOBDataOpcode:
case KRemoteOOBDataRequestReplyOpcode:
case KRemoteOOBDataRequestNegativeReplyOpcode:
@@ -659,13 +716,11 @@
case KSetEventFilterOpcode:
case KCreateNewUnitKeyOpcode:
case KWriteAuthenticationEnableOpcode:
- case KHostNumberOfCompletedPacketsOpcode:
case KWriteEncryptionModeOpcode:
case KWritePageTimeoutOpcode:
case KReadConnectionAcceptTimeoutOpcode:
case KWriteConnectionAcceptTimeoutOpcode:
case KWriteVoiceSettingOpcode:
- case KHostBufferSizeOpcode:
case KReadAFHChannelMapOpcode:
case KReadAFHChannelAssessmentModeOpcode:
case KReadPageTimeoutOpcode:
@@ -714,6 +769,10 @@
case KSendKeypressNotificationOpcode:
case KWriteSimplePairingDebugModeOpcode:
+
+ // below here are command complete events we definitely shouldn't receive
+ // but have been left for safety until a complete analysis is done.
+ case KHostNumberOfCompletedPacketsOpcode:
// Catch all the events we do not handle
LOG1(_L("Warning!! Unhandled Command Complete Event (opcode:%d)"), aOpcode);
@@ -795,6 +854,19 @@
}
}
+void CHCIFacade::WriteSimplePairingModeOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
+ {
+ LOG_FUNC
+ if(aHciErr == EOK)
+ {
+ iLinksMgr->SecMan().SetLocalSimplePairingMode(ETrue);
+ }
+ else
+ {
+ iInitialisationError = ETrue;
+ }
+ }
+
void CHCIFacade::CommandStatusEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand)
{
LOG_FUNC
@@ -877,12 +949,6 @@
iLinksMgr->SynchronousConnectionComplete(hciErr, conn, syncOpts);
break;
- }
-
- case KHostNumberOfCompletedPacketsOpcode:
- {
- iLinksMgr->CompletedPackets(KInvalidConnectionHandle, 0); //no packets
- break;
}
case KReadRemoteExtendedFeaturesOpcode:
@@ -915,7 +981,13 @@
iLinksMgr->PacketTypeChange(hciErr, KInvalidConnectionHandle,0);
break;
}
-
+
+ case KWriteSimplePairingModeOpcode:
+ {
+ WriteSimplePairingModeOpcode(hciErr, &commandStatusEvent, aRelatedCommand);
+ break;
+ }
+
default:
// Complete any other commands with an error
CommandCompleteEvent(opcode, hciErr, NULL, NULL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/hostmbufpool.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,382 @@
+// Copyright (c) 1999-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"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "hostmbufpool.h"
+
+#include <bluetooth/hcicommandqueue.h>
+#include <bluetooth/hci/hostnumberofcompletedpacketscommand.h>
+#include <bluetooth/hci/hcievents.h>
+#include <bluetooth/hci/commandcompleteevent.h>
+#include <bluetooth/hci/hciutil.h>
+
+#include "linkconsts.h"
+#include "linkutil.h"
+
+#include <bluetooth/logger.h>
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
+#endif
+
+__DEBUG_ONLY(PANICCATEGORY("mbufpool");)
+
+
+CHostMBufPool* CHostMBufPool::NewL(MHCICommandQueue& aCommandQueue)
+ {
+ LOG_STATIC_FUNC
+ CHostMBufPool* self = new (ELeave) CHostMBufPool(aCommandQueue);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CHostMBufPool::DeletePool(TSglQue<TPoolBuffer>& aQueue)
+ {
+ LOG_FUNC
+ TPoolBuffer* buffer = NULL;
+ TSglQueIter<TPoolBuffer> iter(aQueue);
+ while(buffer=iter++, buffer)
+ {
+ aQueue.Remove(*buffer);
+ DeleteBuffer(buffer);
+ }
+ }
+
+void CHostMBufPool::DeleteBuffer(TPoolBuffer*& aBuffer)
+ {
+ LOG_FUNC
+ if(aBuffer)
+ {
+ aBuffer->iMBufChain.Free();
+ delete aBuffer;
+ aBuffer = NULL;
+ }
+ }
+
+CHostMBufPool::~CHostMBufPool()
+ {
+ LOG_FUNC
+ Cancel();
+ // iMBufRequester is cleaned in it's destructor (not much of an R-class...but it is what it is)
+ DeletePool(iBufferPool);
+ DeletePool(iWaitingAllocPool);
+ DeleteBuffer(iBufferBeingAllocd);
+ }
+
+CHostMBufPool::CHostMBufPool(MHCICommandQueue& aCommandQueue)
+ : CActive(EPriorityHigh)
+ // High priority so that buffers are allocated occur before more data is read, this prevents
+ // the cases the data floods the device and exhausts the buffers before any more can be allocated.
+ // This maximises throughput since we will ensure we send packet completion notifications in a
+ // timely manner.
+ , iCmdQ(aCommandQueue)
+ , iBufferPool(_FOFF(TPoolBuffer,iLink))
+ , iWaitingAllocPool(_FOFF(TPoolBuffer,iLink))
+ , iCurrAckHandle(KErrNotFound)
+ {
+ LOG_FUNC
+ }
+
+void CHostMBufPool::ConstructL()
+/**
+2nd phase constructor for the Host MBuf Pool.
+
+This method will attempt to reserve enough MBufs from the global pool
+for bluetooth use.
+@leave KErrNoMemory If the required number of MBufs couldn't be reserved
+*/
+ {
+ LOG_FUNC
+ LOG2(_L("CHostMBufPool: now reserving %d size %d MBufChains"), KStackACLBuffersNum, KLinkMgrIncomingBufferSize);
+
+ for (TInt i=0; i<=KStackACLBuffersNum-1; i++)
+ {
+ TPoolBuffer* thisBuffer = CreatePoolBufferL();
+ AddToBufferPool(*thisBuffer);
+ }
+
+ CActiveScheduler::Add(this);
+ }
+
+CHostMBufPool::TPoolBuffer* CHostMBufPool::CreatePoolBufferL()
+ {
+ LOG_FUNC
+ TPoolBuffer* newBuffer = new(ELeave) TPoolBuffer();
+ CleanupStack::PushL(newBuffer);
+ newBuffer->iCurrentHandle = KInvalidConnectionHandle; // we assert on this later
+ newBuffer->iMBufChain.AllocL(KLinkMgrIncomingBufferSize);
+ CleanupStack::Pop(newBuffer);
+ return newBuffer;
+ }
+
+void CHostMBufPool::DoCancel()
+ {
+ LOG_FUNC
+ iMBufRequester.Cancel();
+ }
+
+RMBufChain CHostMBufPool::TakeBufferL(THCIConnHandle aConnHandle)
+/**
+Takes a buffer from the pool and schedules an asynchronous allocation
+of the next buffer. Only when that allocation has succeeded will the host
+controller be signalled with a host_number_of_completed_packets. Hence,
+if we cannot allocate a buffer from the global MBuf pool, the host controller
+will be flowed off and no data will be lost.
+*/
+ {
+ LOG_FUNC
+ ASSERT_DEBUG(aConnHandle != KInvalidConnectionHandle);
+
+ // Speculatively attempt to allocate any queued allocations that may have previously failed.
+ TryToAllocQueuedBuffer();
+
+ TPoolBuffer* ready = iBufferPool.First();
+
+ if(!ready)
+ {
+ // Whoops run out of buffers - even though we were trying to prevent this with
+ // flow control, in the case of disconnection the controller will assume all the
+ // data for a connection handle will be flushed and therefore the buffers associated
+ // with that connection handle will be free. Unfortunately for us we don't have
+ // that much control with the MBuf pool (since flow control is for asynchronous
+ // buffer allocation rather than waiting for the given MBufs to be relinquished
+ // by a higher layer).
+ // So the controller could think we have more buffers than we actually have...
+ LOG(_L8("CHostMBufPool: Ran out of buffers!!!!"));
+ LEAVEL(KErrOverflow);
+ }
+
+ // If here then we should have a valid pool buffer to use
+ __ASSERT_DEBUG(!ready->iMBufChain.IsEmpty(), Panic(ELinkMgrHostControllerHasOverflowedHost));
+ __ASSERT_DEBUG(ready->iCurrentHandle == KInvalidConnectionHandle, Panic(ELinkMgrHostControllerHasOverflowedHost));
+
+ RemoveFromBufferPool(*ready);
+ ready->iCurrentHandle = aConnHandle;
+
+ RMBufChain retChain;
+ retChain.Assign(ready->iMBufChain);
+
+ if (IsActive())
+ {
+ //This buffer will be reclaimed from the global pool
+ //after the one(s) we're currently trying to reclaim
+ LOG(_L8("CHostMBufPool: TakeBuffer, buffer taken while alloc outstanding: queued alloc"));
+ iWaitingAllocPool.AddLast(*ready);
+ }
+ else
+ {
+ LOG(_L8("CHostMBufPool: TakeBuffer, buffer taken"));
+ AllocNewBuffer(*ready);
+ }
+
+ return retChain;
+ }
+
+void CHostMBufPool::InvalidateByConnH(THCIConnHandle aConnHandle)
+ {
+ LOG_FUNC
+ ASSERT_DEBUG(aConnHandle != KInvalidConnectionHandle);
+
+ // We need to scan through the two pending "lists" to remove the
+ // connection handle from record so we don't try to provide a
+ // packet completion notification (the controller already assumes
+ // the buffers are free as they are entitled to by the spec).
+
+ // The current buffer being allocated
+ if(iBufferBeingAllocd && iBufferBeingAllocd->iCurrentHandle == aConnHandle)
+ {
+ iBufferBeingAllocd->iCurrentHandle = KInvalidConnectionHandle;
+ }
+
+ // The list of buffers waiting to be allocted
+ TPoolBuffer* buffer = NULL;
+ TSglQueIter<TPoolBuffer> iter(iWaitingAllocPool);
+ while(buffer=iter++, buffer)
+ {
+ if(buffer->iCurrentHandle == aConnHandle)
+ {
+ buffer->iCurrentHandle = KInvalidConnectionHandle;
+ }
+ }
+
+ // Finally we need to purge any batched up completions if they
+ // are for this connection handle
+ if(iCurrAckHandle == aConnHandle)
+ {
+ iCurrAckHandle = KErrNotFound;
+ iCurrCompletedPackets = 0;
+ }
+ }
+
+void CHostMBufPool::RunL()
+ {
+ LOG_FUNC
+ LEAVEIFERRORL(iStatus.Int());
+
+ // We've successfully allocated a new MBufChain
+ TPoolBuffer* justAllocd = iBufferBeingAllocd;
+ iBufferBeingAllocd = NULL;
+ THCIConnHandle justAllocdHandle = justAllocd->iCurrentHandle;
+
+ // Return buffer to pool for re-use
+ AddToBufferPool(*justAllocd);
+ justAllocd->iCurrentHandle = KInvalidConnectionHandle;
+
+ // If connection handle is still valid then we need to provide a completion
+ // notification for the packet to the connection handle it was from.
+ if(justAllocdHandle != KInvalidConnectionHandle)
+ {
+ if (iCurrAckHandle == KErrNotFound)
+ {
+ // This is the first completion we have seen
+ iCurrAckHandle = justAllocdHandle;
+ }
+ ASSERT_DEBUG(iCurrAckHandle != KInvalidConnectionHandle); // just to be sure
+
+ TBool ackNow = (justAllocdHandle != iCurrAckHandle);
+
+ if (!ackNow)
+ {
+ iCurrCompletedPackets++;
+ LOG2(_L8("CHostMBufPool: CompletedPackets++ for conn: %d [->%d]"), justAllocdHandle, iCurrCompletedPackets);
+ ackNow = (iCurrCompletedPackets >= KStackACLBuffersTideMarkNum);
+ }
+
+ if (ackNow)
+ {
+ TInt err = KErrNone;
+
+ if (iCurrCompletedPackets > 0)
+ {
+ LOG2(_L8("CHostMBufPool: Sending HostNumberOfCompletedPackets for conn: %d [%d completed]"), iCurrAckHandle, iCurrCompletedPackets);
+ //Acknowledge the completed packets
+ TRAP(err, HostNumberOfCompletedPacketsL(iCurrAckHandle, iCurrCompletedPackets));
+ //if this failed we probably couldn't alloc the memory for the command frame,
+ //the HC is still flowed off.
+ __ASSERT_DEBUG(err == KErrNone, Panic(ELinkMgrCouldNotSendHostNumberOfCompletedPackets));
+ LEAVEIFERRORL(err);
+ }
+
+ iCurrCompletedPackets = (justAllocdHandle != iCurrAckHandle) ? 1 : 0;
+ iCurrAckHandle = justAllocdHandle;
+ }
+ }
+
+ TryToAllocQueuedBuffer();
+ }
+
+void CHostMBufPool::TryToAllocQueuedBuffer()
+ {
+ LOG_FUNC
+ if (!iWaitingAllocPool.IsEmpty() && !IsActive())
+ {
+ TPoolBuffer* needsAlloc = iWaitingAllocPool.First();
+ iWaitingAllocPool.Remove(*needsAlloc);
+ AllocNewBuffer(*needsAlloc);
+ }
+ }
+
+void CHostMBufPool::AllocNewBuffer(TPoolBuffer& aBuffer)
+ {
+ LOG_FUNC
+ ASSERT_DEBUG(!iBufferBeingAllocd);
+ iBufferBeingAllocd = &aBuffer;
+ iMBufRequester.Alloc(aBuffer.iMBufChain, KLinkMgrIncomingBufferSize, iStatus);
+ SetActive();
+ }
+
+void CHostMBufPool::HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aNumPackets)
+ {
+ RArray<THCIConnectionHandle> connHandles;
+ connHandles.AppendL(aConnH);
+ CleanupClosePushL(connHandles);
+
+ RArray<THCINumOfCompletedPackets> numPackets;
+ numPackets.AppendL(aNumPackets);
+ CleanupClosePushL(numPackets);
+
+ CHostNumberOfCompletedPacketsCommand* cmd = CHostNumberOfCompletedPacketsCommand::NewL(1, connHandles, numPackets);
+ // Ownership of the arrays is taken by the command object.
+ CleanupStack::Pop(2, &connHandles); // &numPackets, &connHandles
+
+ // This is a priority command as we want to try to get this out as soon as possible (and not wait
+ // for all normal control aspects to be processed). This command shouldn't normally consume any credits
+ // so as a priority command it has little impact.
+ // Ownership of cmd transfered even if MhcqAddPriorityCommandL leaves
+ iCmdQ.MhcqAddPriorityCommandL(cmd, *this);
+ }
+
+void CHostMBufPool::MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
+ {
+ LOG_FUNC
+ // We don't expect a non-error event back because we're only sending Host_Number_of_Completed_Packet commands
+ if(aEvent.EventCode() == ECommandCompleteEvent)
+ {
+ const THCICommandCompleteEvent& completeEvent = THCICommandCompleteEvent::Cast(aEvent);
+ if(completeEvent.CommandOpcode() == KHostNumberOfCompletedPacketsOpcode)
+ {
+ // a regular error for a Host_Number_Of_Completed_Packets command
+ TInt err = CHciUtil::SymbianErrorCode(completeEvent.ErrorCode());
+ if(err != KErrNone) // we shouldn't get a non-erroring event back, but just in case
+ {
+ Error(err);
+ }
+ }
+ else // an unexpected command complete event
+ {
+ LOG1(_L8("CHostMBufPool: Unexpected HCI command complete event; opcode = 0x%04x"), completeEvent.CommandOpcode());
+ DEBUG_PANIC_LINENUM;
+ }
+ }
+ else // some unexpected event
+ {
+ LOG1(_L8("CHostMBufPool: Unexpected HCI event received; code = 0x%02x"), aEvent.EventCode());
+ DEBUG_PANIC_LINENUM;
+ }
+ }
+
+void CHostMBufPool::MhcqcCommandErrored(TInt aErrorCode, const CHCICommandBase* /*aCommand*/)
+ {
+ LOG_FUNC
+ Error(aErrorCode);
+ }
+
+TInt CHostMBufPool::RunError(TInt aError)
+ {
+ LOG_FUNC
+ if(iBufferBeingAllocd)
+ {
+ TPoolBuffer* justFailedToAlloc = iBufferBeingAllocd;
+ iBufferBeingAllocd = NULL;
+ // Add to wait for alloc queue - we may get another chance
+ iWaitingAllocPool.AddFirst(*justFailedToAlloc);
+ }
+ Error(aError);
+ return KErrNone;
+ }
+
+void CHostMBufPool::Error(TInt IF_FLOGGING(aError))
+ {
+ LOG_FUNC
+ // So there has been some internal error when handling controller to host
+ // flow control. Tough, we've done our best for now - the only real thing
+ // that might be worth doing is a hard reset to start-up clean.
+ LOG1(_L8("CHostMBufPool: ERROR (%d) - inbound data to the stack may stall soon"), aError);
+ }
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/hostmbufpool.h Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,101 @@
+// Copyright (c) 2006-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"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+
+
+#ifndef HOSTMBUFPOOL
+#define HOSTMBUFPOOL
+
+#include <e32base.h>
+#include <bttypes.h>
+#include <es_mbuf.h>
+#include <bluetooth/hcicommandqueueclient.h>
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+
+class MHCICommandQueue;
+
+
+NONSHARABLE_CLASS(CHostMBufPool)
+ : public CActive
+ , private MHCICommandQueueClient
+ {
+
+ NONSHARABLE_STRUCT(TPoolBuffer)
+ {
+ RMBufChain iMBufChain;
+ THCIConnHandle iCurrentHandle;
+ TSglQueLink iLink;
+ };
+
+public:
+ static CHostMBufPool* NewL(MHCICommandQueue& aCommandQueue);
+ ~CHostMBufPool();
+
+ RMBufChain TakeBufferL(THCIConnHandle aConnHandle);
+
+ void InvalidateByConnH(THCIConnHandle aConnHandle);
+
+private:
+ CHostMBufPool(MHCICommandQueue& aCommandQueue);
+ void ConstructL();
+
+ void DeletePool(TSglQue<TPoolBuffer>& aPool);
+ void DeleteBuffer(TPoolBuffer*& aBuffer);
+ void AllocNewBuffer(TPoolBuffer& aBuffer);
+ TPoolBuffer* CreatePoolBufferL();
+ void HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aNumPackets);
+ void TryToAllocQueuedBuffer();
+
+ inline void AddToBufferPool(TPoolBuffer& aBuffer);
+ inline void RemoveFromBufferPool(TPoolBuffer& aBuffer);
+
+ void Error(TInt aError);
+
+private: // from CActive
+ void RunL();
+ void DoCancel();
+ TInt RunError(TInt aError);
+
+private: // from MHCICommandQueueClient
+ void MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
+ void MhcqcCommandErrored(TInt aErrorCode, const CHCICommandBase* aCommand);
+
+private:
+ MHCICommandQueue& iCmdQ;
+
+ TSglQue<TPoolBuffer> iBufferPool;
+ TSglQue<TPoolBuffer> iWaitingAllocPool;
+ TPoolBuffer* iBufferBeingAllocd;
+
+ // We batch up completed packets notifications for a connection handle so that they are
+ // only sent every 'x' packets OR if we get a packet for a different connection handle.
+ TInt iCurrAckHandle; // current handle of packets being batched for completion
+ TUint iCurrCompletedPackets; // number of packets already completed for current handle
+
+ RMBufAsyncRequest iMBufRequester;
+ };
+
+inline void CHostMBufPool::AddToBufferPool(TPoolBuffer& aBuffer)
+ {
+ iBufferPool.AddLast(aBuffer);
+ }
+
+inline void CHostMBufPool::RemoveFromBufferPool(TPoolBuffer& aBuffer)
+ {
+ iBufferPool.Remove(aBuffer);
+ }
+
+#endif //HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+
+#endif // HOSTMBUFPOOL
--- a/bluetooth/btstack/linkmgr/hostresolver.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hostresolver.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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,6 +24,8 @@
#include <es_prot.h>
#include <bluetooth/hcicommandqueue.h>
#include <bluetooth/hcicommandqueueclient.h>
+#include <bluetooth/hci/hcitypes.h>
+#include <bluetooth/hci/hciconsts.h>
// BT1.1: Could make these runtime configurable.
--- a/bluetooth/btstack/linkmgr/linkconsts.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkconsts.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2001-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"
@@ -69,7 +69,7 @@
// Physical Link Config
//
-const TUint16 KLinkMgrIncomingBufferSize = 672; //L2Cap Default MTU
+const TUint16 KStackACLBuffersSize = 1021; // size of 3DH-5 (largest packet size)
const TUint16 KStackACLBuffersNum = 16;
const TUint16 KStackACLBuffersTideMarkNum = 8;
@@ -81,6 +81,9 @@
const TUint16 KStackSCOBuffersNum = 0;
#endif
+const TUint16 KLinkMgrIncomingBufferHeaderSize = 1; // header is just the ACL flags
+const TUint16 KLinkMgrIncomingBufferSize = KStackACLBuffersSize + KLinkMgrIncomingBufferHeaderSize;
+
static const THCIScanEnable KHCIDefaultScanMode = EInquiryAndPageScan;
static const TUint16 KHCIDefaultAcceptTimeout = 0x1FA0; // time=n*0.625ms
--- a/bluetooth/btstack/linkmgr/linkmgr.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmgr.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmgr.h Tue Jul 06 15:33:04 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/linkmuxer.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmuxer.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -68,7 +68,10 @@
}
CLinkMuxer::CLinkMuxer(CLinkMgrProtocol& aLinkMgrProtocol, CHCIFacade& aHCIFacade)
- : iHCIFacade(aHCIFacade), iChannelsFree(KHCITransportNoChannels), iLinkMgrProtocol(aLinkMgrProtocol)
+ : iHCIFacade(aHCIFacade)
+ , iChannelsFree(KHCITransportNoChannels)
+ , iFlowControlMode(EFlowControlToHostControllerOnly) // by design flow control to the controller is always used
+ , iLinkMgrProtocol(aLinkMgrProtocol)
/**
We expect the transport to notify us when the transport channels are ready
**/
@@ -189,56 +192,61 @@
}
#endif
+void CLinkMuxer::ResetFlowControlMode()
+ {
+ LOG_FUNC
+ iFlowControlMode = EFlowControlToHostControllerOnly;
+ iCtrlerToHostSet = EFalse;
+ }
+
void CLinkMuxer::RecordHostControllerToHostFlowControl(TBool aFlowFlag)
/**
- Called when HCIFacade receives a Command Complete event to the SetHostControllerToHostFlowControl command
- @param aFlowFlag - true is command succeeded, false otherwise
-
+ Called when HCIFacade successfully configures some level of controller to host
+ flow control
+ @param aFlowFlag - true if flow control set-up succeeded, false otherwise
**/
- {
+ {
LOG_FUNC
- // check our current mode
- switch (iFlowControlMode)
- {
- case ENoFlowControl:
- {
-#ifdef _DEBUG
- if(aFlowFlag)
- {iFlowControlMode=EFlowControlFromHostControllerOnly;}
-#else
- Panic(ELinkMgrNoFlowControlSetInReleaseBuild);
-#endif
- break;
- }
- case EFlowControlToHostControllerOnly:
- {
- if(aFlowFlag)
- {iFlowControlMode=ETwoWayFlowControlEnabled;}
- break;
- }
- case EFlowControlFromHostControllerOnly:
- {
-#ifdef _DEBUG
- if(aFlowFlag==EFalse)
- {iFlowControlMode=ENoFlowControl;}
-#else
- Panic(ELinkMgrNoFlowControlSetInReleaseBuild);
-#endif
- break;
- }
- case ETwoWayFlowControlEnabled:
- {
- if(aFlowFlag==EFalse)
- {
- // tried to do two-way but the HC can't to HC->H FC
- iFlowControlMode=EFlowControlToHostControllerOnly;
- }
- break;
- }
- default:
- Panic(ELinkMgrNoSuchFlowControlMode);
- } //switch
- }
+
+ __ASSERT_DEBUG(!iCtrlerToHostSet, Panic(ELinkMgrFlowControlUnexpectedUpdate));
+
+ switch (iFlowControlMode)
+ {
+ case EFlowControlToHostControllerOnly:
+ if(aFlowFlag)
+ {
+ // Success! We're using using two way flow control
+ iFlowControlMode = ETwoWayFlowControlEnabled;
+ }
+ else
+ {
+ // Fail! we only allow one shot to set this up on initialisation
+ // so inform the data controller that any reserved memory can be
+ // be released.
+ iDataController->NoExplicitInboundPoolNeeded();
+ }
+ break;
+
+ case ETwoWayFlowControlEnabled:
+ // We shouldn't get this twice (we only have one shot of setting it up
+ // and to reach this point we've been in this function once before).
+ break;
+
+ case EFlowControlFromHostControllerOnly:
+ // fall-through
+ case ENoFlowControl:
+ Panic(ELinkMgrNoFlowControlSetInReleaseBuild);
+ break;
+
+ default:
+ Panic(ELinkMgrNoSuchFlowControlMode);
+ break;
+ }
+
+ iCtrlerToHostSet = ETrue;
+ }
+
+
CACLDataQController* CLinkMuxer::HandleLocalReadBufferSizeResult(
--- a/bluetooth/btstack/linkmgr/linkmuxer.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmuxer.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2001-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"
@@ -31,7 +31,7 @@
class CHCICmdQController;
/**
- Regulates the issuing of buffers send down the same channel.
+ Regulates the issuing of buffers sent down the same channel.
The mux decides and notifies the appropriate Q to send data when the wire
is free. The mux will need to be fed with 'the wire is free' events and
@@ -43,17 +43,22 @@
{
public:
static CLinkMuxer* NewL(CLinkMgrProtocol& aLinkMgrProtocol, CHCIFacade& aHCIFacade);
- void ObtainHostControllerBufferSizeL();
+
void RecordHostControllerToHostFlowControl(TBool aFlowFlag);
- CACLDataQController* HandleLocalReadBufferSizeResult(TUint16 aAclMaxLen,
- TUint8 /*aScoMaxLen*/,TUint16 aNoACL,TUint16 /*aNoSCO*/);
+ CACLDataQController* HandleLocalReadBufferSizeResult(TUint16 aAclMaxLen, TUint8 /*aScoMaxLen*/,
+ TUint16 aNoACL, TUint16 /*aNoSCO*/);
TInt ACLPacketMTU() const;
- CACLDataQController& DataQController() const {return *iDataController;};
+ CACLDataQController& DataQController() const {return *iDataController;}
+
void ChannelsFree(THCITransportChannel aChannel); // notification of free channels
void ChannelsClosed(THCITransportChannel aChannel); // notification of closed channels
- static TInt TryToSendCallBackStatic(TAny* aCLinkMuxer);
+
void TryToSend(); // request to send on certain channels
+
+ TFlowControlMode FlowControlMode() const {return iFlowControlMode;}
+ void ResetFlowControlMode();
+
#ifdef STACK_SCO_DATA
TBool CanWriteSCOData();
#endif
@@ -65,6 +70,8 @@
void ConstructL();
CLinkMuxer(CLinkMgrProtocol& aLinkMgrProtocol, CHCIFacade& aHCIFacade);
void DoSend(/*THCITransportChannel aChannel*/); // request to send on certain channels
+ static TInt TryToSendCallBackStatic(TAny* aCLinkMuxer);
+
private:
// owned resources
CHCICmdQController* iCommandController;
@@ -73,7 +80,8 @@
// non-owned resources
CHCIFacade& iHCIFacade;
THCITransportChannel iChannelsFree;
- TFlowControlMode iFlowControlMode;
+ TFlowControlMode iFlowControlMode;
+ TBool iCtrlerToHostSet;
CLinkMgrProtocol& iLinkMgrProtocol;
TInt iACLPacketMTU;
};
--- a/bluetooth/btstack/linkmgr/linkutil.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkutil.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2000-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"
@@ -191,6 +191,8 @@
EVendorSAPBadVendorEvent =250,
EBTACLSAPIndeterminateInitiator =251,
EBTACLSAPUnexpectedSecurityResult =252,
+ ELinkMgrFlowControlUnexpectedUpdate =253,
+ ELinkMgrFlowControlChangeOfMind =254,
};
/**
--- a/bluetooth/btstack/linkmgr/physicallinks.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -145,6 +145,7 @@
delete iPhysicalLinkMetrics;
delete iPinRequester;
delete iNumericComparator;
+ delete iUserConfirmer;
delete iPasskeyEntry;
delete iArbitrationDelay;
delete iRoleSwitchCompleteCallBack;
@@ -927,7 +928,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 +942,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 +992,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 +1064,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 +1703,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 +1764,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 +1778,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 +1799,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 +1902,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 +1924,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 +2290,7 @@
(aEvent.EventType() & ENotifyHoldMode)) &&
(aEvent.ErrorCode() == KErrNone))
{
- iArbitrationDelay->Start();
+ iArbitrationDelay->Restart();
}
}
@@ -3378,17 +3404,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 +3428,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 +3475,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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.cpp Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.h Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxchannel.inl Tue Jul 06 15:33:04 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 Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/rfcomm/rfcommmuxer.cpp Tue Jul 06 15:33:04 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/bluetooth/btstack/secman/SecManNotifiers.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/secman/SecManNotifiers.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2005-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,6 +17,7 @@
#define _SECMANNOTIFIERS_H
#include <e32base.h>
+#include <bluetooth/hci/hcitypes.h>
class TBTDevAddr;
--- a/bluetooth/btstack/secman/secman.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/secman/secman.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -160,7 +160,6 @@
void ClearHCICommandQueue();
public: // command functions
- void WriteSimplePairingModeL(TUint8 aSimplePairingMode);
void WriteSimplePairingDebugModeL(TUint8 aSimplePairingDebugMode);
void IOCapabilityRequestReplyL(const TBTDevAddr& aBDADDR, THCIIoCapability aIOCapability, THCIOobDataPresence aOOBDataPresent, THCIAuthenticationRequirement aAuthenticationRequirements);
void IOCapabilityRequestNegativeReplyL(const TBTDevAddr& aBDADDR, TUint8 aReason);
@@ -190,7 +189,6 @@
void SimplePairingCompleteEvent(const THCIEventBase& aEvent);
void KeypressNotificationEvent(const THCIEventBase& aEvent);
- void WriteSimplePairingModeOpcode(const THCICommandCompleteEvent& aCompleteEvent);
void RemoteOOBDataRequestReplyOpcode(const THCICommandCompleteEvent& aCompleteEvent);
void RemoteOOBDataRequestNegativeReplyOpcode(const THCICommandCompleteEvent& aCompleteEvent);
void WriteSimplePairingDebugModeOpcode(const THCICommandCompleteEvent& aCompleteEvent);
--- a/bluetooth/btstack/secman/secmanhci.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetooth/btstack/secman/secmanhci.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -118,14 +118,6 @@
return *iCommandQueue;
}
-void CSecManCommandController::WriteSimplePairingModeL(TUint8 aSimplePairingMode)
- {
- LOG_FUNC
- // Ownership of cmd transfered
- CWriteSimplePairingModeCommand* cmd = CWriteSimplePairingModeCommand::NewL(aSimplePairingMode);
- CommandQueue().MhcqAddCommandL(cmd, *this);
- }
-
void CSecManCommandController::WriteSimplePairingDebugModeL(TUint8 aSimplePairingDebugMode)
{
LOG_FUNC
@@ -207,10 +199,8 @@
switch(aEvent.EventCode())
{
case ECommandCompleteEvent:
- {
CommandCompleteEvent(aEvent);
break;
- }
case ECommandStatusEvent:
CommandStatusEvent(aEvent);
@@ -314,11 +304,7 @@
THCIErrorCode hciErr = aEvent.ErrorCode();
switch (opcode)
- {
- case KWriteSimplePairingModeOpcode:
- WriteSimplePairingModeOpcode(completeEvent);
- break;
-
+ {
case KRemoteOOBDataRequestReplyOpcode:
RemoteOOBDataRequestReplyOpcode(completeEvent);
break;
@@ -364,17 +350,6 @@
THCIErrorCode hciErr = commandStatusEvent.ErrorCode();
}
-void CSecManCommandController::WriteSimplePairingModeOpcode(const THCICommandCompleteEvent& aCompleteEvent)
- {
- LOG_FUNC
- if(aCompleteEvent.ErrorCode() == EOK)
- {
- iSecMan.SetLocalSimplePairingMode(ETrue);
- }
- // if we got an error then we make the reasonable assumption that the local controller is not
- // capable of secure simple pairing.
- }
-
void CSecManCommandController::RemoteOOBDataRequestReplyOpcode(const THCICommandCompleteEvent& aCompleteEvent)
{
LOG_FUNC
--- a/bluetoothmgmt/bluetoothclientlib/btlib/btbaseband.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/bluetoothclientlib/btlib/btbaseband.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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,6 +18,7 @@
#include <bt_sock.h>
#include <bluetooth/hci/hcierrors.h>
#include <bluetooth/aclsockaddr.h>
+#include <bluetooth/hci/aclpacketconsts.h>
#include "btsocketpanic.h"
//.................................
--- a/bluetoothmgmt/bluetoothclientlib/inc/bt_sock.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bt_sock.h Tue Jul 06 15:33:04 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/bluetoothmgmt/bluetoothclientlib/inc/bttypes.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bttypes.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -745,6 +745,20 @@
const TUint KLIAC=0x9e8b00;
/**
+@publishedAll
+@released
+
+HCI Scan enable mask
+*/
+enum THCIScanEnable
+ {
+ ENoScansEnabled = 0x00, /*!< No scans enabled */
+ EInquiryScanOnly = 0x01, /*!< Inquiry scan enabled */
+ EPageScanOnly = 0x02, /*!< Page scan enabled */
+ EInquiryAndPageScan = 0x03 /*!< Inquiry and page scan enabled */
+ };
+
+/**
L2CAP channel modes
@publishedAll
@released
--- a/bluetoothmgmt/bluetoothclientlib/inc/pairing.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/bluetoothclientlib/inc/pairing.h Tue Jul 06 15:33:04 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"
@@ -24,6 +24,7 @@
#include <e32std.h>
#include <bt_sock.h>
+#include <bttypespartner.h>
/**
The UID indicating the dedicated bonding service request.
--- a/bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -534,15 +534,19 @@
CBTManSession::~CBTManSession()
{
LOG_FUNC
+
+ delete iSubSessions;
+ Server().DeleteContainer(iContainer);
+ Server().DropSession();
+
if (iMessageArray)
{
+ __ASSERT_DEBUG(iMessageArray->Count()== 0, PanicServer(EBTManOutstandingMessagesOnClosedSession));
+
CompleteOutstandingMessages();
iMessageArray->ResetAndDestroy();
}
delete iMessageArray;
- delete iSubSessions;
- Server().DeleteContainer(iContainer);
- Server().DropSession();
}
void CBTManSession::CompleteOutstandingMessages()
--- a/bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -19,6 +19,7 @@
#include <e32property.h>
#include <f32file.h>
#include <s32file.h>
+#include <bluetooth/hci/hciconsts.h>
#include "btmanserverutil.h"
#include "btmanserverburmgr.h"
#include "BTManServer.h"
--- a/bluetoothmgmt/btmgr/Inc/BTManServer.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bluetoothmgmt/btmgr/Inc/BTManServer.h Tue Jul 06 15:33:04 2010 +0300
@@ -362,6 +362,7 @@
EBTManClientShouldBeBusy,
EBTManBadState,
EBTManUnexpectedDbError,
+ EBTManOutstandingMessagesOnClosedSession,
};
--- a/bt_plat/bluetooth_audio_adaptation_api/inc/btaudiostreaminputbase.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bt_plat/bluetooth_audio_adaptation_api/inc/btaudiostreaminputbase.h Tue Jul 06 15:33:04 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.
--- a/bthci/bthci2/corehci/interface/hcitypes.h Wed Jun 23 19:28:39 2010 +0300
+++ b/bthci/bthci2/corehci/interface/hcitypes.h Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -181,17 +181,6 @@
EPointToPointAndBroadcastEncryption = 0x02, /*!< Point to point and broadcast encryption enabled */
};
-enum THCIScanEnable
-/**
-HCI Scan enable mask
-*/
- {
- ENoScansEnabled = 0x00, /*!< No HCI scans enabled */
- EInquiryScanOnly = 0x01, /*!< HCI inquiry scan enabled */
- EPageScanOnly = 0x02, /*!< HCI page scan enabled */
- EInquiryAndPageScan = 0x03 /*!< HCI inquiry and page scan enabled */
- };
-
enum THCIInquiryMode
/**
HCI Inquiry mode flag
--- a/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Wed Jun 23 19:28:39 2010 +0300
+++ b/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -324,7 +324,7 @@
MHCICompletingEventQuery* completingEventInterface = NULL;
err = iSendingCommand->Command().Extension_(KCompletingEventExpectUid, reinterpret_cast<TAny*&>(completingEventInterface), NULL);
if( (err == KErrNone && !completingEventInterface->MhceqCompletingEventExpected()) ||
- (err == KErrNotSupported && consumed == 0))
+ (err == KErrExtensionNotSupported && consumed == 0))
{
// Certain commands (e.g. the Number of Host Complete Packets
// command) use no credits and do not normally return any
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/EABI/btaudioadaptationU.DEF Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,10 @@
+EXPORTS
+ _ZN23CBTAudioStreamInputBase4NewLER22MBTAudioStreamObserverR21MBTAudioErrorObserver @ 1 NONAME
+ _ZN29CBTAudioStreamInputAdaptation10DisconnectEv @ 2 NONAME
+ _ZN29CBTAudioStreamInputAdaptation13BufferEmptiedERK6TDesC8 @ 3 NONAME
+ _ZN29CBTAudioStreamInputAdaptation16EncoderInterfaceE4TUid @ 4 NONAME
+ _ZN29CBTAudioStreamInputAdaptation4StopEv @ 5 NONAME
+ _ZN29CBTAudioStreamInputAdaptation5StartEv @ 6 NONAME
+ _ZN29CBTAudioStreamInputAdaptation7ConnectEv @ 7 NONAME
+ _ZN29CBTAudioStreamInputAdaptation9SetFormatE7TFourCC @ 8 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/bwins/btaudioadaptationU.DEF Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,10 @@
+EXPORTS
+ ?NewL@CBTAudioStreamInputBase@@SAPAV1@AAVMBTAudioStreamObserver@@AAVMBTAudioErrorObserver@@@Z @ 1 NONAME ; class CBTAudioStreamInputBase * CBTAudioStreamInputBase::NewL(class MBTAudioStreamObserver &, class MBTAudioErrorObserver &)
+ ?BufferEmptied@CBTAudioStreamInputAdaptation@@UAEXABVTDesC8@@@Z @ 2 NONAME ; void CBTAudioStreamInputAdaptation::BufferEmptied(class TDesC8 const &)
+ ?Connect@CBTAudioStreamInputAdaptation@@UAEHXZ @ 3 NONAME ; int CBTAudioStreamInputAdaptation::Connect(void)
+ ?Disconnect@CBTAudioStreamInputAdaptation@@UAEXXZ @ 4 NONAME ; void CBTAudioStreamInputAdaptation::Disconnect(void)
+ ?EncoderInterface@CBTAudioStreamInputAdaptation@@UAEPAXVTUid@@@Z @ 5 NONAME ; void * CBTAudioStreamInputAdaptation::EncoderInterface(class TUid)
+ ?SetFormat@CBTAudioStreamInputAdaptation@@UAEHVTFourCC@@@Z @ 6 NONAME ; int CBTAudioStreamInputAdaptation::SetFormat(class TFourCC)
+ ?Start@CBTAudioStreamInputAdaptation@@UAEHXZ @ 7 NONAME ; int CBTAudioStreamInputAdaptation::Start(void)
+ ?Stop@CBTAudioStreamInputAdaptation@@UAEXXZ @ 8 NONAME ; void CBTAudioStreamInputAdaptation::Stop(void)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/group/bld.inf Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2005-2006 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Build information file for project btaudioadaptation_stub
+*
+*/
+
+
+PRJ_PLATFORMS
+DEFAULT
+
+#if defined __BT_STEREO_AUDIO
+
+PRJ_MMPFILES
+../group/btaudiostreaminputadaptation.mmp
+
+#endif // __BT_STEREO_AUDIO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/group/btaudiostreaminputadaptation.mmp Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2005-2006 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Project definition file for project btaudioadaptation_stub
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+#if defined(WINS) || defined(WINSCW)
+TARGET btaudioadaptation.dll
+#else
+TARGET btaudioadaptation_stub.dll
+#endif
+
+CAPABILITY CAP_GENERAL_DLL
+TARGETTYPE DLL
+UID 0x1000008d 0x10208977
+
+VENDORID VID_DEFAULT
+
+SOURCEPATH ../src
+SOURCE btaudiostreaminputadaptation.cpp
+
+USERINCLUDE ../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib // user library
+
+DEBUGLIBRARY flogger.lib // file logging services
+
+EXPORTLIBRARY btaudioadaptation.lib
+LINKAS btaudioadaptation.dll
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/inc/btaudioadaptationdebug.h Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,150 @@
+/*
+* Copyright (c) 2005 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Debug definitions for BT Audio Adaptation
+*
+*/
+
+
+#ifndef BT_AUDIO_ADAPTATION_DEBUG_H
+#define BT_AUDIO_ADAPTATION_DEBUG_H
+
+#include <f32file.h>
+
+
+#ifdef _DEBUG
+
+// Print options
+
+#define KPRINTERROR 0x00000001 // Print error
+#define KPRINTFTRACE 0x00000002 // Print function trace
+#define KPRINTSTATE 0x00000004 // Print state machine infos
+
+const TInt KDebugMask = KPRINTERROR | KPRINTFTRACE | KPRINTSTATE ;
+
+
+// Un-comment/comment this definition to enable/disable memory tracing
+//#define MEMTRACE
+
+#ifdef __WINS__
+
+// File logging for WINS
+#define __FLOGGING__
+
+#else
+
+// Logging with RDebug for target HW
+#define __CLOGGING__
+
+#endif //__WINS__
+
+#endif // _DEBUG
+
+
+// ==================================================================
+// File logging
+// ==================================================================
+//
+#if defined(__FLOGGING__)
+
+#include <e32std.h>
+
+_LIT(KLogFile,"BTAudioAdaptationLog.txt");
+_LIT(KLogDirFullName,"c:\\logs\\bt\\");
+_LIT(KLogDir,"BT");
+
+#include <f32file.h>
+#include <flogger.h>
+
+#define FLOG(a) { FPrint(a); }
+
+#define FTRACE(a) { a; }
+
+#define BT_AUDIO_ADAPTATION_TRACE_OPT(a,p) {if((KDebugMask)&(a))p;}
+
+
+
+
+inline void FPrint(const TRefByValue<const TDesC> aFmt, ...)
+ {
+ VA_LIST list;
+ VA_START(list,aFmt);
+ RFileLogger::WriteFormat(KLogDir, KLogFile, EFileLoggingModeAppend, aFmt, list);
+#ifdef MEMTRACE
+ TInt size;
+ User::Heap().AllocSize(size);
+ RFileLogger::WriteFormat(KLogDir, KLogFile, EFileLoggingModeAppend, _L("[BTAudioAdaptation]\t MEM\tAllocated from heap: %d B. Total heap size: %d B"), size, User::Heap().Size());
+#endif
+ }
+
+
+inline void FHex(const TUint8* aPtr, TInt aLen)
+ {
+ RFileLogger::HexDump(KLogDir, KLogFile, EFileLoggingModeAppend, 0, 0, aPtr, aLen);
+ }
+
+
+inline void FHex(const TDesC8& aDes)
+ {
+ FHex(aDes.Ptr(), aDes.Length());
+ }
+
+
+// ==================================================================
+// RDebug logging
+// ==================================================================
+//
+#elif defined(__CLOGGING__)
+
+#include <e32svr.h>
+
+#define FLOG(a) { RDebug::Print(a); }
+
+#define FHex(a)
+
+#define FTRACE(a) { a; }
+
+#define BT_AUDIO_ADAPTATION_TRACE_OPT(a,p) {if((KDebugMask)&(a))p;}
+
+
+inline void FPrint(const TRefByValue<const TDesC> aFmt, ...)
+ {
+ VA_LIST list;
+ VA_START(list,aFmt);
+ TInt tmpInt = VA_ARG(list, TInt);
+ TInt tmpInt2 = VA_ARG(list, TInt);
+ TInt tmpInt3 = VA_ARG(list, TInt);
+ VA_END(list);
+ RDebug::Print(aFmt, tmpInt, tmpInt2, tmpInt3);
+ }
+
+
+// ==================================================================
+// No loggings --> Reduced binary size
+// ==================================================================
+//
+#else // if no __FLOGGING__ and no __CLOGGING__
+
+#define FLOG(a)
+
+#define FTRACE(a)
+
+#define FHex(a)
+
+#define BT_AUDIO_ADAPTATION_TRACE_OPT(a,p)
+
+#endif // ...loggings
+
+#endif // BTAUDIOADAPTATION_DEBUG_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/inc/btaudiostreaminputadaptation.h Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2005-2006 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This header specifies the implementation of BT Audio Adaptation API.
+*
+*/
+
+
+#ifndef __BTAUDIOSTREAMINPUTADAPTATION_H__
+#define __BTAUDIOSTREAMINPUTADAPTATION_H__
+
+#include <e32base.h>
+#include <e32std.h>
+#include "btaudiostreaminputbase.h"
+
+/**
+ * This class implements the interface specified by CBTAudioStreamInputBase.
+ *
+ * This class contains the stub implementation of the CAudioStreamInputAdaptation,
+ * that inherits from CBTAudioStreamInputBase.
+ *
+ * To the user it seems as if he's operating with the base class, because he calls,
+ * but in practice the class he uses is an instance of this class.
+ *
+ * @lib btaudioadaptation.lib
+ * @since S60 v3.1
+ */
+NONSHARABLE_CLASS(CBTAudioStreamInputAdaptation) : public CBTAudioStreamInputBase
+ {
+ public:
+ static CBTAudioStreamInputAdaptation* NewL( MBTAudioStreamObserver& aStreamObserver, MBTAudioErrorObserver& aErrorObserver );
+ virtual ~CBTAudioStreamInputAdaptation();
+
+ public:
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is called when the client has processed the buffer it got
+ * from the Receive method.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param aBuffer refers to the buffer that was received earlier in the Receive method.
+ * @return void
+ */
+ IMPORT_C void BufferEmptied( const TDesC8& aBuffer );
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for connecting to the audio subsystem.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param void.
+ * @return a Symbian OS wide error code.
+ */
+ IMPORT_C TInt Connect();
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for disconnecting from the audio subsystem.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param void.
+ * @return void
+ */
+ IMPORT_C void Disconnect();
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for passing the custom interfaces that are
+ * needed sometimes for configuring the hardware encoder.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param aInterfaceId specifies the id of custom interface that the client
+ * wants to get.
+ * @return A pointer to the requested interface. Client must cast it into a correct class.
+ */
+ IMPORT_C TAny* EncoderInterface(TUid aInterfaceId);
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for choosing the encoder for the audio data.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param aDesiredFourCC specifies the encoder that the client wants to use.
+ * @return a Symbian OS wide error code.
+ */
+ IMPORT_C TInt SetFormat(TFourCC aDesiredFourCC);
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for starting the recording from the audio subsystem.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param void.
+ * @return a Symbian OS wide error code.
+ */
+ IMPORT_C TInt Start();
+
+ /**
+ * From CBTAudioStreamInputBase.
+ * This method is for stopping the recording from the audio subsystem.
+ *
+ * See BT Audio Adaptation API and BT Audio Adaptation Design specifications
+ * for detailed explanation.
+ *
+ * @since S60 v3.1
+ * @param void.
+ * @return a Symbian OS wide error code.
+ */
+ IMPORT_C void Stop();
+
+ private:
+ CBTAudioStreamInputAdaptation(MBTAudioStreamObserver& aStreamObserver, MBTAudioErrorObserver& aErrorObserver);
+ void ConstructL();
+ void RunL();
+ void DoCancel();
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/layers.sysdef.xml Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE SystemDefinition SYSTEM "sysdef_1_4_0.dtd" [
+ <!ENTITY layer_real_source_path "sf/adaptation/stubs/btaudioadaptation_stub" >
+]>
+
+<SystemDefinition name="btaudioadaptation_stub" schema="1.4.0">
+ <systemModel>
+ <layer name="stubs_layer">
+ <module name="btaudioadaptation_stub">
+ <unit unitID="lcdo.btaudioadaptation_stub" mrp="" bldFile="&layer_real_source_path;/group" name="btaudioadaptation_stub" filter="oem_build"/>
+ </module>
+ </layer>
+ </systemModel>
+</SystemDefinition>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/rom/btaudioadaptation.iby Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2009 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef __BTAUDIOADAPTATION_IBY__
+#define __BTAUDIOADAPTATION_IBY__
+
+file=ABI_DIR\BUILD_DIR\btaudioadaptation_stub.dll SHARED_LIB_DIR\btaudioadaptation.dll
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/src/btaudiostreaminputadaptation.cpp Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,150 @@
+/*
+* Copyright (c) 2005-2006 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Contains stub implementation of CBTAudioStreamInputAdaptation class,
+* which implements BT Audio Adaptation API.
+*
+*/
+
+
+#include <e32std.h>
+
+#include "btaudiostreaminputadaptation.h"
+#include "btaudioadaptationdebug.h"
+
+CBTAudioStreamInputAdaptation::CBTAudioStreamInputAdaptation(MBTAudioStreamObserver& /*aStreamObserver*/, MBTAudioErrorObserver& /*aErrorObserver*/)
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::CBTAudioStreamInputAdaptation() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::CBTAudioStreamInputAdaptation() <-")));
+ }
+
+void CBTAudioStreamInputAdaptation::ConstructL()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::ConstructL() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::ConstructL() <-")));
+ }
+
+// ---------------------------------------------------------------------------
+// Static factory method for the abstract base class.
+// This just calls the factory method of the concrete implementation class.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBTAudioStreamInputBase* CBTAudioStreamInputBase::NewL(MBTAudioStreamObserver& aStreamObserver, MBTAudioErrorObserver& aErrorObserver)
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioInput::NewL() ->")));
+ CBTAudioStreamInputBase* audioInput = (CBTAudioStreamInputAdaptation::NewL(aStreamObserver, aErrorObserver));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioInput::NewL() <-")));
+ return audioInput;
+ }
+
+// ---------------------------------------------------------------------------
+// Static factory method.
+// ---------------------------------------------------------------------------
+//
+CBTAudioStreamInputAdaptation* CBTAudioStreamInputAdaptation::NewL(MBTAudioStreamObserver& aStreamObserver, MBTAudioErrorObserver& aErrorObserver)
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::NewL() ->")));
+ CBTAudioStreamInputAdaptation* self = new (ELeave) CBTAudioStreamInputAdaptation(aStreamObserver, aErrorObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::NewL() <-")));
+ return self;
+ }
+
+CBTAudioStreamInputAdaptation::~CBTAudioStreamInputAdaptation()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::~CBTAudioStreamInputAdaptation() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::~CBTAudioStreamInputAdaptation() <-")));
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Returns KErrNotSupported always - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTAudioStreamInputAdaptation::Start()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Start() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Start() <-")));
+ return KErrNotSupported;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Returns a NULL pointer always - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TAny* CBTAudioStreamInputAdaptation::EncoderInterface(TUid /*aInterfaceId*/)
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::EncoderInterface() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::EncoderInterface() <-")));
+ return (TAny *) 0;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Doesn't do anything - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBTAudioStreamInputAdaptation::BufferEmptied( const TDesC8& /*aBuffer*/ )
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::BufferEmptied() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::BufferEmptied() <-")));
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Doesn't do anything - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBTAudioStreamInputAdaptation::Stop()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Stop() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Stop() <-")));
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Returns KErrNotSupported always - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTAudioStreamInputAdaptation::SetFormat(TFourCC /*aDesiredFourCC*/)
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::SetFormat() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::SetFormat() <-")));
+ return KErrNotSupported;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Returns KErrNotSupported always - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTAudioStreamInputAdaptation::Connect()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Connect() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Connect() <-")));
+ return KErrNotSupported;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CBTAudioStreamInputBase.
+// Doesn't do anything - this is the stub implementation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBTAudioStreamInputAdaptation::Disconnect()
+ {
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Disconnect() ->")));
+ BT_AUDIO_ADAPTATION_TRACE_OPT( KPRINTFTRACE, FLOG(_L("[BTAudioAdaptation]\t CBTAudioStreamInputAdaptation::Disconnect() <-")));
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btsimulator/btaudioadaptation_stub/sysdef_1_4_0.dtd Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,86 @@
+ <!ELEMENT SystemDefinition (systemModel?, build?)>
+ <!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (logicalset* | module*)*>
+ <!ATTLIST layer
+ name CDATA #REQUIRED
+ levels CDATA #IMPLIED
+ span CDATA #IMPLIED>
+ <!ELEMENT logicalset (logicalsubset* | module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalset name CDATA #REQUIRED>
+ <!ELEMENT logicalsubset (module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalsubset name CDATA #REQUIRED>
+ <!ELEMENT module (component* | unit* | package* | prebuilt*)*>
+ <!ATTLIST module
+ name CDATA #REQUIRED
+ level CDATA #IMPLIED>
+ <!ELEMENT component (unit* | package* | prebuilt*)*>
+ <!ATTLIST component name CDATA #REQUIRED>
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+ unitID ID #REQUIRED
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ bldFile CDATA #REQUIRED
+ priority CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT package EMPTY>
+ <!ATTLIST package
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT prebuilt EMPTY>
+ <!ATTLIST prebuilt
+ name CDATA #REQUIRED
+ version CDATA #REQUIRED
+ late (Y|N) #IMPLIED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT build (option* | target+ | targetList+ | unitList+ | configuration+)*>
+ <!ELEMENT unitList (unitRef+)>
+ <!ATTLIST unitList
+ name ID #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT unitRef EMPTY>
+ <!ATTLIST unitRef unit IDREF #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+ name ID #REQUIRED
+ abldTarget CDATA #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+ name ID #REQUIRED
+ abldOption CDATA #REQUIRED
+ description CDATA #REQUIRED
+ enable (Y | N | y | n) #REQUIRED>
+ <!ELEMENT configuration (unitListRef+ | layerRef+ | task+)*>
+ <!ATTLIST configuration
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ filter CDATA #REQUIRED>
+ <!ELEMENT task ( unitListRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT unitListRef EMPTY>
+ <!ATTLIST unitListRef unitList IDREF #REQUIRED>
+ <!ELEMENT layerRef EMPTY>
+ <!ATTLIST layerRef layerName CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+ command CDATA #REQUIRED
+ targetList IDREFS #IMPLIED
+ unitParallel (Y | N | y | n) #REQUIRED
+ targetParallel (Y | N | y | n) #IMPLIED>
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+ name CDATA #REQUIRED
+ cwd CDATA #REQUIRED
+ command CDATA #REQUIRED>
--- a/package_definition.xml Wed Jun 23 19:28:39 2010 +0300
+++ b/package_definition.xml Tue Jul 06 15:33:04 2010 +0300
@@ -1,6 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<SystemDefinition schema="3.0.0">
<package id="bt" name="Bluetooth" levels="adaptation hw-if plugin framework server app-if">
+ <collection id="bt_plat" name="Bluetooth Platform Interfaces" level="app-if">
+ <component id="bluetooth_audio_adaptation_api" name="Bluetooth Audio Adaptation API" class="api" filter="s60">
+ <meta rel="Api" href="bt_plat/bluetooth_audio_adaptation_api/bluetooth_audio_adaptation_api.metaxml"/>
+ <unit bldFile="bt_plat/bluetooth_audio_adaptation_api/group"/>
+ </component>
+ <component id="bluetooth_power_management_api" name="Bluetooth Power Management API" class="api" filter="s60">
+ <meta rel="Api" href="bt_plat/bluetooth_power_management_api/bluetooth_power_management_api.metaxml"/>
+ <unit bldFile="bt_plat/bluetooth_power_management_api/group"/>
+ </component>
+ <component id="at_command_handler_plugin_api" name="AT Command Handler Plugin API" class="api" filter="s60">
+ <meta rel="Api" href="bt_plat/at_command_handler_plugin_api/at_command_handler_plugin_api.metaxml"/>
+ <unit bldFile="bt_plat/at_command_handler_plugin_api/group"/>
+ </component>
+ </collection>
<collection id="bluetooth" name="Bluetooth Core" level="framework">
<component id="btstack" name="Bluetooth Stack" introduced="6.0" purpose="optional">
<unit bldFile="bluetooth/btstack" mrp="bluetooth/btstack/bluetooth_stack.mrp"/>
@@ -76,12 +90,14 @@
</component>
</collection>
<collection id="bt_info" name="Bluetooth Info" level="app-if">
- <component id="bt_plat" filter="s60" class="api">
- <unit bldFile="bt_plat/group"/>
- </component>
<component id="bt_metadata" name="Bluetooth Metadata" class="config" introduced="^3" purpose="development" target="desktop">
<unit mrp="bt_info/bt_metadata/bt_metadata.mrp"/>
</component>
</collection>
+ <collection id="btsimulator" name="Bluetooth Simulator" level="internal-utils">
+ <component id="btaudioadaptation_stub" name="Bluetooth Audio Adaption Stub" introduced="^3" purpose="optional" filter="s60">
+ <unit bldFile="btsimulator/btaudioadaptation_stub/group"/>
+ </component>
+ </collection>
</package>
</SystemDefinition>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/package_map.xml Tue Jul 06 15:33:04 2010 +0300
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<PackageMap root="sf" layer="os" />
\ No newline at end of file