--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/hcifacade_commands.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,602 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// These functions are called by parts of the stack that would like to issue
+// HCI commands.
+// The general pattern is for these functions create a new command and then
+// add it to the command Q, which takes ownership of the command.
+//
+//
+
+#include <bluetooth/logger.h>
+#include "hcifacade.h"
+#include "linkutil.h"
+#include "linkconsts.h"
+#include "hostresolver.h"
+
+#include <e32std.h>
+#include <bt_sock.h>
+#include "debug.h"
+#include <utf.h>
+#include <es_ini.h>
+#include <btextnotifiers.h>
+
+#include <bluetooth/hcicommandqueue.h>
+#include <bluetooth/hcicommandqitem.h>
+
+// Command Headers
+#include <bluetooth/hci/writescanenablecommand.h>
+#include <bluetooth/hci/createaclconnectioncommand.h>
+#include <bluetooth/hci/setupsynchronousconnectioncommand.h>
+#include <bluetooth/hci/acceptsynchronousconnectionrequestcommand.h>
+#include <bluetooth/hci/rejectsynchronousconnectionrequestcommand.h>
+#include <bluetooth/hci/disconnectcommand.h>
+#include <bluetooth/hci/writelinkpolicysettingscommand.h>
+#include <bluetooth/hci/hostnumberofcompletedpacketscommand.h>
+#include <bluetooth/hci/acceptconnectionrequestcommand.h>
+#include <bluetooth/hci/rejectconnectionrequestcommand.h>
+#include <bluetooth/hci/readremoteversioninfocommand.h>
+#include <bluetooth/hci/readremotesupportedfeaturescommand.h>
+#include <bluetooth/hci/readremoteextendedfeaturescommand.h>
+#include <bluetooth/hci/readclockoffsetcommand.h>
+#include <bluetooth/hci/remotenamerequestcommand.h>
+#include <bluetooth/hci/flushcommand.h>
+#include <bluetooth/hci/seteventmaskcommand.h>
+#include <bluetooth/hci/writelocalnamecommand.h>
+#include <bluetooth/hci/linkkeyrequestreplycommand.h>
+#include <bluetooth/hci/linkkeyrequestreplynegativecommand.h>
+#include <bluetooth/hci/changelinkkeycommand.h>
+#include <bluetooth/hci/pincoderequestreplycommand.h>
+#include <bluetooth/hci/pincoderequestreplynegativecommand.h>
+#include <bluetooth/hci/changeconnectionpackettypecommand.h>
+#include <bluetooth/hci/authenticationrequestedcommand.h>
+#include <bluetooth/hci/setconnectionencryptioncommand.h>
+#include <bluetooth/hci/sniffmodecommand.h>
+#include <bluetooth/hci/exitsniffmodecommand.h>
+#include <bluetooth/hci/holdmodecommand.h>
+#include <bluetooth/hci/parkmodecommand.h>
+#include <bluetooth/hci/exitparkmodecommand.h>
+#include <bluetooth/hci/switchrolecommand.h>
+#include <bluetooth/hci/writeclassofdevicecommand.h>
+#include <bluetooth/hci/setafhhostchannelclassificationcommand.h>
+#include <bluetooth/hci/writeafhchannelassessmentmodecommand.h>
+#include <bluetooth/hci/setcontrollertohostflowcontrolcommand.h>
+#include <bluetooth/hci/readclassofdevicecommand.h>
+#include <bluetooth/hci/readbuffersizecommand.h>
+#include <bluetooth/hci/hostbuffersizecommand.h>
+#include <bluetooth/hci/writecurrentiaclapcommand.h>
+#include <bluetooth/hci/vendordebugcommand.h>
+#include <bluetooth/hci/addscoconnectioncommand.h>
+#include <bluetooth/hci/remotenamerequestcancelcommand.h>
+#include <bluetooth/hci/refreshencryptionkeycommand.h>
+#include <bluetooth/hci/writelinksupervisiontimeoutcommand.h>
+
+
+void CHCIFacade::SCOConnectL(THCIConnHandle aACLHandle, TUint16 aPacketTypeMask, const TBTDevAddr& aBdaddr)
+/**
+ @pre Callers should check that the ACL Handle exists
+
+ Attempts to attach an SCO link to the baseband
+**/
+ {
+ TBTDevHCIVersion hciVersion = iLinkMgrProtocol.GetHWHCIVersion(); // Read Hardware HCI Version
+ if (hciVersion.iHCIVersion > EHWHCIv1_1) // May not support Add_SCO_Connection
+ {
+ #pragma message("KBTVoiceSetting - hardware specific value. KBTVoiceSetting should be replaced by HCI implementation, and should NOT be modified in a BT stack.")
+ SetupSynchronousConnectionCommandL(aACLHandle,KBTSync64KBit,KBTSync64KBit,KeSCOMaxLatencyDontCare,KBTVoiceSetting,EeSCORetransmitDontCare,(aPacketTypeMask >> KSCOvsSyncHVOffset) | KNoEDReSCOPacketMask, aBdaddr); // Need to specify not to use EDR eSCO packets, as they are enabled by default
+ }
+ else // Supports Add_SCO_Connection
+ {
+ CAddSCOConnectionCommand* cmd = CAddSCOConnectionCommand::NewL(aACLHandle, aPacketTypeMask, aBdaddr);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+ }
+
+void CHCIFacade::SetupSynchronousConnectionCommandL(THCIConnHandle aACLHandle,
+ TUint aTransmitBandwidth, TUint aReceiveBandwidth, TUint16 aMaxLatency,
+ TUint16 aVoiceSettings, TUint8 aRetransmissionEffort,
+ TBTSyncPacketTypes aPacketTypeMask, const TBTDevAddr& aBdaddr)
+/**
+ @pre Callers should check that the ACL Handle exists
+
+ Attempts to attach a synchronous link to the baseband
+**/
+ {
+ CSetupSynchronousConnectionCommand* cmd = CSetupSynchronousConnectionCommand::NewL(aACLHandle, aTransmitBandwidth, aReceiveBandwidth, aMaxLatency, aVoiceSettings, aRetransmissionEffort, aPacketTypeMask, aBdaddr);
+ #pragma message("NB. This message relates to the CommandsEvents of the HCI(v2). It appears here because CE source code is generated.")
+ #pragma message("Value of iVoiceSetting (see HCI Command) member is closely related to hardware used. ")
+ #pragma message("Bits: Input Coding, Input Data, Input Sample Size and Linear_PCM_Bit_pos, should be set...")
+ #pragma message("...according to hardware capabilities, and OR-ed to create appropriate iVoiceSetting value.")
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::AcceptSynchronousConnectionL(const TBTDevAddr& aBdaddr,
+ TUint aTransmitBandwidth, TUint aReceiveBandwidth, TUint16 aMaxLatency,
+ TUint16 aContentFormat, TUint8 aRetransmissionEffort, TBTSyncPacketTypes aPacketTypeMask)
+ {
+ CAcceptSynchronousConnectionRequestCommand* cmd = CAcceptSynchronousConnectionRequestCommand::NewL(aBdaddr, aTransmitBandwidth, aReceiveBandwidth, aMaxLatency, aContentFormat, aRetransmissionEffort, aPacketTypeMask);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+
+void CHCIFacade::RejectSynchronousConnectionL(const TBTDevAddr& aBdaddr, THCIErrorCode aReason)
+ {
+ CRejectSynchronousConnectionRequestCommand* cmd = CRejectSynchronousConnectionRequestCommand::NewL(aBdaddr, aReason);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+
+void CHCIFacade::ConnectL(const TBTDevAddr& aAddr,
+ TUint16 aPacketType,
+ TUint8 aPageScanRepetitionMode,
+ TUint8 aPageScanMode,
+ TUint16 aClockOffset,
+ TUint8 aAllowRoleSwitch)
+ {
+ CCreateACLConnectionCommand* cmd = CCreateACLConnectionCommand::NewL(aAddr, aPacketType, aPageScanRepetitionMode, aPageScanMode, aClockOffset, aAllowRoleSwitch);
+
+ // Before the CreateConnection command can be added to the queue we try
+ // to ensure any inquiry is cancelled as some hardware will disallow the
+ // connect otherwise.
+ iLinkMgrProtocol.InquiryMgr().Suspend();
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::DisconnectL(THCIConnHandle aConnH, THCIErrorCode aErr)
+ {
+ CDisconnectCommand* cmd = CDisconnectCommand::NewL(aConnH, aErr);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteLinkPolicySettingsL(THCIConnHandle aConnH, TUint16 aSettings)
+ {
+ CWriteLinkPolicySettingsCommand* cmd = CWriteLinkPolicySettingsCommand::NewL(aConnH, aSettings);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteScanEnableL(THCIScanEnable aEnable)
+ {
+ CWriteScanEnableCommand* cmd = CWriteScanEnableCommand::NewL(aEnable);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::HostNumberOfCompletedPacketsL(THCIConnHandle aConnH, TUint16 aFrags)
+ {
+ RArray<THCIConnectionHandle> connHandles;
+ connHandles.Append(aConnH);
+
+ RArray<THCINumOfCompletedPackets> numPackets;
+ numPackets.Append(aFrags);
+
+ CHostNumberOfCompletedPacketsCommand* cmd = CHostNumberOfCompletedPacketsCommand::NewL(1, connHandles, numPackets);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::AcceptConnectionRequestL(const TBTDevAddr& aAddr, TUint8 aRole)
+ {
+ CAcceptConnectionRequestCommand* cmd = CAcceptConnectionRequestCommand::NewL(aAddr, aRole);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::RejectConnectionRequestL(const TBTConnect& aConnect, THCIErrorCode aReason)
+ {
+ CRejectConnectionRequestCommand* cmd = CRejectConnectionRequestCommand::NewL(aConnect.iBdaddr, aReason);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+
+void CHCIFacade::ReadRemoteVersionL(THCIConnHandle aHandle)
+ {
+ CReadRemoteVersionInfoCommand* cmd = CReadRemoteVersionInfoCommand::NewL(aHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ReadRemoteSupportedFeaturesL(THCIConnHandle aHandle)
+ {
+ CReadRemoteSupportedFeaturesCommand* cmd = CReadRemoteSupportedFeaturesCommand::NewL(aHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ReadRemoteExtendedFeaturesL(THCIConnHandle aHandle, TUint8 aPageNumber)
+ {
+ TInt err = KErrNotSupported;
+ TBTDevHCIVersion hciVersion = iLinkMgrProtocol.GetHWHCIVersion(); // Read Hardware HCI Version
+ if (hciVersion.iHCIVersion > EHWHCIv1_1) // May not support Read_Remote_Extended_Features command
+ {
+ // Maybe migrate this to use HCIv2 so command is owned by physical link
+ CReadRemoteExtendedFeaturesCommand* cmd = NULL;
+ TRAP(err, cmd = CReadRemoteExtendedFeaturesCommand::NewL(aHandle, aPageNumber));
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ if(err == KErrNone)
+ {
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, *this));
+ }
+ }
+ if(err != KErrNone)
+ {
+ // Some error occured but we have to signal the SSP state
+ iLinksMgr->ReadRemoteExtendedFeaturesComplete(EUnknownOpcode, aHandle, TUint64(0), KRemoteExtendedFeaturesPage1, 0);
+ User::Leave(err);
+ }
+ }
+
+
+void CHCIFacade::ReadClockOffsetL(THCIConnHandle aHandle)
+/**
+ Create a command to find remote clock offset
+**/
+ {
+ CReadClockOffsetCommand* cmd = CReadClockOffsetCommand::NewL(aHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::RefreshEncryptionKeyL(THCIConnHandle aHandle)
+ {
+ CRefreshEncryptionKeyCommand* cmd = CRefreshEncryptionKeyCommand::NewL(aHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteLinkSupervisionTimeoutL(THCIConnHandle aHandle, TInt aTimeout)
+ {
+ CWriteLinkSupervisionTimeoutCommand* cmd = CWriteLinkSupervisionTimeoutCommand::NewL(aHandle, aTimeout);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::FlushL(THCIConnHandle aConnH)
+ {
+ CFlushCommand* cmd = CFlushCommand::NewL(aConnH);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::SetEventMaskL(const THCIEventMask& aEventMask)
+ {
+ static const TUint8 KSizeOf64BitsInBytes = 8;
+ TBuf8<KSizeOf64BitsInBytes> eventMask;
+ eventMask.SetLength(KSizeOf64BitsInBytes);
+ TUint8* ptr = const_cast<TUint8*>(eventMask.Ptr());
+ LittleEndian::Put32(ptr, aEventMask.iLoBytes);
+ LittleEndian::Put32(ptr+sizeof(TUint32), aEventMask.iHiBytes);
+
+ CSetEventMaskCommand* cmd = CSetEventMaskCommand::NewL(eventMask);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteLocalNameL(const TDesC8& aName)
+ {
+ CWriteLocalNameCommand* cmd = CWriteLocalNameCommand::NewL(aName);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+TInt CHCIFacade::LinkKeyRequestReply(const TBTDevAddr& aBdaddr, const TDesC8& aLinkKey) const
+/**
+ We have obtained a linkkey, tell HC
+**/
+ {
+ CLinkKeyRequestReplyCommand* cmd = NULL;
+ TBTLinkKey linkkey;
+ linkkey.Copy(aLinkKey);
+
+ TRAPD(err, cmd = CLinkKeyRequestReplyCommand::NewL(aBdaddr, linkkey));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, const_cast<CHCIFacade&>(*this)));
+ }
+ return err;
+ }
+
+TInt CHCIFacade::LinkKeyRequestNegativeReply(const TBTDevAddr& aBdaddr) const
+/**
+ We have not obtained a linkkey, tell HC
+**/
+ {
+ CLinkKeyRequestReplyNegativeCommand* cmd = NULL;
+
+ TRAPD(err, cmd = CLinkKeyRequestReplyNegativeCommand::NewL(aBdaddr));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, const_cast<CHCIFacade&>(*this)));
+ }
+ return err;
+ }
+
+TInt CHCIFacade::ChangeConnectionLinkKey(THCIConnHandle aConnHandle)
+/**
+Change the link key for the specified connection handle
+**/
+ {
+ CChangeLinkKeyCommand* cmd = NULL;
+
+ TRAPD(err, cmd = CChangeLinkKeyCommand::NewL(aConnHandle));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, *this));
+ }
+ return err;
+ }
+
+
+TInt CHCIFacade::PINCodeRequestReply(const TBTDevAddr& aBdaddr,const TDesC8& aPIN) const
+/**
+ We have obtained a PIN, tell HC
+**/
+ {
+ CPINCodeRequestReplyCommand* cmd = NULL;
+ TBTPinCode pin;
+ pin.Copy(aPIN);
+ TPtrC8 pinContents(pin().iPIN, pin().iLength);
+
+ TRAPD(err, cmd = CPINCodeRequestReplyCommand::NewL(aBdaddr, pin().iLength, pinContents));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, const_cast<CHCIFacade&>(*this)));
+ }
+ return err;
+ }
+
+TInt CHCIFacade::PINCodeRequestNegativeReply(const TBTDevAddr& aBdaddr) const
+/**
+ We have not obtained a PIN, tell HC
+**/
+ {
+ CPINCodeRequestReplyNegativeCommand* cmd = NULL;
+
+ TRAPD(err, cmd = CPINCodeRequestReplyNegativeCommand::NewL(aBdaddr));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, const_cast<CHCIFacade&>(*this)));
+ }
+ return err;
+ }
+
+TInt CHCIFacade::ChangeConnectionPacketType(THCIConnHandle aConnHandle, TUint16 aType)
+ {
+ CChangeConnectionPacketTypeCommand* cmd = NULL;
+
+ TRAPD(err, cmd = CChangeConnectionPacketTypeCommand::NewL(aConnHandle, aType));
+ if (err == KErrNone)
+ {
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ TRAP(err, iCmdController->MhcqAddCommandL(cmd, *this));
+ }
+ return err;
+ }
+
+void CHCIFacade::AuthenticateL(THCIConnHandle aConnHandle)
+/**
+ Do an authentication
+**/
+ {
+ CAuthenticationRequestedCommand* cmd = CAuthenticationRequestedCommand::NewL(aConnHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::SetEncryptL(THCIConnHandle aConnHandle,TBool aEnable)
+/**
+ Creates command to enable/disable encryption on a given link
+**/
+ {
+ CSetConnectionEncryptionCommand* cmd = CSetConnectionEncryptionCommand::NewL(aConnHandle, aEnable);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::SniffL(THCIConnHandle aHandleToRemote)
+ {
+ CSniffModeCommand* cmd = CSniffModeCommand::NewL(aHandleToRemote, KBTSniffModeMaxInterval, KBTSniffModeMinInterval, KBTSniffModeAttempt, KBTSniffModeTimeout);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ExitSniffL(THCIConnHandle aHandleToRemote)
+ {
+ CExitSniffModeCommand* cmd = CExitSniffModeCommand::NewL(aHandleToRemote);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::HoldL(THCIConnHandle aHandle)
+ {
+ CHoldModeCommand* cmd = CHoldModeCommand::NewL(aHandle, KBTHoldModeMaxInterval, KBTHoldModeMinInterval);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ParkL(THCIConnHandle aHandle)
+ {
+ CParkModeCommand* cmd = CParkModeCommand::NewL(aHandle, KBTParkModeBeaconMaxInterval, KBTParkModeBeaconMinInterval);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ExitParkL(THCIConnHandle aHandle)
+ {
+ CExitParkModeCommand* cmd = CExitParkModeCommand::NewL(aHandle);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ChangeRoleL(TBTBasebandRole aRole, const TBTDevAddr& aAddr)
+ {
+ CSwitchRoleCommand* cmd = CSwitchRoleCommand::NewL(aAddr, aRole);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteDeviceClassL(TUint aCoD)
+ {
+ CWriteClassOfDeviceCommand* cmd = CWriteClassOfDeviceCommand::NewL(aCoD);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::SetAFHHostChannelClassificationL(const TBTAFHHostChannelClassification& aChannelClassification)
+ {
+ __ASSERT_DEBUG(aChannelClassification.Validate()==KErrNone,
+ __BTDEBUGGER());
+ if(aChannelClassification.Validate()!=KErrNone)
+ {
+ //NB If this is called by one of Bluetooth's "Publish
+ //and Subscribe" subscribers, then the KErrNotSupported
+ //will be dropped - no error will be reported to the user...
+ //which is good - we do not want the user reacting to errors.
+ User::Leave(KErrNotSupported);
+ }
+ if(iAFHTimer->IsActive())
+ {
+ //Timer is active => a host channel classification has just been sent.
+ //Setup timer so that this command is postponed to occur more than one second after
+ //that last host channel classification command - as per spec.
+ //NB You only need the latest Host Channel Classification command
+ //when the timer fires.
+ iAFHTimer->SetPending(aChannelClassification);
+ }
+ else
+ {
+ //Start AFHHost Channel Classification Command blocking timer with a
+ //long timeout (in case command never completes).
+ //This will be updated when/if the command does complete.
+ iAFHTimer->After(KAFHHostChannelClassificationCommandCompleteTimer);
+
+ CSetAFHHostChannelClassificationCommand* cmd = CSetAFHHostChannelClassificationCommand::NewL(aChannelClassification);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+ }
+
+void CHCIFacade::WriteAFHChannelAssessmentModeL(TBool aEnable)
+ {
+ CWriteAFHChannelAssessmentModeCommand* cmd = CWriteAFHChannelAssessmentModeCommand::NewL(aEnable?1:0);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::SetControllerToHostFlowControlL()
+ {
+ CSetControllerToHostFlowControlCommand* cmd = CSetControllerToHostFlowControlCommand::NewL(ETrue);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::ReadDeviceClassL()
+ {
+ CReadClassOfDeviceCommand* cmd = CReadClassOfDeviceCommand::NewL();
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+
+void CHCIFacade::ObtainHostControllerBufferSizeL()
+ {
+ CReadBufferSizeCommand* cmd = CReadBufferSizeCommand::NewL();
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::AdvertiseHostBufferSizeL(TUint16 aNumBuffers)
+ {
+ CHostBufferSizeCommand* cmd = CHostBufferSizeCommand::NewL(KLinkMgrIncomingBufferSize, KStackSCOBuffersSize, aNumBuffers, KStackSCOBuffersNum);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::WriteIACLAPL(TUint8 aNumCurrentIAC, TUint aIAC_LAP[])
+ {
+ RArray<TUint32> iacLap;
+
+ for (TInt count = 0; count < aNumCurrentIAC; count++)
+ {
+ iacLap.Append(aIAC_LAP[count]);
+ }
+
+ CWriteCurrentIACLAPCommand* cmd = CWriteCurrentIACLAPCommand::NewL(aNumCurrentIAC, iacLap);
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }
+
+void CHCIFacade::VendorSpecificCommandL(const THCIOpcode aOpcode,
+ const TDesC8& aParameters)
+ {
+ CVendorDebugCommand* cmd = CVendorDebugCommand::NewL(aOpcode);
+
+ CleanupStack::PushL(cmd);
+ if(aParameters.Length() > cmd->Command().MaxLength())
+ {
+ User::Leave(KErrOverflow);
+ }
+ CleanupStack::Pop(); // We don't leave from this point on.
+
+ cmd->Command() = aParameters;
+
+ // Ownership of cmd transfered even if MhcqAddCommandL leaves
+ iCmdController->MhcqAddCommandL(cmd, *this);
+ }