382 iDevice = device; |
382 iDevice = device; |
383 |
383 |
384 // Store the result of the retrieval for usage later. |
384 // Store the result of the retrieval for usage later. |
385 iDeviceResult = aResult; |
385 iDeviceResult = aResult; |
386 |
386 |
387 // the HW asked earlier for a link key - we can respond now |
387 if (iLinkKeyRequestOutstanding) |
388 __ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress)); |
388 { |
389 if(iWaitingForLinkKeyFromRegistry) |
389 // the HW asked earlier for a link key - we can respond now |
390 { |
390 __ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress)); |
391 if (aResult == KErrNone && iDevice.IsValidLinkKey()) |
391 LinkKeyRequestResponseAttempt(ETrue); |
392 { |
392 } |
393 if ( iDevice.LinkKeyType() != ELinkKeyCombination) |
|
394 { |
|
395 if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) |
|
396 { |
|
397 LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) |
|
398 iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); |
|
399 } |
|
400 else |
|
401 if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) |
|
402 { |
|
403 LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) |
|
404 iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); |
|
405 } |
|
406 else |
|
407 { |
|
408 LOG(_L("CPhysicalLink: Issuing link key to HC now")) |
|
409 iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); |
|
410 } |
|
411 } |
|
412 else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled) |
|
413 { |
|
414 LOG(_L("CPhysicalLink: Issuing link key to HC now")) |
|
415 iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); |
|
416 } |
|
417 else |
|
418 { |
|
419 LOG(_L("CPhysicalLink: Current PIN code too short!")) |
|
420 iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); |
|
421 } |
|
422 } |
|
423 else |
|
424 { |
|
425 iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); |
|
426 } |
|
427 } |
|
428 iRequireAuthenticatedLinkKey = EFalse; |
|
429 iWaitingForLinkKeyFromRegistry = EFalse; |
|
430 |
393 |
431 RegistryTaskComplete(aHelper, aResult); // cleans up our helper |
394 RegistryTaskComplete(aHelper, aResult); // cleans up our helper |
432 } |
395 } |
433 |
396 |
434 void CPhysicalLink::RegistryTaskComplete(CBTRegistryHelperBase* aHelper, TRegistryUpdateStatus aRegUpdateStatus, TInt aResult) |
397 void CPhysicalLink::RegistryTaskComplete(CBTRegistryHelperBase* aHelper, TRegistryUpdateStatus aRegUpdateStatus, TInt aResult) |
706 { |
669 { |
707 TRAP_IGNORE(iLinksMan.HCIFacade().ReadRemoteExtendedFeaturesL(iHandle, KRemoteExtendedFeaturesPage1)); |
670 TRAP_IGNORE(iLinksMan.HCIFacade().ReadRemoteExtendedFeaturesL(iHandle, KRemoteExtendedFeaturesPage1)); |
708 } |
671 } |
709 else |
672 else |
710 { |
673 { |
711 // If the remote doesn't support extended features, then neither they support SSP |
674 // If the remote doesn't support extended features, then they cannot support SSP |
712 // (no way to indicate the host supported bit). So set it as disabled. |
675 // (no way to indicate the host supported bit). So set feature as disabled. |
713 TPhysicalLinkSimplePairingMode previousSetting = SimplePairingMode(); |
676 RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); |
714 __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingDisabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); |
|
715 iSimplePairingMode = EPhySimplePairingDisabled; |
|
716 if(SimplePairingMode() != previousSetting) |
|
717 { |
|
718 iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); |
|
719 } |
|
720 } |
677 } |
721 } |
678 } |
722 else |
679 else |
723 { |
680 { |
724 iRemoteFeatures = TBTFeatures(KInvalidRemoteFeatures); |
681 iRemoteFeatures = TBTFeatures(KInvalidRemoteFeatures); |
2833 // However, in UDEB we panic to raise awareness that the hardware is behaving incorrectly. |
2784 // However, in UDEB we panic to raise awareness that the hardware is behaving incorrectly. |
2834 __ASSERT_DEBUG(!iPinRequester, Panic(EBTConnectionPINRequestedTwice)); |
2785 __ASSERT_DEBUG(!iPinRequester, Panic(EBTConnectionPINRequestedTwice)); |
2835 |
2786 |
2836 SetAuthenticationPending(EPinRequestPending); // if not already set (because the remote initiated authentication). |
2787 SetAuthenticationPending(EPinRequestPending); // if not already set (because the remote initiated authentication). |
2837 |
2788 |
2838 __ASSERT_DEBUG(iSimplePairingMode != EPhySimplePairingEnabled, Panic(EBTSSPModeChangedDuringConnection)); |
|
2839 if (iSimplePairingMode == EPhySimplePairingUndefined) |
|
2840 { |
|
2841 iSimplePairingMode = EPhySimplePairingDisabled; |
|
2842 } |
|
2843 |
|
2844 if (!IsConnected()) |
2789 if (!IsConnected()) |
2845 { |
2790 { |
2846 iPeerInSecurityMode3 = ETrue; |
2791 // If the ACL to the peer device is not yet connected, and the peer has initiated |
2847 } |
2792 // authentication then it must be in security mode 3. This information is stored and |
2848 |
2793 // if the connection completes the link will be set as authenticated. |
2849 |
2794 SetPeerInSecurityMode3(); |
|
2795 } |
|
2796 |
|
2797 // We can receive "fast" PIN requests if the remote device initiates pairing and indicates |
|
2798 // it doesn't have a link key. If we see this then we know that we are not engaging in |
|
2799 // simple pairing on this particular link. |
|
2800 RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); |
|
2801 |
2850 if (iPinRequester) |
2802 if (iPinRequester) |
2851 { |
2803 { |
2852 return; |
2804 return; |
2853 } |
2805 } |
2854 |
2806 |
3054 } |
3006 } |
3055 |
3007 |
3056 return isPasskeyMinLengthOK; |
3008 return isPasskeyMinLengthOK; |
3057 } |
3009 } |
3058 |
3010 |
3059 void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& aAddr, MLinkKeyResponseHandler& /*aRequester*/) |
3011 void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& __DEBUG_ONLY(aAddr), MLinkKeyResponseHandler& /*aRequester*/) |
3060 { |
3012 { |
3061 LOG_FUNC |
3013 LOG_FUNC |
|
3014 __ASSERT_DEBUG(aAddr == BDAddr(), Panic(EBTConnectionBadDeviceAddress)); |
|
3015 ASSERT_DEBUG(!iLinkKeyRequestOutstanding); |
|
3016 |
|
3017 iLinkKeyRequestOutstanding = ETrue; |
|
3018 |
3062 // we don't keep a copy of the device record - we just leave the one copy with |
3019 // we don't keep a copy of the device record - we just leave the one copy with |
3063 // the baseband - it can tell us if there's a link key |
3020 // the baseband - it can tell us if there's a link key |
3064 // we can tell if the baseband has the device record or not |
3021 // we can tell if the baseband has the device record or not |
3065 |
3022 |
3066 SetAuthenticationPending(ELinkKeyRequestPending); //authentication process started by remote |
3023 SetAuthenticationPending(ELinkKeyRequestPending); //authentication process started by remote |
3068 // If the ACL to the peer device is not yet connected, and the peer has initiated |
3025 // If the ACL to the peer device is not yet connected, and the peer has initiated |
3069 // authentication then it must be in security mode 3. This information is stored and |
3026 // authentication then it must be in security mode 3. This information is stored and |
3070 // if the connection completes the link will be set as authenticated. |
3027 // if the connection completes the link will be set as authenticated. |
3071 if (!IsConnected()) |
3028 if (!IsConnected()) |
3072 { |
3029 { |
3073 iPeerInSecurityMode3 = ETrue; |
3030 SetPeerInSecurityMode3(); |
3074 } |
3031 } |
3075 |
3032 |
3076 if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address())) |
3033 if (iLinkKeyRequestOutstanding) |
3077 { |
3034 { // might have already been called via SetPeerInSecurityMode3() |
3078 // If we are doing DedicatedBonding then we should ignore the existing linkkey |
3035 LinkKeyRequestResponseAttempt(); |
3079 // in an attempt to generate a stronger one if possible. |
3036 } |
3080 // Security mode 3 is a odd case - because we get what looks like double pairing (the remote |
|
3081 // initiated pairing on connection, then the dedicated bonding pairing). So we have removed |
|
3082 // this feature for security mode 3 devices...they will have to suffer for their transgressions |
|
3083 LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply")); |
|
3084 iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); |
|
3085 iRequireAuthenticatedLinkKey = EFalse; |
|
3086 } |
|
3087 else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey()) |
|
3088 { |
|
3089 if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) |
|
3090 { |
|
3091 LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) |
|
3092 iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); |
|
3093 } |
|
3094 else |
|
3095 { |
|
3096 if (iDevice.LinkKeyType() != ELinkKeyCombination) |
|
3097 { |
|
3098 if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) |
|
3099 { |
|
3100 LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) |
|
3101 iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); |
|
3102 } |
|
3103 else |
|
3104 { |
|
3105 LOG(_L("CPhysicalLink: Issuing link key to HC now")) |
|
3106 iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey()); |
|
3107 } |
|
3108 } |
|
3109 else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled) |
|
3110 { |
|
3111 LOG(_L("CPhysicalLink: Issuing link key to HC now")) |
|
3112 iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey()); |
|
3113 } |
|
3114 else |
|
3115 { |
|
3116 LOG(_L("CPhysicalLink: Current PIN code too short!")) |
|
3117 iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); |
|
3118 } |
|
3119 } |
|
3120 iRequireAuthenticatedLinkKey = EFalse; |
|
3121 } |
|
3122 else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound) |
|
3123 { |
|
3124 LOG(_L("CPhysicalLink: No Link key available for the device")); |
|
3125 iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); |
|
3126 iRequireAuthenticatedLinkKey = EFalse; |
|
3127 } |
|
3128 else |
|
3129 { |
|
3130 LOG(_L("CPhysicalLink: Waiting for link key from Registry!")) |
|
3131 // we're still waiting for the device....we'll respond when it turns up |
|
3132 iWaitingForLinkKeyFromRegistry = ETrue; |
|
3133 } |
|
3134 |
|
3135 } |
3037 } |
3136 |
3038 |
3137 TInt CPhysicalLink::PINCodeRequestReply(const TBTDevAddr& aDevAddr, const TDesC8& aPin) const |
3039 TInt CPhysicalLink::PINCodeRequestReply(const TBTDevAddr& aDevAddr, const TDesC8& aPin) const |
3138 { |
3040 { |
3139 ASSERT_DEBUG(aDevAddr == this->BDAddr()); |
3041 ASSERT_DEBUG(aDevAddr == this->BDAddr()); |
3611 iIOCapsReceived = ETrue; |
3513 iIOCapsReceived = ETrue; |
3612 iIOCapability = aIOCapability; |
3514 iIOCapability = aIOCapability; |
3613 iOOBDataPresence = aOOBDataPresence; |
3515 iOOBDataPresence = aOOBDataPresence; |
3614 iAuthenticationRequirement = aAuthenticationRequirement; |
3516 iAuthenticationRequirement = aAuthenticationRequirement; |
3615 |
3517 |
3616 //If we haven't determined the SSP pairing mode till now then enable it and notify the state m/c. |
3518 // If we haven't determined the SSP pairing mode the link is operating in yet then enable it, |
3617 //This condition is to cater the fast remote device which responds very quickly, |
3519 // since we have received a I/O cap response the simple pairing must be enabled. |
3618 //even before we determine whether it supports simple pairing!*/ |
3520 // This condition is to cater the fast remote device which responds very quickly, |
3619 __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingEnabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); |
3521 // even before we determine whether it supports simple pairing! |
3620 if(SimplePairingMode() == EPhySimplePairingUndefined) |
3522 RemoteSimplePairingModeDetermined(EPhySimplePairingEnabled); |
3621 { |
|
3622 //Since we have received a I/O cap response the simple pairing must be enabled |
|
3623 iSimplePairingMode = EPhySimplePairingEnabled; |
|
3624 iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); |
|
3625 } |
|
3626 } |
3523 } |
3627 |
3524 |
3628 |
3525 |
3629 TBool CPhysicalLink::AuthWithMITM() const |
3526 TBool CPhysicalLink::AuthWithMITM() const |
3630 { |
3527 { |
3755 TBasebandTime CPhysicalLink::GetSniffInterval() const |
3652 TBasebandTime CPhysicalLink::GetSniffInterval() const |
3756 { |
3653 { |
3757 return iSniffInterval; |
3654 return iSniffInterval; |
3758 } |
3655 } |
3759 |
3656 |
|
3657 void CPhysicalLink::LinkKeyRequestResponseAttempt(TBool aForceResponse) |
|
3658 { |
|
3659 ASSERT_DEBUG(iLinkKeyRequestOutstanding); |
|
3660 |
|
3661 if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address())) |
|
3662 { |
|
3663 // If we are doing DedicatedBonding then we should ignore the existing linkkey |
|
3664 // in an attempt to generate a stronger one if possible. |
|
3665 // Security mode 3 is a odd case - because we get what looks like double pairing (the remote |
|
3666 // initiated pairing on connection, then the dedicated bonding pairing). So we have removed |
|
3667 // this feature for security mode 3 devices...they will have to suffer for their transgressions |
|
3668 LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply")); |
|
3669 DoLinkKeyResponse(EFalse); |
|
3670 iRequireAuthenticatedLinkKey = EFalse; |
|
3671 } |
|
3672 else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey()) |
|
3673 { |
|
3674 if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) |
|
3675 { |
|
3676 LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) |
|
3677 DoLinkKeyResponse(EFalse); |
|
3678 } |
|
3679 else if (iDevice.LinkKeyType() != ELinkKeyCombination) |
|
3680 { |
|
3681 if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) |
|
3682 { |
|
3683 LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) |
|
3684 DoLinkKeyResponse(EFalse); |
|
3685 } |
|
3686 else |
|
3687 { |
|
3688 LOG(_L("CPhysicalLink: non - combination key, auth OK")) |
|
3689 DoLinkKeyResponse(ETrue); |
|
3690 } |
|
3691 } |
|
3692 else // Standard (legacy) Combination Key |
|
3693 { |
|
3694 if (SimplePairingMode() == EPhySimplePairingUndefined) |
|
3695 { |
|
3696 LOG(_L("CPhysicalLink: Waiting for Secure Simple Pairing mode to be determined")); |
|
3697 // wait for ssp mode to be determined...then try again |
|
3698 } |
|
3699 else if (IsPasskeyMinLengthOK() && SimplePairingMode() == EPhySimplePairingDisabled) |
|
3700 { |
|
3701 LOG(_L("CPhysicalLink: Combination key, Passkey len OK, no SSP")); |
|
3702 DoLinkKeyResponse(ETrue); |
|
3703 } |
|
3704 else |
|
3705 { |
|
3706 LOG(_L("CPhysicalLink: Current link key is not sufficient!")) |
|
3707 DoLinkKeyResponse(EFalse); |
|
3708 } |
|
3709 } |
|
3710 iRequireAuthenticatedLinkKey = EFalse; |
|
3711 } |
|
3712 else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound) |
|
3713 { |
|
3714 LOG(_L("CPhysicalLink: No Link key available for the device")); |
|
3715 DoLinkKeyResponse(EFalse); |
|
3716 iRequireAuthenticatedLinkKey = EFalse; |
|
3717 } |
|
3718 else if (aForceResponse) |
|
3719 { |
|
3720 LOG(_L("CPhysicalLink: Forcing a link key response (-ve as we don't have a link key yet)")); |
|
3721 DoLinkKeyResponse(EFalse); |
|
3722 } |
|
3723 else |
|
3724 { |
|
3725 LOG(_L("CPhysicalLink: Waiting for link key from Registry!")) |
|
3726 // we're still waiting for the device....we'll respond when it turns up |
|
3727 } |
|
3728 } |
|
3729 |
|
3730 /** |
|
3731 Send a link key response for an outstanding request, assumes that all details |
|
3732 have be validated. |
|
3733 */ |
|
3734 void CPhysicalLink::DoLinkKeyResponse(TBool aPositive) |
|
3735 { |
|
3736 LOG_FUNC |
|
3737 ASSERT_DEBUG(iLinkKeyRequestOutstanding); |
|
3738 |
|
3739 if(aPositive) |
|
3740 { |
|
3741 LOG(_L("CPhysicalLink: Providing link key to HC...")) |
|
3742 ASSERT_DEBUG(iDevice.IsValidLinkKey()); |
|
3743 iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); |
|
3744 } |
|
3745 else |
|
3746 { |
|
3747 LOG(_L("CPhysicalLink: Indicating no link key to HC...")); |
|
3748 iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); |
|
3749 } |
|
3750 iLinkKeyRequestOutstanding = EFalse; |
|
3751 } |
|
3752 |
|
3753 void CPhysicalLink::RemoteSimplePairingModeDetermined(TPhysicalLinkSimplePairingMode aSimplePairingMode) |
|
3754 { |
|
3755 LOG2(_L8("Current SimplePairingMode = %d, aSimplePairingMode = %d"), SimplePairingMode(), aSimplePairingMode); |
|
3756 ASSERT_DEBUG(aSimplePairingMode != EPhySimplePairingUndefined); // must be a definite value |
|
3757 __ASSERT_DEBUG(SimplePairingMode() == aSimplePairingMode || SimplePairingMode() == EPhySimplePairingUndefined, Panic(EBTSSPModeChangedDuringConnection)); |
|
3758 |
|
3759 const TPhysicalLinkSimplePairingMode previousSetting = iSimplePairingMode; |
|
3760 iSimplePairingMode = aSimplePairingMode; |
|
3761 if (previousSetting != iSimplePairingMode) |
|
3762 { |
|
3763 iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); |
|
3764 |
|
3765 // Also we may be waiting to respond to a link key request. |
|
3766 if (iLinkKeyRequestOutstanding) |
|
3767 { |
|
3768 LinkKeyRequestResponseAttempt(); |
|
3769 } |
|
3770 } |
|
3771 } |
|
3772 |
|
3773 void CPhysicalLink::SetPeerInSecurityMode3() |
|
3774 { |
|
3775 iPeerInSecurityMode3 = ETrue; |
|
3776 |
|
3777 // We also now know that the remote cannot possibly do SSP, *and* the LMP will |
|
3778 // likely lock our finding if the remote does SSP anyway while we do SM3. |
|
3779 RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); |
|
3780 } |
|
3781 |
3760 // |
3782 // |
3761 // TLowPowModeCmdController |
3783 // TLowPowModeCmdController |
3762 // |
3784 // |
3763 |
3785 |
3764 TLowPowModeCmdController::TLowPowModeCmdController(CPhysicalLink& aLink, MHCICommandQueue& aCmdController) : |
3786 TLowPowModeCmdController::TLowPowModeCmdController(CPhysicalLink& aLink, MHCICommandQueue& aCmdController) : |