bluetooth/btstack/linkmgr/hcifacade_events.cpp
changeset 0 29b1cd4cb562
child 16 9f17f914e828
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file is made up of 4 different sections:
       
    15 // - Command Complete processing functions
       
    16 // These are private functions that implement a specific command 
       
    17 // complete event, one per handled opcode.
       
    18 // - Event processing functions
       
    19 // These are private functions that implement a specific
       
    20 // command event, one per handled event. These events may or may not
       
    21 // be matched to a particular command. 
       
    22 // - Data event processing functions
       
    23 // These are private functions that implement a specific data event,
       
    24 // one per handled event.
       
    25 // - HCI APIs
       
    26 // These are the functions that are called directly by the 
       
    27 // different parts of the HCI and make up the MHCICommandQueueClient 
       
    28 // and MHCIDataEventObserver interfaces.
       
    29 // 
       
    30 //
       
    31 
       
    32 #include <bluetooth/logger.h>
       
    33 #include "hcifacade.h"
       
    34 #include "physicallinksmanager.h"
       
    35 #include "linkmgr.h"
       
    36 #include "hostresolver.h"
       
    37 #include "linkutil.h"
       
    38 #include "linkmuxer.h"
       
    39 #include "linkflowcontrol.h"
       
    40 #include "linkconsts.h"
       
    41 #include "VendorSAP.h"
       
    42 #include "vendorspecific.h"
       
    43 #include "AclDataQController.h"
       
    44 #include "pairingserver.h"
       
    45 #include "oobdata.h"
       
    46 
       
    47 #include <e32std.h>
       
    48 #include <bt_sock.h>
       
    49 #include <utf.h>
       
    50 #include <es_ini.h>
       
    51 #include <btextnotifiers.h>
       
    52 #include <bluetooth/hcicommandqueue.h>
       
    53 #include <bluetooth/hci/hciopcodes.h>
       
    54 
       
    55 #include <bluetooth/hci/command.h>
       
    56 
       
    57 // Command Events
       
    58 #include <bluetooth/hci/connectioncompleteevent.h>
       
    59 #include <bluetooth/hci/connectionrequestevent.h>
       
    60 #include <bluetooth/hci/disconnectioncompleteevent.h>
       
    61 #include <bluetooth/hci/authenticationcompleteevent.h>
       
    62 #include <bluetooth/hci/encryptionchangeevent.h>
       
    63 #include <bluetooth/hci/readremsuppfeatcompleteevent.h>
       
    64 #include <bluetooth/hci/readremoteextendedfeaturescompleteevent.h>
       
    65 #include <bluetooth/hci/readremverinfocompleteevent.h>
       
    66 #include <bluetooth/hci/commandstatusevent.h>
       
    67 #include <bluetooth/hci/hardwareerrorevent.h>
       
    68 #include <bluetooth/hci/rolechangeevent.h>
       
    69 #include <bluetooth/hci/numberofcompletedpacketsevent.h>
       
    70 #include <bluetooth/hci/modechangeevent.h>
       
    71 #include <bluetooth/hci/pincoderequestevent.h>
       
    72 #include <bluetooth/hci/linkkeyrequestevent.h>
       
    73 #include <bluetooth/hci/linkkeynotificationevent.h>
       
    74 #include <bluetooth/hci/maxslotschangeevent.h>
       
    75 #include <bluetooth/hci/readclockoffsetevent.h>
       
    76 #include <bluetooth/hci/connectionpackettypechangedevent.h>
       
    77 #include <bluetooth/hci/linksupervisiontimeoutchangedevent.h>
       
    78 #include <bluetooth/hci/synchronousconnectioncompleteevent.h>
       
    79 #include <bluetooth/hci/vendordebugevent.h>
       
    80 #include <bluetooth/hci/vendordebugcompleteevent.h>
       
    81 #include <bluetooth/hci/writesimplepairingmodecommand.h>
       
    82 #include <bluetooth/hci/readlocalsupportedcommandscommand.h>
       
    83 
       
    84 
       
    85 // Command Complete Events
       
    86 #include <bluetooth/hci/writelinkpolicysettingscompleteevent.h>
       
    87 #include <bluetooth/hci/readbdaddrcompleteevent.h>
       
    88 #include <bluetooth/hci/readbuffersizecompleteevent.h>
       
    89 #include <bluetooth/hci/readclassofdevicecompleteevent.h>
       
    90 #include <bluetooth/hci/readlocalversioninfocompleteevent.h>
       
    91 #include <bluetooth/hci/flushcompleteevent.h>
       
    92 #include <bluetooth/hci/readlocalsupportedfeaturescompleteevent.h>
       
    93 #include <bluetooth/hci/readlocalsupportedcommandscompleteevent.h>
       
    94 #include <bluetooth/hci/readlocaloobdatacompleteevent.h>
       
    95 #include <bluetooth/hci/remoteoobdatarequestreplycompleteevent.h>
       
    96 #include <bluetooth/hci/remoteoobdatarequestnegativereplycompleteevent.h>
       
    97 #include <bluetooth/hci/readinquiryresponsetransmitpowerlevelcompleteevent.h>
       
    98 
       
    99 // Related commands
       
   100 
       
   101 #include <bluetooth/hci/readremoteextendedfeaturescommand.h>
       
   102 #include <bluetooth/hci/readinquiryresponsetransmitpowerlevelcommand.h>
       
   103 
       
   104 #ifdef __FLOG_ACTIVE
       
   105 _LIT8(KLogComponent, LOG_COMPONENT_HCI_FACADE);
       
   106 #endif
       
   107 
       
   108 // ----------------------------------------------------------------------------
       
   109 // Command Complete processing functions
       
   110 // ----------------------------------------------------------------------------
       
   111 
       
   112 void CHCIFacade::WriteLinkPolicySettingsOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   113 	{
       
   114 	LOG_FUNC
       
   115 	THCIConnHandle connH(KInvalidConnectionHandle);
       
   116 	
       
   117 	if (aEvent != NULL)
       
   118 		{
       
   119 		const TWriteLinkPolicySettingsCompleteEvent& writeLinkPolicyCompleteEvent = TWriteLinkPolicySettingsCompleteEvent::Cast(*aEvent);
       
   120 		connH = writeLinkPolicyCompleteEvent.ConnectionHandle();
       
   121 		}
       
   122 		
       
   123 	iLinksMgr->WriteLinkPolicySettingsCompleteEvent(aHciErr, connH);
       
   124 	}
       
   125 
       
   126 void CHCIFacade::ResetOpcode(THCIErrorCode /*aHciErr*/, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   127 	{
       
   128 	LOG_FUNC
       
   129 	// We only expect a reset command event when we are initialising
       
   130 	__ASSERT_ALWAYS(iInitState == EResetting, Panic(EHCICmdQNotInitialising));
       
   131 	iInitState = EReset;
       
   132 	if (iControllerInitialisor != NULL)
       
   133 		{
       
   134 		iControllerInitialisor->MciiPostResetCommand();
       
   135 		}
       
   136 	else
       
   137 		{
       
   138 		// There is no initialisation plugin so behave as if there
       
   139 		// were and it had completed its post reset phase
       
   140 		McioPostResetCommandComplete(KErrNone);
       
   141 		}
       
   142 	}
       
   143 
       
   144 void CHCIFacade::ReadBdaddrOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   145 /**
       
   146 	Got the local address
       
   147 	Tell LinkMgr protocol
       
   148 **/
       
   149 	{
       
   150 	LOG_FUNC
       
   151 	if ((aHciErr == EOK) && (aEvent != NULL))
       
   152 		{
       
   153 		const TReadBdaddrCompleteEvent& readBdaddrCompleteEvent = TReadBdaddrCompleteEvent::Cast(*aEvent);
       
   154 		iLinkMgrProtocol.SetLocalBTAddress(readBdaddrCompleteEvent.BDADDR());
       
   155 		}
       
   156 	// do nothing if error
       
   157 	}
       
   158 
       
   159 void CHCIFacade::ReadBufferSizeOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   160 	{
       
   161 	LOG_FUNC
       
   162 	if ((aHciErr == EOK) && (aEvent != NULL))
       
   163 		{
       
   164 		const TReadBufferSizeCompleteEvent& readBufSizeCompleteEvent = TReadBufferSizeCompleteEvent::Cast(*aEvent);
       
   165 
       
   166 		TUint aclPacketLen = readBufSizeCompleteEvent.HCACLDataPacketLength();
       
   167 		TUint scoPacketLen = readBufSizeCompleteEvent.HCSynchronousDataPacketLength();
       
   168 		TUint noAclPackets = readBufSizeCompleteEvent.HCTotalNumACLDataPackets();
       
   169 		TUint noScoPackets = readBufSizeCompleteEvent.HCTotalNumSynchronousDataPackets();
       
   170 
       
   171 		iLinkMuxer->HandleLocalReadBufferSizeResult(aclPacketLen, scoPacketLen, noAclPackets, noScoPackets);
       
   172 		LOG3(_L("Link [HCIFacade_Events.cpp]: ReadBufferSizeResult - aErr %d, aAclMaxLen %d, aNoACL %d"), aHciErr, aclPacketLen, noAclPackets);
       
   173 		}
       
   174 	}
       
   175 
       
   176 void CHCIFacade::ReadClassOfDeviceOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   177 	{
       
   178 	LOG_FUNC
       
   179 	TUint cod(0);
       
   180 	
       
   181 	if ((aHciErr == EOK) && (aEvent != NULL))
       
   182 		{
       
   183 		const TReadClassOfDeviceCompleteEvent& readCoDCompleteEvent = TReadClassOfDeviceCompleteEvent::Cast(*aEvent);
       
   184 		cod = readCoDCompleteEvent.ClassOfDevice();
       
   185 		}
       
   186 
       
   187 	LOG2(_L("HCIFacade: ReadClassOfDevice Result Event (%d, 0x%x)"), aHciErr, cod);
       
   188 	iLinkMgrProtocol.UpdateDeviceClass(aHciErr == EOK, cod);
       
   189 	}
       
   190 
       
   191 void CHCIFacade::WriteLocalNameOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   192 	{
       
   193 	LOG_FUNC
       
   194 	LOG(_L("HCIFacade: SetLocalName Command Complete Event"));
       
   195 	iLinkMgrProtocol.InquiryMgr().SetLocalNameComplete(CHciUtil::SymbianErrorCode(aHciErr));
       
   196 	iLinkMgrProtocol.UpdateLocalDeviceName(aHciErr == EOK);
       
   197 	}
       
   198 
       
   199 void CHCIFacade::WriteCurrentIACLAPOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   200 	{
       
   201 	LOG_FUNC
       
   202 	LOG(_L("HCIFacade: WriteCurrentIACLAP Command Complete Event"));
       
   203 	
       
   204 	iLinkMgrProtocol.UpdateLimitedDiscoverable(aHciErr == EOK);
       
   205 	}
       
   206 
       
   207 void CHCIFacade::WriteClassOfDeviceOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   208 	{
       
   209 	LOG_FUNC
       
   210 	LOG(_L("HCIFacade: WriteClassOfDevice Command Complete Event"));
       
   211 
       
   212 	iLinkMgrProtocol.UpdateDeviceClass(aHciErr == EOK);
       
   213 	}
       
   214 
       
   215 void CHCIFacade::SetControllerToHostFlowControlOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   216 	{
       
   217 	LOG_FUNC
       
   218 	LOG(_L("HCIFacade: SetControllerToHostFlowControl Command Complete Event"));
       
   219 	iLinkMuxer->RecordHostControllerToHostFlowControl(aHciErr == EOK ? ETrue:EFalse);
       
   220 	}
       
   221 
       
   222 void CHCIFacade::WriteScanEnableOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   223 	{
       
   224 	LOG_FUNC
       
   225 	LOG(_L("HCIFacade: WriteScanEnable Command Complete Event"));
       
   226 
       
   227 	iLinkMgrProtocol.UpdateLocalDeviceScanEnable(aHciErr == EOK);
       
   228 	}
       
   229 
       
   230 void CHCIFacade::SetAFHHostChannelClassificationOpcode(THCIErrorCode /*aHciErr*/, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   231 	{
       
   232 	LOG_FUNC
       
   233 	LOG(_L("HCIFacade: WriteAFHHostChannelClassification Command Complete Event"));
       
   234 
       
   235 	//Update timer to fire after required interval
       
   236 	//between AFH Host Channel Classification Commands 
       
   237 	iAFHTimer->Cancel();
       
   238 	iAFHTimer->After(KAFHHostChannelClassificationIntervalTimer);
       
   239 	}
       
   240 
       
   241 void CHCIFacade::WriteAFHChannelAssessmentModeOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   242 	{
       
   243 	LOG_FUNC
       
   244 	LOG(_L("HCIFacade: WriteAFHChannelAssessmentMode Command Complete Event"));
       
   245 	//If 'status' is not EOK, the registry will not be updated. In particular, if
       
   246 	//channel assessment is not supported the AFHChannelAssessmentMode
       
   247 	//will remain set to ETrue. As this value is only used to update the 
       
   248 	//controller, it does not matter.
       
   249 	iLinkMgrProtocol.UpdateAFHChannelAssessmentMode(aHciErr == EOK);
       
   250 	}
       
   251 
       
   252 
       
   253 void CHCIFacade::ReadLocalVersionInfoOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   254 	{
       
   255 	LOG_FUNC
       
   256 	TBTDevHCIVersion hciVersion;
       
   257 	TBTDevLMPVersion lmpVersion;
       
   258 
       
   259 	if (aEvent != NULL)
       
   260 		{
       
   261 		const TReadLocalVersionInfoCompleteEvent& readLocalVersionCompleteEvent = TReadLocalVersionInfoCompleteEvent::Cast(*aEvent);
       
   262 		
       
   263 		hciVersion.iHCIVersion = readLocalVersionCompleteEvent.Version();
       
   264 		hciVersion.iHCIRevision = readLocalVersionCompleteEvent.Revision();
       
   265 		lmpVersion.iLMPVersion = readLocalVersionCompleteEvent.LMPVersion();
       
   266 		lmpVersion.iManufacturerID = readLocalVersionCompleteEvent.ManufacturerName();
       
   267 		lmpVersion.iLMPSubVersion = readLocalVersionCompleteEvent.LMPSubversion();
       
   268 		}
       
   269 	iLinkMgrProtocol.SetLocalVersion(aHciErr, hciVersion, lmpVersion);
       
   270 	
       
   271 	if(aHciErr == EOK && aEvent)
       
   272 		{
       
   273 		if(hciVersion.iHCIVersion > EHWHCIv1_1) // Only send a supported commands command
       
   274 			{
       
   275 			CReadLocalSupportedCommandsCommand* cmd = NULL;
       
   276 			TRAPD(err, cmd = CReadLocalSupportedCommandsCommand::NewL());
       
   277 			if(err == KErrNone)
       
   278 				{
       
   279 				static_cast<void>(SendInitialisationCommand(cmd));
       
   280 				}
       
   281 			}
       
   282 		}
       
   283 
       
   284 	iReadLocalVersionComplete = ETrue;
       
   285 	if (iReadLocalSupportedFeaturesComplete)
       
   286 		{
       
   287 		SetSupportedEventMasks();		
       
   288 		}
       
   289 	}
       
   290 
       
   291 void CHCIFacade::SetSupportedEventMasks()
       
   292 	{
       
   293 	TBTDevHCIVersion hciVersion;
       
   294 	TUint32 supportedEventMaskLoBytes;
       
   295 	TUint32 supportedEventMaskHiBytes;
       
   296 	
       
   297 	// We Dont mask the LoBytes events yet
       
   298 	supportedEventMaskLoBytes = THCIEventMask::KDefaultLoBytes;
       
   299 	supportedEventMaskHiBytes = THCIEventMask::KDefaultHiBytes;
       
   300 	
       
   301 	hciVersion = iLinkMgrProtocol.GetHWHCIVersion();
       
   302 	
       
   303 	if (hciVersion.iHCIVersion < EHWHCIv1_2)
       
   304 		{
       
   305 		// By default we support the core spec v1.2 however the HiBytes for the supported
       
   306 		// events are not used pre v1.2 and by clearing them it allows us to work with old 
       
   307 		// controllers if required
       
   308 		supportedEventMaskHiBytes = 0;
       
   309 		}		
       
   310 
       
   311 	if (iLinkMgrProtocol.IsExtendedInquiryResponseSupportedLocally())
       
   312 		{ 
       
   313 		supportedEventMaskHiBytes |=	THCIEventMask::EExtendedInquiryResultEvent;
       
   314 		}
       
   315 	
       
   316 	if (iLinkMgrProtocol.IsSecureSimplePairingSupportedLocally())
       
   317 		{  
       
   318 		supportedEventMaskHiBytes |=	THCIEventMask::EIOCapabilityRequestEvent|
       
   319 										THCIEventMask::EIOCapabilityRequestReplyEvent|
       
   320 										THCIEventMask::EUserConfirmationRequestEvent|
       
   321 										THCIEventMask::EUserPasskeyRequestEvent|
       
   322 										THCIEventMask::ERemoteOOBDataRequestEvent|
       
   323 										THCIEventMask::ESimplePairingCompleteEvent|
       
   324 										THCIEventMask::EUserPasskeyNotificationEvent|
       
   325 										THCIEventMask::EKeypressNotificationEvent;
       
   326 		}
       
   327 	
       
   328 	if (hciVersion.iHCIVersion == EHWHCIv2_1)
       
   329 		{  
       
   330 		supportedEventMaskHiBytes |=	THCIEventMask::ERemoteHostSupportedFeaturesNotificationEvent;
       
   331 		supportedEventMaskHiBytes |=	THCIEventMask::ELinkSupervisionTimeoutChangedEvent;
       
   332 		supportedEventMaskHiBytes |=	THCIEventMask::EEncryptionKeyRefreshCompleteEvent;
       
   333 		supportedEventMaskHiBytes |=	THCIEventMask::ERemoteHostSupportedFeaturesNotificationEvent;
       
   334 		}		
       
   335 	
       
   336 	THCIEventMask eventMask = {supportedEventMaskLoBytes, supportedEventMaskHiBytes};
       
   337 	TRAPD(err, SetEventMaskL(eventMask));
       
   338 	__ASSERT_DEBUG(err == KErrNone, Panic(EHCIControllerInitialisation));
       
   339 	(void) (err != err);
       
   340 	}
       
   341 
       
   342 void CHCIFacade::ReadLocalSupportedFeaturesOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   343 	{
       
   344 	LOG_FUNC
       
   345 	if ((aHciErr == EOK) && (aEvent != NULL))
       
   346 		{
       
   347 		const TReadLocalSupportedFeaturesCompleteEvent& readLocalFeaturesCompleteEvent = TReadLocalSupportedFeaturesCompleteEvent::Cast(*aEvent);
       
   348 		TBTFeatures features(readLocalFeaturesCompleteEvent.LMPFeatures());
       
   349 		iLinkMgrProtocol.SetLocalFeatures(aHciErr, features);
       
   350 
       
   351 		if(iLinkMgrProtocol.IsSecureSimplePairingSupportedLocally())
       
   352 			{
       
   353 			CWriteSimplePairingModeCommand* cmd = NULL;
       
   354 			TRAP_IGNORE(cmd = CWriteSimplePairingModeCommand::NewL(ESimplePairingEnabled));
       
   355 			static_cast<void>(SendInitialisationCommand(cmd));
       
   356 			iLinksMgr->SecMan().SetLocalSimplePairingMode(ETrue); //probably unnecessary
       
   357 			}
       
   358 		else
       
   359 			{
       
   360 			iLinksMgr->SecMan().SetLocalSimplePairingMode(EFalse);
       
   361 			}
       
   362 		}
       
   363 	else
       
   364 		{
       
   365 		iLinkMgrProtocol.SetLocalFeatures(aHciErr, TBTFeatures(0));
       
   366 		}
       
   367 
       
   368 	iReadLocalSupportedFeaturesComplete = ETrue;
       
   369 	if (iReadLocalVersionComplete)
       
   370 		{
       
   371 		SetSupportedEventMasks();		
       
   372 		}
       
   373 
       
   374 	}
       
   375 
       
   376 void CHCIFacade::ReadLocalSupportedCommandsOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   377 	{
       
   378 	LOG_FUNC
       
   379 	if ((aHciErr == EOK) && (aEvent != NULL))
       
   380 		{
       
   381 		const TReadLocalSupportedCommandsCompleteEvent& readLocalCommandsCompleteEvent = TReadLocalSupportedCommandsCompleteEvent::Cast(*aEvent);
       
   382 		TBluetoothHciCommands commands(readLocalCommandsCompleteEvent.SupportedCommands());
       
   383 		iLinkMgrProtocol.SetLocalCommands(aHciErr, commands);
       
   384 
       
   385 		if (iLinkMgrProtocol.IsCommandSupportedLocally(ESupportedReadInquiryResponseTransmitPowerCommand))
       
   386 			{
       
   387 			CReadInquiryResponseTransmitPowerLevelCommand* cmd = NULL;
       
   388 			TRAP_IGNORE(cmd = CReadInquiryResponseTransmitPowerLevelCommand::NewL());
       
   389 			if(cmd)
       
   390 				{
       
   391 				static_cast<void>(SendInitialisationCommand(cmd));
       
   392 				}
       
   393 			}
       
   394 
       
   395 		}
       
   396 	else
       
   397 		{
       
   398 		TBluetoothHciCommands commands;
       
   399 		iLinkMgrProtocol.SetLocalCommands(aHciErr, commands);
       
   400 		}
       
   401 	}
       
   402 
       
   403 void CHCIFacade::FlushOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   404 	{
       
   405 	LOG_FUNC
       
   406 	THCIConnHandle connH(KInvalidConnectionHandle);
       
   407 
       
   408 	if (aEvent != NULL)
       
   409 		{
       
   410 		const TFlushCompleteEvent& flushCompleteEvent = TFlushCompleteEvent::Cast(*aEvent);
       
   411 		connH = flushCompleteEvent.ConnectionHandle();
       
   412 		}
       
   413 
       
   414 	LOG(_L("Link [HCIFacade_Events.cpp]: FlushCompleteEvent"));
       
   415 	iLinkMgrProtocol.ACLController().FlushComplete(CHciUtil::SymbianErrorCode(aHciErr), connH);
       
   416 	}
       
   417 
       
   418 void CHCIFacade::SwitchRoleOpcode(THCIErrorCode aHciErr, const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   419 	{
       
   420 	LOG_FUNC
       
   421 	if (aHciErr != EOK)
       
   422 		{
       
   423 		// Role change failed, probably "Role change not allowed", notify clients
       
   424 		iLinksMgr->RoleChangeRejectedByHW(aHciErr);
       
   425 		return;						
       
   426 		}		
       
   427 	}
       
   428 
       
   429 void CHCIFacade::SetEventMaskOpcode(THCIErrorCode __DEBUG_ONLY(aHciErr), const THCIEventBase* /*aEvent*/, const CHCICommandBase* /*aRelatedCommand*/)
       
   430 	{
       
   431 	LOG_FUNC
       
   432 	#ifdef _DEBUG
       
   433 	LOG1(_L("HCIFacade: SetEventMask Result Event (%d)"), aHciErr); // leave in at all?
       
   434 	#endif
       
   435 	__ASSERT_DEBUG(aHciErr ==  EOK, Panic(EHCIControllerInitialisation));
       
   436 	iLinkMgrProtocol.LocalSupportedFeaturesAvailable();
       
   437 	}
       
   438 
       
   439 void CHCIFacade::ReadInquiryResponseTransmitPowerLevelOpcode(THCIErrorCode aHciErr, const THCIEventBase* aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   440 	{
       
   441 	if (aHciErr == EOK && aEvent)
       
   442 		{
       
   443 		const TReadInquiryResponseTransmitPowerLevelCompleteEvent& readInquiryResponseTransmitPowerLevelCompleteEvent = TReadInquiryResponseTransmitPowerLevelCompleteEvent::Cast(*aEvent);
       
   444 		TInt8 txPowerLevel = readInquiryResponseTransmitPowerLevelCompleteEvent.TxPowerLevel();
       
   445 		iLinkMgrProtocol.UpdateInquiryResponseTxPowerLevel(txPowerLevel);
       
   446 		FTRACE(FPrint(_L("HCIFacade: TxPowerLevel (%d)"), txPowerLevel));
       
   447 		}
       
   448 	}
       
   449 
       
   450 
       
   451 // ----------------------------------------------------------------------------
       
   452 // Event processing functions
       
   453 // ----------------------------------------------------------------------------
       
   454 
       
   455 void CHCIFacade::ConnectionCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand)
       
   456 	/**
       
   457 	   Some connection request has completed.
       
   458 
       
   459 	   This may be a successful connection complete, or a failure.
       
   460 	**/
       
   461 	{
       
   462 	LOG_FUNC
       
   463 	TBTConnect conn;
       
   464 	const TConnectionCompleteEvent& connCompleteEvent = TConnectionCompleteEvent::Cast(aEvent);
       
   465 	THCIErrorCode err = aEvent.ErrorCode();
       
   466 	
       
   467 	conn.iConnH = connCompleteEvent.ConnectionHandle();
       
   468 	conn.iBdaddr = connCompleteEvent.BDADDR();
       
   469 	conn.iLinkType = TLinkType(connCompleteEvent.LinkType());
       
   470 	conn.iEncryptMode = TEncryptMode(connCompleteEvent.EncryptionMode());
       
   471 	
       
   472 	LOG2(_L("Link [HCIFacade_Events.cpp]: Connection complete event. Code %d, link type=%d [from]"), err,conn.iLinkType);
       
   473 	LOGHEXDESC(conn.iBdaddr.Des());
       
   474 	iLinksMgr->ConnectionComplete(err, conn);
       
   475 
       
   476 	if(!aRelatedCommand  ||
       
   477 		(aRelatedCommand && (aRelatedCommand->Opcode() == KCreateACLConnectionOpcode)))
       
   478 		// this has only to do with paging, that is actively creating connections 
       
   479 		// to maintain symmetry with updating UI we do it here, and not trouble PHYmgr
       
   480 		{
       
   481 		iLinkMgrProtocol.SetUIConnecting(EFalse);
       
   482 		}
       
   483 	}
       
   484 
       
   485 void CHCIFacade::AuthenticationCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   486 	{
       
   487 	LOG_FUNC
       
   488 	const TAuthenticationCompleteEvent& authCompleteEvent = TAuthenticationCompleteEvent::Cast(aEvent);
       
   489 	iLinksMgr->AuthenticationComplete(aEvent.ErrorCode(), authCompleteEvent.ConnectionHandle());
       
   490 	}
       
   491 
       
   492 void CHCIFacade::ReadRemSuppFeatCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   493 	{
       
   494 	LOG_FUNC
       
   495 	const TReadRemSuppFeatCompleteEvent& readRemSuppFeatCompleteEvent = TReadRemSuppFeatCompleteEvent::Cast(aEvent);
       
   496 
       
   497 	LOG(_L("Link [HCIFacade_Events.cpp]: ReadRemoteSupportedFeaturesCompleteEvent"));
       
   498 	
       
   499 	TBTFeatures features(readRemSuppFeatCompleteEvent.LMPFeatures());
       
   500 	iLinksMgr->ReadRemoteSupportedFeaturesComplete(aEvent.ErrorCode(), readRemSuppFeatCompleteEvent.ConnectionHandle(), features);
       
   501 	}
       
   502 
       
   503 void CHCIFacade::ReadRemoteExtendedFeaturesCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   504 	{
       
   505 	LOG_FUNC
       
   506 	const TReadRemoteExtendedFeaturesCompleteEvent& readRemoteExtendedFeaturesCompleteEvent = TReadRemoteExtendedFeaturesCompleteEvent::Cast(aEvent);
       
   507 
       
   508 	LOG(_L("Link [HCIFacade_Events.cpp]: ReadRemoteExtendedFeaturesCompleteEvent"));
       
   509 	
       
   510 	TUint64 features = readRemoteExtendedFeaturesCompleteEvent.ExtendedLMPFeatures();
       
   511 	TUint8 pageNumber = readRemoteExtendedFeaturesCompleteEvent.PageNumber();
       
   512 	TUint8 maxPageNumber = readRemoteExtendedFeaturesCompleteEvent.MaximumPageNumber();
       
   513 	iLinksMgr->ReadRemoteExtendedFeaturesComplete(aEvent.ErrorCode(), readRemoteExtendedFeaturesCompleteEvent.ConnectionHandle(), features, pageNumber, maxPageNumber);
       
   514 	}
       
   515 
       
   516 
       
   517 void CHCIFacade::ReadRemVerInfoCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   518 	{
       
   519 	LOG_FUNC
       
   520 	const TReadRemVerInfoCompleteEvent& readRemVerInfoCompleteEvent = TReadRemVerInfoCompleteEvent::Cast(aEvent);
       
   521 	TBTDevRemoteHwVersion ver;
       
   522 	
       
   523 	ver.iLMPVersion = readRemVerInfoCompleteEvent.LMPVersion();
       
   524 	ver.iManufacturerID = readRemVerInfoCompleteEvent.ManufacturerName();
       
   525 	ver.iLMPSubVersion = readRemVerInfoCompleteEvent.LMPSubversion();
       
   526 
       
   527 	LOG(_L("Link [HCIFacade_Events.cpp]: ReadRemoteVersionInformationCompleteEvent"));
       
   528 
       
   529 	iLinksMgr->ReadRemoteVersionInfoComplete(aEvent.ErrorCode(), readRemVerInfoCompleteEvent.ConnectionHandle(), ver);
       
   530 	}
       
   531 
       
   532 void CHCIFacade::CommandCompleteEvent(THCIOpcode aOpcode, THCIErrorCode aHciErr, 
       
   533 										const THCIEventBase* aEvent, const CHCICommandBase* aRelatedCommand)
       
   534 	{
       
   535 	LOG_FUNC
       
   536 	LOG3(_L("aOpcode=%d, aHciErr=%d, iOutstandingCommands.Count()=%d"), aOpcode, aHciErr, iOutstandingCommands.Count());
       
   537 
       
   538 	switch(aOpcode)
       
   539 		{
       
   540 	case KWriteLinkPolicySettingsOpcode:
       
   541 		WriteLinkPolicySettingsOpcode(aHciErr, aEvent, aRelatedCommand);
       
   542 		break;
       
   543 		
       
   544 	case KResetOpcode:
       
   545 		__ASSERT_ALWAYS(iOutstandingCommands.Count()==1, Panic(EHCICtrlrInitOnlyOneResetCmdAllowed));
       
   546 		ResetOpcode(aHciErr, aEvent, aRelatedCommand);
       
   547 		break;
       
   548 		
       
   549 	case KWriteLocalNameOpcode:
       
   550 		WriteLocalNameOpcode(aHciErr, aEvent, aRelatedCommand);
       
   551 		break;
       
   552 		
       
   553 	case KReadClassOfDeviceOpcode:
       
   554 		ReadClassOfDeviceOpcode(aHciErr, aEvent, aRelatedCommand);
       
   555 		break;
       
   556 		
       
   557 	case KWriteCurrentIACLAPOpcode:
       
   558 		WriteCurrentIACLAPOpcode(aHciErr, aEvent, aRelatedCommand);
       
   559 		break;
       
   560 		
       
   561 	case KWriteClassOfDeviceOpcode:
       
   562 		WriteClassOfDeviceOpcode(aHciErr, aEvent, aRelatedCommand);
       
   563 		break;
       
   564 		
       
   565 	case KSetControllerToHostFlowControlOpcode:
       
   566 		SetControllerToHostFlowControlOpcode(aHciErr, aEvent, aRelatedCommand);
       
   567 		break;
       
   568 		
       
   569 	case KWriteScanEnableOpcode:
       
   570 		WriteScanEnableOpcode(aHciErr, aEvent, aRelatedCommand);
       
   571 		break;
       
   572 		
       
   573 	case KSetAFHHostChannelClassificationOpcode:
       
   574 		SetAFHHostChannelClassificationOpcode(aHciErr, aEvent, aRelatedCommand);
       
   575 		break;
       
   576 		
       
   577 	case KWriteAFHChannelAssessmentModeOpcode:
       
   578 		WriteAFHChannelAssessmentModeOpcode(aHciErr, aEvent, aRelatedCommand);
       
   579 		break;
       
   580 		
       
   581 	case KReadLocalVersionInfoOpcode:
       
   582 		ReadLocalVersionInfoOpcode(aHciErr, aEvent, aRelatedCommand);
       
   583 		break;
       
   584 		
       
   585 	case KReadLocalSupportedFeaturesOpcode:
       
   586 		ReadLocalSupportedFeaturesOpcode(aHciErr, aEvent, aRelatedCommand);
       
   587 		break;
       
   588 	
       
   589 	case KReadLocalSupportedCommandsOpcode:
       
   590 		ReadLocalSupportedCommandsOpcode(aHciErr, aEvent, aRelatedCommand);
       
   591 		break;
       
   592 		
       
   593 	case KReadBufferSizeOpcode:
       
   594 		ReadBufferSizeOpcode(aHciErr, aEvent, aRelatedCommand);
       
   595 		break;
       
   596 		
       
   597 	case KReadBdaddrOpcode:
       
   598 		ReadBdaddrOpcode(aHciErr, aEvent, aRelatedCommand);
       
   599 		break;
       
   600 		
       
   601 	case KFlushOpcode:
       
   602 		FlushOpcode(aHciErr, aEvent, aRelatedCommand);
       
   603 		break;
       
   604 		
       
   605 	case KSwitchRoleOpcode:
       
   606 		SwitchRoleOpcode(aHciErr, aEvent, aRelatedCommand);
       
   607 		break;
       
   608 
       
   609 	case KSetEventMaskOpcode:
       
   610 		SetEventMaskOpcode(aHciErr, aEvent, aRelatedCommand);
       
   611 		break;
       
   612 
       
   613 	case KReadInquiryResponseTransmitPowerLevelOpcode:
       
   614 		ReadInquiryResponseTransmitPowerLevelOpcode(aHciErr, aEvent, aRelatedCommand);
       
   615 		break;
       
   616 
       
   617 	// Inquiry related events
       
   618 	case KInquiryCancelOpcode:
       
   619 	case KRemoteNameRequestCancelOpcode:
       
   620 		// Only the inquiry manager issues remote name requests.
       
   621 		FTRACE(FPrint(_L("Error!! Unsolicited inquiry-type command complete event (opcode: 0x%04x)"), aOpcode));
       
   622 		__ASSERT_DEBUG(EFalse, Panic(EHCIUnmatchedInquiryEvent));
       
   623 		break;
       
   624 
       
   625 	// Security related events that are sent from the facade.
       
   626 	case KWriteSimplePairingModeOpcode:
       
   627 	case KReadLocalOOBDataOpcode:
       
   628 	case KRemoteOOBDataRequestReplyOpcode:
       
   629 	case KRemoteOOBDataRequestNegativeReplyOpcode:
       
   630 	case KIOCapabilityRequestReplyOpcode:
       
   631 	case KUserConfirmationRequestReplyOpcode:
       
   632 	case KUserConfirmationRequestNegativeReplyOpcode:
       
   633 	case KUserPasskeyRequestReplyOpcode:
       
   634 	case KUserPasskeyRequestNegativeReplyOpcode:
       
   635 	case KIOCapabilityRequestNegativeReplyOpcode:
       
   636 		iLinksMgr->SecMan().HCIEventHandler().MhcqcCommandEventReceived(*aEvent, aRelatedCommand);
       
   637 		break;
       
   638 		
       
   639 	// List of valid command complete event opcodes that we ignore
       
   640 	case KRejectConnectionRequestOpcode:
       
   641 	case KReadStoredLinkKeyOpcode:
       
   642 	case KWriteStoredLinkKeyOpcode:
       
   643 	case KDeleteStoredLinkKeyOpcode:
       
   644 	case KReadScanEnableOpcode:
       
   645 	case KReadEncryptionModeOpcode:
       
   646 	case KReadNumberOfSupportedIACOpcode:
       
   647 	case KReadVoiceSettingOpcode:
       
   648 	case KReadAuthenticationEnableOpcode:
       
   649 	case KReadCountryCodeOpcode:
       
   650 	case KReadCurrentIACLAPOpcode:
       
   651 	case KWriteLinkSupervisionTimeoutOpcode:
       
   652 	case KLinkKeyRequestReplyOpcode:
       
   653 	case KLinkKeyRequestReplyNegativeOpcode:
       
   654 	case KPINCodeRequestReplyOpcode:
       
   655 	case KPINCodeRequestReplyNegativeOpcode:
       
   656 	case KRoleDiscoveryOpcode:
       
   657 	case KPeriodicInquiryModeOpcode:
       
   658 	case KExitPeriodicInquiryModeOpcode:
       
   659 	case KSetEventFilterOpcode:
       
   660 	case KCreateNewUnitKeyOpcode:
       
   661 	case KWriteAuthenticationEnableOpcode:
       
   662 	case KHostNumberOfCompletedPacketsOpcode:
       
   663 	case KWriteEncryptionModeOpcode:
       
   664 	case KWritePageTimeoutOpcode:
       
   665 	case KReadConnectionAcceptTimeoutOpcode:
       
   666 	case KWriteConnectionAcceptTimeoutOpcode:
       
   667 	case KWriteVoiceSettingOpcode:
       
   668 	case KHostBufferSizeOpcode:
       
   669 	case KReadAFHChannelMapOpcode:
       
   670 	case KReadAFHChannelAssessmentModeOpcode:
       
   671 	case KReadPageTimeoutOpcode:
       
   672 	case KCreateConnectionCancelOpcode:
       
   673 	case KReadLMPHandleOpcode:
       
   674 	case KReadLinkPolicySettingsOpcode:
       
   675 	case KReadDefaultLinkPolicySettingsOpcode:
       
   676 	case KWriteDefaultLinkPolicySettingsOpcode:	
       
   677 	case KReadPINTypeOpcode:
       
   678 	case KWritePINTypeOpcode:		
       
   679 	case KReadPageScanActivityOpcode:
       
   680 	case KWritePageScanActivityOpcode:
       
   681 	case KReadInquiryScanActivityOpcode:
       
   682 	case KWriteInquiryScanActivityOpcode:
       
   683 	case KReadAutomaticFlushTimeoutOpcode:
       
   684 	case KWriteAutomaticFlushTimeoutOpcode:
       
   685 	case KReadNumBroadcastRetransmissionsOpcode:
       
   686 	case KWriteNumBroadcastRetransmissionsOpcode:
       
   687 	case KReadHoldModeActivityOpcode:
       
   688 	case KWriteHoldModeActivityOpcode:
       
   689 	case KReadTransmitPowerLevelOpcode:
       
   690 	case KReadSynchronousFlowControlEnableOpcode:
       
   691 	case KWriteSynchronousFlowControlEnableOpcode:		
       
   692 	case KReadLinkSupervisionTimeoutOpcode:
       
   693 	case KReadPageScanPeriodOpcode:
       
   694 	case KWritePageScanPeriodOpcode:
       
   695 	case KReadPageScanOpcode:
       
   696 	case KWritePageScanOpcode:
       
   697 	case KReadInquiryScanTypeOpcode:
       
   698 	case KWriteInquiryScanTypeOpcode:
       
   699 	case KReadInquiryModeOpcode:
       
   700 	case KReadPageScanTypeOpcode:
       
   701 	case KWritePageScanTypeOpcode:
       
   702 	case KReadLocalExtendedFeaturesOpcode:
       
   703 	case KReadFailedContactCounterOpcode:
       
   704 	case KResetFailedContactCounterOpcode:
       
   705 	case KReadLinkQualityOpcode:
       
   706 	case KReadRSSIOpcode:
       
   707 	case KReadClockOpcode:
       
   708 	case KReadLoopbackModeOpcode:
       
   709 	case KWriteLoopbackModeOpcode:
       
   710 	case KEnableDeviceUnderTestModeOpcode:
       
   711 	case KReadExtendedInquiryResponseOpcode:
       
   712 
       
   713 	case KReadSimplePairingModeOpcode:
       
   714 	case KSendKeypressNotificationOpcode:
       
   715 
       
   716 	case KWriteSimplePairingDebugModeOpcode:
       
   717 		
       
   718 		// Catch all the events we do not handle
       
   719 		LOG1(_L("Warning!! Unhandled Command Complete Event (opcode:%d)"), aOpcode);
       
   720 		break;
       
   721 		
       
   722 	default:
       
   723 		THCIOpcode OGF=static_cast<THCIOpcode>(aOpcode&KOGFMask);
       
   724 
       
   725 		if(OGF==KVendorDebugOGF)
       
   726 			{
       
   727 			LOG(_L("Link: [HCIFacade_Events.cpp]: Vendor Specfic Command Complete Event"));
       
   728 			if(iLinkMgrProtocol.VendorSpecificSAP())
       
   729 				{
       
   730 				if (aEvent)
       
   731 					{
       
   732 					TPtrC8 eventPacket(TVendorDebugCompleteEvent::Cast(*aEvent).VendorDebugData());
       
   733 					iLinkMgrProtocol.VendorSpecificSAP()->VendorCommandCompleteEvent(aHciErr, &eventPacket);
       
   734 					}
       
   735 				else
       
   736 					{
       
   737 					FLOG(_L("Link: [HCIFacade_Events.cpp]: Vendor Specific Command Complete Event is NULL"));
       
   738 					iLinkMgrProtocol.VendorSpecificSAP()->VendorCommandCompleteEvent(aHciErr, NULL);
       
   739 					}
       
   740 				}
       
   741 			break;
       
   742 			}
       
   743 
       
   744 		LOG2(_L("Link [HCIFacade_Events.cpp]: Warning: Unknown Command complete event! Opcode %d error code %d"), aOpcode, aHciErr);
       
   745 
       
   746 		__ASSERT_DEBUG(EFalse, Panic(EHCIUnknownCommandCompleteOpcode));			
       
   747 		break;				
       
   748 		}
       
   749 		
       
   750 	if(iInitState == EPostReset)
       
   751 		{
       
   752 		__ASSERT_ALWAYS(iOutstandingCommands.Count() > 0, Panic(EHCICtrlrInitNoOutstandingCmds));
       
   753 		TInt position(FindOutstandingCommandOpCode(aOpcode));
       
   754 		
       
   755 		if (position < 0)
       
   756 			{
       
   757 			// HCI matches the incoming event to a command which stack has not sent and hence we must panic.
       
   758 			// More explicitly HCI cmdQ has got a command (aRelatedCommand != NULL) which was not sent by stack. 
       
   759 			// (position <0 i.e. not found)
       
   760 			
       
   761 			__ASSERT_ALWAYS(!aRelatedCommand, Panic(EHCICtrlrInitCmdNotFound));
       
   762 			}
       
   763 		else
       
   764 			{
       
   765 			iOutstandingCommands.Remove(position);
       
   766 			if (!iInitialisationError && iOutstandingCommands.Count() == 0)
       
   767 				{
       
   768 				// start the CmdQ
       
   769 				iCmdController->Start();
       
   770 				iInitState = EInitialised;
       
   771 				// if we haven't error'd, power is ON
       
   772 				iLinkMgrProtocol.UpdateLocalDevicePower(EBTOn);	
       
   773 				}
       
   774 			}
       
   775 		}
       
   776 	else if(iInitState == EReset)
       
   777 		{
       
   778 		// If an initialisor is present, ResetOpcode() calls its MciiPostResetCommand()
       
   779 		// function. If this sends an async command, it does not call McioPostResetCommandComplete(),
       
   780 		// and iInitState will not get updated and still be set to EReset.
       
   781 		// We should remove the command from the queue, without updating iInitState.
       
   782 		__ASSERT_ALWAYS(iOutstandingCommands.Count() == 1, Panic(EHCICtrlrInitNoOutstandingCmds));
       
   783 		__ASSERT_DEBUG(aOpcode == KResetOpcode, Panic(EHCICtrlrInitCmdNotFound));
       
   784 		TInt position(FindOutstandingCommandOpCode(aOpcode));
       
   785 		__ASSERT_ALWAYS(position >= 0, Panic(EHCICtrlrInitCmdNotFound));
       
   786 		iOutstandingCommands.Remove(position);		
       
   787 		}
       
   788 	else if(iInitState == EResetting)
       
   789 		{
       
   790 		__ASSERT_ALWAYS(iOutstandingCommands.Count()==1, Panic(EHCICtrlrInitOnlyOneResetCmdAllowed));
       
   791 		}
       
   792 	else
       
   793 		{
       
   794 		__ASSERT_ALWAYS(iOutstandingCommands.Count()==0, Panic(EHCICtrlrInitFailedToRemoveCmd));
       
   795 		}
       
   796 	}
       
   797 
       
   798 void CHCIFacade::CommandStatusEvent(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand)
       
   799 	{
       
   800 	LOG_FUNC
       
   801 	const TCommandStatusEvent& commandStatusEvent = TCommandStatusEvent::Cast(aEvent);
       
   802 	THCIOpcode opcode = commandStatusEvent.CommandOpcode();
       
   803 	THCIErrorCode hciErr = commandStatusEvent.ErrorCode();
       
   804 	
       
   805 	if (hciErr != EOK)
       
   806 		{
       
   807 		// got an error
       
   808 		// map onto the event that would have occurred: some things we will have to let the client work out
       
   809 		// e.g. they should check error and connection handle etc.
       
   810 		switch (opcode)
       
   811 			{
       
   812 		case KCreateACLConnectionOpcode:
       
   813 		case KAcceptConnectionRequestOpcode:
       
   814 			{
       
   815 			TBTConnect nulldevice;
       
   816 			nulldevice.iBdaddr = MAKE_TINT64(0,0);
       
   817 			nulldevice.iLinkType = EACLLink;
       
   818 			iLinksMgr->ConnectionComplete(hciErr, nulldevice);
       
   819 
       
   820 			if(opcode == KCreateACLConnectionOpcode)
       
   821 				// this has only to do with paging, that is actively creating connections 
       
   822 				// to maintain symmetry with updating UI we do it here, and not trouble PHYmgr
       
   823 				{
       
   824 				iLinkMgrProtocol.SetUIConnecting(EFalse);
       
   825 				}
       
   826 			break;
       
   827 			}
       
   828 			
       
   829 		case KAuthenticationRequestedOpcode:
       
   830 			iLinksMgr->AuthenticationComplete(hciErr, KInvalidConnectionHandle);
       
   831 			break;
       
   832 			
       
   833 		case KDisconnectOpcode:
       
   834 			iLinksMgr->Disconnection(hciErr, KInvalidConnectionHandle, hciErr); // reason=aStatus
       
   835 			break;
       
   836 			
       
   837 		case KAddSCOConnectionOpcode:
       
   838 			{
       
   839 			TBTConnect nulldevice;
       
   840 			nulldevice.iBdaddr = MAKE_TINT64(0,0);
       
   841 			nulldevice.iLinkType = ESCOLink;
       
   842 			iLinksMgr->ConnectionComplete(hciErr, nulldevice);
       
   843 			break;
       
   844 			}
       
   845 			
       
   846 		case KSetConnectionEncryptionOpcode:
       
   847 			iLinksMgr->EncryptionChange(hciErr, KInvalidConnectionHandle, EFalse); // no encryption
       
   848 			break;
       
   849 			
       
   850 		case KReadRemoteSupportedFeaturesOpcode:
       
   851 			iLinksMgr->ReadRemoteSupportedFeaturesComplete(hciErr, KInvalidConnectionHandle, TBTFeatures(0)); // no bitmask
       
   852 			break;
       
   853 			
       
   854 		case KReadClockOffsetOpcode:
       
   855 			iLinksMgr->ClockOffset(hciErr, KInvalidConnectionHandle, 0);
       
   856 			break;
       
   857 			
       
   858 		case KReadRemoteVersionInfoOpcode:
       
   859 			{
       
   860 			TBTDevRemoteHwVersion nullversion;
       
   861 			nullversion.iLMPVersion=0;
       
   862 			nullversion.iManufacturerID=0;
       
   863 			nullversion.iLMPSubVersion=0;
       
   864 		
       
   865 			iLinksMgr->ReadRemoteVersionInfoComplete(hciErr, KInvalidConnectionHandle, nullversion);
       
   866 			break;
       
   867 			}
       
   868 			
       
   869 		case KSetupSynchronousConnectionOpcode:
       
   870 		case KAcceptSynchronousConnectionRequestOpcode:
       
   871 			{
       
   872 		    TBTConnect conn;
       
   873 		    conn.iConnH = 0;
       
   874 		    conn.iLinkType = EeSCOLink;
       
   875 
       
   876 			TBTSyncConnectOpts syncOpts(0, 0, 0, 0, EuLawLog);
       
   877 
       
   878 			iLinksMgr->SynchronousConnectionComplete(hciErr, conn, syncOpts);
       
   879 			break;
       
   880 			}				
       
   881 
       
   882 		case KHostNumberOfCompletedPacketsOpcode:
       
   883 			{
       
   884 			iLinksMgr->CompletedPackets(KInvalidConnectionHandle, 0); //no packets
       
   885 			break;
       
   886 			}
       
   887 		
       
   888 		case KReadRemoteExtendedFeaturesOpcode:
       
   889 			{
       
   890 			// Maybe migrate this to use HCIv2 so command is owned by physical link
       
   891 			__ASSERT_ALWAYS(aRelatedCommand, Panic(EHCIUnexpectedEvent));
       
   892 			__ASSERT_ALWAYS(aRelatedCommand->Opcode() == KReadRemoteExtendedFeaturesOpcode, Panic(EHCICommandBadArgument));
       
   893 			const CReadRemoteExtendedFeaturesCommand* cmd = reinterpret_cast<const CReadRemoteExtendedFeaturesCommand*>(aRelatedCommand);
       
   894 			iLinksMgr->ReadRemoteExtendedFeaturesComplete(hciErr, cmd->ConnectionHandle(), TUint64(0), cmd->PageNumber(), 0);
       
   895 			break;
       
   896 			}
       
   897 		// Deal with low power mode request failures. 
       
   898 		// We only change state when we receive successful responses to low power 
       
   899 		// mode requests. Errors can be safely ignored as we haven't changed state
       
   900 		// at this time. 
       
   901 		// Whilst it would be preferable to handle these responses doing so would 
       
   902 		// require substantial changes to the functions that handle low power mode 
       
   903 		// requests in order for them to take full advantage of HCIv2. At present 
       
   904 		// this problem only occurs in debug mode and so this is solution is preferable. 
       
   905 		case KHoldModeOpcode:
       
   906 		case KParkModeOpcode:
       
   907 		case KExitParkModeOpcode:
       
   908 		case KSniffModeOpcode:
       
   909 		case KExitSniffModeOpcode:
       
   910 			{
       
   911 			break;
       
   912 			}
       
   913 		case KChangeConnectionPacketTypeOpcode:	
       
   914 			{
       
   915 			iLinksMgr->PacketTypeChange(hciErr, KInvalidConnectionHandle,0);
       
   916 			break;
       
   917 			}
       
   918 		
       
   919 		default:
       
   920 			// Complete any other commands with an error
       
   921 			CommandCompleteEvent(opcode, hciErr, NULL, NULL);
       
   922 			break;	
       
   923 			}
       
   924 		}
       
   925 	else // Error free status event
       
   926 		{
       
   927 		switch (opcode)
       
   928 			{
       
   929 		case KCreateACLConnectionOpcode:
       
   930 			// protocol looks after the ui gubbins
       
   931 			iLinkMgrProtocol.SetUIConnecting(ETrue);		
       
   932 			break;
       
   933 			
       
   934 		case KAuthenticationRequestedOpcode:
       
   935 			// tell secman that it really going through authentication
       
   936 			iLinksMgr->SecMan().AuthenticationInProgress();
       
   937 			break;
       
   938 		
       
   939 		default:
       
   940 			break;
       
   941 			}
       
   942 		}
       
   943 	}
       
   944 
       
   945 void CHCIFacade::ReadClockOffsetEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   946 	{
       
   947 	LOG_FUNC
       
   948 	const TReadClockOffsetEvent& readClockOffsetEvent = TReadClockOffsetEvent::Cast(aEvent);
       
   949 
       
   950 	LOG(_L("Link [HCIFacade_Events.cpp]: ReadClockOffsetResultEvent"));
       
   951 	iLinksMgr->ClockOffset(aEvent.ErrorCode(), readClockOffsetEvent.ConnectionHandle(), readClockOffsetEvent.ClockOffset());
       
   952 	}
       
   953 
       
   954 void CHCIFacade::ConnectionPacketTypeChangedEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   955 	{
       
   956 	LOG_FUNC
       
   957 	const TConnectionPacketTypeChangedEvent& connPacketTypeChangedEvent = TConnectionPacketTypeChangedEvent::Cast(aEvent);
       
   958 
       
   959 	LOG(_L("Link [HCIFacade_Events.cpp]:ConnectionPacketTypeChangedEvent"));
       
   960 	// we need to pass onto the connections manager - this will let the connections know
       
   961 	// and subsequently the baseband model
       
   962 	iLinksMgr->PacketTypeChange(aEvent.ErrorCode(), connPacketTypeChangedEvent.ConnectionHandle(), connPacketTypeChangedEvent.PacketType());
       
   963 	}
       
   964 
       
   965 void CHCIFacade::LinkSupervisionTimeoutChangedEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   966 	{
       
   967 	LOG_FUNC
       
   968 	const TLinkSupervisionTimeoutChangedEvent& linkSupervisionTimeoutChangedEvent = TLinkSupervisionTimeoutChangedEvent::Cast(aEvent);
       
   969 
       
   970 	iLinksMgr->LinkSupervisionTimeoutChange(aEvent.ErrorCode(),
       
   971 											linkSupervisionTimeoutChangedEvent.ConnectionHandle(),
       
   972 											linkSupervisionTimeoutChangedEvent.LinkSupervisionTimeout());
       
   973 	}
       
   974 
       
   975 void CHCIFacade::SynchronousConnectionCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   976 	{
       
   977 	LOG_FUNC
       
   978 	const TSynchronousConnectionCompleteEvent& syncConnCompleteEvent = TSynchronousConnectionCompleteEvent::Cast(aEvent);
       
   979 	
       
   980     TBTConnect conn;
       
   981     conn.iConnH = syncConnCompleteEvent.ConnectionHandle();
       
   982     conn.iBdaddr = syncConnCompleteEvent.BDADDR();
       
   983     conn.iLinkType = TLinkType(syncConnCompleteEvent.LinkType());
       
   984 	
       
   985 	LOG(_L("Link [HCIFacade_Events.cpp]: Synchronous connection complete [from]"));
       
   986 	LOGHEXDESC(conn.iBdaddr.Des());
       
   987 
       
   988 	TBTSyncConnectOpts syncOpts(syncConnCompleteEvent.TransmissionInterval(), 
       
   989 								syncConnCompleteEvent.RetransmissionWindow(),
       
   990 								syncConnCompleteEvent.RxPacket_Length(),
       
   991 								syncConnCompleteEvent.TxPacket_Length(),
       
   992 								TAirMode(syncConnCompleteEvent.AirMode()));
       
   993 
       
   994 	iLinksMgr->SynchronousConnectionComplete(aEvent.ErrorCode(), conn, syncOpts);
       
   995 	}
       
   996 
       
   997 void CHCIFacade::VendorDebugEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   998 	{
       
   999 	LOG_FUNC
       
  1000 	LOG(_L("Link [HCIFacade_Events.cpp]: **WARNING** - Just received a Vendor Specific Debug Event !"));
       
  1001 
       
  1002 	if(iLinkMgrProtocol.VendorSpecificSAP())
       
  1003 		{
       
  1004 		const TVendorDebugEvent& vendorEvent = TVendorDebugEvent::Cast(aEvent);
       
  1005 
       
  1006 		const TDesC8& des = vendorEvent.VendorDebugData();
       
  1007 		iLinkMgrProtocol.VendorSpecificSAP()->VendorDebugEvent(aEvent.ErrorCode(), &des);
       
  1008 		}	
       
  1009 	}
       
  1010 
       
  1011 void CHCIFacade::ConnectionRequestEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1012 /**
       
  1013    A connection request has come in.
       
  1014    
       
  1015    Tell connections mgr = it will decide whether to accept or not
       
  1016 **/
       
  1017 	{
       
  1018 	LOG_FUNC
       
  1019 	TBTConnect conn;
       
  1020 	const TConnectionRequestEvent& connRequestEvent = TConnectionRequestEvent::Cast(aEvent);
       
  1021 	THCIErrorCode err = aEvent.ErrorCode();
       
  1022 	
       
  1023 	conn.iBdaddr = connRequestEvent.BDADDR();
       
  1024 	conn.iCoD = connRequestEvent.ClassOfDevice();
       
  1025 	conn.iLinkType = TLinkType(connRequestEvent.LinkType());
       
  1026 
       
  1027 	LOG(_L("Link [HCIFacade_Events.cpp]: Connection request [from]"));
       
  1028 	LOGHEXDESC(conn.iBdaddr.Des());
       
  1029 	
       
  1030 	iLinksMgr->ConnectionRequest(conn);	// passes Address and CoD
       
  1031 	}
       
  1032 
       
  1033 void CHCIFacade::DisconnectionCompleteEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1034 /**
       
  1035    Disconnect indication up from hardware.
       
  1036    
       
  1037    Called for local or remote initiated baseband disconnect, or on
       
  1038    hardware failure.
       
  1039    Any flushed ACL data will be indicated up to us seperately.
       
  1040    
       
  1041    @param aErr    HCI Error code -- if not EOK we didn't actually connect.
       
  1042    @param aConnH  Handle the disconnect happended on.
       
  1043    @param aReason If aErr == EOK, this tells us why we disconnect. Else not valid.
       
  1044 **/
       
  1045 	{
       
  1046 	LOG_FUNC
       
  1047 	const TDisconnectionCompleteEvent& disconnCompleteEvent = TDisconnectionCompleteEvent::Cast(aEvent);
       
  1048 	THCIErrorCode err = aEvent.ErrorCode();
       
  1049 	THCIConnHandle connH = disconnCompleteEvent.ConnectionHandle();
       
  1050 	THCIErrorCode reason = THCIErrorCode(disconnCompleteEvent.Reason());
       
  1051 	
       
  1052 	LOG2(_L("HCI: disconnection complete event, handle %d, error %d"), connH, err);
       
  1053 	iLinksMgr->Disconnection(err, connH, reason);
       
  1054 	}
       
  1055 
       
  1056 void CHCIFacade::EncryptionChangeEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1057 	{
       
  1058 	LOG_FUNC
       
  1059 	const TEncryptionChangeEvent& encryptChangeEvent = TEncryptionChangeEvent::Cast(aEvent);
       
  1060 	iLinksMgr->EncryptionChange(aEvent.ErrorCode(), encryptChangeEvent.ConnectionHandle(), encryptChangeEvent.EncryptionEnable());
       
  1061 	}
       
  1062 
       
  1063 void CHCIFacade::HardwareErrorEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1064 	{
       
  1065 	LOG_FUNC
       
  1066 	const THardwareErrorEvent& hardwareErrorEvent = THardwareErrorEvent::Cast(aEvent);
       
  1067 	TUint8 hwErr = hardwareErrorEvent.HardwareCode();
       
  1068 	
       
  1069 	// Just log event, QDP is responsible for 'rebooting' the stack if required
       
  1070 	LOG1(_L("Link [HCIFacade_Events.cpp]: Error! HardwareErrorEvent Received: %d"), hwErr);
       
  1071 	}
       
  1072 
       
  1073 void CHCIFacade::RoleChangeEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1074 	{
       
  1075 	LOG_FUNC
       
  1076 	const TRoleChangeEvent& roleChangeEvent = TRoleChangeEvent::Cast(aEvent);
       
  1077 
       
  1078 	LOG(_L("Link [HCIFacade_Events.cpp]: RoleChangeEvent"));
       
  1079 	iLinksMgr->RoleChange(aEvent.ErrorCode(), roleChangeEvent.BDADDR(), TBTBasebandRole(roleChangeEvent.Newrole()));
       
  1080 	}
       
  1081 
       
  1082 void CHCIFacade::ModeChangeEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1083 	{
       
  1084 	LOG_FUNC
       
  1085 	const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent);
       
  1086 	TBTLinkMode mode = EActiveMode;
       
  1087 	switch(modeChangeEvent.CurrentMode())
       
  1088 		{
       
  1089 	// Mode 0, as defined for the Mode Change Event, is Active Mode
       
  1090 	case 0: 
       
  1091 		break;
       
  1092 		
       
  1093 	case 1: 
       
  1094 		mode = EHoldMode; 
       
  1095 		break;
       
  1096 		
       
  1097 	case 2:	
       
  1098 		mode = ESniffMode;
       
  1099 		break;
       
  1100 		
       
  1101 	case 3:
       
  1102 		mode = EParkMode;
       
  1103 		break;
       
  1104 		
       
  1105 	default:
       
  1106 		__ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument));
       
  1107 		break;
       
  1108 		}
       
  1109 
       
  1110 	LOG(_L("Link [HCIFacade_Events.cpp]: ModeChangeEvent"));
       
  1111 	iLinksMgr->ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), mode, modeChangeEvent.Interval());
       
  1112 	}
       
  1113 
       
  1114 void CHCIFacade::PINCodeRequestEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1115 	{
       
  1116 	LOG_FUNC
       
  1117 	const TPINCodeRequestEvent& pinCodeRequestEvent = TPINCodeRequestEvent::Cast(aEvent);
       
  1118 
       
  1119 	iLinksMgr->PinRequest(pinCodeRequestEvent.BDADDR(), *this);
       
  1120 	}
       
  1121 
       
  1122 void CHCIFacade::LinkKeyRequestEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1123 	{
       
  1124 	LOG_FUNC
       
  1125 	const TLinkKeyRequestEvent& linkKeyRequestEvent = TLinkKeyRequestEvent::Cast(aEvent);
       
  1126 
       
  1127 	// Tell the Connections Manager
       
  1128 	// this is something the Connections look after - they can tell the Registry when they want of the new key
       
  1129 	iLinksMgr->LinkKeyRequest(linkKeyRequestEvent.BDADDR(), *this);
       
  1130 	}
       
  1131 
       
  1132 void CHCIFacade::LinkKeyNotificationEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1133 	{
       
  1134 	LOG_FUNC
       
  1135 	const TLinkKeyNotificationEvent& linkKeyNotEvent = TLinkKeyNotificationEvent::Cast(aEvent);
       
  1136 
       
  1137 	// Tell the Connections Manager
       
  1138 	// this is something the Connections look after - they can tell the Registry when they want of the new key
       
  1139 	iLinksMgr->NewLinkKey(linkKeyNotEvent.BDADDR(), linkKeyNotEvent.LinkKey(), static_cast<THCILinkKeyType>(linkKeyNotEvent.KeyType()));
       
  1140 	}
       
  1141 
       
  1142 void CHCIFacade::MaxSlotsChangeEvent(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
  1143 	{
       
  1144 	LOG_FUNC
       
  1145 	const TMaxSlotsChangeEvent& maxSlotsChangeEvent = TMaxSlotsChangeEvent::Cast(aEvent);
       
  1146 
       
  1147 	LOG(_L("Link [HCIFacade_Events.cpp]: MaxSlotsChangeEvent"));
       
  1148 	iLinksMgr->MaxSlotsChange(maxSlotsChangeEvent.ConnectionHandle(), maxSlotsChangeEvent.LMPMaxSlots());
       
  1149 	}
       
  1150 
       
  1151 // ----------------------------------------------------------------------------
       
  1152 // Data event processing functions
       
  1153 // ----------------------------------------------------------------------------
       
  1154 
       
  1155 void CHCIFacade::NumberOfCompletedPacketsEvent(THCIEventBase& aEvent)
       
  1156 /**
       
  1157 	Packets sent by HC to remote device.
       
  1158 	For informational scheduling purposes, this connection handle just
       
  1159 	cleared its oldest aNum packets.
       
  1160 **/
       
  1161 	{
       
  1162 	LOG_FUNC
       
  1163 	const TNumberOfCompletedPacketsEvent& numCompletedPacketsEvent = TNumberOfCompletedPacketsEvent::Cast(aEvent);
       
  1164 	TUint numPackets;
       
  1165 
       
  1166 	TUint numHandles = numCompletedPacketsEvent.NumberofHandles();
       
  1167 	for (TUint index = 0; index < numHandles; index++)
       
  1168 		{
       
  1169 		numPackets = numCompletedPacketsEvent.HCNumOfCompletedPackets(index);
       
  1170 		
       
  1171 		LOG1(_L("HCIFacade: Notifying DataQ Controller of %d Completed packets"), numPackets);
       
  1172 
       
  1173 		iLinksMgr->CompletedPackets(numCompletedPacketsEvent.ConnectionHandle(index), numPackets);
       
  1174 		}
       
  1175 	}
       
  1176 
       
  1177 // ----------------------------------------------------------------------------
       
  1178 // HCI APIs
       
  1179 // ----------------------------------------------------------------------------
       
  1180 
       
  1181 // MHCICommandQueueClient
       
  1182 void CHCIFacade::MhcqcCommandEventReceived(const THCIEventBase& aEvent,
       
  1183 										   const CHCICommandBase* aRelatedCommand)
       
  1184 	{
       
  1185 	LOG_FUNC
       
  1186 	switch(aEvent.EventCode())
       
  1187 		{
       
  1188 	case EConnectionCompleteEvent:
       
  1189 		ConnectionCompleteEvent(aEvent, aRelatedCommand);
       
  1190 		break;
       
  1191 		
       
  1192 	case EAuthenticationCompleteEvent:
       
  1193 		AuthenticationCompleteEvent(aEvent, aRelatedCommand);
       
  1194 		break;
       
  1195 		
       
  1196 	case EReadRemSuppFeatCompleteEvent:
       
  1197 		ReadRemSuppFeatCompleteEvent(aEvent, aRelatedCommand);
       
  1198 		break;
       
  1199 	
       
  1200 	case EReadRemoteExtendedFeaturesCompleteEvent:
       
  1201 		ReadRemoteExtendedFeaturesCompleteEvent(aEvent, aRelatedCommand);
       
  1202 		break;
       
  1203 		
       
  1204 	case EReadRemVerInfoCompleteEvent:
       
  1205 		ReadRemVerInfoCompleteEvent(aEvent, aRelatedCommand);
       
  1206 		break;
       
  1207 		
       
  1208 	case ECommandCompleteEvent:
       
  1209 		{
       
  1210 		const THCICommandCompleteEvent* completeEvent = reinterpret_cast<const THCICommandCompleteEvent*>(&aEvent);
       
  1211 		CommandCompleteEvent(completeEvent->CommandOpcode(), aEvent.ErrorCode(), &aEvent, aRelatedCommand);
       
  1212 		break;
       
  1213 		}
       
  1214 		
       
  1215 	case ECommandStatusEvent:
       
  1216 		CommandStatusEvent(aEvent, aRelatedCommand);
       
  1217 		break;
       
  1218 		
       
  1219 	case EReadClockOffsetEvent:
       
  1220 		ReadClockOffsetEvent(aEvent, aRelatedCommand);
       
  1221 		break;
       
  1222 		
       
  1223 	case EConnectionPacketTypeChangedEvent:
       
  1224 		ConnectionPacketTypeChangedEvent(aEvent, aRelatedCommand);
       
  1225 		break;
       
  1226 		
       
  1227 	case ELinkSupervisionTimeoutChangedEvent:
       
  1228 		LinkSupervisionTimeoutChangedEvent(aEvent, aRelatedCommand);
       
  1229 		break;
       
  1230 		
       
  1231 	case ESynchronousConnectionCompleteEvent:
       
  1232 		SynchronousConnectionCompleteEvent(aEvent, aRelatedCommand);
       
  1233 		break;
       
  1234 		
       
  1235 	case EConnectionRequestEvent:
       
  1236 		ConnectionRequestEvent(aEvent, aRelatedCommand);
       
  1237 		break;
       
  1238 		
       
  1239 	case EDisconnectionCompleteEvent:
       
  1240 		DisconnectionCompleteEvent(aEvent, aRelatedCommand);
       
  1241 		break;
       
  1242 		
       
  1243 	case EEncryptionChangeEvent:
       
  1244 		EncryptionChangeEvent(aEvent, aRelatedCommand);
       
  1245 		break;
       
  1246 		
       
  1247 	case EHardwareErrorEvent:
       
  1248 		HardwareErrorEvent(aEvent, aRelatedCommand);
       
  1249 		break;
       
  1250 		
       
  1251 	case ERoleChangeEvent:
       
  1252 		RoleChangeEvent(aEvent, aRelatedCommand);
       
  1253 		break;
       
  1254 		
       
  1255 	case EModeChangeEvent:
       
  1256 		ModeChangeEvent(aEvent, aRelatedCommand);
       
  1257 		break;
       
  1258 		
       
  1259 	case EPINCodeRequestEvent:
       
  1260 		PINCodeRequestEvent(aEvent, aRelatedCommand);
       
  1261 		break;
       
  1262 		
       
  1263 	case ELinkKeyRequestEvent:
       
  1264 		LinkKeyRequestEvent(aEvent, aRelatedCommand);
       
  1265 		break;
       
  1266 		
       
  1267 	case ELinkKeyNotificationEvent:
       
  1268 		LinkKeyNotificationEvent(aEvent, aRelatedCommand);
       
  1269 		break;
       
  1270 		
       
  1271 	case EMaxSlotsChangeEvent:
       
  1272 		MaxSlotsChangeEvent(aEvent, aRelatedCommand);
       
  1273 		break;
       
  1274 
       
  1275 	case EVendorDebugEvent:
       
  1276 		VendorDebugEvent(aEvent, aRelatedCommand);
       
  1277 		break;
       
  1278 
       
  1279 	// Inquiry based events.
       
  1280 	// By default these should be caused by the inquiry manager and so be returned to it.
       
  1281 	case EInquiryCompleteEvent:
       
  1282 	case EInquiryResultEvent:
       
  1283 	case EInquiryResultwithRSSIEvent:
       
  1284 	case EExtendedInquiryResultEvent:
       
  1285 	case ERemoteNameReqCompleteEvent:
       
  1286 	case ERemoteHostSupportedFeaturesNotificationEvent:
       
  1287 		FTRACE(FPrint(_L("Error!! Unsolicited inquiry-type event (event code:%d)"), aEvent.EventCode()));
       
  1288 		__ASSERT_DEBUG(EFalse, Panic(EHCIUnmatchedInquiryEvent));
       
  1289 		break;
       
  1290 
       
  1291 	// Security based events.
       
  1292 	case EIOCapabilityRequestEvent:
       
  1293 	case EIOCapabilityResponseEvent:
       
  1294 	case EUserConfirmationRequestEvent:
       
  1295 	case ERemoteOOBDataRequestEvent:
       
  1296 	case ESimplePairingCompleteEvent:
       
  1297 	case EUserPasskeyNotificationEvent:
       
  1298 	case EKeypressNotificationEvent:
       
  1299 		iLinksMgr->SecMan().HCIEventHandler().MhcqcCommandEventReceived(aEvent, aRelatedCommand);
       
  1300 		break;
       
  1301 
       
  1302 	// Catch all the events we do not handle
       
  1303 	case EChangeLinkKeyEvent:
       
  1304 	case EMasterLinkKeyEvent:
       
  1305 	case EQOSSetupCompleteEvent:
       
  1306 	case EReturnLinkKeysEvent:
       
  1307 	case EFlowSpecificationCompleteEvent:
       
  1308 	case ESynchronousConnectionChangedEvent:
       
  1309 	case ELoopbackCommandEvent:
       
  1310 	case EPageScanModeChangeEvent:
       
  1311 	case EPageScanRepetitionModeChangeEvent:
       
  1312 	case EUserPasskeyRequestEvent:
       
  1313 	case EEncryptionKeyRefreshCompleteEvent:		
       
  1314 		LOG1(_L("Warning!! Unhandled Command Event (event code:%d)"), aEvent.EventCode());
       
  1315 		break;
       
  1316 		
       
  1317 	default:
       
  1318 		LOG1(_L("Warning!! Unknown Command Event Received (event code:%d)"), aEvent.EventCode());
       
  1319 		__ASSERT_DEBUG(EFalse, Panic(EHCIUnknownCommandEvent));
       
  1320 		break;
       
  1321 		}
       
  1322 	}
       
  1323 
       
  1324 void CHCIFacade::MhcqcCommandErrored(TInt aErrorCode, const CHCICommandBase* aCommand)
       
  1325 	{
       
  1326 	LOG_FUNC
       
  1327 	LOG1(_L("MhcqcCommandErrored: error code:%d"), aErrorCode);
       
  1328 
       
  1329 	// The stack maybe in a state that requires a response from the errored command so
       
  1330 	// fake up a command status event. This will be correctly processed by the stack even if the 
       
  1331 	// errored command was not expecting a command status event.
       
  1332 	if (aCommand != NULL)
       
  1333 		{
       
  1334 		LOG1(_L("... associated Command (opcode=%d)"), aCommand->Opcode());
       
  1335 
       
  1336 		THCIErrorCode err(ECommandDisallowed);		
       
  1337 		if ((aErrorCode < KHCIErrorBase) && (aErrorCode > (KHCIErrorBase - static_cast<TInt>(KMaxTUint8)))) // error code is 8bits
       
  1338 			{
       
  1339 			// aErrorCode is an HCI Error, use it to inform stack
       
  1340 			err = (THCIErrorCode) (KHCIErrorBase - aErrorCode);
       
  1341 			}
       
  1342 			
       
  1343 		if (iInitState != EInitialised)
       
  1344 			{
       
  1345 			__ASSERT_ALWAYS(iOutstandingCommands.Count(), Panic(EHCICtrlrInitNoOutstandingCmds));
       
  1346 			iInitialisationError = ETrue;
       
  1347 			}
       
  1348 		
       
  1349 		TBuf8<256> fakeCommandStatusBuffer;
       
  1350 		TCommandStatusEvent fakeCommandStatusEvent(err, 1, aCommand->Opcode(), fakeCommandStatusBuffer);
       
  1351 		MhcqcCommandEventReceived(fakeCommandStatusEvent, aCommand);
       
  1352 		
       
  1353 		}
       
  1354 	}
       
  1355 
       
  1356 // MHCIDataEventObserver
       
  1357 void CHCIFacade::MhdeoEventNotification(THCIEventBase& aEvent)
       
  1358 	{
       
  1359 	LOG_FUNC
       
  1360 	switch(aEvent.EventCode())
       
  1361 		{
       
  1362 	case ENumberOfCompletedPacketsEvent:
       
  1363 		NumberOfCompletedPacketsEvent(aEvent);
       
  1364 		break;
       
  1365 		
       
  1366 	case EFlushOccurredEvent:
       
  1367 		LOG(_L("Link [HCIFacade_Events.cpp]: FlushOccuredEvent - NOT HANDLED"));
       
  1368 		break;
       
  1369 		
       
  1370 	case EDataBufferOverflowEvent:
       
  1371 		Panic(ELinkMgrOverflowedHostController);  // this is really bad - out HC modelling has gone wrong...
       
  1372 		break;
       
  1373 		
       
  1374 	case EQOSViolationEvent:
       
  1375 		LOG(_L("Link [HCIFacade_Events.cpp]: Warning!! Unhandled QOSViolationEvent"));
       
  1376 		// we don't do QOS at the moment -drop
       
  1377 		break;
       
  1378 		
       
  1379 	default:
       
  1380 		LOG(_L("HCIFacade: Warning!! Unknown Data Event Received"));
       
  1381 		__ASSERT_DEBUG(EFalse, Panic(EHCIUnknownDataEvent));
       
  1382 		break;
       
  1383 		}
       
  1384 	}
       
  1385 
       
  1386