author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 06 Jul 2010 15:33:04 +0300 | |
changeset 32 | f72906e669b4 |
parent 31 | b9d1744dc449 |
child 36 | 230aed0f16aa |
child 42 | 206564d58f40 |
--- 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>