# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1273587336 -10800 # Node ID 9f17f914e82844cfcfe8ce04b5798a1abea5e528 # Parent f8503e232b0c18039af618e590aa543a00c72dbb Revision: 201017 Kit: 201019 diff -r f8503e232b0c -r 9f17f914e828 atext/client/src/atextcommon.cpp --- 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; } // --------------------------------------------------------------------------- diff -r f8503e232b0c -r 9f17f914e828 atext/server/inc/atextcommonsession.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 atext/server/inc/atextmetadata.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 atext/server/inc/atextsession.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 atext/server/src/atextcommonsession.cpp --- 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(); diff -r f8503e232b0c -r 9f17f914e828 atext/server/src/atextmetadata.cpp --- 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 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 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(); diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/common/bt_v2.mmp --- 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/ACLSAP.cpp --- 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(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 } diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/AclDataQController.cpp --- 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/AclDataQController.h --- 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 #include +#include 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; diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hcifacade.cpp --- 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 #include +#include + #include #include #include -#include #include #include #include @@ -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& aQueue) - { - LOG_FUNC - TPoolBuffer* tmpItem = NULL; - TSglQueIter 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hcifacade.h --- 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& aPool); - -private: - CHCIFacade& iHCIFacade; - CAsyncCallBack* iBufferFreeCallback; - - TSglQue iBufferPool; - TSglQue 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hcifacade_commands.cpp --- 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 #include #include -#include #include #include #include @@ -186,20 +185,6 @@ iCmdController->MhcqAddCommandL(cmd, *this); } -void CHCIFacade::HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aFrags) - { - RArray connHandles; - connHandles.Append(aConnH); - - RArray 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); diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hcifacade_events.cpp --- 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 #include +#include #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(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); diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hostmbufpool.cpp --- /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 +#include +#include +#include +#include + +#include "linkconsts.h" +#include "linkutil.h" + +#include + +#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& aQueue) + { + LOG_FUNC + TPoolBuffer* buffer = NULL; + TSglQueIter 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 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 connHandles; + connHandles.AppendL(aConnH); + CleanupClosePushL(connHandles); + + RArray 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/hostmbufpool.h --- /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 +#include +#include +#include + +#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& 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 iBufferPool; + TSglQue 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/linkconsts.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/linkmuxer.cpp --- 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( diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/linkmuxer.h --- 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; }; diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/linkutil.h --- 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, }; /** diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/physicallinks.cpp --- 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 diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/linkmgr/physicallinks.h --- 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); diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/secman/secman.cpp --- 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)); } diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/secman/secman.h --- 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); diff -r f8503e232b0c -r 9f17f914e828 bluetooth/btstack/secman/secmanhci.cpp --- 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 diff -r f8503e232b0c -r 9f17f914e828 bt_plat/at_command_handler_plugin_api/inc/atext.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bt_plat/at_command_handler_plugin_api/inc/atextpluginbase.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/generator/Commands.txt --- 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 ']') # diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/generator/command.py --- 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): diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/generator/dllmmp.tmpl --- 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 + diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/generator/parameter.py --- 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 != '' + + diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/interface/hostnumberofcompletedpacketscommand.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/interface/writecurrentiaclapcommand.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/CommandsEvents/interface/writestoredlinkkeycommand.h --- 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 diff -r f8503e232b0c -r 9f17f914e828 bthci/bthci2/hcicmdq/src/HciCmdQController.cpp --- 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(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 diff -r f8503e232b0c -r 9f17f914e828 bthci/hci2implementations/CommandsEvents/symbian/group/commandsevents_symbian.mmp --- 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 + diff -r f8503e232b0c -r 9f17f914e828 bthci/hci2implementations/CommandsEvents/symbian/src/hostnumberofcompletedpacketscommand.cpp --- 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() { diff -r f8503e232b0c -r 9f17f914e828 bthci/hci2implementations/CommandsEvents/symbian/src/writecurrentiaclapcommand.cpp --- 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() { diff -r f8503e232b0c -r 9f17f914e828 bthci/hci2implementations/CommandsEvents/symbian/src/writestoredlinkkeycommand.cpp --- 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() {