--- a/atext/client/src/atextcommon.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/client/src/atextcommon.cpp Tue May 11 17:15:36 2010 +0300
@@ -55,7 +55,7 @@
Close();
}
TRACE_FUNC_EXIT
- return KErrNone;
+ return retVal;
}
// ---------------------------------------------------------------------------
--- a/atext/server/inc/atextcommonsession.h Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/inc/atextcommonsession.h Tue May 11 17:15:36 2010 +0300
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2008 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"
@@ -253,7 +253,7 @@
/**
* Session to ECOM
*/
- REComSession iEComSession;
+ REComSession* iEComSession;
/**
* Instance of plugin
--- a/atext/server/inc/atextmetadata.h Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/inc/atextmetadata.h Tue May 11 17:15:36 2010 +0300
@@ -302,6 +302,13 @@
*/
CATExtPluginBase* iOldHandler;
+ /**
+ * Pointer to editor handler; set when editor mode started,
+ * NULL when editor mode not active.
+ * Not own.
+ */
+ TATExtPluginEntry* iEditorHandler;
+
};
/**
@@ -521,6 +528,22 @@
TBool aMultiPart );
/**
+ * Writes multipart or single part reply buffer to client for handle.
+ * Used for creating a reply for HandleCommand().
+ *
+ * @since S60 5.0
+ * @param aMultiPart ETrue (default behavior) if multipart reply wanted,
+ * EFalse otherwise.
+ * For multipart replies the reply may be over
+ * KDefaultCmdBufLength.
+ * @param aStartOfEditor ETrue if start of editor mode,
+ * EFalse otherwise
+ * @return Symbian error code on error, KErrNone otherwise
+ */
+ TInt WriteHandleCmdReplyBuffer( TBool aMultiPart,
+ TBool aStartOfEditor );
+
+ /**
* Clears internal initialized command handler data. This is currently used
* only by CompleteCommandMessage() and is called when the data is not
* needed anymore. It also prepares the internal data for a new
--- a/atext/server/inc/atextsession.h Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/inc/atextsession.h Tue May 11 17:15:36 2010 +0300
@@ -1,5 +1,5 @@
/*
-* 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"
@@ -418,7 +418,7 @@
/**
* Session to ECOM
*/
- REComSession iEComSession;
+ REComSession* iEComSession;
/**
* ECOM listener
--- a/atext/server/src/atextcommonsession.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/src/atextcommonsession.cpp Tue May 11 17:15:36 2010 +0300
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2008 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"
@@ -11,7 +11,7 @@
*
* Contributors:
*
-* Description:
+* Description:
*
*/
@@ -132,6 +132,7 @@
CATExtCommonSession::CATExtCommonSession( CATExtSrvCommon& aServer,
const TVersion& aVersion ) :
iServer( aServer ),
+ iEComSession( NULL ),
iVersion( aVersion )
{
}
@@ -158,13 +159,12 @@
TRACE_FUNC_EXIT
User::Leave( retTemp );
}
- REComSession& ecomSession = REComSession::OpenL();
- CleanupClosePushL( ecomSession );
+ iEComSession = &REComSession::OpenL();
RImplInfoPtrArray implementations;
CleanupResetDestroyClosePushL( implementations );
TUid ifUid = TUid::Uid( ATEXT_INTERFACE_COM_UID );
- iEComSession.ListImplementationsL( ifUid,
- implementations );
+ iEComSession->ListImplementationsL( ifUid,
+ implementations );
if ( implementations.Count() != 1 )
{
TRACE_FUNC_EXIT
@@ -173,9 +173,7 @@
TUid pluginUid = implementations[0]->ImplementationUid();
iCommonBase = CATExtCommonBase::NewL( pluginUid, *this, connectionName );
CleanupStack::PopAndDestroy( &implementations );
- CleanupStack::Pop( &ecomSession );
CleanupStack::PopAndDestroy( &connectionName );
- iEComSession = ecomSession;
TRACE_FUNC_EXIT
}
@@ -488,7 +486,10 @@
}
delete iCommonBase;
iCommonBase = NULL;
- iEComSession.Close();
+ if ( iEComSession )
+ {
+ iEComSession->Close();
+ }
if ( !aSyncClose )
{
REComSession::FinalClose();
--- a/atext/server/src/atextmetadata.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/src/atextmetadata.cpp Tue May 11 17:15:36 2010 +0300
@@ -211,6 +211,22 @@
TRACE_FUNC_EXIT
return retTemp;
}
+ // First check if in editor mode
+ if ( iCmdData.iEditorHandler )
+ {
+ iCmdData.iReplyExpected = EFalse;
+ iCmdData.iHandler = iCmdData.iEditorHandler;
+ iCmdData.iHandler->iInstance->HandleCommand( iCmdData.iCmdBuffer,
+ iCmdData.iCmdReplyBuffer,
+ EFalse );
+ aComplInfo.iProcessed = ETrue;
+ aComplInfo.iReplyExpected = ETrue;
+ // Note: The aComplInfo.iReplyExpected is used only for normal mode and
+ // is set to ETrue here to skip a check in CATExtSession::IpcHandleCommand().
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+ // Not in editor so handle in normal mode
TRACE_INFO(( _L8("Received command '%S'"), &iCmdData.iCmdBuffer ));
// Now the command exists. Load the plugins for a command and check support.
TRAPD( retTrap, CreateAndFindSupportL(iCmdData.iCmdBuffer,
@@ -327,20 +343,42 @@
TRACE_FUNC_EXIT
return KErrInUse;
}
+ if ( !iCmdData.iCmdMessage.Handle() )
+ {
+ TRACE_FUNC_EXIT
+ return KErrBadHandle;
+ }
+ TBool startOfEditor = EFalse;
+ if ( aReplyType == EReplyTypeEditor)
+ {
+ // If completion is for editor command then set iCmdData.iEditorHandler
+ // for the first time only
+ if ( !iCmdData.iEditorHandler )
+ {
+ iCmdData.iEditorHandler = FindInstanceFromPlugindata( aPlugin );
+ iCmdData.iReplyExpected = ETrue; // reply expected when first reply in editor mode
+ startOfEditor = ETrue;
+ }
+ }
+ else
+ {
+ // If completion was something else than EReplyTypeEditor then just end
+ // editor mode (no need to check iEditorHandler)
+ if ( iCmdData.iEditorHandler )
+ {
+ iCmdData.iReplyExpected = ETrue; // reply expected when last reply in editor mode
+ }
+ iCmdData.iEditorHandler = NULL;
+ }
// Next check if aPlugin is set (the call comes from a plugin and not from
// ATEXT) and a reply is not needed. In this case do nothing as it is wrong
// behavior from the plugin (a plugin must not complete messages where no
// reply is expected; this is done by ATEXT)
- if ( aPlugin && !iCmdData.iReplyExpected )
+ if ( aPlugin && !iCmdData.iReplyExpected && !iCmdData.iEditorHandler )
{
TRACE_FUNC_EXIT
return KErrAlreadyExists;
}
- if ( !iCmdData.iCmdMessage.Handle() )
- {
- TRACE_FUNC_EXIT
- return KErrBadHandle;
- }
// Finally write the data and complete the message
TPckg<TATExtensionReplyType> replyType( aReplyType );
TInt writeError = iCmdData.iCmdMessage.Write( EATExtHandleCmdParamReplyType,
@@ -356,20 +394,7 @@
{
CreateEmptyOrErrorBuffer( iCmdData.iCmdReplyBuffer, aErrorReply );
}
- if ( aMultiPart )
- {
- WriteReplyBufferToClient( iCmdData.iCmdReplyBuffer,
- EATExtHandleCmdParamReply,
- iCmdData.iCmdMessage,
- ETrue,
- EATExtHandleCmdParamLength );
- }
- else
- {
- WriteReplyBufferToClient( iCmdData.iCmdReplyBuffer,
- EATExtHandleCmdParamReply,
- iCmdData.iCmdMessage );
- }
+ WriteHandleCmdReplyBuffer( aMultiPart, startOfEditor );
}
iCmdData.iCmdStarted = EFalse;
iCmdData.iReplyExpected = EFalse;
@@ -380,6 +405,38 @@
}
// ---------------------------------------------------------------------------
+// Writes multipart or single part reply buffer to client for handle.
+// Used for creating a reply for HandleCommand().
+// ---------------------------------------------------------------------------
+//
+TInt CATExtMetadata::WriteHandleCmdReplyBuffer( TBool aMultiPart,
+ TBool aStartOfEditor )
+ {
+ TRACE_FUNC_ENTRY
+ if ( iCmdData.iEditorHandler && !aStartOfEditor )
+ {
+ TRACE_FUNC_EXIT
+ return KErrNotReady;
+ }
+ if ( aMultiPart )
+ {
+ WriteReplyBufferToClient( iCmdData.iCmdReplyBuffer,
+ EATExtHandleCmdParamReply,
+ iCmdData.iCmdMessage,
+ ETrue,
+ EATExtHandleCmdParamLength );
+ }
+ else
+ {
+ WriteReplyBufferToClient( iCmdData.iCmdReplyBuffer,
+ EATExtHandleCmdParamReply,
+ iCmdData.iCmdMessage );
+ }
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
// Clears internal initialized command handler data. This is currently used
// only by CompleteCommandMessage() and is called when the data is not needed
// anymore. It also prepares the internal data for a new HandleCommand() call.
@@ -964,6 +1021,7 @@
iCmdData.iReplyExpected = EFalse;
iCmdData.iHandler = NULL;
iCmdData.iOldHandler = NULL;
+ iCmdData.iEditorHandler = NULL;
iCarriageReturn = KDefaultCarriageReturn;
iLineFeed = KDefaultLineFeed;
iQuietMode = EFalse;
@@ -1185,7 +1243,7 @@
TRACE_FUNC_ENTRY
if ( iCmdData.iCmdStarted ||
(iCmdData.iCmdMessage.Handle() && iCmdData.iCmdBuffer.Length()>0) ||
- iCmdData.iCmdReplyBuffer.Length()>0 )
+ iCmdData.iCmdReplyBuffer.Length()>0 )
{
TRACE_FUNC_EXIT
return ETrue;
@@ -1227,6 +1285,7 @@
iPluginData = NULL;
iCmdData.iHandler = NULL;
iCmdData.iOldHandler = NULL;
+ iCmdData.iEditorHandler = NULL;
TRACE_FUNC_EXIT
return KErrNone;
}
@@ -1248,6 +1307,7 @@
if ( iCmdData.iHandler && iCmdData.iHandler->iInstance )
{
iCmdData.iHandler->iInstance->HandleCommandCancel();
+ iCmdData.iEditorHandler = NULL;
}
CompleteCommandMessage( NULL,
aError,
@@ -2336,6 +2396,7 @@
iCmdData.iCmdStarted = ETrue;
iCmdData.iCmdMessage = aEntrySupport.iMessage;
iCmdData.iHandler = aEntrySupport.iEntry;
+ iCmdData.iEditorHandler = NULL;
}
// No "else" here as HandleCommandL() is used also with observer plugins
if ( !aAtCmdFull )
@@ -2372,6 +2433,12 @@
TRACE_FUNC_EXIT
User::Leave( KErrGeneral );
}
+ if ( !aEntrySupport.iSupportFound )
+ {
+ // No initial support found -> do nothing
+ TRACE_FUNC_EXIT
+ return;
+ }
TInt i;
TInt count = aEntrySupport.iSupport->Count();
for ( i=aEntrySupport.iStartIndex; i<count; i++ )
@@ -2382,11 +2449,7 @@
continue;
}
aEntrySupport.iEntry = &(*iPluginData)[oneCmdSupport.iEntryIndex];
- TBool supported = EFalse;
- if ( !aEntrySupport.iSupportFound )
- {
- supported = HandleCommandSupportL( aEntrySupport, aAtCmdFull );
- }
+ TBool supported = HandleCommandSupportL( aEntrySupport, aAtCmdFull );
if ( supported )
{
HandleCommandL( aEntrySupport, EFalse, aAtCmdFull );
--- a/atext/server/src/atextsession.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/atext/server/src/atextsession.cpp Tue May 11 17:15:36 2010 +0300
@@ -11,7 +11,7 @@
*
* Contributors:
*
-* Description:
+* Description:
*
*/
@@ -199,6 +199,7 @@
//
CATExtSession::CATExtSession( CATExtSrv& aServer, const TVersion& aVersion ) :
iServer( aServer ),
+ iEComSession( NULL ),
iListener( NULL ),
iMetadata( NULL ),
iVersion( aVersion )
@@ -217,8 +218,7 @@
TRACE_FUNC_EXIT
User::Leave( KErrGeneral );
}
- REComSession& ecomSession = REComSession::OpenL();
- CleanupClosePushL( ecomSession );
+ iEComSession = &REComSession::OpenL();
TPckgBuf<TUid> ifUidPckgBuf;
TInt retTemp = ReadStructFromMessage( ifUidPckgBuf,
EATExtConnectParamUid,
@@ -239,10 +239,10 @@
User::Leave( retTemp );
}
// Create listener
- CATExtListen* listener = CATExtListen::NewLC( ecomSession, this );
+ CATExtListen* listener = CATExtListen::NewLC( *iEComSession, this );
listener->AddInterfaceUid( ifUidPckgBuf() );
// Create metadata. Pass iListener to add the UIDs
- CATExtMetadata* metadata = CATExtMetadata::NewLC( ecomSession,
+ CATExtMetadata* metadata = CATExtMetadata::NewLC( *iEComSession,
listener,
*this );
metadata->CreateImplementationMetadataL( ifUidPckgBuf(), connectionName );
@@ -250,8 +250,6 @@
CleanupStack::Pop( metadata );
CleanupStack::Pop( listener );
CleanupStack::PopAndDestroy( &connectionName );
- CleanupStack::Pop( &ecomSession );
- iEComSession = ecomSession;
iListener = listener;
iMetadata = metadata;
TRACE_FUNC_EXIT
@@ -322,6 +320,7 @@
}
// Third, check a case where there is support but reply is not
// expected. In this case "" must be returned to complete processing.
+ // Note: The EFalse setting is used only for normal mode.
if ( !complInfo.iReplyExpected )
{
// Return ""
@@ -334,8 +333,8 @@
TRACE_FUNC_EXIT
return retTemp;
}
- // The rest are for known command with reply. This case is handled in
- // HandleCommand().
+ // The rest are for known command with reply or data in editor mode.
+ // This case is handled in HandleCommand().
TRACE_INFO(( _L8("Command handled: wait for asynchronous reply or do nothing") ));
TRACE_FUNC_EXIT
return KErrNone;
@@ -896,7 +895,10 @@
iListener = NULL;
delete iMetadata;
iMetadata = NULL;
- iEComSession.Close();
+ if ( iEComSession )
+ {
+ iEComSession->Close();
+ }
if ( !aSyncClose )
{
REComSession::FinalClose();
--- a/bluetooth/btstack/common/bt_v2.mmp Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/common/bt_v2.mmp Tue May 11 17:15:36 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/linkmgr/ACLSAP.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/ACLSAP.cpp Tue May 11 17:15:36 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"
@@ -1333,53 +1333,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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/AclDataQController.cpp Tue May 11 17:15:36 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,9 @@
#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 +53,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 +68,11 @@
CACLDataQController::~CACLDataQController()
{
LOG_FUNC
-
+
+#ifdef HOSTCONTROLLER_TO_HOST_FLOW_CONTROL
+ delete iMBufPool;
+#endif
+
delete iDataQ;
iAclConns.Reset();
iAclConns.Close();
@@ -81,6 +86,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 +94,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 +438,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 +640,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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/AclDataQController.h Tue May 11 17:15:36 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/hcifacade.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade.cpp Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade.h Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade_commands.cpp Tue May 11 17:15:36 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"
@@ -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,20 +185,6 @@
iCmdController->MhcqAddCommandL(cmd, *this);
}
-void CHCIFacade::HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aFrags)
- {
- RArray<THCIConnectionHandle> connHandles;
- connHandles.Append(aConnH);
-
- RArray<THCINumOfCompletedPackets> numPackets;
- numPackets.Append(aFrags);
-
- CHostNumberOfCompletedPacketsCommand* cmd = CHostNumberOfCompletedPacketsCommand::NewL(1, connHandles, numPackets);
-
- // 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hcifacade_events.cpp Tue May 11 17:15:36 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 May 11 17:15:36 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 May 11 17:15:36 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/linkconsts.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkconsts.h Tue May 11 17:15:36 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/linkmuxer.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmuxer.cpp Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkmuxer.h Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/linkutil.h Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Tue May 11 17:15:36 2010 +0300
@@ -556,6 +556,10 @@
{
iDevice.SetClockOffset(jle.iClockOffset);
}
+ if(juice->IsCoDFromHCI())
+ {
+ iDevice.SetDeviceClass(jle.iCoD);
+ }
}
void CPhysicalLink::StoreDeviceL( TBool aPreventDeviceAddition )
@@ -2302,6 +2306,14 @@
LOG_FUNC
TInt err = KErrNone;
+ __ASSERT_DEBUG(aReason == EAuthenticationFailure
+ || aReason == ERemoteUserEndedConnection
+ || aReason == ERemoteLowResources
+ || aReason == ERemoteAboutToPowerOff
+ || aReason == EUnsupportedRemoteLMPFeature
+ || aReason == EPairingWithUnitKeyNotSupported,
+ Panic (EInvalidDisconnectReason)); // Check the error code is valid with the spec
+
if (iLinkState.LinkState() == TBTBasebandLinkState::ELinkPending)
{
// If the Link is not yet up then we cannot know the correct connection handle
@@ -2898,6 +2910,13 @@
return iAuthStateMask & ELinkKeyRequestPending;
}
+TBool CPhysicalLink::IsAuthenticationRequestPending() const
+ {
+ LOG_FUNC
+ return iAuthStateMask & EAuthenticationRequestPending;
+ }
+
+
void CPhysicalLink::SetAuthenticationPending(TUint8 aState)
{
LOG_FUNC
--- a/bluetooth/btstack/linkmgr/physicallinks.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.h Tue May 11 17:15:36 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"
@@ -379,6 +379,9 @@
void SetAuthenticationPending(TUint8 aFlag);
virtual void AuthenticationComplete(TUint8 aFlag);
+ TBool IsAuthenticationRequestPending() const;
+
+
static TInt OverrideLPMTimeoutCallback(TAny* aCPhysicalLink);// async callback
static TInt TerminateCallback(TAny* aCPhysicalLink);// async callback
TInt Terminate(THCIErrorCode aReason);
--- a/bluetooth/btstack/secman/secman.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/secman/secman.cpp Tue May 11 17:15:36 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"
@@ -585,7 +585,7 @@
else if (!link->IsPairingExpected()
|| ((link->AuthenticationRequirement() == EMitmNotReqDedicatedBonding
|| link->AuthenticationRequirement() == EMitmReqDedicatedBonding)
- && !IsDedicatedBondingAttempted(aAddr)))
+ && !link->IsAuthenticationRequestPending()))
{
TRAPD(err,link->NewUserConfirmerL(aAddr, *this, ETrue));
if(err)
@@ -610,7 +610,7 @@
TBTSecEventUserConfirmationComplete event(ETrue);
requester->SendEvent(event);
}
-
+ link->PinRequestSent();
// note: -- check errors here
TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr));
}
--- a/bluetooth/btstack/secman/secman.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/secman/secman.h Tue May 11 17:15:36 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 Tue Apr 27 17:48:21 2010 +0300
+++ b/bluetooth/btstack/secman/secmanhci.cpp Tue May 11 17:15:36 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/bt_plat/at_command_handler_plugin_api/inc/atext.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bt_plat/at_command_handler_plugin_api/inc/atext.h Tue May 11 17:15:36 2010 +0300
@@ -1,5 +1,5 @@
/*
-* 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"
@@ -69,15 +69,39 @@
IMPORT_C TInt SynchronousClose();
/**
- * Handles a command.
+ * Handles a command. This API supports two modes:
+ * Normal mode (!EReplyTypeEditor) for normal use cases
+ * Editor mode (EReplyTypeEditor) for special AT commands with text mode
+ *
+ * Notes for parameters below:
+ * (1) Command to be handled is used in normal mode only.
+ * Editor mode is entered when the first EReplyTypeEditor reply is received (5).
+ * Editor mode is ended when the first !EReplyTypeEditor reply is received (5).
+ * (2) Data received is character set independent; this API is called byte-by-byte
+ * in editor mode.
+ * (3) The reply string is not used in editor mode's text input.
+ * Only editor mode's start condition (prompt) and end condition
+ * (!EReplyTypeEditor) handle the possibly existing reply string.
+ * (4) The remaining reply length setting is not used in editor mode's text input.
+ * It is only used in editor mode's start condition (prompt) and end condition
+ * (!EReplyTypeEditor)
+ * (5) Normal mode: Other than EReplyTypeEditor reply.
+ * Editor mode: Started with EReplyTypeEditor, continued with EReplyTypeEditor,
+ * Ended with !EReplyTypeEditor
+ * Note: the first reply with EReplyTypeEditor is the "prompt".
+ * Subsequent replies with EReplyTypeEditor are ignored.
+ *
+ * Note: The editor mode supported by this API should only be used for
+ * commands not requiring support for signals. These commands include cases
+ * such as DCD signal required by command AT+CMGS.
*
* @since S60 v5.0
* @param aStatus The request status
- * @param aCmd The command to be handled.
- * @param aReply The descriptor to hold reply to this command;
+ * @param aCmd The command to be handled (1) or data for editor mode (2).
+ * @param aReply The descriptor to hold reply to this command (3).
* @param aRemainingReplyLength Tells the length of remaining reply if it is not 0;
- * the remainings can be fetched by GetNextPartOfReply().
- * @param aReplyType Reply type for the handled AT command
+ * the remainings can be fetched by GetNextPartOfReply() (4).
+ * @param aReplyType Reply type for the handled AT command (1) or editor mode (2) (5).
* @return Symbian error code on error, KErrNone otherwise
*/
IMPORT_C TInt HandleCommand( TRequestStatus& aStatus,
@@ -88,6 +112,9 @@
/**
* Cancels a command handling request.
+ * Calling this API in editor mode also causes ATEXT to reset the information
+ * about the plugin currently handling byte-by-byte data.
+ * This causes the next command to be handled in normal mode.
*
* @since S60 v5.0
* @return Symbian error code on error, KErrNone otherwise
--- a/bt_plat/at_command_handler_plugin_api/inc/atextpluginbase.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bt_plat/at_command_handler_plugin_api/inc/atextpluginbase.h Tue May 11 17:15:36 2010 +0300
@@ -33,9 +33,10 @@
enum TATExtensionReplyType
{
EReplyTypeUndefined, // For error conditions (handling failed)
- EReplyTypeOther, // For other than OK or ERROR
- EReplyTypeOk, // For "OK"
- EReplyTypeError, // For "ERROR"
+ EReplyTypeOther, // !(EReplyTypeOk||EReplyTypeError||EReplyTypeEditor)
+ EReplyTypeOk, // For "OK" (or "" in quiet mode)
+ EReplyTypeError, // For "ERROR" (or "" in quiet mode)
+ EReplyTypeEditor, // For editor mode
};
/** Default buffer length for command reply buffer */
@@ -143,6 +144,11 @@
* After an extension plugin has handled or decided to reject the given AT
* command, it must inform ATEXT by HandleCommandCompleted() with a proper
* error code.
+ *
+ * Note that in editor mode the setting of aReplyNeeded is always "ETrue"
+ * when a plugin processing the editor mode meets the end condition for the
+ * editor mode (!EReplyTypeEditor reply in editor mode). In this case the
+ * plugin must create the last reply even when aReplyNeeded is EFalse.
*
* @since S60 5.0
* @param aCmd The AT command to be handled. Its format may vary depending
--- a/bthci/bthci2/CommandsEvents/generator/Commands.txt Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/generator/Commands.txt Tue May 11 17:15:36 2010 +0300
@@ -12,7 +12,6 @@
#
# Description:
#
-
# Bluetooth HCI Commands to be generated
# Syntax is documented below. ("[]" brackets are used for grouping with regexp wildcards, and wildcard operators will only directly follow a ']')
#
--- a/bthci/bthci2/CommandsEvents/generator/command.py Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/generator/command.py Tue May 11 17:15:36 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"
@@ -40,7 +40,7 @@
import re
import string
-from parameter import makeParameters, makeMembers
+from parameter import makeParameters, makeMembers, makeNonOwnedParameters, makeOwnedParameters
from time import strftime
from utils import doTimeStampCompareAndWrite
@@ -49,16 +49,32 @@
ctor_str = ""
for p in aParams:
- ctor_str += 'a' + p.getName() + ', '
+ if not p.Owned():
+ ctor_str += 'a' + p.getName() + ', '
return ctor_str[:-2]
+
+def makeConstructLParameters(aParams):
+ conl_str = ""
+
+ for p in aParams:
+ if p.Owned():
+ conl_str += 'a' + p.getName() + ', '
+
+ return conl_str[:-2]
+
+# determines if a custom ConstructL needs to be created for this class
+# currently this is only needed for handling owned parameters.
+def customConstructL(aParams):
+ return makeConstructLParameters(aParams) != ''
# makes member initialization part of constructor
def makeMemberInitialization(aParams):
init_str = ", "
for p in aParams:
- init_str += 'i' + p.getName() + '(a' + p.getName() + ')\n\t, '
+ if not p.Owned():
+ init_str += 'i' + p.getName() + '(a' + p.getName() + ')\n\t, '
return init_str[:-4]
@@ -71,12 +87,12 @@
return def_str + 'IMPORT_C static C' + aClass +'* NewL();'
-def makeNewLImp(aClass, aParamString, aConsParamString):
+def makeNewLImp(aClass, aParamString, aConsParamString, aConstructLString):
imp_str = ''
imp_str += 'EXPORT_C C' + aClass + '* C' + aClass + '::NewL(' + aParamString + ')\n\t{\n\t'
imp_str += 'C' + aClass + '* self = new (ELeave) C' + aClass + '(' + aConsParamString + ');\n\t'
imp_str += 'CleanupStack::PushL(self);\n\t'
- imp_str += 'self->CHCICommandBase::BaseConstructL();\n\t'
+ imp_str += 'self->' + aConstructLString + ';\n\t'
imp_str += 'CleanupStack::Pop(self);\n\t'
imp_str += 'return self;\n\t}'
return imp_str
@@ -86,20 +102,33 @@
imp_str = ''
if len(aParams) > 0:
- imp_str += makeNewLImp(aClass, makeParameters(aParams), makeConstructorParameters(aParams))
+ imp_str += makeNewLImp(aClass, makeParameters(aParams), makeConstructorParameters(aParams), makeConstructLCall(aParams))
imp_str += '\n\n'
- imp_str += makeNewLImp(aClass, '', '')
- return imp_str
+ imp_str += makeNewLImp(aClass, '', '', 'CHCICommandBase::BaseConstructL()')
+ return imp_str
+
+def makeConstructLCall(aParams):
+ imp_str = ''
+ if customConstructL(aParams):
+ imp_str += 'ConstructL(' + makeConstructLParameters(aParams) + ')'
+ else:
+ imp_str += 'CHCICommandBase::BaseConstructL()'
+ return imp_str
-# makes class constructor definition
+# makes class constructor definition (also ConstructL if appropriate).
def makeConstructorDefinitions(aParams, aClass):
def_str = ''
if len(aParams) > 0:
- def_str += 'C' + aClass + '(' + makeParameters(aParams) + ');\n\t'
+ def_str += 'C' + aClass + '(' + makeNonOwnedParameters(aParams) + ');\n\t'
+
+ def_str += 'C' + aClass + '();'
+
+ if customConstructL(aParams):
+ def_str += '\n\tvoid ConstructL(' + makeOwnedParameters(aParams) + ');'
- return def_str + 'C' + aClass + '();'
+ return def_str
# makes class constructor implementation
def makeConstructorImplementations(aParams, aClass, aMatchParams):
@@ -110,7 +139,7 @@
ExpCmdComplete = aMatchParams[2]
if len(aParams) > 0:
- imp_str += 'C' + aClass + 'Command::C' + aClass + 'Command(' + makeParameters(aParams) + ')\n\t: CHCICommandBase(K' + aClass + 'Opcode)\n\t' + makeMemberInitialization(aParams) + '\n\t{\n\t'
+ imp_str += 'C' + aClass + 'Command::C' + aClass + 'Command(' + makeNonOwnedParameters(aParams) + ')\n\t: CHCICommandBase(K' + aClass + 'Opcode)\n\t' + makeMemberInitialization(aParams) + '\n\t{\n\t'
if int(CreditsConsumed) != 1:
imp_str += 'SetCreditsConsumed(' + str(CreditsConsumed) + ');\n\t'
if ExpCmdStatus == 'False':
@@ -128,6 +157,11 @@
imp_str += 'SetExpectsCommandCompleteEvent(EFalse);\n\t'
imp_str += '}'
+
+ if customConstructL(aParams):
+ imp_str += '\n\nvoid C' + aClass + 'Command::ConstructL(' + makeOwnedParameters(aParams) + ')\n\t{\n\tCHCICommandBase::BaseConstructL();\n\t'
+ imp_str += makeOwnedMemberAssignment(aParams)
+ imp_str += '\n\t}'
return imp_str
@@ -200,6 +234,15 @@
ass_str += p.memberAssignment() + '\n\t'
return ass_str[:-2]
+
+def makeOwnedMemberAssignment(aParams):
+ ass_str = ''
+
+ for p in aParams:
+ if p.Owned():
+ ass_str += p.memberAssignment() + '\n\t'
+
+ return ass_str[:-2]
# make getter definition of form Param()
def makeAccessorDefinitions(aParams):
--- a/bthci/bthci2/CommandsEvents/generator/dllmmp.tmpl Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/generator/dllmmp.tmpl Tue May 11 17:15:36 2010 +0300
@@ -59,3 +59,6 @@
OPTION cw -strict on -w pedantic,unused,hidevirtual,padding,ptrintconv
UNPAGED
+
+SMPSAFE
+
--- a/bthci/bthci2/CommandsEvents/generator/parameter.py Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/generator/parameter.py Tue May 11 17:15:36 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"
@@ -21,6 +21,24 @@
param_str += p.toParameter() + ', '
return param_str[:-2]
+
+def makeOwnedParameters(aParams):
+ param_str = ""
+
+ for p in aParams:
+ if p.Owned():
+ param_str += p.toParameter() + ', '
+
+ return param_str[:-2]
+
+def makeNonOwnedParameters(aParams):
+ param_str = ""
+
+ for p in aParams:
+ if not p.Owned():
+ param_str += p.toParameter() + ', '
+
+ return param_str[:-2]
# Creates a ;\n\t separated string of parameters suitable for class member declarations.
def makeMembers(aParams):
@@ -145,3 +163,8 @@
# Returns a string of the format 'iName = aName;'
def memberAssignment(self):
return 'i' + self.getName() + ' = a' + self.getName() + ';'
+
+ def Owned(self):
+ return self.iArray != ''
+
+
--- a/bthci/bthci2/CommandsEvents/interface/hostnumberofcompletedpacketscommand.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/interface/hostnumberofcompletedpacketscommand.h Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandheader.tmpl
-// on Wed, 25 Jul 2007 17:00:38 (time stamp)
+// on Wed, 07 Apr 2010 11:43:50 (time stamp)
//
//
@@ -55,8 +55,9 @@
virtual TInt Extension_(TUint aExtensionId, TAny*& aInterface, TAny* aData);
private:
- CHostNumberOfCompletedPacketsCommand(TUint8 aNumberOfHandles, const RArray< THCIConnectionHandle >& aConnectionHandle, const RArray< THCINumOfCompletedPackets >& aHostNumOfCompletedPackets);
+ CHostNumberOfCompletedPacketsCommand(TUint8 aNumberOfHandles);
CHostNumberOfCompletedPacketsCommand();
+ void ConstructL(const RArray< THCIConnectionHandle >& aConnectionHandle, const RArray< THCINumOfCompletedPackets >& aHostNumOfCompletedPackets);
// From CHCICommandBase - knows how to format the parameters of this specific command
// into the HCTL frame
--- a/bthci/bthci2/CommandsEvents/interface/writecurrentiaclapcommand.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/interface/writecurrentiaclapcommand.h Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandheader.tmpl
-// on Wed, 25 Jul 2007 17:00:39 (time stamp)
+// on Wed, 07 Apr 2010 11:43:52 (time stamp)
//
//
@@ -54,8 +54,9 @@
virtual TInt Extension_(TUint aExtensionId, TAny*& aInterface, TAny* aData);
private:
- CWriteCurrentIACLAPCommand(TUint8 aNumCurrentIAC, const RArray< TUint32 >& aIACLAP);
+ CWriteCurrentIACLAPCommand(TUint8 aNumCurrentIAC);
CWriteCurrentIACLAPCommand();
+ void ConstructL(const RArray< TUint32 >& aIACLAP);
// From CHCICommandBase - knows how to format the parameters of this specific command
// into the HCTL frame
--- a/bthci/bthci2/CommandsEvents/interface/writestoredlinkkeycommand.h Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/CommandsEvents/interface/writestoredlinkkeycommand.h Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandheader.tmpl
-// on Wed, 25 Jul 2007 17:00:40 (time stamp)
+// on Wed, 07 Apr 2010 11:43:53 (time stamp)
//
//
@@ -55,8 +55,9 @@
virtual TInt Extension_(TUint aExtensionId, TAny*& aInterface, TAny* aData);
private:
- CWriteStoredLinkKeyCommand(TUint8 aNumKeysToWrite, const RArray< TBTDevAddr >& aBDADDR, const RArray< TBTLinkKey >& aLinkKey);
+ CWriteStoredLinkKeyCommand(TUint8 aNumKeysToWrite);
CWriteStoredLinkKeyCommand();
+ void ConstructL(const RArray< TBTDevAddr >& aBDADDR, const RArray< TBTLinkKey >& aLinkKey);
// From CHCICommandBase - knows how to format the parameters of this specific command
// into the HCTL frame
--- a/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Tue May 11 17:15:36 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
--- a/bthci/hci2implementations/CommandsEvents/symbian/group/commandsevents_symbian.mmp Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/hci2implementations/CommandsEvents/symbian/group/commandsevents_symbian.mmp Tue May 11 17:15:36 2010 +0300
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template dllmmp.tmpl
-// on Fri, 26 Mar 2010 16:28:21 (time stamp)
+// on Wed, 07 Apr 2010 12:58:00 (time stamp)
//
//
@@ -363,3 +363,4 @@
UNPAGED
SMPSAFE
+
--- a/bthci/hci2implementations/CommandsEvents/symbian/src/hostnumberofcompletedpacketscommand.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/hci2implementations/CommandsEvents/symbian/src/hostnumberofcompletedpacketscommand.cpp Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandsource.tmpl
-// on Thu, 29 May 2008 15:17:49 (time stamp)
+// on Wed, 07 Apr 2010 11:59:26 (time stamp)
//
//
@@ -38,9 +38,9 @@
EXPORT_C CHostNumberOfCompletedPacketsCommand* CHostNumberOfCompletedPacketsCommand::NewL(TUint8 aNumberOfHandles, const RArray< THCIConnectionHandle >& aConnectionHandle, const RArray< THCINumOfCompletedPackets >& aHostNumOfCompletedPackets)
{
- CHostNumberOfCompletedPacketsCommand* self = new (ELeave) CHostNumberOfCompletedPacketsCommand(aNumberOfHandles, aConnectionHandle, aHostNumOfCompletedPackets);
+ CHostNumberOfCompletedPacketsCommand* self = new (ELeave) CHostNumberOfCompletedPacketsCommand(aNumberOfHandles);
CleanupStack::PushL(self);
- self->CHCICommandBase::BaseConstructL();
+ self->ConstructL(aConnectionHandle, aHostNumOfCompletedPackets);
CleanupStack::Pop(self);
return self;
}
@@ -56,11 +56,9 @@
// Constructors
-CHostNumberOfCompletedPacketsCommand::CHostNumberOfCompletedPacketsCommand(TUint8 aNumberOfHandles, const RArray< THCIConnectionHandle >& aConnectionHandle, const RArray< THCINumOfCompletedPackets >& aHostNumOfCompletedPackets)
+CHostNumberOfCompletedPacketsCommand::CHostNumberOfCompletedPacketsCommand(TUint8 aNumberOfHandles)
: CHCICommandBase(KHostNumberOfCompletedPacketsOpcode)
, iNumberOfHandles(aNumberOfHandles)
- , iConnectionHandle(aConnectionHandle)
- , iHostNumOfCompletedPackets(aHostNumOfCompletedPackets)
{
SetCreditsConsumed(0);
SetExpectsCommandStatusEvent(EFalse);
@@ -75,6 +73,13 @@
SetExpectsCommandCompleteEvent(EFalse);
}
+void CHostNumberOfCompletedPacketsCommand::ConstructL(const RArray< THCIConnectionHandle >& aConnectionHandle, const RArray< THCINumOfCompletedPackets >& aHostNumOfCompletedPackets)
+ {
+ CHCICommandBase::BaseConstructL();
+ iConnectionHandle = aConnectionHandle;
+ iHostNumOfCompletedPackets = aHostNumOfCompletedPackets;
+ }
+
// Destructor
CHostNumberOfCompletedPacketsCommand::~CHostNumberOfCompletedPacketsCommand()
{
--- a/bthci/hci2implementations/CommandsEvents/symbian/src/writecurrentiaclapcommand.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/hci2implementations/CommandsEvents/symbian/src/writecurrentiaclapcommand.cpp Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandsource.tmpl
-// on Thu, 29 May 2008 15:17:52 (time stamp)
+// on Wed, 07 Apr 2010 11:59:28 (time stamp)
//
//
@@ -38,9 +38,9 @@
EXPORT_C CWriteCurrentIACLAPCommand* CWriteCurrentIACLAPCommand::NewL(TUint8 aNumCurrentIAC, const RArray< TUint32 >& aIACLAP)
{
- CWriteCurrentIACLAPCommand* self = new (ELeave) CWriteCurrentIACLAPCommand(aNumCurrentIAC, aIACLAP);
+ CWriteCurrentIACLAPCommand* self = new (ELeave) CWriteCurrentIACLAPCommand(aNumCurrentIAC);
CleanupStack::PushL(self);
- self->CHCICommandBase::BaseConstructL();
+ self->ConstructL(aIACLAP);
CleanupStack::Pop(self);
return self;
}
@@ -56,10 +56,9 @@
// Constructors
-CWriteCurrentIACLAPCommand::CWriteCurrentIACLAPCommand(TUint8 aNumCurrentIAC, const RArray< TUint32 >& aIACLAP)
+CWriteCurrentIACLAPCommand::CWriteCurrentIACLAPCommand(TUint8 aNumCurrentIAC)
: CHCICommandBase(KWriteCurrentIACLAPOpcode)
, iNumCurrentIAC(aNumCurrentIAC)
- , iIACLAP(aIACLAP)
{
SetExpectsCommandStatusEvent(EFalse);
}
@@ -70,6 +69,12 @@
SetExpectsCommandStatusEvent(EFalse);
}
+void CWriteCurrentIACLAPCommand::ConstructL(const RArray< TUint32 >& aIACLAP)
+ {
+ CHCICommandBase::BaseConstructL();
+ iIACLAP = aIACLAP;
+ }
+
// Destructor
CWriteCurrentIACLAPCommand::~CWriteCurrentIACLAPCommand()
{
--- a/bthci/hci2implementations/CommandsEvents/symbian/src/writestoredlinkkeycommand.cpp Tue Apr 27 17:48:21 2010 +0300
+++ b/bthci/hci2implementations/CommandsEvents/symbian/src/writestoredlinkkeycommand.cpp Tue May 11 17:15:36 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"
@@ -12,7 +12,7 @@
//
// Description:
// This file was generated automatically from the template commandsource.tmpl
-// on Thu, 29 May 2008 15:17:53 (time stamp)
+// on Wed, 07 Apr 2010 11:59:29 (time stamp)
//
//
@@ -38,9 +38,9 @@
EXPORT_C CWriteStoredLinkKeyCommand* CWriteStoredLinkKeyCommand::NewL(TUint8 aNumKeysToWrite, const RArray< TBTDevAddr >& aBDADDR, const RArray< TBTLinkKey >& aLinkKey)
{
- CWriteStoredLinkKeyCommand* self = new (ELeave) CWriteStoredLinkKeyCommand(aNumKeysToWrite, aBDADDR, aLinkKey);
+ CWriteStoredLinkKeyCommand* self = new (ELeave) CWriteStoredLinkKeyCommand(aNumKeysToWrite);
CleanupStack::PushL(self);
- self->CHCICommandBase::BaseConstructL();
+ self->ConstructL(aBDADDR, aLinkKey);
CleanupStack::Pop(self);
return self;
}
@@ -56,11 +56,9 @@
// Constructors
-CWriteStoredLinkKeyCommand::CWriteStoredLinkKeyCommand(TUint8 aNumKeysToWrite, const RArray< TBTDevAddr >& aBDADDR, const RArray< TBTLinkKey >& aLinkKey)
+CWriteStoredLinkKeyCommand::CWriteStoredLinkKeyCommand(TUint8 aNumKeysToWrite)
: CHCICommandBase(KWriteStoredLinkKeyOpcode)
, iNumKeysToWrite(aNumKeysToWrite)
- , iBDADDR(aBDADDR)
- , iLinkKey(aLinkKey)
{
SetExpectsCommandStatusEvent(EFalse);
}
@@ -71,6 +69,13 @@
SetExpectsCommandStatusEvent(EFalse);
}
+void CWriteStoredLinkKeyCommand::ConstructL(const RArray< TBTDevAddr >& aBDADDR, const RArray< TBTLinkKey >& aLinkKey)
+ {
+ CHCICommandBase::BaseConstructL();
+ iBDADDR = aBDADDR;
+ iLinkKey = aLinkKey;
+ }
+
// Destructor
CWriteStoredLinkKeyCommand::~CWriteStoredLinkKeyCommand()
{