|
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 |