bluetooth/btstack/secman/secman.cpp
changeset 0 29b1cd4cb562
child 8 2b6718f05bdb
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 
       
    17 #include <bluetooth/logger.h>
       
    18 
       
    19 #include <bluetooth/hci/hciutil.h>
       
    20 
       
    21 #include "secman.h"
       
    22 #include "secevent.h"
       
    23 #include "hostresolver.h"
       
    24 #include "pairingserver.h"
       
    25 #include "oobdata.h"
       
    26 #include "simplepairingresult.h"
       
    27 #include "btaccessrequesterstatemachine.h"
       
    28 
       
    29 #ifdef BT_LINKMGR_V2
       
    30 #include "physicallinks.h"
       
    31 #include "physicallinksmanager.h"
       
    32 #else
       
    33 #include "PhysicalLinks.h"
       
    34 #include "PhysicalLinksManager.h"
       
    35 #endif
       
    36 
       
    37 
       
    38 #ifdef __FLOG_ACTIVE
       
    39 _LIT8(KLogComponent, LOG_COMPONENT_SECMAN);
       
    40 #endif
       
    41 
       
    42 #ifdef _DEBUG
       
    43 PANICCATEGORY("secman");
       
    44 #endif
       
    45 
       
    46 static const TInt KBTSecManAccessRequesterArrayGranularity = 4;
       
    47 static const TInt KBTSecManNotifierRequesterArrayGranularity = 4;
       
    48 
       
    49 
       
    50 //------------------------------------------------------------------------//
       
    51 //class CBTSecMan
       
    52 //------------------------------------------------------------------------//
       
    53 
       
    54 CBTSecMan* CBTSecMan::NewL()
       
    55 	{
       
    56 	LOG_STATIC_FUNC
       
    57 	CBTSecMan* self = CBTSecMan::NewLC();
       
    58 	CleanupStack::Pop(self);
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 CBTSecMan* CBTSecMan::NewLC()
       
    63 	{
       
    64 	LOG_STATIC_FUNC
       
    65 	CBTSecMan* self = new(ELeave) CBTSecMan();
       
    66 	CleanupStack::PushL(self);
       
    67 	self->ConstructL();
       
    68 	return self;
       
    69 	}
       
    70 
       
    71 CBTSecMan::CBTSecMan()
       
    72 	: iAccessRequesters(KBTSecManAccessRequesterArrayGranularity)
       
    73 	, iPendingAccessRequesters(KBTSecManAccessRequesterArrayGranularity)
       
    74 	, iNotifierRequesters(KBTSecManNotifierRequesterArrayGranularity)
       
    75 	, iLocalSimplePairingMode(EFalse)
       
    76 	, iDebugMode (EFalse)
       
    77 	{
       
    78 	LOG_FUNC
       
    79 	}
       
    80 
       
    81 void CBTSecMan::ConstructL()
       
    82 	{
       
    83 	LOG_FUNC
       
    84 	iStateMachine = CBTAccessRequesterStateFactory::NewL();
       
    85 	iCommandController = CSecManCommandController::NewL(*this);
       
    86 	
       
    87 	iOobDataManager = COobDataManager::NewL(*this);
       
    88 	iSimplePairingResultList = CSimplePairingResultList::NewL();
       
    89 	iAuthenticationResultList = CAuthenticationResultList::NewL();
       
    90 	iPairingServer = CPairingServer::NewL(*iOobDataManager, *iSimplePairingResultList, *iAuthenticationResultList);
       
    91 	}
       
    92 
       
    93 void CBTSecMan::SetLocalSimplePairingMode(TBool aEnabled)
       
    94 	{
       
    95 	LOG_FUNC
       
    96 	iLocalSimplePairingMode=aEnabled;
       
    97 	}
       
    98 
       
    99 TBool CBTSecMan::LocalSimplePairingMode() const
       
   100 	{
       
   101 	LOG_FUNC
       
   102 	return iLocalSimplePairingMode;
       
   103 	}
       
   104 
       
   105 void CBTSecMan::SimplePairingSupportDetermined(const TBTDevAddr& aBDAddr)
       
   106 	{
       
   107 	LOG_FUNC
       
   108 
       
   109 	// Pending requesters must be notified first than the active requester. 
       
   110 	// Otherwise it wouldn't work properly and pending requesters would not be notified at all.
       
   111 	for (TInt i=0; i<iPendingAccessRequesters.Count(); i++)
       
   112 		{
       
   113 		CBTAccessRequester* requester = iPendingAccessRequesters[i];
       
   114 		if (requester->DeviceAddress() == aBDAddr && requester->BasebandConnected())
       
   115 			{
       
   116 			TBTSecEvent event(TBTSecEvent::EPhysicalLinkUp);
       
   117 			requester->SendEvent(event);
       
   118 			}	
       
   119 		}
       
   120 
       
   121 	CBTAccessRequester* requester = this->FindActiveAccessRequester(aBDAddr);
       
   122 	// There should only be one active access requester
       
   123 	if (requester && requester->BasebandConnected())
       
   124 		{
       
   125 		TBTSecEvent event(TBTSecEvent::EPhysicalLinkUp);
       
   126 		requester->SendEvent(event);
       
   127 		}
       
   128 	}
       
   129 
       
   130 void CBTSecMan::SetPhysicalLinksMgr(const CPhysicalLinksManager& aConnectionsMgr)
       
   131 	{
       
   132 	LOG_FUNC
       
   133 	iPhysicalLinksManager = &const_cast<CPhysicalLinksManager&>(aConnectionsMgr);
       
   134 	iPairingServer->SetPhysicalLinksManager(*iPhysicalLinksManager);
       
   135 	}
       
   136 
       
   137 void CBTSecMan::ClearPhysicalLinksMgr()
       
   138 	{
       
   139 	LOG_FUNC
       
   140 	iPhysicalLinksManager = NULL;
       
   141 	iPairingServer->ClearPhysicalLinkMgr();
       
   142 	}
       
   143 
       
   144 // Passes a reference to the LinksMgrProtocol ultimately to the PairingServer 
       
   145 void CBTSecMan::SetLinksMgrProtocol(CLinkMgrProtocol& aLinkMgrProtocol)
       
   146 	{
       
   147 	LOG_FUNC
       
   148 	iPairingServer->SetLinksMgrProtocol(aLinkMgrProtocol);
       
   149 	}
       
   150 
       
   151 void CBTSecMan::ClearLinksMgrProtocol()
       
   152 	{
       
   153 	LOG_FUNC
       
   154 	iPairingServer->ClearLinksMgrProtocol();
       
   155 	}
       
   156 
       
   157 void CBTSecMan::SetHCICommandQueue(MHCICommandQueue& aCommandQueue)
       
   158 	{
       
   159 	LOG_FUNC
       
   160 	iCommandController->SetHCICommandQueue(aCommandQueue);
       
   161 	iOobDataManager->SetHCICommandQueue(aCommandQueue);
       
   162 	}
       
   163 
       
   164 void CBTSecMan::ClearHCICommandQueue()
       
   165 	{
       
   166 	LOG_FUNC
       
   167 	iCommandController->ClearHCICommandQueue();
       
   168 	iOobDataManager->ClearHCICommandQueue();
       
   169 	}
       
   170 
       
   171 CPhysicalLinksManager& CBTSecMan::ConnectionsManager() const
       
   172 	{
       
   173 	LOG_FUNC
       
   174 	__ASSERT_ALWAYS(iPhysicalLinksManager, PANIC(KBTSecPanic,EBTSecNullPhysicalLinksManager));
       
   175 	return *iPhysicalLinksManager;
       
   176 	}
       
   177 
       
   178 COobDataManager& CBTSecMan::OobDataManager() const
       
   179 	{
       
   180 	LOG_FUNC
       
   181 	return *iOobDataManager;
       
   182 	}
       
   183 
       
   184 TBool CBTSecMan::DebugMode() const
       
   185 	{
       
   186 	LOG_FUNC
       
   187 	return iDebugMode;
       
   188 	}
       
   189 
       
   190 void CBTSecMan::SetDebugMode(TBool aOn)
       
   191 	{
       
   192 	LOG_FUNC
       
   193 	// SecMan owns the policy about simple pairing debug mode - here we only allow it to be 
       
   194 	// turned on.  So ignore any "off" requests.  (Stack must be unloaded for debug mode to be
       
   195 	// turned off).
       
   196 	if(aOn && !iDebugMode)
       
   197 		{
       
   198 		// First try to set debug mode. If we fail to send the command then we will just be
       
   199 		// stuck in non-debug mode...
       
   200 		static const TUint8 KSimplePairingDebugModeEnabled = 0x01;
       
   201 		TRAP_IGNORE(iCommandController->WriteSimplePairingDebugModeL(KSimplePairingDebugModeEnabled));
       
   202 		}
       
   203 	}
       
   204 
       
   205 void CBTSecMan::ClearDebugMode()
       
   206 	{
       
   207 	LOG_FUNC
       
   208 	// Used to clear debug mode when the stack is reset
       
   209 	iDebugMode = EFalse;
       
   210 	ConnectionsManager().SimplePairingDebugModeChanged(EFalse);
       
   211 	}
       
   212 
       
   213 void CBTSecMan::DebugModeChanged(TBool aOn)
       
   214 	{
       
   215 	__ASSERT_DEBUG(aOn, PANIC(KBTSecPanic, EBTSecDebugModeTurnedOff));
       
   216 	iDebugMode = aOn;
       
   217 	ConnectionsManager().SimplePairingDebugModeChanged(aOn);
       
   218 	}
       
   219 
       
   220 CBTSecMan::~CBTSecMan()
       
   221 	{
       
   222 	LOG_FUNC
       
   223 	
       
   224 	iAccessRequesters.ResetAndDestroy();
       
   225 	iAccessRequesters.Close();
       
   226 
       
   227 	iPendingAccessRequesters.ResetAndDestroy();
       
   228 	iPendingAccessRequesters.Close();
       
   229 	
       
   230 	iNotifierRequesters.ResetAndDestroy();
       
   231 	iNotifierRequesters.Close();
       
   232 	
       
   233 	delete iStateMachine;
       
   234 	delete iCommandController;
       
   235 	delete iPairingServer;
       
   236 	delete iOobDataManager;
       
   237 	delete iSimplePairingResultList;
       
   238 	delete iAuthenticationResultList;
       
   239 	}
       
   240 
       
   241 CBTAccessRequester* CBTSecMan::FindActiveAccessRequester(const TBTDevAddr& aAddr) const
       
   242 	{
       
   243 	LOG_FUNC
       
   244 	CBTAccessRequester* ret = NULL;
       
   245 	TInt ix = iAccessRequesters.Find(aAddr, CompareAccessRequesterByBDAddr);
       
   246 	if(ix >= 0)
       
   247 		{
       
   248 		ret = iAccessRequesters[ix];
       
   249 		}
       
   250 	return ret;
       
   251 	}
       
   252 
       
   253 TBool CBTSecMan::CompareAccessRequesterByBDAddr(const TBTDevAddr* aKey, const CBTAccessRequester& aAccessRequester)
       
   254 	{
       
   255 	LOG_STATIC_FUNC
       
   256 	return (!aKey || (*aKey) == aAccessRequester.DeviceAddress());
       
   257 	}
       
   258 
       
   259 TBool CBTSecMan::CompareAccessRequesterByRequester(const MAccessRequestResponseHandler* aKey, const CBTAccessRequester& aAccessRequester)
       
   260 	{
       
   261 	LOG_STATIC_FUNC
       
   262 	return aKey == &aAccessRequester.ServiceRequester();
       
   263 	}
       
   264 
       
   265 void CBTSecMan::AccessRequestL(const TBTServiceSecurity& aSecurity,
       
   266 							   const TBTServiceSecurityPerDevice* const aOverride,
       
   267 							   const TBTDevAddr& aBDAddr,
       
   268 							   TAccessType aAccessType,
       
   269 							   MAccessRequestResponseHandler& aRequester)
       
   270 /**
       
   271 Handle an access request...
       
   272 Create a new CBTAccessRequester object to handle the request.
       
   273 **/
       
   274 	{
       
   275 	LOG_FUNC
       
   276 
       
   277 #ifdef _DEBUG
       
   278 	// Check that a service isn't queuing multiple access requesters.
       
   279 	TInt ix = iAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   280 	__ASSERT_DEBUG(ix == KErrNotFound, PANIC(KBTSecPanic, EBTSecServiceTryingToQueueMultipleAccessRequesters));
       
   281 	ix = iPendingAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   282 	__ASSERT_DEBUG(ix == KErrNotFound, PANIC(KBTSecPanic, EBTSecServiceTryingToQueueMultipleAccessRequesters));
       
   283 #endif // _DEBUG
       
   284 
       
   285 	// find the baseband this SAP is running on
       
   286 	CPhysicalLink& con = *iPhysicalLinksManager->FindPhysicalLink(aBDAddr);
       
   287 	CBTAccessRequester* p = CBTAccessRequester::NewLC(con, aSecurity,
       
   288 													  aOverride,
       
   289 													  aRequester,
       
   290 													  aAccessType,
       
   291 													  *this);
       
   292 	
       
   293 	CBTAccessRequester* requester = FindActiveAccessRequester(aBDAddr);
       
   294 	if(requester)
       
   295 		{
       
   296 		User::LeaveIfError(iPendingAccessRequesters.Append(p));
       
   297 		CleanupStack::Pop(p); //clean up of p now handled by iPendingAccessRequesters
       
   298 		}
       
   299 	else
       
   300 		{
       
   301 		User::LeaveIfError(iAccessRequesters.Append(p));
       
   302 		CleanupStack::Pop(p); //clean up of p now handled by iAccessRequesters
       
   303 		// Try to start- it may not happen (depends on if device retrieved from registry)
       
   304 		p->Start();
       
   305 		}
       
   306 	
       
   307 	}
       
   308 
       
   309 void CBTSecMan::CancelRequest(MAccessRequestResponseHandler& aRequester)
       
   310 	{
       
   311 	LOG_FUNC
       
   312 	// search through access requesters to find correct one
       
   313 	LOG1(_L8("\tCBTSecMan::CancelRequest from SAP 0x%08x"), &aRequester)
       
   314 
       
   315 	CBTAccessRequester* request = NULL;
       
   316 	
       
   317 	TInt ix = iAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   318 	if(ix >= 0)
       
   319 		{
       
   320 		request = iAccessRequesters[ix];
       
   321 		}
       
   322 	else
       
   323 		{
       
   324 		ix = iPendingAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   325 		if(ix >= 0)
       
   326 			{
       
   327 			request = iPendingAccessRequesters[ix];
       
   328 			}
       
   329 		}
       
   330 	
       
   331 	if(request)
       
   332 		{
       
   333 		static_cast<void>(FinishAccessRequest(request)); // don't need to call back to requester...
       
   334 		}
       
   335 	
       
   336 #ifdef _DEBUG
       
   337 	// Do a sanity test to check that there aren't multiple access requesters per service
       
   338 	ix = iAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   339 	__ASSERT_DEBUG(ix == KErrNotFound, PANIC(KBTSecPanic, EBTSecMultipleActiveAccessRequestersForService));
       
   340 	ix = iPendingAccessRequesters.Find(aRequester, CompareAccessRequesterByRequester);
       
   341 	__ASSERT_DEBUG(ix == KErrNotFound, PANIC(KBTSecPanic, EBTSecMultiplePendingAccessRequestersForService));
       
   342 #endif // _DEBUG
       
   343 	}
       
   344 
       
   345 void CBTSecMan::GetPassKeyLengthAndOriginator(const TBTDevAddr& aAddr, TUint& aPasskeyMinLength,
       
   346 											  TBool& aLocallyInitiatedAuthentication,
       
   347 											  TBool& aStrongKeyRequired)
       
   348 
       
   349 /**
       
   350 If authorisation request was initiated locally it will return true and will
       
   351 return the passkey minimal length requred by user
       
   352 **/
       
   353 	{
       
   354 	LOG_FUNC
       
   355 	TUint tmpPasskeyLength = 0;
       
   356 	TBluetoothMitmProtection mitmReqs = EMitmNotRequired;
       
   357 	TBool locallyInitiated = EFalse;
       
   358 	TInt count = iAccessRequesters.Count();
       
   359 	aStrongKeyRequired = EFalse;
       
   360 
       
   361 	// find all pending AccessRequesters for given BTAddr and find maximum of PasskeyMinLength
       
   362 	if(count != 0)
       
   363 		{
       
   364 		for (TInt i=0; i<count;i++)
       
   365 			{
       
   366 			CBTAccessRequester* requester = iAccessRequesters[i];
       
   367 			if (requester->IsAuthenticationReqPending(aAddr, tmpPasskeyLength, mitmReqs))
       
   368 				{
       
   369 				locallyInitiated = ETrue;
       
   370 				if (aPasskeyMinLength < tmpPasskeyLength)
       
   371 					{
       
   372 					aPasskeyMinLength = tmpPasskeyLength;
       
   373 					}
       
   374 				if(mitmReqs == EMitmRequired)
       
   375 					{
       
   376 					aStrongKeyRequired = ETrue;
       
   377 					}
       
   378 				}
       
   379 			}
       
   380 		}
       
   381 	aLocallyInitiatedAuthentication = locallyInitiated;
       
   382 	}
       
   383 
       
   384 
       
   385 
       
   386 TBool CBTSecMan::IsDedicatedBondingAttempted(const TBTDevAddr& aAddr)
       
   387 	{
       
   388 	LOG_FUNC
       
   389 
       
   390 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   391 
       
   392 	if(requester && (requester->AccessType() == EDedicatedBonding) )
       
   393 		{
       
   394 		return ETrue;
       
   395 		}
       
   396 	else
       
   397 		{
       
   398 		return EFalse;
       
   399 		}
       
   400 	}
       
   401 
       
   402 TBool CBTSecMan::IsOutboundAccessRequest(const TBTDevAddr& aAddr)
       
   403 	{
       
   404 	LOG_FUNC
       
   405 	// For now the only outbound access request is for dedicated bonding
       
   406 	// attempts (so we share the code).
       
   407 	return IsDedicatedBondingAttempted(aAddr);
       
   408 	}
       
   409 
       
   410 
       
   411 void CBTSecMan::AuthenticationInProgress()
       
   412 /**
       
   413 When authentication request was sent to HW, HCI will notify SecMan
       
   414 **/
       
   415 	{
       
   416 	LOG_FUNC
       
   417 	// find first pending AccessRequesters and set AuthenticationInProgress flag
       
   418 	for (TInt i=0; i<iAccessRequesters.Count(); i++)
       
   419 		{
       
   420 		CBTAccessRequester* requester = iAccessRequesters[i];
       
   421 
       
   422 		if (requester->AuthenticationRequired() && !requester->AuthenticationInProgress())
       
   423 			{
       
   424 			TBTSecEvent event(TBTSecEvent::EAuthenticationRequested);
       
   425 			requester->SendEvent(event);
       
   426 			break;
       
   427 			}
       
   428 		}
       
   429 	}
       
   430 
       
   431 void CBTSecMan::IOCapabilityRequestFromRemote(const TBTDevAddr& aAddr)
       
   432 	{
       
   433 	LOG_FUNC
       
   434 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   435 	if(requester)
       
   436 		{
       
   437 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   438 		TBTSecEvent event(TBTSecEvent::EIOCapsRequested);
       
   439 		requester->SendEvent(event);
       
   440 		}
       
   441 	else
       
   442 		{
       
   443 		LOG(_L8("\tCBTAccessRequester NOT FOUND!\n"));
       
   444 		CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   445 		__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing)); // If we've got an IO Capability Response we should have a link
       
   446 
       
   447 		if(link->IsPairable())
       
   448 			{
       
   449 			link->SetAuthenticationPending(ESimplePairingPending);
       
   450 			THCIOobDataPresence oobPresence = EOOBDataNotPresent;
       
   451 			if (link->HasRemoteOobData())
       
   452 				{
       
   453 				oobPresence = EOOBDataPresent;
       
   454 				}
       
   455 			THCIAuthenticationRequirement authReq = link->AuthenticationRequirement();
       
   456 			if(ConnectionsManager().IsAcceptPairedOnlyMode())
       
   457 				{
       
   458 				// in paired only mode, only MITM pairings are acceptable.
       
   459 				switch(authReq)
       
   460 					{
       
   461 				case EMitmNotReqNoBonding:
       
   462 				case EMitmReqNoBonding:
       
   463 					authReq = EMitmReqNoBonding;
       
   464 					break;
       
   465 				case EMitmNotReqDedicatedBonding:
       
   466 				case EMitmReqDedicatedBonding:
       
   467 					authReq = EMitmReqDedicatedBonding;
       
   468 					break;
       
   469 				case EMitmNotReqGeneralBonding:
       
   470 				case EMitmReqGeneralBonding:
       
   471 					authReq = EMitmReqGeneralBonding;
       
   472 					break;
       
   473 	            default:
       
   474 	                PANIC(KBTSecPanic, EBTSecUnexpectedIoCapability);
       
   475 	                break;
       
   476 					}
       
   477 				link->SetLocalMITM(ETrue);
       
   478 				}
       
   479 			else
       
   480 				{
       
   481 				link->SetLocalMITM(EFalse);
       
   482 				}
       
   483 		
       
   484 			TRAP_IGNORE(iCommandController->IOCapabilityRequestReplyL(aAddr, EIOCapsDisplayYesNo, oobPresence, authReq));
       
   485 			}
       
   486 		else
       
   487 			{
       
   488 			TRAP_IGNORE(iCommandController->IOCapabilityRequestNegativeReplyL(aAddr, EPairingNotAllowed));
       
   489 			}
       
   490 		}
       
   491 	}
       
   492 
       
   493 
       
   494 void CBTSecMan::IOCapabilityAskForResponse(const TBTDevAddr& aAddr,
       
   495 										THCIIoCapability aIOCapability,
       
   496 										THCIOobDataPresence aOOBDataPresent,
       
   497 										THCIAuthenticationRequirement aAuthenticationRequirements)
       
   498 	{
       
   499 	LOG_FUNC
       
   500 	
       
   501 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   502 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing)); // If we've got an IO Capability Response we should have a link
       
   503 	link->IOCapabilityAskForResponse(aIOCapability, aOOBDataPresent, aAuthenticationRequirements);
       
   504 	
       
   505 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   506 	if(requester)
       
   507 		{
       
   508 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   509 		TBTSecEventIoCapabilityResponse event(aIOCapability, aOOBDataPresent, aAuthenticationRequirements);
       
   510 		requester->SendEvent(event);
       
   511 		}
       
   512 	}
       
   513 
       
   514 void CBTSecMan::RemoteOOBDataRequest(const TBTDevAddr& aAddr)
       
   515 	{
       
   516 	LOG_FUNC
       
   517 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   518 	if(requester)
       
   519 		{
       
   520 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   521 		TBTSecEvent event(TBTSecEvent::ERemoteOOBDataRequested);
       
   522 		requester->SendEvent(event);
       
   523 		}
       
   524 
       
   525 	TBluetoothSimplePairingHash hashC;
       
   526 	TBluetoothSimplePairingRandomizer randomizerR;
       
   527 	if(OobDataManager().GetRemoteOobData(aAddr, hashC, randomizerR))
       
   528 		{
       
   529 		TRAP_IGNORE(iCommandController->RemoteOOBDataRequestReplyL(aAddr, hashC, randomizerR));
       
   530 		}
       
   531 	else
       
   532 		{
       
   533 		TRAP_IGNORE(iCommandController->RemoteOOBDataRequestNegativeReplyL(aAddr));
       
   534 		}
       
   535 	}
       
   536 
       
   537 void CBTSecMan::RemoteOOBDataRequestComplete(const TBTDevAddr& aAddr)
       
   538 	{
       
   539 	LOG_FUNC
       
   540 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   541 	if(requester)
       
   542 		{
       
   543 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   544 		TBTSecEvent event(TBTSecEvent::ERemoteOOBDataRequestComplete);
       
   545 		requester->SendEvent(event);
       
   546 		}
       
   547 	}
       
   548 
       
   549 void CBTSecMan::UserConfirmationRequest(const TBTDevAddr& aAddr, TUint32 aNumericValue)
       
   550 	{
       
   551 	LOG_FUNC
       
   552 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   553 	if(requester)
       
   554 		{
       
   555 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   556 		TBTSecEventUserConfirmationRequest event(aNumericValue);
       
   557 		requester->SendEvent(event);
       
   558 		}
       
   559 
       
   560 	if(requester != FindActiveAccessRequester(aAddr))
       
   561 		{
       
   562 		// The previous requester has been completed so move on.
       
   563 		TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
       
   564 		return; // No passkey or comparison dialogs; disconnect instead
       
   565 		}
       
   566 
       
   567 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   568 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   569 	__ASSERT_DEBUG(!link->InstanceNumericComparator(), PANIC(KBTSecPanic, EBTSecConnectionNumericComparisonTwice));
       
   570 	if(link->InstanceNumericComparator())
       
   571 		{
       
   572 		return;
       
   573 		}
       
   574 
       
   575 	if(link->AuthWithMITM())
       
   576 		{
       
   577 		TBool locallyInitiated; //Authentication
       
   578 		TBool strongKeyRequired;
       
   579 		TUint minPasskeyLength=0;
       
   580 
       
   581 		GetPassKeyLengthAndOriginator(aAddr, minPasskeyLength, locallyInitiated, strongKeyRequired);
       
   582 		TRAPD(err,link->NewNumericComparatorL(aAddr, *this, aNumericValue, locallyInitiated));
       
   583 		if(err)
       
   584 			{
       
   585 			if(requester)
       
   586 				{
       
   587 				requester->CompleteRequest(EBTSecManAccessDenied);
       
   588 				}
       
   589 			else
       
   590 				{
       
   591 				TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
       
   592 				return;// No passkey or comparison dialogs; disconnect instead
       
   593 				}
       
   594 			}
       
   595 		}
       
   596 	else
       
   597 		{
       
   598 		// Just Work...
       
   599 		if(requester)
       
   600 			{
       
   601 			LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   602 			TBTSecEventUserConfirmationComplete event(ETrue);
       
   603 			requester->SendEvent(event);
       
   604 			}
       
   605 
       
   606 		// note: -- check errors here
       
   607 		TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr));
       
   608 		}
       
   609 	}
       
   610 
       
   611 void CBTSecMan::UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError)
       
   612 	{
       
   613 	LOG_FUNC
       
   614 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   615 	if (requester)
       
   616 		{
       
   617 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   618 		if (aError == KErrNone)
       
   619 			{
       
   620 			TBTSecEventUserConfirmationComplete event(aResult);
       
   621 			requester->SendEvent(event);
       
   622 			}
       
   623 		else
       
   624 			{
       
   625 			TBTSecEventUserConfirmationComplete event(EFalse);  // Failed, so send EFalse
       
   626 			requester->SendEvent(event);
       
   627 			}
       
   628 		}
       
   629 
       
   630 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   631 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   632 
       
   633 	if (aError!=KErrNone)
       
   634 		{
       
   635 		// there was an error somewhere a long the way so respond negatively
       
   636 		// note: -- check errors here
       
   637 		TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
       
   638 		}
       
   639 	else
       
   640 		{
       
   641 		// got a result
       
   642 		if(aResult)
       
   643 			{
       
   644 			link->PinRequestSent();
       
   645 			// note: -- check errors here
       
   646 			TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr));
       
   647 			}
       
   648 		else
       
   649 			{
       
   650 			// note: -- check errors here
       
   651 			TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
       
   652 			}
       
   653 		}
       
   654 	link->DeleteNumericComparator();
       
   655 	}
       
   656 
       
   657 void CBTSecMan::PasskeyNotification(const TBTDevAddr& aAddr, TUint32 aPasskey)
       
   658 	{
       
   659 	LOG_FUNC
       
   660 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   661 	if (requester)
       
   662 		{
       
   663 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   664 		TBTSecEventPasskeyNotification event(aPasskey);
       
   665 		requester->SendEvent(event);
       
   666 		}
       
   667 
       
   668 	if(requester != FindActiveAccessRequester(aAddr))
       
   669 		{
       
   670 		// the previous requester has been completed so move on.
       
   671 		return;
       
   672 		}
       
   673 
       
   674 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   675 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   676 
       
   677 	__ASSERT_DEBUG(!link->InstancePasskeyEntry(), PANIC(KBTSecPanic, EBTSecConnectionPasskeyNotificationTwice));
       
   678 
       
   679 	if(link->InstancePasskeyEntry())
       
   680 		{
       
   681 		return;
       
   682 		}
       
   683 
       
   684 	TBool locallyInitiated; //Authentication
       
   685 	TBool strongKeyRequired;
       
   686 	TUint minPasskeyLength=0;
       
   687 
       
   688 	GetPassKeyLengthAndOriginator(aAddr, minPasskeyLength, locallyInitiated, strongKeyRequired);
       
   689 	TRAPD(err, link->NewPasskeyEntryL(aAddr, *this,aPasskey, locallyInitiated));
       
   690 	if(err != KErrNone)
       
   691 		{
       
   692 		if(requester)
       
   693 			{
       
   694 			requester->CompleteRequest(EBTSecManAccessDenied);
       
   695 			}
       
   696 		}
       
   697 	}
       
   698 
       
   699 void CBTSecMan::KeypressNotification(const TBTDevAddr& aAddr, TUint8 aNotificationType)
       
   700 	{
       
   701 	LOG_FUNC
       
   702 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   703 	if (requester)
       
   704 		{
       
   705 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   706 		TBTSecEventKeypressEntry event(aNotificationType);
       
   707 		requester->SendEvent(event);
       
   708 		}
       
   709 
       
   710 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   711 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   712 
       
   713 	if (link->InstancePasskeyEntry())
       
   714 		{
       
   715 		THCIPasskeyEntryNotificationType keyType = static_cast<THCIPasskeyEntryNotificationType>(aNotificationType);
       
   716 		link->PasskeyEntryKeyPressed(keyType);
       
   717 		}
       
   718 	}
       
   719 
       
   720 void CBTSecMan::PasskeyNotificationComplete(const TBTDevAddr& aAddr, TInt aError)
       
   721 	{
       
   722 	LOG_FUNC
       
   723 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
       
   724 	if (requester)
       
   725 		{
       
   726 		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
       
   727 		TBTSecEvent event(TBTSecEvent::EKeypressComplete, aError);
       
   728 		requester->SendEvent(event);
       
   729 		}
       
   730 
       
   731 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   732 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   733 	link->DeletePasskeyEntry();
       
   734 	}
       
   735 
       
   736 void CBTSecMan::AccessRequestComplete(CBTAccessRequester* aAccessRequester, TInt aResult)
       
   737 /**
       
   738 The access request has been fully completed.
       
   739 Delete the CBTAccessRequester that was handling the request.
       
   740 **/
       
   741 	{
       
   742 	LOG_FUNC
       
   743 	MAccessRequestResponseHandler& service = FinishAccessRequest(aAccessRequester);
       
   744 	// now tell the service
       
   745 	service.AccessRequestComplete(aResult);
       
   746 	}
       
   747 	
       
   748 MAccessRequestResponseHandler& CBTSecMan::FinishAccessRequest(CBTAccessRequester* aAccessRequester)
       
   749 	{
       
   750 	LOG_FUNC
       
   751 	TBTDevAddr addr = aAccessRequester->DeviceAddress();
       
   752 
       
   753 	// find the originating service *now*
       
   754 	MAccessRequestResponseHandler& service = const_cast<MAccessRequestResponseHandler&>
       
   755 											(aAccessRequester->ServiceRequester());
       
   756 
       
   757 	CBTAccessRequester* newRequester = NULL;
       
   758 	// Determine if this is an active access requester.
       
   759 	TInt ix = iAccessRequesters.Find(aAccessRequester);
       
   760 	if(ix >= 0)
       
   761 		{
       
   762 		// We need to replace this requester with a new one.
       
   763 		// Find the new access requester
       
   764 		ix = iPendingAccessRequesters.Find(addr, CompareAccessRequesterByBDAddr);
       
   765 		if(ix >= 0)
       
   766 			{
       
   767 			newRequester = iPendingAccessRequesters[ix];
       
   768 			iPendingAccessRequesters.Remove(ix);
       
   769 			iPendingAccessRequesters.GranularCompress();
       
   770 			}
       
   771 		// Remove bindings for the completed access requester (and substitute with new one if neccessary)
       
   772 		ix = iAccessRequesters.Find(aAccessRequester);
       
   773 		__ASSERT_DEBUG(ix >= 0, PANIC(KBTSecPanic, EBTSecAccessRequesterCompletedWhenNotActive));
       
   774 		if(newRequester)
       
   775 			{
       
   776 			iAccessRequesters[ix] = newRequester;
       
   777 			}
       
   778 		else
       
   779 			{
       
   780 			iAccessRequesters.Remove(ix);
       
   781 			}
       
   782 		}
       
   783 	else
       
   784 		{
       
   785 		// This must be a pending requester - in which case we just complete it.
       
   786 		__ASSERT_DEBUG(ix == KErrNotFound, PANIC(KBTSecPanic, EBTSecAccessRequesterShouldHaveNotBeenFound));
       
   787 		ix = iPendingAccessRequesters.Find(aAccessRequester);
       
   788 		__ASSERT_DEBUG(ix >= 0, PANIC(KBTSecPanic, EBTSecAccessRequesterShouldHaveBeenFound));
       
   789 		iPendingAccessRequesters.Remove(ix);
       
   790 		iPendingAccessRequesters.GranularCompress();
       
   791 		}
       
   792 
       
   793 	// Cleanup the access requester
       
   794 	delete aAccessRequester, aAccessRequester = NULL;
       
   795 
       
   796 	// Start the new requester if there is one.
       
   797 	if(newRequester)
       
   798 		{
       
   799 		newRequester->Start();
       
   800 		}
       
   801 	
       
   802 	return service;
       
   803 	}
       
   804 
       
   805 void CBTSecMan::SimplePairingComplete(const TBTDevAddr& aAddr, THCIErrorCode aError)
       
   806 	{
       
   807 	LOG_FUNC
       
   808 	TInt err = CHciUtil::SymbianErrorCode(aError);
       
   809 
       
   810 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
       
   811 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
       
   812 
       
   813 	if (link->InstancePasskeyEntry() && link->IsPasskeyEntryActive())
       
   814 		{
       
   815 		link->CancelPasskeyEntry();
       
   816 		PasskeyNotificationComplete(aAddr, err);
       
   817 		}
       
   818 	if (link->InstanceNumericComparator() && link->IsNumericComparatorActive())
       
   819 		{
       
   820 		link->CancelNumericComparator();
       
   821 		UserConfirmationComplete(aAddr, EFalse, err);
       
   822 		}
       
   823 
       
   824 	iPhysicalLinksManager->SimplePairingComplete(aAddr, aError);
       
   825 
       
   826  	// Add result to list (always with HCI error code).
       
   827  	// Pairing results will be added only if pairing that involved numeric Comparison or passkey entry.
       
   828  	// It should not be added if the pairing completed using Just Works
       
   829  	if(link->AuthWithMITM())
       
   830  		{
       
   831  		iSimplePairingResultList->NewResult(aAddr, (KHCIErrorBase - aError));
       
   832  		}
       
   833 	}
       
   834 
       
   835 void CBTSecMan::AuthenticationComplete(const TBTDevAddr& aAddr, THCIErrorCode aError)
       
   836 	{
       
   837 	LOG_FUNC
       
   838 	iAuthenticationResultList->NewResult(aAddr, (KHCIErrorBase - aError));
       
   839 	}
       
   840 
       
   841 void CBTSecMan::AddNotifierRequestToQueL(CSecNotifierRequester& aRequest)
       
   842 /**
       
   843 Add notifier request to front of queue.  If there are no other requests already in the queue,
       
   844 initiate this request.
       
   845 **/
       
   846 	{
       
   847 	LOG_FUNC
       
   848 	TInt count = iNotifierRequesters.Count();
       
   849 	User::LeaveIfError(iNotifierRequesters.Insert(&aRequest,0));	//add to front of queue since requests are taken from the back
       
   850 	if(count == 0)	// ok since count was calculated before we inserted the new element
       
   851 		{
       
   852 		iActiveNotifierRequester = &aRequest;
       
   853 		aRequest.DoRequest();
       
   854 		}
       
   855 	else
       
   856 		{
       
   857 		LOG(_L8("\tSecman: Request queued, should start later..."));
       
   858 		}
       
   859 	}
       
   860 
       
   861 void CBTSecMan::RemoveNotifierRequestFromQue(CSecNotifierRequester& aRequest)
       
   862 /**
       
   863 Remove the request from the queue.  If aRequest is the currently active request then we can activate
       
   864 the next one in the queue.  Otherwise, aRequest is being deleted prematurely and we must simply
       
   865 remove it from the array.
       
   866 **/
       
   867 	{
       
   868 	LOG_FUNC
       
   869 	TInt count = iNotifierRequesters.Count();
       
   870 	TInt found = 0;
       
   871 	for (TInt i=(count-1); i>=0; i--)
       
   872 		{
       
   873 		if (iNotifierRequesters[i] == &aRequest)
       
   874 			{
       
   875 			found++;
       
   876 			iNotifierRequesters.Remove(i);
       
   877 			}
       
   878 		}
       
   879 	__ASSERT_DEBUG(found, PANIC(KBTSecPanic, EBTSecBadNotifierArray));
       
   880 
       
   881 	if(&aRequest == iActiveNotifierRequester)
       
   882 		{
       
   883 		//start the next request if there is one...
       
   884 		count = iNotifierRequesters.Count();
       
   885 		if (count > 0)
       
   886 			{
       
   887 			LOG(_L8("\tCBTSecMan - auto-starting next notifier request from queue"));
       
   888 			iActiveNotifierRequester = iNotifierRequesters[count-1];
       
   889 			iActiveNotifierRequester->DoRequest();
       
   890 			}
       
   891 		else
       
   892 			{
       
   893 			iActiveNotifierRequester = NULL;
       
   894 			}
       
   895 		}
       
   896 	}
       
   897 
       
   898 CBTAccessRequesterStateFactory* CBTSecMan::StateMachine()
       
   899 	{
       
   900 	LOG_FUNC
       
   901 	return iStateMachine;
       
   902 	}
       
   903 
       
   904 CSecNotifierRequester::CSecNotifierRequester(CBTSecMan& aSecMan)
       
   905 	: CActive(EPriorityStandard)
       
   906 	, iInquiryMgr(aSecMan.ConnectionsManager().LinkManagerProtocol().InquiryMgr())
       
   907 	, iSecMgr(aSecMan)
       
   908 	{
       
   909 	LOG_FUNC
       
   910 	}
       
   911 
       
   912 void CSecNotifierRequester::ConstructL(const TBTDevAddr& aAddr)
       
   913 	{
       
   914 	LOG_FUNC
       
   915 	LEAVEIFERRORL(iNotifier.Connect());
       
   916 
       
   917 	// find the name at this stage for this device - may not be there yet
       
   918 	iDeviceName = iInquiryMgr.DeviceNameFromCache(aAddr);
       
   919 
       
   920 	if (!iDeviceName || iDeviceName->Length() ==0)
       
   921 		{
       
   922 		// cache didn't have name - so we'll ask for it as a HR action
       
   923 		TRAP_IGNORE(iHR = iInquiryMgr.NewHostResolverL());
       
   924 		iHRNameRecord = new TNameRecord;
       
   925 
       
   926 		// ignore error - only an optimisation - don't want to leave if there's
       
   927 		// a problem doing this optimisation
       
   928 		if (iHR && iHRNameRecord)
       
   929 			{
       
   930 			iHR->SetNotify(this);
       
   931 
       
   932 			TInquirySockAddr i;
       
   933 			i.SetAction(KHostResName);
       
   934 			i.SetBTAddr(aAddr);
       
   935 			iHRNameRecord->iAddr = i;
       
   936 			iHR->GetByAddress(*iHRNameRecord);
       
   937 			}
       
   938 		}
       
   939 
       
   940 	iDevAddr = aAddr;
       
   941 
       
   942 	iSecMgr.AddNotifierRequestToQueL(*this);
       
   943 	iIsAddedToNotifierQue = ETrue;
       
   944 	}
       
   945 
       
   946 void CSecNotifierRequester::RemoveMyselfFromQue()
       
   947 	{
       
   948 	LOG_FUNC
       
   949 	iSecMgr.RemoveNotifierRequestFromQue(*this);
       
   950 	}
       
   951 
       
   952 CSecNotifierRequester::~CSecNotifierRequester()
       
   953 	{
       
   954 	LOG_FUNC
       
   955 	Cancel();
       
   956 
       
   957 	//remove ourself from the notifier que if we're still on it.
       
   958 	if (iIsAddedToNotifierQue)
       
   959 		{
       
   960 		RemoveMyselfFromQue();
       
   961 		iIsAddedToNotifierQue = EFalse;
       
   962 		}
       
   963 
       
   964 	delete iHR;
       
   965 	delete iHRNameRecord;
       
   966 
       
   967 	iNotifier.Close();
       
   968 	}
       
   969 
       
   970 void CSecNotifierRequester::QueryComplete(TInt aErr)
       
   971 	{
       
   972 	LOG_FUNC
       
   973 	if (aErr==KErrNone && iHRNameRecord)
       
   974 		{
       
   975 		// now have device name - update notifiers
       
   976 		// we do have a copy of the name - but it is now wide :-|
       
   977 		// and also we have iDeviceName that is still NULL, so best bet is
       
   978 		// to just set our pointer and use the cache one (which we *know* is there!)
       
   979 		TBTDevAddr a = TBTSockAddr::Cast(iHRNameRecord->iAddr).BTAddr();
       
   980 		iDeviceName = iInquiryMgr.DeviceNameFromCache(a);
       
   981 		DoUpdateNotifier();
       
   982 		}
       
   983 
       
   984 	delete iHRNameRecord;
       
   985 	iHRNameRecord = NULL;
       
   986 	}
       
   987 
       
   988 void CSecNotifierRequester::HandleTimeout()
       
   989 	{
       
   990 	LOG_FUNC
       
   991 	// A timer user should implement this function
       
   992 	__ASSERT_DEBUG(EFalse, PANIC(KBTSecPanic, EBTSecNotifierRequesterUsingTimerWithoutHandling));
       
   993 	}
       
   994 
       
   995 
       
   996 
       
   997 CSecNotifierRequesterTimer* CSecNotifierRequesterTimer::NewL(CSecNotifierRequester& aObserver)
       
   998 	{
       
   999 	LOG_STATIC_FUNC
       
  1000 	CSecNotifierRequesterTimer* self = new(ELeave) CSecNotifierRequesterTimer(aObserver);
       
  1001 	CleanupStack::PushL(self);
       
  1002 	self->ConstructL();
       
  1003 	CleanupStack::Pop(self);
       
  1004 	return self;
       
  1005 	}
       
  1006 
       
  1007 CSecNotifierRequesterTimer::CSecNotifierRequesterTimer(CSecNotifierRequester& aObserver)
       
  1008 	: CTimer(EPriorityStandard)
       
  1009 	, iObserver(aObserver)
       
  1010 	{
       
  1011 	LOG_FUNC
       
  1012 	CActiveScheduler::Add(this);
       
  1013 	}
       
  1014 
       
  1015 CSecNotifierRequesterTimer::~CSecNotifierRequesterTimer()
       
  1016 	{
       
  1017 	LOG_FUNC
       
  1018 	Cancel();
       
  1019 	}
       
  1020 
       
  1021 void CSecNotifierRequesterTimer::Start(TTimeIntervalMicroSeconds32 aTimeout)
       
  1022 	{
       
  1023 	LOG_FUNC
       
  1024 	After(aTimeout);
       
  1025 	}
       
  1026 
       
  1027 void CSecNotifierRequesterTimer::ConstructL()
       
  1028 	{
       
  1029 	LOG_FUNC
       
  1030 	CTimer::ConstructL();
       
  1031 	}
       
  1032 
       
  1033 void CSecNotifierRequesterTimer::RunL()
       
  1034 	{
       
  1035 	LOG_FUNC
       
  1036 	iObserver.HandleTimeout();
       
  1037 	}
       
  1038 
       
  1039 
       
  1040 //------------------------------------------------------------------------//
       
  1041 //class CBTPinRequester
       
  1042 //------------------------------------------------------------------------//
       
  1043 
       
  1044 
       
  1045 CBTPinRequester* CBTPinRequester::NewL(const TBTDevAddr& aAddr,
       
  1046 									   MPINCodeResponseHandler& aRequester,
       
  1047 									   CBTSecMan& aSecMan,
       
  1048 									   TUint aPasskeyMinLength,
       
  1049 									   TBool aInternallyInitiated,
       
  1050 									   TBool aStrongKeyRequired,
       
  1051 									   TUint aRecommendedPasskeyMinLength)
       
  1052 	{
       
  1053 	LOG_STATIC_FUNC
       
  1054 	CBTPinRequester* s = CBTPinRequester::NewLC(aAddr, aRequester, aSecMan,
       
  1055 	                                            aPasskeyMinLength, aInternallyInitiated, aStrongKeyRequired, aRecommendedPasskeyMinLength);
       
  1056 	CleanupStack::Pop(s);
       
  1057 	return s;
       
  1058 	}
       
  1059 
       
  1060 CBTPinRequester* CBTPinRequester::NewLC(const TBTDevAddr& aAddr,
       
  1061 										MPINCodeResponseHandler& aRequester,
       
  1062 										CBTSecMan& aSecMan,
       
  1063 										TUint aPasskeyMinLength,
       
  1064 										TBool aInternallyInitiated,
       
  1065 										TBool aStrongKeyRequired,
       
  1066 										TUint aRecommendedPasskeyMinLength)
       
  1067 	{
       
  1068 	LOG_STATIC_FUNC
       
  1069 	CBTPinRequester* s = new(ELeave) CBTPinRequester(aRequester, aSecMan,
       
  1070 	                                                 aPasskeyMinLength, aInternallyInitiated, aStrongKeyRequired, aRecommendedPasskeyMinLength);
       
  1071 	CleanupStack::PushL(s);
       
  1072 	s->ConstructL(aAddr);
       
  1073 	return s;
       
  1074 	}
       
  1075 
       
  1076 CBTPinRequester::CBTPinRequester(MPINCodeResponseHandler& aHandler,
       
  1077 								 CBTSecMan& aSecMan,
       
  1078 								 TUint aPasskeyMinLength,
       
  1079 								 TBool aInternallyInitiated,
       
  1080 								 TBool aStrongKeyRequired,
       
  1081 								 TUint aRecommendedPasskeyMinLength)
       
  1082 	: CSecNotifierRequester(aSecMan)
       
  1083 	, iHandler(&aHandler)
       
  1084 	, iSecMan(aSecMan)
       
  1085 	, iPasskeyMinLength(aPasskeyMinLength)
       
  1086 	, iInternallyInitiated(aInternallyInitiated)
       
  1087 	, iStrongKeyRequired(aStrongKeyRequired)
       
  1088 	, iRecommendedPasskeyMinLength(aRecommendedPasskeyMinLength)
       
  1089 	{
       
  1090 	LOG_FUNC
       
  1091 	CActiveScheduler::Add(this);
       
  1092 	}
       
  1093 
       
  1094 void CBTPinRequester::ConstructL(const TBTDevAddr& aAddr)
       
  1095 	{
       
  1096 	LOG_FUNC
       
  1097 	iTimer = CSecNotifierRequesterTimer::NewL(*this);
       
  1098 	CSecNotifierRequester::ConstructL(aAddr);
       
  1099 	}
       
  1100 
       
  1101 CBTPinRequester::~CBTPinRequester()
       
  1102 	{
       
  1103 	LOG_FUNC
       
  1104 	delete iTimer;
       
  1105 	Cancel();
       
  1106 	CBase::Delete(iUpdateNotifier.iNameUpdater); // Delete through the CBase virtual destructor.
       
  1107 	}
       
  1108 
       
  1109 
       
  1110 void CBTPinRequester::UpdateHandler(MPINCodeResponseHandler& aNewHandler)
       
  1111 	{
       
  1112 	LOG_FUNC
       
  1113 	iHandler = &aNewHandler;
       
  1114 	}
       
  1115 
       
  1116 
       
  1117 void CBTPinRequester::DoUpdateNotifier()
       
  1118 	{
       
  1119 	LOG_FUNC
       
  1120  	if(IsActive())
       
  1121  		{
       
  1122  		switch(iNotifierType)
       
  1123 	 		{
       
  1124 	 	case ESspAwareNotifier:
       
  1125 	 		UpdateSspAwareNotifier();
       
  1126 	 		break;
       
  1127 	 	case ELegacyNotifier:
       
  1128 	 		UpdateLegacyNotifier();
       
  1129 	 		break;
       
  1130 	 	default:
       
  1131 			DEBUG_PANIC_LINENUM
       
  1132 	 		break;
       
  1133 	 		}
       
  1134 		}
       
  1135 	}
       
  1136 
       
  1137 void CBTPinRequester::UpdateSspAwareNotifier()
       
  1138 	{
       
  1139 	LOG_FUNC
       
  1140 	if(!iUpdateNotifier.iNameUpdater)
       
  1141 		{
       
  1142 		//Create a new CSecNotifierUpdateAO object
       
  1143 		TRAP_IGNORE(iUpdateNotifier.iNameUpdater = CSecNotifierUpdateAO<TBTDeviceNameUpdateParamsPckg>::NewL(iNotifier, KBTPinCodeEntryNotifierUid));
       
  1144 		}
       
  1145 	if(iUpdateNotifier.iNameUpdater)
       
  1146 		{
       
  1147 		TBTDeviceName deviceName(KNullDesC);
       
  1148 		TInt err = KErrNotFound;
       
  1149 		if(iDeviceName)
       
  1150 			{
       
  1151 			TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt.
       
  1152 			}
       
  1153 		TBTDeviceNameUpdateParamsPckg pckg = TBTDeviceNameUpdateParams(deviceName, err);
       
  1154 		iUpdateNotifier.iNameUpdater->DoUpdate(pckg);
       
  1155 		}
       
  1156 	}
       
  1157 
       
  1158 void CBTPinRequester::UpdateLegacyNotifier()
       
  1159 	{
       
  1160 	LOG_FUNC
       
  1161 	if(!iUpdateNotifier.iLegacyUpdater)
       
  1162 		{
       
  1163 		//Create a new CSecNotifierUpdateAO object
       
  1164 		TRAP_IGNORE(iUpdateNotifier.iLegacyUpdater = CSecNotifierUpdateAO<TBTNotifierUpdateParamsPckg>::NewL(iNotifier, KBTManPinNotifierUid));
       
  1165 		}
       
  1166 	if(iUpdateNotifier.iLegacyUpdater)
       
  1167 		{
       
  1168 		TBTNotifierUpdateParamsPckg pckg;
       
  1169 		if(iDeviceName)
       
  1170 			{
       
  1171 			TRAPD(err, pckg().iName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1172 			pckg().iResult = err; 	// Error code can be KErrNone
       
  1173 			if(err != KErrNone)
       
  1174 				{
       
  1175 				pckg().iName = KNullDesC;
       
  1176 				}
       
  1177 			}
       
  1178 		else
       
  1179 			{
       
  1180 			pckg().iName = KNullDesC;
       
  1181 			pckg().iResult = KErrNotFound;
       
  1182 			}
       
  1183 
       
  1184 		iUpdateNotifier.iLegacyUpdater->DoUpdate(pckg);
       
  1185 		}
       
  1186 	}
       
  1187 
       
  1188 void CBTPinRequester::DoRequest()
       
  1189 	{
       
  1190 	LOG_FUNC
       
  1191 	// The initial request for a PIN code entry dialog (that is SSP aware).  If this fails
       
  1192 	// we will attempt to use the legacy notifier.
       
  1193 
       
  1194 	TBTDeviceName deviceName(KNullDesC);
       
  1195 	if(iDeviceName)
       
  1196 		{
       
  1197 		TRAP_IGNORE(deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt.
       
  1198 		}
       
  1199 
       
  1200 	iPinCodeEntryParamsPckg
       
  1201 		= TBTPinCodeEntryNotifierParams(iDevAddr, deviceName, iPasskeyMinLength, iInternallyInitiated, iStrongKeyRequired, iRecommendedPasskeyMinLength);
       
  1202 
       
  1203 	iNotifierType = ESspAwareNotifier;
       
  1204 	iNotifier.StartNotifierAndGetResponse(iStatus, KBTPinCodeEntryNotifierUid, iPinCodeEntryParamsPckg, iPassKey);
       
  1205 	iTimer->Start(KPinRequesterTimeout);
       
  1206 	SetActive();
       
  1207 	}
       
  1208 
       
  1209 void CBTPinRequester::FriendlyNameRetrieved(const TDesC& /*aName*/, TInt /*aResult*/)
       
  1210 	{
       
  1211 	LOG_FUNC
       
  1212 	// do nothing for now as it is not used anywhere
       
  1213 	__ASSERT_DEBUG(0, PANIC(KBTSecPanic, EBTSecNotImplemented));
       
  1214 	}
       
  1215 
       
  1216 
       
  1217 void CBTPinRequester::DoCancel()
       
  1218 	{
       
  1219 	LOG_FUNC
       
  1220 	iTimer->Cancel();
       
  1221 	// Cancel the appropriate notifier.
       
  1222 	switch(iNotifierType)
       
  1223 		{
       
  1224 	case ESspAwareNotifier:
       
  1225 		iNotifier.CancelNotifier(KBTPinCodeEntryNotifierUid);
       
  1226 		if(iUpdateNotifier.iNameUpdater)
       
  1227 			{
       
  1228 			iUpdateNotifier.iNameUpdater->Cancel();
       
  1229 			}
       
  1230 		break;
       
  1231 	case ELegacyNotifier:
       
  1232 		iNotifier.CancelNotifier(KBTManPinNotifierUid);
       
  1233 		if(iUpdateNotifier.iLegacyUpdater)
       
  1234 			{
       
  1235 			iUpdateNotifier.iNameUpdater->Cancel();
       
  1236 			}
       
  1237 		break;
       
  1238 	default:
       
  1239 		DEBUG_PANIC_LINENUM
       
  1240 		break;
       
  1241 		}
       
  1242 	iNotifierType = EInvalid;
       
  1243 	}
       
  1244 
       
  1245 void CBTPinRequester::RunL()
       
  1246 	{
       
  1247 	LOG_FUNC
       
  1248 	iTimer->Cancel();
       
  1249 	switch(iNotifierType)
       
  1250 		{
       
  1251 	case ESspAwareNotifier:
       
  1252 		HandleSspAwareNotifierL();
       
  1253 		break;
       
  1254 	case ELegacyNotifier:
       
  1255 		HandleLegacyNotifierL();
       
  1256 		break;
       
  1257 	default:
       
  1258 		DEBUG_PANIC_LINENUM
       
  1259 		break;
       
  1260 		}
       
  1261 	}
       
  1262 
       
  1263 
       
  1264 void CBTPinRequester::HandleSspAwareNotifierL()
       
  1265 	{
       
  1266 	LOG_FUNC
       
  1267 	ASSERT_DEBUG(iNotifierType == ESspAwareNotifier);
       
  1268 
       
  1269 	//got a PIN or error, so we are finished with this notifier.
       
  1270 	iNotifier.CancelNotifier(KBTPinCodeEntryNotifierUid);
       
  1271 
       
  1272 	TInt err = iStatus.Int();
       
  1273 
       
  1274 	if(err == KErrNotFound)
       
  1275 		{
       
  1276 		// Failed to find the SSP aware notifier, as such we should attempt to use
       
  1277 		// the legacy notifier.
       
  1278 
       
  1279 		// First we prevent any updaters to the new notifier type.
       
  1280 		delete iUpdateNotifier.iNameUpdater;
       
  1281 		iUpdateNotifier.iNameUpdater = NULL;
       
  1282 
       
  1283 		// Next we notify using the legacy notifier.
       
  1284 		iLegacyPinCodeParamsPckg().iBDAddr = iDevAddr;
       
  1285 		if(iDeviceName)
       
  1286 			{
       
  1287 			TRAPD(err, iLegacyPinCodeParamsPckg().iName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1288 			if(err != KErrNone)
       
  1289 				{
       
  1290 				iLegacyPinCodeParamsPckg().iName = KNullDesC;
       
  1291 				}
       
  1292 			}
       
  1293 		else
       
  1294 			{
       
  1295 			iLegacyPinCodeParamsPckg().iName = KNullDesC;
       
  1296 			}
       
  1297 		if(iStrongKeyRequired)
       
  1298 			{
       
  1299 			// As we cannot signal this any other way if a strong key is required, then we must
       
  1300 			// force a long passkey length.  This has potential IOP issues.
       
  1301 			iLegacyPinCodeParamsPckg().iPasskeyMinLength = KHCIPINCodeSize;
       
  1302 			}
       
  1303 		else
       
  1304 			{
       
  1305 			iLegacyPinCodeParamsPckg().iPasskeyMinLength = iPasskeyMinLength;
       
  1306 			}
       
  1307 		iLegacyPinCodeParamsPckg().iLocallyInitiated = iInternallyInitiated;
       
  1308 
       
  1309 		iNotifierType = ELegacyNotifier;
       
  1310 		iNotifier.StartNotifierAndGetResponse(iStatus, KBTManPinNotifierUid, iLegacyPinCodeParamsPckg, iPassKey);
       
  1311 		iTimer->Start(KPinRequesterTimeout); // restart
       
  1312 		SetActive();
       
  1313 		}
       
  1314 	else
       
  1315 		{
       
  1316 		// The SSP aware PIN code entry notifier was found...
       
  1317 
       
  1318 		//remove ourself from the notifier que, allowing the next notifier to be activated
       
  1319 		iSecMan.RemoveNotifierRequestFromQue(*this);
       
  1320 		iIsAddedToNotifierQue = EFalse;
       
  1321 
       
  1322 		iNotifierType = EInvalid; // whatever happened we're done.
       
  1323 		if(err != KErrNone)
       
  1324 			{
       
  1325 			// The notifier signalled some other error - so be unpairable.
       
  1326 			iHandler->PINCodeRequestNegativeReply(iDevAddr);
       
  1327 			}
       
  1328 		else
       
  1329 			{
       
  1330 			// got a PIN
       
  1331 			iHandler->PINCodeRequestReply(iDevAddr, iPassKey);
       
  1332 			}
       
  1333 		}
       
  1334 	}
       
  1335 
       
  1336 
       
  1337 void CBTPinRequester::HandleLegacyNotifierL()
       
  1338 	{
       
  1339 	LOG_FUNC
       
  1340 	ASSERT_DEBUG(iNotifierType == ELegacyNotifier);
       
  1341 
       
  1342 	//got a PIN or error, so finish off: unload the plugin
       
  1343 	iNotifier.CancelNotifier(KBTManPinNotifierUid);
       
  1344 
       
  1345 	//remove ourself from the notifier que, allowing the next notifier to be activated
       
  1346 	RemoveMyselfFromQue();
       
  1347 	iIsAddedToNotifierQue = EFalse;
       
  1348 
       
  1349 	iNotifierType = EInvalid; // whatever happened we're done.
       
  1350 	if (iStatus.Int())
       
  1351 		{
       
  1352 		// it failed - be unpairable
       
  1353 		iHandler->PINCodeRequestNegativeReply(iDevAddr);
       
  1354 		}
       
  1355 	else
       
  1356 		{
       
  1357 		// got a PIN
       
  1358 		iHandler->PINCodeRequestReply(iDevAddr, iPassKey);
       
  1359 		}
       
  1360 	}
       
  1361 
       
  1362 
       
  1363 TInt CBTPinRequester::RunError(TInt IF_FLOGGING(aError))
       
  1364 	{
       
  1365 	LOG_FUNC
       
  1366 	LOG1(_L8("\tCBTPinRequester::RunError(%d)\n"), aError);
       
  1367 
       
  1368 	switch(iNotifierType)
       
  1369 		{
       
  1370 	case ESspAwareNotifier:
       
  1371 	case ELegacyNotifier:
       
  1372 		break;
       
  1373 	default:
       
  1374 		DEBUG_PANIC_LINENUM
       
  1375 		break;
       
  1376 		}
       
  1377 
       
  1378 	iNotifierType = EInvalid;
       
  1379 	iHandler->PINCodeRequestNegativeReply(iDevAddr);
       
  1380 	return KErrNone;
       
  1381 	}
       
  1382 
       
  1383 void CBTPinRequester::HandleTimeout()
       
  1384 	{
       
  1385 	LOG_FUNC
       
  1386 	// Cancel the request...
       
  1387 	Cancel();
       
  1388 	// Complete with a -ve reply
       
  1389 	iHandler->PINCodeRequestNegativeReply(iDevAddr);
       
  1390 	}
       
  1391 
       
  1392 //------------------------------------------------------------------------//
       
  1393 //class CBTAuthorisor
       
  1394 //------------------------------------------------------------------------//
       
  1395 
       
  1396 CBTAuthorisor* CBTAuthorisor::NewL(CBTAccessRequester& aParent, CBTSecMan& aSecMan, TUid aServiceUID)
       
  1397 	{
       
  1398 	LOG_STATIC_FUNC
       
  1399 	CBTAuthorisor* s = CBTAuthorisor::NewLC(aParent, aSecMan, aServiceUID);
       
  1400 	CleanupStack::Pop(s);
       
  1401 	return s;
       
  1402 	}
       
  1403 
       
  1404 CBTAuthorisor* CBTAuthorisor::NewLC(CBTAccessRequester& aParent, CBTSecMan& aSecMan, TUid aServiceUID)
       
  1405 	{
       
  1406 	LOG_STATIC_FUNC
       
  1407 	CBTAuthorisor* s = new(ELeave) CBTAuthorisor(aParent, aSecMan, aServiceUID);
       
  1408 	CleanupStack::PushL(s);
       
  1409 	s->ConstructL(aParent.DeviceAddress());
       
  1410 	return s;
       
  1411 	}
       
  1412 
       
  1413 CBTAuthorisor::CBTAuthorisor(CBTAccessRequester& aAccessRequester, CBTSecMan& aSecMan, TUid aServiceUID) :
       
  1414 	CSecNotifierRequester(aSecMan),iAccessRequester(aAccessRequester)
       
  1415 	{
       
  1416 	LOG_FUNC
       
  1417 	iAuthorisationParamsPckg().iUid = aServiceUID;
       
  1418 	CActiveScheduler::Add(this);
       
  1419 	}
       
  1420 
       
  1421 CBTAuthorisor::~CBTAuthorisor()
       
  1422 	{
       
  1423 	LOG_FUNC
       
  1424 	Cancel();
       
  1425 	delete iUpdateNotifierAO;
       
  1426 	}
       
  1427 
       
  1428 
       
  1429 void CBTAuthorisor::DoUpdateNotifier()
       
  1430 	{
       
  1431 	LOG_FUNC
       
  1432 	if(IsActive())
       
  1433 		{
       
  1434 		if(!iUpdateNotifierAO)
       
  1435 			{
       
  1436 			//Create a new CSecNotifierUpdateAO object
       
  1437 			TRAP_IGNORE(iUpdateNotifierAO = CSecNotifierUpdateAO<TBTNotifierUpdateParamsPckg>::NewL(iNotifier, KBTManAuthNotifierUid));
       
  1438 			}
       
  1439 
       
  1440 		if( (iUpdateNotifierAO) && (!iUpdateNotifierAO->IsActive()) )
       
  1441 			{
       
  1442 			TBTNotifierUpdateParamsPckg pckg;
       
  1443 			if(iDeviceName)
       
  1444 				{
       
  1445 				TRAPD(err, pckg().iName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1446 				pckg().iResult = err; 	// Error code can be KErrNone
       
  1447 				if (err!=KErrNone)
       
  1448 					{
       
  1449 					pckg().iName = KNullDesC;
       
  1450 					}
       
  1451 				}
       
  1452 			else
       
  1453 				{
       
  1454 				pckg().iName = KNullDesC;
       
  1455 				pckg().iResult = KErrNotFound;
       
  1456 				}
       
  1457 
       
  1458 			iUpdateNotifierAO->DoUpdate(pckg);
       
  1459 			}
       
  1460 		}
       
  1461 	}
       
  1462 
       
  1463 void CBTAuthorisor::DoRequest()
       
  1464 /**
       
  1465 Start the RNotifier plugin that deals with authorisation.
       
  1466 **/
       
  1467 	{
       
  1468 	LOG_FUNC
       
  1469 	TInt err(KErrNone);
       
  1470 
       
  1471 	if (iDeviceName)
       
  1472 		{
       
  1473 		TRAP(err, iAuthorisationParamsPckg().iName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1474 		if (err!=KErrNone)
       
  1475 			{
       
  1476 			iAuthorisationParamsPckg().iName = KNullDesC;
       
  1477 			}
       
  1478 		}
       
  1479 	else
       
  1480 		{
       
  1481 		iAuthorisationParamsPckg().iName = KNullDesC;
       
  1482 		}
       
  1483 	iAuthorisationParamsPckg().iBDAddr  = iDevAddr;
       
  1484 
       
  1485 	TBTSecEvent event(TBTSecEvent::EAuthorisationRequested);
       
  1486 	iAccessRequester.SendEvent(event);
       
  1487 
       
  1488 	iNotifier.StartNotifierAndGetResponse(iStatus, KBTManAuthNotifierUid, iAuthorisationParamsPckg, iResultPckg);
       
  1489 	SetActive();
       
  1490 	}
       
  1491 
       
  1492 
       
  1493 void CBTAuthorisor::DoCancel()
       
  1494 	{
       
  1495 	LOG_FUNC
       
  1496 	iNotifier.CancelNotifier(KBTManAuthNotifierUid);
       
  1497 	}
       
  1498 
       
  1499 void CBTAuthorisor::RunL()
       
  1500 	{
       
  1501 	LOG_FUNC
       
  1502 
       
  1503 	// unload the plugin
       
  1504 	iNotifier.CancelNotifier(KBTManAuthNotifierUid);
       
  1505 
       
  1506 	// remove ourself from the notifier queue, allowing the next notifier to be activated
       
  1507 	RemoveMyselfFromQue();
       
  1508 	iIsAddedToNotifierQue = EFalse;
       
  1509 
       
  1510 	// notify owner of completion
       
  1511 	LOG1(_L8("\tCBTAuthorisor::RunL(): iStatus = %d\n"), iStatus.Int());
       
  1512 	if (iStatus.Int() != KErrNone)
       
  1513 		{
       
  1514 		// If anything went wrong, then deny access
       
  1515 		TBTSecEventAuthorisationComplete event(EFalse);
       
  1516 		iAccessRequester.SendEvent(event);
       
  1517 		}
       
  1518 	else
       
  1519 		{
       
  1520 		// otherwise allow/deny depends on the notifier
       
  1521 		TBTSecEventAuthorisationComplete event(iResultPckg());
       
  1522 		iAccessRequester.SendEvent(event);
       
  1523 		}
       
  1524 	}
       
  1525 
       
  1526 TInt CBTAuthorisor::RunError(TInt aError)
       
  1527 	{
       
  1528 	LOG_FUNC
       
  1529 	//will never get called as our RunL doesn't leave.
       
  1530 	LOG1(_L8("\tCBTAuthorisor::RunError(%d)\n"), aError);
       
  1531 	return aError;
       
  1532 	}
       
  1533 
       
  1534 
       
  1535 //------------------------------------------------------------------------//
       
  1536 //class CSecNotifierUpdateAO
       
  1537 //------------------------------------------------------------------------//
       
  1538 
       
  1539 template <class T>
       
  1540 CSecNotifierUpdateAO<T>* CSecNotifierUpdateAO<T>::NewL(RNotifier& aNotifier, TUid aNotifierUid)
       
  1541 	{
       
  1542 	LOG_STATIC_FUNC
       
  1543 	CSecNotifierUpdateAO* s = CSecNotifierUpdateAO::NewLC(aNotifier, aNotifierUid);
       
  1544 	CleanupStack::Pop(s);
       
  1545 	return s;
       
  1546 	}
       
  1547 
       
  1548 template <class T>
       
  1549 CSecNotifierUpdateAO<T>* CSecNotifierUpdateAO<T>::NewLC(RNotifier& aNotifier, TUid aNotifierUid)
       
  1550 	{
       
  1551 	LOG_STATIC_FUNC
       
  1552 	CSecNotifierUpdateAO* s = new(ELeave) CSecNotifierUpdateAO();
       
  1553 	CleanupStack::PushL(s);
       
  1554 	s->ConstructL(aNotifier, aNotifierUid);
       
  1555 	return s;
       
  1556 	}
       
  1557 
       
  1558 template <class T>
       
  1559 CSecNotifierUpdateAO<T>::CSecNotifierUpdateAO()
       
  1560 	: CActive(EPriorityStandard)
       
  1561 	{
       
  1562 	LOG_FUNC
       
  1563 	CActiveScheduler::Add(this);
       
  1564 	}
       
  1565 
       
  1566 template <class T>
       
  1567 CSecNotifierUpdateAO<T>::~CSecNotifierUpdateAO()
       
  1568 	{
       
  1569 	LOG_FUNC
       
  1570 	Cancel();
       
  1571 	}
       
  1572 
       
  1573 template <class T>
       
  1574 void CSecNotifierUpdateAO<T>::ConstructL(RNotifier& aNotifier, TUid aNotifierUid)
       
  1575 	{
       
  1576 	LOG_FUNC
       
  1577 	iNotifier = aNotifier;
       
  1578 	iNotifierUid = aNotifierUid;
       
  1579 	}
       
  1580 
       
  1581 
       
  1582 template <class T>
       
  1583 void CSecNotifierUpdateAO<T>::DoUpdate(const T& aPckg)
       
  1584 	{
       
  1585 	LOG_FUNC
       
  1586 	if (IsActive())
       
  1587 		{
       
  1588 		TRAP_IGNORE(iPckgQueue.AppendL(aPckg));  // An update will be missed if OOM
       
  1589 		}
       
  1590 	else
       
  1591 		{
       
  1592 		//Retain a copy so that it does not go out of memory scope
       
  1593 		iPckg = aPckg;
       
  1594 
       
  1595 		// We're not expecting an answer... but we want to use an asynchronous API
       
  1596 		// and so we need to "get a response"
       
  1597 		iNotifier.UpdateNotifierAndGetResponse(iStatus, iNotifierUid, iPckg, iAnswer);
       
  1598 		SetActive();
       
  1599 		}
       
  1600 	}
       
  1601 
       
  1602 template <class T>
       
  1603 void CSecNotifierUpdateAO<T>::DoUpdateSynchronous(const T& aPckg)
       
  1604 	{
       
  1605 	LOG_FUNC
       
  1606 	//we're not expecting an answer so discard error as well...
       
  1607 	TInt err = iNotifier.UpdateNotifier(iNotifierUid, aPckg, iAnswer);
       
  1608 	LOG1(_L8("\tCSecNotifierUpdateAO::DoUpdateSynchronous error (%d)\n"), err);
       
  1609 	}
       
  1610 
       
  1611 
       
  1612 template <class T>
       
  1613 void CSecNotifierUpdateAO<T>::RunL()
       
  1614 	{
       
  1615 	LOG_FUNC
       
  1616 	//We can't do anything if an error is returned - just make sure we haven't done anything stupid...
       
  1617 	__ASSERT_DEBUG((iStatus==KErrNone)||(iStatus==KErrNoMemory)||(iStatus==KErrNotReady), PANIC(KBTSecPanic, EBTSecBadNotifierUpdate));
       
  1618 	if (iPckgQueue.Count() != 0)
       
  1619 		{
       
  1620 		iPckg = iPckgQueue[0];
       
  1621 		iPckgQueue.Remove(0);
       
  1622 		iNotifier.UpdateNotifierAndGetResponse(iStatus, iNotifierUid, iPckg, iAnswer);
       
  1623 		SetActive();
       
  1624 		}
       
  1625 	}
       
  1626 
       
  1627 template <class T>
       
  1628 void CSecNotifierUpdateAO<T>::DoCancel()
       
  1629 	{
       
  1630 	LOG_FUNC
       
  1631 	iPckgQueue.Close();
       
  1632 	iNotifier.CancelNotifier(iNotifierUid); // no other API on Notifier to just cancel the update; but typically we'll want to cancel the whole notifier at this point(?)
       
  1633 	}
       
  1634 
       
  1635 template <class T>
       
  1636 TInt CSecNotifierUpdateAO<T>::RunError(TInt IF_FLOGGING(aError))
       
  1637 	{
       
  1638 	LOG_FUNC
       
  1639 	LOG1(_L8("\tCSecNotifierUpdateAO::RunError(%d)\n"), aError);
       
  1640 	return KErrNone;
       
  1641 	}
       
  1642 
       
  1643 
       
  1644 
       
  1645 //------------------------------------------------------------------------//
       
  1646 //class CBTNumericComparator
       
  1647 //------------------------------------------------------------------------//
       
  1648 CBTNumericComparator* CBTNumericComparator::NewL(const TBTDevAddr aAddr,
       
  1649 												 CBTSecMan& aSecMan,
       
  1650 												 TUint32 aNumericValue,
       
  1651 												 TBTNumericComparisonParams::TComparisonScenario aComparisonScenario, 
       
  1652 												 TBool aInternallyInitiated)
       
  1653 	{
       
  1654 	LOG_STATIC_FUNC
       
  1655 	CBTNumericComparator* s = CBTNumericComparator::NewLC(aAddr, aSecMan, aNumericValue, aComparisonScenario, aInternallyInitiated);
       
  1656 	CleanupStack::Pop(s);
       
  1657 	return s;
       
  1658 	}
       
  1659 
       
  1660 CBTNumericComparator* CBTNumericComparator::NewLC(const TBTDevAddr aAddr,
       
  1661 												  CBTSecMan& aSecMan,
       
  1662 												  TUint32 aNumericValue,
       
  1663 												  TBTNumericComparisonParams::TComparisonScenario aComparisonScenario, 
       
  1664 												  TBool aInternallyInitiated)
       
  1665 	{
       
  1666 	LOG_STATIC_FUNC
       
  1667 	CBTNumericComparator* s = new(ELeave) CBTNumericComparator(aSecMan, aNumericValue, aComparisonScenario, aInternallyInitiated);
       
  1668 	CleanupStack::PushL(s);
       
  1669 	s->ConstructL(aAddr);
       
  1670 	return s;
       
  1671 	}
       
  1672 
       
  1673 CBTNumericComparator::CBTNumericComparator(CBTSecMan& aSecMan, TUint32 aNumericValue, TBTNumericComparisonParams::TComparisonScenario aComparisonScenario, TBool aInternallyInitiated)
       
  1674 	: CSecNotifierRequester(aSecMan)
       
  1675 	, iSecMan(aSecMan)
       
  1676 	, iNumericValue(aNumericValue)
       
  1677 	, iComparisonScenario(aComparisonScenario)
       
  1678 	, iInternallyInitiated(aInternallyInitiated)
       
  1679 	{
       
  1680 	LOG_FUNC
       
  1681 	CActiveScheduler::Add(this);
       
  1682 	}
       
  1683 
       
  1684 CBTNumericComparator::~CBTNumericComparator()
       
  1685 	{
       
  1686 	LOG_FUNC
       
  1687 	Cancel();
       
  1688 	delete iNameUpdater;
       
  1689 	}
       
  1690 
       
  1691 
       
  1692 void CBTNumericComparator::DoUpdateNotifier()
       
  1693 	{
       
  1694 	LOG_FUNC
       
  1695 	if(IsActive())
       
  1696 		{
       
  1697 		if(!iNameUpdater)
       
  1698 			{
       
  1699 			//Create a new CSecNotifierUpdateAO object
       
  1700 			TRAP_IGNORE(iNameUpdater = CSecNotifierUpdateAO<TBTDeviceNameUpdateParamsPckg>::NewL(iNotifier, KBTNumericComparisonNotifierUid));
       
  1701 			}
       
  1702 		if(iNameUpdater)
       
  1703 			{
       
  1704 			TBTDeviceName deviceName(KNullDesC);
       
  1705 			TInt err = KErrNotFound;
       
  1706 			if(iDeviceName)
       
  1707 				{
       
  1708 				TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt.
       
  1709 				}
       
  1710 
       
  1711 			TBTDeviceNameUpdateParamsPckg pckg = TBTDeviceNameUpdateParams(deviceName, err);
       
  1712 			iNameUpdater->DoUpdate(pckg);
       
  1713 			}
       
  1714 		}
       
  1715 	}
       
  1716 
       
  1717 void CBTNumericComparator::DoRequest()
       
  1718 /**
       
  1719 Start the RNotifier plugin that deals with authorisation.
       
  1720 **/
       
  1721 	{
       
  1722 	LOG_FUNC
       
  1723 	TInt err(KErrNone);
       
  1724 
       
  1725 	TBTDeviceName deviceName;
       
  1726 
       
  1727 	if (iDeviceName)
       
  1728 		{
       
  1729 		TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1730 		if (err!=KErrNone)
       
  1731 			{
       
  1732 			deviceName = KNullDesC;
       
  1733 			}
       
  1734 		}
       
  1735 	else
       
  1736 		{
       
  1737 		deviceName = KNullDesC;
       
  1738 		}
       
  1739 	iNumericComparisonParamsPckg = TBTNumericComparisonParams(iDevAddr, deviceName, iNumericValue, iComparisonScenario, iInternallyInitiated);
       
  1740 
       
  1741 	iNotifier.StartNotifierAndGetResponse(iStatus, KBTNumericComparisonNotifierUid, iNumericComparisonParamsPckg, iResultPckg);
       
  1742 	SetActive();
       
  1743 	}
       
  1744 
       
  1745 
       
  1746 void CBTNumericComparator::DoCancel()
       
  1747 	{
       
  1748 	LOG_FUNC
       
  1749 	iNotifier.CancelNotifier(KBTNumericComparisonNotifierUid);
       
  1750 	if(iNameUpdater)
       
  1751 		{
       
  1752 		iNameUpdater->Cancel();
       
  1753 		}
       
  1754 	}
       
  1755 
       
  1756 void CBTNumericComparator::RunL()
       
  1757 	{
       
  1758 	LOG_FUNC
       
  1759 	// got an answer so unload the notifier
       
  1760 	iNotifier.CancelNotifier(KBTNumericComparisonNotifierUid);
       
  1761 
       
  1762 	//remove ourself from the notifier que, allowing the next notifier to be activated
       
  1763 	RemoveMyselfFromQue();
       
  1764 	iIsAddedToNotifierQue = EFalse;
       
  1765 
       
  1766 	__ASSERT_DEBUG(iNumericComparisonParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress));
       
  1767 
       
  1768 	iSecMan.UserConfirmationComplete(iDevAddr, iResultPckg(), iStatus.Int());
       
  1769 	}
       
  1770 
       
  1771 TInt CBTNumericComparator::RunError(TInt aError)
       
  1772 	{
       
  1773 	LOG_FUNC
       
  1774 	//will never get called as our RunL doesn't leave.
       
  1775 	LOG1(_L8("\tCBTNumericComparator::RunError(%d)\n"), aError);
       
  1776 	return aError;
       
  1777 	}
       
  1778 
       
  1779 
       
  1780 //------------------------------------------------------------------------//
       
  1781 //class CBTPasskeyEntry
       
  1782 //------------------------------------------------------------------------//
       
  1783 CBTPasskeyEntry* CBTPasskeyEntry::NewL(const TBTDevAddr aAddr,
       
  1784 												 CBTSecMan& aSecMan,
       
  1785 												 TUint32 aNumericValue,
       
  1786 												 TBool aInternallyInitiated)
       
  1787 	{
       
  1788 	LOG_STATIC_FUNC
       
  1789 	CBTPasskeyEntry* s = CBTPasskeyEntry::NewLC(aAddr, aSecMan, /*aAccessRequester,*/ aNumericValue, aInternallyInitiated);
       
  1790 	CleanupStack::Pop(s);
       
  1791 	return s;
       
  1792 	}
       
  1793 
       
  1794 CBTPasskeyEntry* CBTPasskeyEntry::NewLC(const TBTDevAddr aAddr,
       
  1795 												  CBTSecMan& aSecMan,
       
  1796 												  TUint32 aNumericValue,
       
  1797 												  TBool aInternallyInitiated)
       
  1798 	{
       
  1799 	LOG_STATIC_FUNC
       
  1800 	CBTPasskeyEntry* s = new(ELeave) CBTPasskeyEntry(aSecMan, /*aAccessRequester,*/ aNumericValue, aInternallyInitiated);
       
  1801 	CleanupStack::PushL(s);
       
  1802 	s->ConstructL(aAddr);
       
  1803 	return s;
       
  1804 	}
       
  1805 
       
  1806 CBTPasskeyEntry::CBTPasskeyEntry(CBTSecMan& aSecMan,
       
  1807 								 TUint32 aNumericValue,
       
  1808 								 TBool aInternallyInitiated)
       
  1809 	: CSecNotifierRequester(aSecMan)
       
  1810 	, iSecMan(aSecMan)
       
  1811 	, iNumericValue(aNumericValue)
       
  1812 	, iInternallyInitiated(aInternallyInitiated)
       
  1813 	{
       
  1814 	LOG_FUNC
       
  1815 	CActiveScheduler::Add(this);
       
  1816 	}
       
  1817 
       
  1818 CBTPasskeyEntry::~CBTPasskeyEntry()
       
  1819 	{
       
  1820 	LOG_FUNC
       
  1821 	Cancel();
       
  1822 	delete iKeypressUpdater;
       
  1823 	delete iNameUpdater;
       
  1824 	}
       
  1825 
       
  1826 void CBTPasskeyEntry::KeyPressed(THCIPasskeyEntryNotificationType aKeyType)
       
  1827 	{
       
  1828 	LOG_FUNC
       
  1829 	if(IsActive())
       
  1830 		{
       
  1831 		if(!iKeypressUpdater)
       
  1832 			{
       
  1833 			//Create a new CSecNotifierUpdateAO object
       
  1834 			TRAP_IGNORE(iKeypressUpdater = CSecNotifierUpdateAO<TBTPasskeyDisplayUpdateParamsPckg>::NewL(iNotifier, KBTPasskeyDisplayNotifierUid));
       
  1835 			}
       
  1836 		if (iKeypressUpdater)
       
  1837 			{
       
  1838 			TBTPasskeyDisplayUpdateParamsPckg pckg = TBTPasskeyDisplayUpdateParams(aKeyType);
       
  1839 			iKeypressUpdater->DoUpdate(pckg);
       
  1840 			}
       
  1841 		}
       
  1842 	}
       
  1843 
       
  1844 void CBTPasskeyEntry::DoUpdateNotifier()
       
  1845 	{
       
  1846 	LOG_FUNC
       
  1847 	if(IsActive())
       
  1848 		{
       
  1849 		if(!iNameUpdater)
       
  1850 			{
       
  1851 			//Create a new CSecNotifierUpdateAO object
       
  1852 			TRAP_IGNORE(iNameUpdater = CSecNotifierUpdateAO<TBTDeviceNameUpdateParamsPckg>::NewL(iNotifier, KBTPasskeyDisplayNotifierUid));
       
  1853 			}
       
  1854 		if(iNameUpdater)
       
  1855 			{
       
  1856 			TBTDeviceName deviceName(KNullDesC);
       
  1857 			TInt err = KErrNotFound;
       
  1858 			if(iDeviceName)
       
  1859 				{
       
  1860 				TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt.
       
  1861 				}
       
  1862 			TBTDeviceNameUpdateParamsPckg pckg = TBTDeviceNameUpdateParams(deviceName, err);
       
  1863 			iNameUpdater->DoUpdate(pckg);
       
  1864 			}
       
  1865 		}
       
  1866 	}
       
  1867 
       
  1868 void CBTPasskeyEntry::DoRequest()
       
  1869 /**
       
  1870 Start the RNotifier plugin that deals with authorisation.
       
  1871 **/
       
  1872 	{
       
  1873 	LOG_FUNC
       
  1874 	TBTDeviceName deviceName;
       
  1875 
       
  1876 	if (iDeviceName)
       
  1877 		{
       
  1878 		TRAPD(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
       
  1879 		if (err!=KErrNone)
       
  1880 			{
       
  1881 			deviceName = KNullDesC;
       
  1882 			}
       
  1883 		}
       
  1884 	else
       
  1885 		{
       
  1886 		deviceName = KNullDesC;
       
  1887 		}
       
  1888 	iPasskeyDisplayParamsPckg = TBTPasskeyDisplayParams(iDevAddr, deviceName, iNumericValue, iInternallyInitiated);
       
  1889 
       
  1890 	iNotifier.StartNotifierAndGetResponse(iStatus, KBTPasskeyDisplayNotifierUid, iPasskeyDisplayParamsPckg, iResultPckg);
       
  1891 	SetActive();
       
  1892 	}
       
  1893 
       
  1894 
       
  1895 void CBTPasskeyEntry::DoCancel()
       
  1896 	{
       
  1897 	LOG_FUNC
       
  1898 	iNotifier.CancelNotifier(KBTPasskeyDisplayNotifierUid);
       
  1899 	if(iKeypressUpdater)
       
  1900 		{
       
  1901 		iKeypressUpdater->Cancel();
       
  1902 		}
       
  1903 	if(iNameUpdater)
       
  1904 		{
       
  1905 		iNameUpdater->Cancel();
       
  1906 		}
       
  1907 	}
       
  1908 
       
  1909 void CBTPasskeyEntry::RunL()
       
  1910 	{
       
  1911 	LOG_FUNC
       
  1912 	//got a PIN or error, so finish off: unload the plugin
       
  1913 	iNotifier.CancelNotifier(KBTPasskeyDisplayNotifierUid);
       
  1914 
       
  1915 	//remove ourself from the notifier que, allowing the next notifier to be activated
       
  1916 	RemoveMyselfFromQue();
       
  1917 	iIsAddedToNotifierQue = EFalse;
       
  1918 
       
  1919 	__ASSERT_DEBUG(iPasskeyDisplayParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress));
       
  1920 
       
  1921 	iSecMan.PasskeyNotificationComplete(iDevAddr, iStatus.Int());
       
  1922 	}
       
  1923 
       
  1924 TInt CBTPasskeyEntry::RunError(TInt aError)
       
  1925 	{
       
  1926 	LOG_FUNC
       
  1927 	//will never get called as our RunL doesn't leave.
       
  1928 	LOG1(_L8("\tCBTPasskeyEntry::RunError(%d)\n"), aError);
       
  1929 	return aError;
       
  1930 	}
       
  1931