bluetooth/btstack/secman/secmanhci.cpp
changeset 0 29b1cd4cb562
child 16 9f17f914e828
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 1999-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 //
       
    15 
       
    16 #include <bluetooth/logger.h>
       
    17 
       
    18 #include "secman.h"
       
    19 #include "linkutil.h"
       
    20 
       
    21 #include <bluetooth/hcicommandqueue.h>
       
    22 
       
    23 #include <bluetooth/hci/event.h>
       
    24 #include <bluetooth/hci/writesimplepairingmodecommand.h>
       
    25 #include <bluetooth/hci/writesimplepairingdebugmodecommand.h>
       
    26 #include <bluetooth/hci/iocapabilityrequestreplycommand.h>
       
    27 #include <bluetooth/hci/iocapabilityrequestnegativereplycommand.h>
       
    28 #include <bluetooth/hci/iocapabilityrequestnegativereplycommand.h>
       
    29 #include <bluetooth/hci/userconfirmationrequestreplycommand.h>
       
    30 #include <bluetooth/hci/userconfirmationrequestnegativereplycommand.h>
       
    31 #include <bluetooth/hci/remoteoobdatarequestreplycommand.h>
       
    32 #include <bluetooth/hci/remoteoobdatarequestnegativereplycommand.h>
       
    33 #include <bluetooth/hci/readlocaloobdatacommand.h>
       
    34 
       
    35 #include <bluetooth/hci/commandcompleteevent.h>
       
    36 #include <bluetooth/hci/commandstatusevent.h>
       
    37 
       
    38 #include <bluetooth/hci/iocapabilityrequestevent.h>
       
    39 #include <bluetooth/hci/iocapabilityresponseevent.h>
       
    40 #include <bluetooth/hci/userconfirmationrequestevent.h>
       
    41 #include <bluetooth/hci/userpasskeynotificationevent.h>
       
    42 #include <bluetooth/hci/remoteoobdatarequestevent.h>
       
    43 #include <bluetooth/hci/simplepairingcompleteevent.h>
       
    44 #include <bluetooth/hci/keypressnotificationevent.h>
       
    45 #include <bluetooth/hci/remotehostsupportedfeaturesnotificationevent.h>
       
    46 
       
    47 #include <bluetooth/hci/writesimplepairingdebugmodecompleteevent.h>
       
    48 
       
    49 #include <bluetooth/hci/readlocaloobdatacompleteevent.h>
       
    50 #include <bluetooth/hci/remoteoobdatarequestreplycompleteevent.h>
       
    51 #include <bluetooth/hci/remoteoobdatarequestnegativereplycompleteevent.h>
       
    52 
       
    53 
       
    54 #ifdef __FLOG_ACTIVE
       
    55 _LIT8(KLogComponent, LOG_COMPONENT_SECMAN);
       
    56 #endif
       
    57 
       
    58 
       
    59 // ------------------------------------------------------------------------
       
    60 // class CSecManCommandController
       
    61 // ------------------------------------------------------------------------
       
    62 
       
    63 CSecManCommandController::CSecManCommandController(CBTSecMan& aSecMan)
       
    64 	: iSecMan(aSecMan)
       
    65 	{
       
    66 	LOG_FUNC
       
    67 	}
       
    68 
       
    69 CSecManCommandController* CSecManCommandController::NewL(CBTSecMan& aSecMan)
       
    70 	{
       
    71 	LOG_STATIC_FUNC
       
    72 	CSecManCommandController* self = CSecManCommandController::NewLC(aSecMan);
       
    73 	CleanupStack::Pop(self);
       
    74 	return self;
       
    75 	}
       
    76 
       
    77 CSecManCommandController* CSecManCommandController::NewLC(CBTSecMan& aSecMan)
       
    78 	{
       
    79 	LOG_STATIC_FUNC
       
    80 	CSecManCommandController* self = new(ELeave) CSecManCommandController(aSecMan);
       
    81 	CleanupStack::PushL(self);
       
    82 	self->ConstructL();
       
    83 	return self;
       
    84 	}
       
    85 
       
    86 void CSecManCommandController::ConstructL()
       
    87 	{
       
    88 	LOG_FUNC
       
    89 	}
       
    90 
       
    91 CSecManCommandController::~CSecManCommandController()
       
    92 	{
       
    93 	LOG_FUNC
       
    94 	ClearHCICommandQueue();
       
    95 	}
       
    96 
       
    97 void CSecManCommandController::SetHCICommandQueue(MHCICommandQueue& aCommandQueue)
       
    98 	{
       
    99 	LOG_FUNC
       
   100 	__ASSERT_DEBUG(!iCommandQueue, PANIC(KBTSecPanic, EBTSecCommandQueueAlreadyProvided));
       
   101 	iCommandQueue = &aCommandQueue;
       
   102 	}
       
   103 
       
   104 void CSecManCommandController::ClearHCICommandQueue()
       
   105 	{
       
   106 	LOG_FUNC
       
   107 	if(iCommandQueue)
       
   108 		{
       
   109 		iCommandQueue->MhcqRemoveAllCommands(*this);
       
   110 		}
       
   111 	iCommandQueue = NULL;
       
   112 	}
       
   113 
       
   114 MHCICommandQueue& CSecManCommandController::CommandQueue() const
       
   115 	{
       
   116 	LOG_FUNC
       
   117 	__ASSERT_DEBUG(iCommandQueue, PANIC(KBTSecPanic, EBTSecCommandQueueNotAvailable));
       
   118 	return *iCommandQueue;
       
   119 	}
       
   120 
       
   121 void CSecManCommandController::WriteSimplePairingModeL(TUint8 aSimplePairingMode)
       
   122 	{
       
   123 	LOG_FUNC
       
   124 	// Ownership of cmd transfered
       
   125 	CWriteSimplePairingModeCommand* cmd = CWriteSimplePairingModeCommand::NewL(aSimplePairingMode);
       
   126 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   127 	}
       
   128 
       
   129 void CSecManCommandController::WriteSimplePairingDebugModeL(TUint8 aSimplePairingDebugMode)
       
   130 	{
       
   131 	LOG_FUNC
       
   132 	// Ownership of cmd transfered
       
   133 	CWriteSimplePairingDebugModeCommand* cmd = CWriteSimplePairingDebugModeCommand::NewL(aSimplePairingDebugMode);
       
   134 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   135 	}
       
   136 
       
   137 void CSecManCommandController::IOCapabilityRequestReplyL(const TBTDevAddr& aBDADDR,
       
   138 											THCIIoCapability aIOCapability,
       
   139 											THCIOobDataPresence aOOBDataPresent,
       
   140 											THCIAuthenticationRequirement aAuthenticationRequirements)
       
   141 	{
       
   142 	LOG_FUNC
       
   143 	// Ownership of cmd transfered
       
   144 	CIOCapabilityRequestReplyCommand* cmd = CIOCapabilityRequestReplyCommand::NewL(aBDADDR, aIOCapability, aOOBDataPresent, aAuthenticationRequirements);
       
   145 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   146 	}
       
   147 
       
   148 void CSecManCommandController::IOCapabilityRequestNegativeReplyL(const TBTDevAddr& aBDADDR, TUint8 aReason)
       
   149 	{
       
   150 	// Ownership of cmd transfered
       
   151 	CIOCapabilityRequestNegativeReplyCommand* cmd = CIOCapabilityRequestNegativeReplyCommand::NewL(aBDADDR, aReason);
       
   152 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   153 	}
       
   154 
       
   155 void CSecManCommandController::UserConfirmationRequestReplyL(const TBTDevAddr& aBDADDR)
       
   156 	{
       
   157 	LOG_FUNC
       
   158 	// Ownership of cmd transfered
       
   159 	CUserConfirmationRequestReplyCommand* cmd = CUserConfirmationRequestReplyCommand::NewL(aBDADDR);
       
   160 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   161 	}
       
   162 
       
   163 void CSecManCommandController::UserConfirmationRequestNegativeReplyL(const TBTDevAddr& aBDADDR)
       
   164 	{
       
   165 	LOG_FUNC
       
   166 	// Ownership of cmd transfered
       
   167 	CUserConfirmationRequestNegativeReplyCommand* cmd = CUserConfirmationRequestNegativeReplyCommand::NewL(aBDADDR);
       
   168 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   169 	}
       
   170 
       
   171 void CSecManCommandController::RemoteOOBDataRequestReplyL(const TBTDevAddr& aBDADDR,
       
   172 											const TBluetoothSimplePairingHash& aC,
       
   173 											const TBluetoothSimplePairingRandomizer& aR)
       
   174 	{
       
   175 	LOG_FUNC
       
   176 	// Ownership of cmd transfered
       
   177 	CRemoteOOBDataRequestReplyCommand* cmd = CRemoteOOBDataRequestReplyCommand::NewL(aBDADDR, aC, aR);
       
   178 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   179 	}
       
   180 
       
   181 void CSecManCommandController::RemoteOOBDataRequestNegativeReplyL(const TBTDevAddr& aBDADDR)
       
   182 	{
       
   183 	LOG_FUNC
       
   184 	CRemoteOOBDataRequestNegativeReplyCommand* cmd = CRemoteOOBDataRequestNegativeReplyCommand::NewL(aBDADDR);
       
   185 	// Ownership of cmd transfered
       
   186 	CommandQueue().MhcqAddCommandL(cmd, *this);
       
   187 	}
       
   188 
       
   189 void CSecManCommandController::MhcqcCommandErrored(TInt IF_FLOGGING(aErrorCode), const CHCICommandBase* __DEBUG_ONLY(aCommand))
       
   190 	{
       
   191 	LOG_FUNC
       
   192 	__ASSERT_DEBUG(aCommand, PANIC(KBTSecPanic, EBTSecNoCommandAssociatedWithErrorEvent)); // this should never happen
       
   193 	
       
   194 	#ifdef _DEBUG
       
   195 	LOG2(_L("error code:%d opcode:0x%04x"), aErrorCode, aCommand->Opcode());
       
   196 	#else
       
   197 	LOG1(_L("error code:%d"), aErrorCode);
       
   198 	#endif
       
   199 	}
       
   200 
       
   201 // -----------------------------------------------------------------------------------------
       
   202 
       
   203 // From MHCICommandQueueClient
       
   204 void CSecManCommandController::MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* /*aRelatedCommand*/)
       
   205 	{
       
   206 	LOG_FUNC
       
   207 	switch(aEvent.EventCode())
       
   208 		{
       
   209 	case ECommandCompleteEvent:
       
   210 		{
       
   211 		CommandCompleteEvent(aEvent);
       
   212 		break;
       
   213 		}
       
   214 		
       
   215 	case ECommandStatusEvent:
       
   216 		CommandStatusEvent(aEvent);
       
   217 		break;
       
   218 		
       
   219 	case EIOCapabilityRequestEvent:
       
   220 		IOCapabilityRequestEvent(aEvent);
       
   221 		break;
       
   222 		
       
   223 	case EIOCapabilityResponseEvent:
       
   224 		IOCapabilityResponseEvent(aEvent);
       
   225 		break;
       
   226 		
       
   227 	case EUserConfirmationRequestEvent:
       
   228 		UserConfirmationRequestEvent(aEvent);
       
   229 		break;
       
   230 		
       
   231 	case EUserPasskeyRequestEvent:
       
   232 		// Symbian devices are assumed to be DisplayYesNo statically.
       
   233 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecBadUserPasskeyRequest));
       
   234 		break;
       
   235 		
       
   236 	case EUserPasskeyNotificationEvent:
       
   237 		UserPasskeyNotificationEvent(aEvent);
       
   238 		break;
       
   239 		
       
   240 	case ERemoteOOBDataRequestEvent:
       
   241 		RemoteOOBDataRequestEvent(aEvent);
       
   242 		break;
       
   243 		
       
   244 	case EKeypressNotificationEvent:
       
   245 		KeypressNotificationEvent(aEvent);
       
   246 		break;
       
   247 		
       
   248 	case ESimplePairingCompleteEvent:
       
   249 		SimplePairingCompleteEvent(aEvent);
       
   250 		break;
       
   251 
       
   252 	default:
       
   253 		LOG1(_L("Warning!! Unknown Command Event Received (event code: %d)"), aEvent.EventCode());
       
   254 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecUnknownHCIEvent));
       
   255 		break;
       
   256 		}
       
   257 	}
       
   258 
       
   259 void CSecManCommandController::IOCapabilityRequestEvent(const THCIEventBase& aEvent)
       
   260 	{
       
   261 	LOG_FUNC
       
   262 	const TIOCapabilityRequestEvent& event = TIOCapabilityRequestEvent::Cast(aEvent);
       
   263 	iSecMan.IOCapabilityRequestFromRemote(event.BDADDR());
       
   264 	}
       
   265 
       
   266 void CSecManCommandController::IOCapabilityResponseEvent(const THCIEventBase& aEvent)
       
   267 	{
       
   268 	LOG_FUNC
       
   269 	const TIOCapabilityResponseEvent& event = TIOCapabilityResponseEvent::Cast(aEvent);
       
   270 	iSecMan.IOCapabilityAskForResponse(event.BDADDR(), CastToIoCapability(event.IOCapability()), CastToOobDataPresence(event.OOBDataPresent()), CastToAuthenticationRequirements(event.AuthenticationRequirements()));
       
   271 	}
       
   272 
       
   273 void CSecManCommandController::UserConfirmationRequestEvent(const THCIEventBase& aEvent)
       
   274 	{
       
   275 	LOG_FUNC
       
   276 	const TUserConfirmationRequestEvent& event = TUserConfirmationRequestEvent::Cast(aEvent);
       
   277 	iSecMan.UserConfirmationRequest(event.BDADDR(), event.NumericValue());
       
   278 	}
       
   279 
       
   280 void CSecManCommandController::UserPasskeyNotificationEvent(const THCIEventBase& aEvent)
       
   281 	{
       
   282 	LOG_FUNC
       
   283 	const TUserPasskeyNotificationEvent& event = TUserPasskeyNotificationEvent::Cast(aEvent);
       
   284 	iSecMan.PasskeyNotification(event.BDADDR(), event.Passkey());
       
   285 	}
       
   286 
       
   287 void CSecManCommandController::RemoteOOBDataRequestEvent(const THCIEventBase& aEvent)
       
   288 	{
       
   289 	LOG_FUNC
       
   290 	const TRemoteOOBDataRequestEvent& event = TRemoteOOBDataRequestEvent::Cast(aEvent);
       
   291 	iSecMan.RemoteOOBDataRequest(event.BDADDR());
       
   292 	}
       
   293 
       
   294 void CSecManCommandController::SimplePairingCompleteEvent(const THCIEventBase& aEvent)
       
   295 	{
       
   296 	LOG_FUNC
       
   297 	const TSimplePairingCompleteEvent& spevent = TSimplePairingCompleteEvent::Cast(aEvent);
       
   298 	iSecMan.SimplePairingComplete(spevent.BDADDR(), aEvent.ErrorCode());
       
   299 	}
       
   300 
       
   301 void CSecManCommandController::KeypressNotificationEvent(const THCIEventBase& aEvent)
       
   302 	{
       
   303 	LOG_FUNC
       
   304 	const TKeypressNotificationEvent& event = TKeypressNotificationEvent::Cast(aEvent);
       
   305 	iSecMan.KeypressNotification(event.BDADDR(), event.NotificationType());
       
   306 	}
       
   307 
       
   308 
       
   309 void CSecManCommandController::CommandCompleteEvent(const THCIEventBase& aEvent)
       
   310 	{
       
   311 	LOG_FUNC
       
   312 	const THCICommandCompleteEvent& completeEvent = THCICommandCompleteEvent::Cast(aEvent);
       
   313 	THCIOpcode opcode = completeEvent.CommandOpcode();
       
   314 	THCIErrorCode hciErr = aEvent.ErrorCode();
       
   315 	
       
   316 	switch (opcode)
       
   317 		{
       
   318 	case KWriteSimplePairingModeOpcode:
       
   319 		WriteSimplePairingModeOpcode(completeEvent);
       
   320 		break;
       
   321 		
       
   322 	case KRemoteOOBDataRequestReplyOpcode:
       
   323 		RemoteOOBDataRequestReplyOpcode(completeEvent);
       
   324 		break;
       
   325 		
       
   326 	case KRemoteOOBDataRequestNegativeReplyOpcode:
       
   327 		RemoteOOBDataRequestNegativeReplyOpcode(completeEvent);
       
   328 		break;
       
   329 		
       
   330 	case KIOCapabilityRequestReplyOpcode:
       
   331 		// Check bdaddr
       
   332 		break;
       
   333 		
       
   334 	case KWriteSimplePairingDebugModeOpcode:
       
   335 		WriteSimplePairingDebugModeOpcode(completeEvent);
       
   336 		break;
       
   337 	
       
   338 	// Need to handle link key request reply...
       
   339 	// Need to complete link key request negative reply
       
   340 	// Pin code request reply
       
   341 	case KIOCapabilityRequestNegativeReplyOpcode:
       
   342 	case KUserConfirmationRequestReplyOpcode:
       
   343 		// check bdaddr.
       
   344 	case KUserConfirmationRequestNegativeReplyOpcode:
       
   345 		// check bdadrr
       
   346 	case KUserPasskeyRequestReplyOpcode:
       
   347 	case KUserPasskeyRequestNegativeReplyOpcode:
       
   348 		// Catch all the events we do not handle
       
   349 		LOG1(_L("Warning!! Unhandled Command Complete Event (opcode: %d)"), opcode);
       
   350 		break;
       
   351 	
       
   352 	default:
       
   353 		LOG2(_L("Link [HCIFacade_Events.cpp]: Warning: Unknown Command complete event! Opcode %d error code %d"), opcode, hciErr);
       
   354 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecUnknownHCICommandCompleteOpcode));
       
   355 		break;
       
   356 		}
       
   357 	}
       
   358 
       
   359 void CSecManCommandController::CommandStatusEvent(const THCIEventBase& aEvent)
       
   360 	{
       
   361 	LOG_FUNC
       
   362 	const TCommandStatusEvent& commandStatusEvent = TCommandStatusEvent::Cast(aEvent);
       
   363 	THCIOpcode opcode = commandStatusEvent.CommandOpcode();
       
   364 	THCIErrorCode hciErr = commandStatusEvent.ErrorCode();
       
   365 	}
       
   366 
       
   367 void CSecManCommandController::WriteSimplePairingModeOpcode(const THCICommandCompleteEvent& aCompleteEvent)
       
   368 	{
       
   369 	LOG_FUNC
       
   370 	if(aCompleteEvent.ErrorCode() == EOK)
       
   371 		{
       
   372 		iSecMan.SetLocalSimplePairingMode(ETrue);
       
   373 		}
       
   374 	// if we got an error then we make the reasonable assumption that the local controller is not
       
   375 	// capable of secure simple pairing.
       
   376 	}
       
   377 
       
   378 void CSecManCommandController::RemoteOOBDataRequestReplyOpcode(const THCICommandCompleteEvent& aCompleteEvent)
       
   379 	{
       
   380 	LOG_FUNC
       
   381 	const TRemoteOOBDataRequestReplyCompleteEvent& event = TRemoteOOBDataRequestReplyCompleteEvent::Cast(aCompleteEvent);
       
   382 	iSecMan.RemoteOOBDataRequestComplete(event.BDADDR());
       
   383 	}
       
   384 
       
   385 void CSecManCommandController::RemoteOOBDataRequestNegativeReplyOpcode(const THCICommandCompleteEvent& aCompleteEvent)
       
   386 	{
       
   387 	LOG_FUNC
       
   388 	const TRemoteOOBDataRequestNegativeReplyCompleteEvent& event = TRemoteOOBDataRequestNegativeReplyCompleteEvent::Cast(aCompleteEvent);
       
   389 	iSecMan.RemoteOOBDataRequestComplete(event.BDADDR());
       
   390 	}
       
   391 
       
   392 void CSecManCommandController::WriteSimplePairingDebugModeOpcode(const THCICommandCompleteEvent& aCompleteEvent)
       
   393 	{
       
   394 	LOG_FUNC
       
   395 	const TWriteSimplePairingDebugModeCompleteEvent& event = TWriteSimplePairingDebugModeCompleteEvent::Cast(aCompleteEvent);
       
   396 	if(event.ErrorCode() == EOK)
       
   397 		{
       
   398 		iSecMan.DebugModeChanged(ETrue);
       
   399 		}
       
   400 	// ignore errors - debug mode remains the same
       
   401 	}
       
   402 	
       
   403 THCIIoCapability CSecManCommandController::CastToIoCapability(TUint8 aIOCapability)
       
   404 	{
       
   405 	LOG_STATIC_FUNC
       
   406 	switch(aIOCapability)
       
   407 		{
       
   408 	case EIOCapsDisplayOnly:
       
   409 	case EIOCapsDisplayYesNo:
       
   410 	case EIOCapsKeyboardOnly:
       
   411 	case EIOCapsNoInputNoOutput:
       
   412 		// All valid understood values.
       
   413 		break;
       
   414 	default:
       
   415 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecUnexpectedIoCapability));
       
   416 		break;
       
   417 		}
       
   418 	return static_cast<THCIIoCapability>(aIOCapability);
       
   419 	}
       
   420 
       
   421 THCIOobDataPresence CSecManCommandController::CastToOobDataPresence(TUint8 aOOBDataPresent)
       
   422 	{
       
   423 	LOG_STATIC_FUNC
       
   424 	switch(aOOBDataPresent)
       
   425 		{
       
   426 	case EOOBDataNotPresent:
       
   427 	case EOOBDataPresent:
       
   428 		// All valid understood values.
       
   429 		break;
       
   430 	default:
       
   431 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecUnexpectedOobDataPresence));
       
   432 		break;
       
   433 		}
       
   434 	return static_cast<THCIOobDataPresence>(aOOBDataPresent);
       
   435 	}
       
   436 	
       
   437 THCIAuthenticationRequirement CSecManCommandController::CastToAuthenticationRequirements(TUint8 aAuthenticationRequirements)
       
   438 	{
       
   439 	LOG_STATIC_FUNC
       
   440 	switch(aAuthenticationRequirements)
       
   441 		{
       
   442 	case EMitmNotReqNoBonding:
       
   443 	case EMitmReqNoBonding:
       
   444 	case EMitmNotReqDedicatedBonding:
       
   445 	case EMitmReqDedicatedBonding:
       
   446 	case EMitmNotReqGeneralBonding:
       
   447 	case EMitmReqGeneralBonding:
       
   448 		// All valid understood values.
       
   449 		break;
       
   450 	default:
       
   451 		__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecUnexpectedAuthenticationRequirements));
       
   452 		break;
       
   453 		}
       
   454 	return static_cast<THCIAuthenticationRequirement>(aAuthenticationRequirements);
       
   455 	}
       
   456