diff -r 8a27654f7b62 -r 20fda83a6398 bluetooth/btstack/secman/secman.cpp --- a/bluetooth/btstack/secman/secman.cpp Fri Mar 12 15:49:00 2010 +0200 +++ b/bluetooth/btstack/secman/secman.cpp Mon Mar 15 12:44:59 2010 +0200 @@ -555,6 +555,7 @@ CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr); __ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing)); __ASSERT_DEBUG(!link->InstanceNumericComparator(), PANIC(KBTSecPanic, EBTSecConnectionNumericComparisonTwice)); + __ASSERT_DEBUG(!link->InstanceUserConfirmer(), PANIC(KBTSecPanic, EBTSecConnectionUserConfirmationTwice)); if(link->InstanceNumericComparator()) { return; @@ -581,6 +582,22 @@ } } } + else if (!link->IsPairingExpected()) + { + TRAPD(err,link->NewUserConfirmerL(aAddr, *this, ETrue)); + if(err) + { + if(requester) + { + requester->CompleteRequest(EBTSecManAccessDenied); + } + else + { + TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr)); + return;// No passkey or comparison dialogs; disconnect instead + } + } + } else { // Just Work... @@ -596,7 +613,7 @@ } } -void CBTSecMan::UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError) +void CBTSecMan::NumericComparisonComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError) { LOG_FUNC CBTAccessRequester* requester = FindActiveAccessRequester(aAddr); @@ -642,6 +659,63 @@ link->DeleteNumericComparator(); } +void CBTSecMan::UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError) + { + LOG_FUNC + CBTAccessRequester* requester = FindActiveAccessRequester(aAddr); + if (requester) + { + LOG(_L8("\tCBTAccessRequester FOUND!\n")); + if (aError == KErrNone) + { + TBTSecEventUserConfirmationComplete event(aResult); + requester->SendEvent(event); + } + else if (aError == KErrNotFound) // KErrNotFound -> Notifier isn't present, so allow anyway + { + TBTSecEventUserConfirmationComplete event(ETrue); + requester->SendEvent(event); + } + else + { + TBTSecEventUserConfirmationComplete event(EFalse); // Failed, so send EFalse + requester->SendEvent(event); + } + } + + CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr); + __ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing)); + + if (aError==KErrNotFound) // KErrNotFound -> Notifier isn't present, so allow anyway + { + link->PinRequestSent(); + // note: -- check errors here + TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr)); + } + else if (aError!=KErrNone) + { + // there was an error somewhere a long the way so respond negatively + // note: -- check errors here + TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr)); + } + else + { + // got a result + if(aResult) + { + link->PinRequestSent(); + // note: -- check errors here + TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr)); + } + else + { + // note: -- check errors here + TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr)); + } + } + link->DeleteUserConfirmer(); + } + void CBTSecMan::PasskeyNotification(const TBTDevAddr& aAddr, TUint32 aPasskey) { LOG_FUNC @@ -806,9 +880,13 @@ if (link->InstanceNumericComparator() && link->IsNumericComparatorActive()) { link->CancelNumericComparator(); + NumericComparisonComplete(aAddr, EFalse, err); + } + if (link->InstanceUserConfirmer() && link->IsUserConfirmerActive()) + { + link->CancelUserConfirmer(); UserConfirmationComplete(aAddr, EFalse, err); } - iPhysicalLinksManager->SimplePairingComplete(aAddr, aError); // Add result to list (always with HCI error code). @@ -1753,7 +1831,7 @@ __ASSERT_DEBUG(iNumericComparisonParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress)); - iSecMan.UserConfirmationComplete(iDevAddr, iResultPckg(), iStatus.Int()); + iSecMan.NumericComparisonComplete(iDevAddr, iResultPckg(), iStatus.Int()); } TInt CBTNumericComparator::RunError(TInt aError) @@ -1917,3 +1995,133 @@ return aError; } +//------------------------------------------------------------------------// +//class CBTNumericComparator +//------------------------------------------------------------------------// +CBTUserConfirmer* CBTUserConfirmer::NewL(const TBTDevAddr aAddr, + CBTSecMan& aSecMan, + TBool aInternallyInitiated) + { + LOG_STATIC_FUNC + CBTUserConfirmer* s = CBTUserConfirmer::NewLC(aAddr, aSecMan, aInternallyInitiated); + CleanupStack::Pop(s); + return s; + } + +CBTUserConfirmer* CBTUserConfirmer::NewLC(const TBTDevAddr aAddr, + CBTSecMan& aSecMan, + TBool aInternallyInitiated) + { + LOG_STATIC_FUNC + CBTUserConfirmer* s = new(ELeave) CBTUserConfirmer(aSecMan, aInternallyInitiated); + CleanupStack::PushL(s); + s->ConstructL(aAddr); + return s; + } + +CBTUserConfirmer::CBTUserConfirmer(CBTSecMan& aSecMan, TBool aInternallyInitiated) + : CSecNotifierRequester(aSecMan) + , iSecMan(aSecMan) + , iInternallyInitiated(aInternallyInitiated) + { + LOG_FUNC + CActiveScheduler::Add(this); + } + +CBTUserConfirmer::~CBTUserConfirmer() + { + LOG_FUNC + Cancel(); + delete iNameUpdater; + } + + +void CBTUserConfirmer::DoUpdateNotifier() + { + LOG_FUNC + if(IsActive()) + { + if(!iNameUpdater) + { + //Create a new CSecNotifierUpdateAO object + TRAP_IGNORE(iNameUpdater = CSecNotifierUpdateAO::NewL(iNotifier, KBTUserConfirmationNotifierUid)); + } + if(iNameUpdater) + { + TBTDeviceName deviceName(KNullDesC); + TInt err = KErrNotFound; + if(iDeviceName) + { + TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt. + } + + TBTDeviceNameUpdateParamsPckg pckg = TBTDeviceNameUpdateParams(deviceName, err); + iNameUpdater->DoUpdate(pckg); + } + } + } + +void CBTUserConfirmer::DoRequest() +/** +Start the RNotifier plugin that deals with authorisation. +**/ + { + LOG_FUNC + TInt err(KErrNone); + + TBTDeviceName deviceName; + + if (iDeviceName) + { + TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); + if (err!=KErrNone) + { + deviceName = KNullDesC; + } + } + else + { + deviceName = KNullDesC; + } + iUserConfirmationParamsPckg = TBTUserConfirmationParams(iDevAddr, deviceName, iInternallyInitiated); + + iNotifier.StartNotifierAndGetResponse(iStatus, KBTUserConfirmationNotifierUid, iUserConfirmationParamsPckg, iResultPckg); + SetActive(); + } + + +void CBTUserConfirmer::DoCancel() + { + LOG_FUNC + iNotifier.CancelNotifier(KBTUserConfirmationNotifierUid); + if(iNameUpdater) + { + iNameUpdater->Cancel(); + } + } + +void CBTUserConfirmer::RunL() + { + LOG_FUNC + // got an answer so unload the notifier + iNotifier.CancelNotifier(KBTUserConfirmationNotifierUid); + + //remove ourself from the notifier que, allowing the next notifier to be activated + RemoveMyselfFromQue(); + iIsAddedToNotifierQue = EFalse; + + __ASSERT_DEBUG(iUserConfirmationParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress)); + + iSecMan.UserConfirmationComplete(iDevAddr, iResultPckg(), iStatus.Int()); + } + +TInt CBTUserConfirmer::RunError(TInt aError) + { + LOG_FUNC + //will never get called as our RunL doesn't leave. + LOG1(_L8("\tCBTUserConfirmation::RunError(%d)\n"), aError); + return aError; + } + + +