# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1268401740 -7200 # Node ID 8a27654f7b62a073679c046522cd22ae6c37351a # Parent 2b6718f05bdb3ee3386dae8f24d6e2b8c2346c57 Revision: 201001 Kit: 201008 diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/l2cap/L2CapFecNegotiator.cpp --- a/bluetooth/btstack/l2cap/L2CapFecNegotiator.cpp Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/l2cap/L2CapFecNegotiator.cpp Fri Mar 12 15:49:00 2010 +0200 @@ -53,6 +53,26 @@ // Just send what we've got in Preferred. } +void TModeSpecificFecOptionHandlerBase::BuildRequestBasedOnUnacceptableParamsResponse( + TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const + { + LOG_FUNC + // In general the only negotiable parameter is channel mode - that's what we should + // take from the suggested response passed here in aPeer. The rest of the parameters are + // informative and we should use our own values, based on the mode - the remote can not + // reject informative parameters. + // Note on interop: + // Unfortunately <= 9.4 Symbian code _WILL_ reject if e.g. we send a MaxTransmit value + // which is greater than its own preference. To interoperate with those this method is + // overridden in the Legacy handler. + + aPreferred = TRetransmissionAndFlowControlOption(aPeer.LinkMode(), ETrue); + SetMaxTransmit(aPreferred, aFecNegotiator.MaxTransmit()); + ZeroUnspecifiedRequestFields(aPreferred); + } + void TModeSpecificFecOptionHandlerBase::SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 /*aMaxTransmit*/) const { LOG_FUNC @@ -250,6 +270,47 @@ aMaxTransmit); } +void TLegacyFecHandler::BuildRequestBasedOnUnacceptableParamsResponse( + TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const + { + LOG_FUNC + // In general the only negotiable parameter is channel mode - that's what we should + // take from the suggested response passed here in aPeer. The rest of the parameters are + // informative and we should use our own values, based on the mode - the remote can not + // reject informative parameters. + // + // HOWEVER: + // + // Unfortunately <= 9.4 Symbian code _WILL_ reject if e.g. we send a MaxTransmit value + // which is greater than its own preference. To interoperate with those we take + // the whole FEC option suggested by the remote, including the informational parameters. + // <= 9.4 Symbian devices implement RTM and FC modes (and not ERTM and Streaming). + // Additionally, pretty much noone else in the market does - most people jumped from + // Basic straight to ERTM & Streaming. So it can be assumed that: + // Legacy (RTM & FC) ~= pre-ERTM Symbian. + + typedef TRetransmissionAndFlowControlOption TFec; // just 'coz I'm lazy + + // Use the remote's whole suggestion if all informational parameters look edible ... + if (aPeer.TxWindowSize() >= TFec::KMinValidTxWindowSize && + aPeer.MaxTransmit() >= TFec::KMinValidNumberTransmit && + aPeer.RetransmissionTimeout() >= TFec::KMinAcceptableRetransmissionTimeout && + aPeer.MonitorTimeout() >= TFec::KMinAcceptableMonitorTimeout && + aPeer.MaximumPDUSize() >= TFec::KMinValidMaximumPDUSize) + { + aPreferred = aPeer; + } + else // ... otherwise only use channel mode to prevent DoS attacks. + { + aPreferred = TRetransmissionAndFlowControlOption(aPeer.LinkMode(), ETrue); + SetMaxTransmit(aPreferred, aFecNegotiator.MaxTransmit()); + ZeroUnspecifiedRequestFields(aPreferred); + } + } + + // Basic mode TBool TBasicFecHandler::IsOptionValid(const TRetransmissionAndFlowControlOption& /*aFecOption*/) const @@ -476,9 +537,9 @@ if (aIsUnacceptableParameters) { iConfigStatus = EOptionConfigOutstanding; - // Only take the channel mode from peer's proposal and set informational - // (i.e. all other) parameters to our values. - BuildRequest(aFecOption.LinkMode(), iPreferred); + // Build a new request based on suggestion sent by the peer. + iFecNegotiator.ModeSpecificHandlers().BuildRequestBasedOnUnacceptableParamsResponse( + iPreferred, iPeer, iFecNegotiator); } else { diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/l2cap/L2CapFecNegotiator.h --- a/bluetooth/btstack/l2cap/L2CapFecNegotiator.h Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/l2cap/L2CapFecNegotiator.h Fri Mar 12 15:49:00 2010 +0200 @@ -46,6 +46,12 @@ const TRetransmissionAndFlowControlOption& aPeer) const; virtual void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, const TRetransmissionAndFlowControlOption& aPeer) const; + + virtual void BuildRequestBasedOnUnacceptableParamsResponse( + TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const; + // In general configuration procedure (spec chapter 7 General Procedures) if the remote accepts // an option from our ConfigReq, it doesn't have to include it in the response. So before // processing the options from a ConfigRsp we've received, we go through the preferred values @@ -104,6 +110,11 @@ virtual TBool IsOptionValid(const TRetransmissionAndFlowControlOption& aFecOption) const; virtual TBool IsPeerResponseAcceptable(const TRetransmissionAndFlowControlOption& aPreferred, const TRetransmissionAndFlowControlOption& aPeer) const; + virtual void BuildRequestBasedOnUnacceptableParamsResponse( + TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const; + virtual void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; }; @@ -132,6 +143,9 @@ const TRetransmissionAndFlowControlOption& aPeer) const; inline void BuildNegativeResponse(TRetransmissionAndFlowControlOption& aPreferred, const TRetransmissionAndFlowControlOption& aPeer) const; + inline void BuildRequestBasedOnUnacceptableParamsResponse(TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const; inline void PrepareImplicitPeerResponse(TRetransmissionAndFlowControlOption& aImplicitResponse, const TRetransmissionAndFlowControlOption& aPreferred) const; inline void SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 aMaxTransmit) const; diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/l2cap/L2CapFecNegotiator.inl --- a/bluetooth/btstack/l2cap/L2CapFecNegotiator.inl Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/l2cap/L2CapFecNegotiator.inl Fri Mar 12 15:49:00 2010 +0200 @@ -72,6 +72,19 @@ Handler(aPreferred).BuildNegativeResponse(aPreferred, aPeer); } +inline void +TFecOptionHandlerDelegator::BuildRequestBasedOnUnacceptableParamsResponse( + TRetransmissionAndFlowControlOption& aPreferred, + const TRetransmissionAndFlowControlOption& aPeer, + const TL2CapFecNegotiator& aFecNegotiator) const + { +#ifdef __FLOG_ACTIVE + LogCurrentValues(aPreferred, aPeer); +#endif + // Response has suggested mode, dispatch on that. + Handler(aPeer).BuildRequestBasedOnUnacceptableParamsResponse(aPreferred, aPeer, aFecNegotiator); + } + inline void TFecOptionHandlerDelegator::PrepareImplicitPeerResponse(TRetransmissionAndFlowControlOption& aImplicitResponse, const TRetransmissionAndFlowControlOption& aPreferred) const { diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/linkmgr/physicallinks.cpp --- a/bluetooth/btstack/linkmgr/physicallinks.cpp Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Fri Mar 12 15:49:00 2010 +0200 @@ -384,49 +384,12 @@ // Store the result of the retrieval for usage later. iDeviceResult = aResult; - // the HW asked earlier for a link key - we can respond now - __ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress)); - if(iWaitingForLinkKeyFromRegistry) + if (iLinkKeyRequestOutstanding) { - if (aResult == KErrNone && iDevice.IsValidLinkKey()) - { - if ( iDevice.LinkKeyType() != ELinkKeyCombination) - { - if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) - { - LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); - } - else - if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) - { - LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); - } - else - { - LOG(_L("CPhysicalLink: Issuing link key to HC now")) - iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); - } - } - else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled) - { - LOG(_L("CPhysicalLink: Issuing link key to HC now")) - iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); - } - else - { - LOG(_L("CPhysicalLink: Current PIN code too short!")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); - } - } - else - { - iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); - } + // the HW asked earlier for a link key - we can respond now + __ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress)); + LinkKeyRequestResponseAttempt(ETrue); } - iRequireAuthenticatedLinkKey = EFalse; - iWaitingForLinkKeyFromRegistry = EFalse; RegistryTaskComplete(aHelper, aResult); // cleans up our helper } @@ -708,15 +671,9 @@ } else { - // If the remote doesn't support extended features, then neither they support SSP - // (no way to indicate the host supported bit). So set it as disabled. - TPhysicalLinkSimplePairingMode previousSetting = SimplePairingMode(); - __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingDisabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); - iSimplePairingMode = EPhySimplePairingDisabled; - if(SimplePairingMode() != previousSetting) - { - iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); - } + // If the remote doesn't support extended features, then they cannot support SSP + // (no way to indicate the host supported bit). So set feature as disabled. + RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); } } else @@ -740,18 +697,12 @@ if (aErr == EOK && aBitMask & (1 << ESecureSimplePairingHostSupportBit) && iLinksMan.SecMan().LocalSimplePairingMode()) { - __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingEnabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); - iSimplePairingMode = EPhySimplePairingEnabled; + RemoteSimplePairingModeDetermined(EPhySimplePairingEnabled); } else { - __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingDisabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); - iSimplePairingMode = EPhySimplePairingDisabled; + RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); } - if(SimplePairingMode()!=currentSetting) - { - iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); - } break; } default: @@ -2835,18 +2786,19 @@ SetAuthenticationPending(EPinRequestPending); // if not already set (because the remote initiated authentication). - __ASSERT_DEBUG(iSimplePairingMode != EPhySimplePairingEnabled, Panic(EBTSSPModeChangedDuringConnection)); - if (iSimplePairingMode == EPhySimplePairingUndefined) - { - iSimplePairingMode = EPhySimplePairingDisabled; - } - if (!IsConnected()) { - iPeerInSecurityMode3 = ETrue; + // If the ACL to the peer device is not yet connected, and the peer has initiated + // authentication then it must be in security mode 3. This information is stored and + // if the connection completes the link will be set as authenticated. + SetPeerInSecurityMode3(); } - + // We can receive "fast" PIN requests if the remote device initiates pairing and indicates + // it doesn't have a link key. If we see this then we know that we are not engaging in + // simple pairing on this particular link. + RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); + if (iPinRequester) { return; @@ -3056,9 +3008,14 @@ return isPasskeyMinLengthOK; } -void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& aAddr, MLinkKeyResponseHandler& /*aRequester*/) +void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& __DEBUG_ONLY(aAddr), MLinkKeyResponseHandler& /*aRequester*/) { LOG_FUNC + __ASSERT_DEBUG(aAddr == BDAddr(), Panic(EBTConnectionBadDeviceAddress)); + ASSERT_DEBUG(!iLinkKeyRequestOutstanding); + + iLinkKeyRequestOutstanding = ETrue; + // we don't keep a copy of the device record - we just leave the one copy with // the baseband - it can tell us if there's a link key // we can tell if the baseband has the device record or not @@ -3070,68 +3027,13 @@ // if the connection completes the link will be set as authenticated. if (!IsConnected()) { - iPeerInSecurityMode3 = ETrue; - } - - if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address())) - { - // If we are doing DedicatedBonding then we should ignore the existing linkkey - // in an attempt to generate a stronger one if possible. - // Security mode 3 is a odd case - because we get what looks like double pairing (the remote - // initiated pairing on connection, then the dedicated bonding pairing). So we have removed - // this feature for security mode 3 devices...they will have to suffer for their transgressions - LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply")); - iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); - iRequireAuthenticatedLinkKey = EFalse; + SetPeerInSecurityMode3(); } - else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey()) - { - if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) - { - LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); - } - else - { - if (iDevice.LinkKeyType() != ELinkKeyCombination) - { - if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) - { - LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); - } - else - { - LOG(_L("CPhysicalLink: Issuing link key to HC now")) - iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey()); - } - } - else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled) - { - LOG(_L("CPhysicalLink: Issuing link key to HC now")) - iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey()); - } - else - { - LOG(_L("CPhysicalLink: Current PIN code too short!")) - iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); - } - } - iRequireAuthenticatedLinkKey = EFalse; + + if (iLinkKeyRequestOutstanding) + { // might have already been called via SetPeerInSecurityMode3() + LinkKeyRequestResponseAttempt(); } - else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound) - { - LOG(_L("CPhysicalLink: No Link key available for the device")); - iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr); - iRequireAuthenticatedLinkKey = EFalse; - } - else - { - LOG(_L("CPhysicalLink: Waiting for link key from Registry!")) - // we're still waiting for the device....we'll respond when it turns up - iWaitingForLinkKeyFromRegistry = ETrue; - } - } TInt CPhysicalLink::PINCodeRequestReply(const TBTDevAddr& aDevAddr, const TDesC8& aPin) const @@ -3613,16 +3515,11 @@ iOOBDataPresence = aOOBDataPresence; iAuthenticationRequirement = aAuthenticationRequirement; - //If we haven't determined the SSP pairing mode till now then enable it and notify the state m/c. - //This condition is to cater the fast remote device which responds very quickly, - //even before we determine whether it supports simple pairing!*/ - __ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingEnabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection)); - if(SimplePairingMode() == EPhySimplePairingUndefined) - { - //Since we have received a I/O cap response the simple pairing must be enabled - iSimplePairingMode = EPhySimplePairingEnabled; - iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); - } + // If we haven't determined the SSP pairing mode the link is operating in yet then enable it, + // since we have received a I/O cap response the simple pairing must be enabled. + // This condition is to cater the fast remote device which responds very quickly, + // even before we determine whether it supports simple pairing! + RemoteSimplePairingModeDetermined(EPhySimplePairingEnabled); } @@ -3757,6 +3654,131 @@ return iSniffInterval; } +void CPhysicalLink::LinkKeyRequestResponseAttempt(TBool aForceResponse) + { + ASSERT_DEBUG(iLinkKeyRequestOutstanding); + + if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address())) + { + // If we are doing DedicatedBonding then we should ignore the existing linkkey + // in an attempt to generate a stronger one if possible. + // Security mode 3 is a odd case - because we get what looks like double pairing (the remote + // initiated pairing on connection, then the dedicated bonding pairing). So we have removed + // this feature for security mode 3 devices...they will have to suffer for their transgressions + LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply")); + DoLinkKeyResponse(EFalse); + iRequireAuthenticatedLinkKey = EFalse; + } + else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey()) + { + if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug) + { + LOG(_L("CPhysicalLink: Debug mode - Link to debug link key")) + DoLinkKeyResponse(EFalse); + } + else if (iDevice.LinkKeyType() != ELinkKeyCombination) + { + if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable()) + { + LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated")) + DoLinkKeyResponse(EFalse); + } + else + { + LOG(_L("CPhysicalLink: non - combination key, auth OK")) + DoLinkKeyResponse(ETrue); + } + } + else // Standard (legacy) Combination Key + { + if (SimplePairingMode() == EPhySimplePairingUndefined) + { + LOG(_L("CPhysicalLink: Waiting for Secure Simple Pairing mode to be determined")); + // wait for ssp mode to be determined...then try again + } + else if (IsPasskeyMinLengthOK() && SimplePairingMode() == EPhySimplePairingDisabled) + { + LOG(_L("CPhysicalLink: Combination key, Passkey len OK, no SSP")); + DoLinkKeyResponse(ETrue); + } + else + { + LOG(_L("CPhysicalLink: Current link key is not sufficient!")) + DoLinkKeyResponse(EFalse); + } + } + iRequireAuthenticatedLinkKey = EFalse; + } + else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound) + { + LOG(_L("CPhysicalLink: No Link key available for the device")); + DoLinkKeyResponse(EFalse); + iRequireAuthenticatedLinkKey = EFalse; + } + else if (aForceResponse) + { + LOG(_L("CPhysicalLink: Forcing a link key response (-ve as we don't have a link key yet)")); + DoLinkKeyResponse(EFalse); + } + else + { + LOG(_L("CPhysicalLink: Waiting for link key from Registry!")) + // we're still waiting for the device....we'll respond when it turns up + } + } + +/** +Send a link key response for an outstanding request, assumes that all details +have be validated. +*/ +void CPhysicalLink::DoLinkKeyResponse(TBool aPositive) + { + LOG_FUNC + ASSERT_DEBUG(iLinkKeyRequestOutstanding); + + if(aPositive) + { + LOG(_L("CPhysicalLink: Providing link key to HC...")) + ASSERT_DEBUG(iDevice.IsValidLinkKey()); + iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey()); + } + else + { + LOG(_L("CPhysicalLink: Indicating no link key to HC...")); + iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address()); + } + iLinkKeyRequestOutstanding = EFalse; + } + +void CPhysicalLink::RemoteSimplePairingModeDetermined(TPhysicalLinkSimplePairingMode aSimplePairingMode) + { + LOG2(_L8("Current SimplePairingMode = %d, aSimplePairingMode = %d"), SimplePairingMode(), aSimplePairingMode); + ASSERT_DEBUG(aSimplePairingMode != EPhySimplePairingUndefined); // must be a definite value + __ASSERT_DEBUG(SimplePairingMode() == aSimplePairingMode || SimplePairingMode() == EPhySimplePairingUndefined, Panic(EBTSSPModeChangedDuringConnection)); + + const TPhysicalLinkSimplePairingMode previousSetting = iSimplePairingMode; + iSimplePairingMode = aSimplePairingMode; + if (previousSetting != iSimplePairingMode) + { + iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr()); + + // Also we may be waiting to respond to a link key request. + if (iLinkKeyRequestOutstanding) + { + LinkKeyRequestResponseAttempt(); + } + } + } + +void CPhysicalLink::SetPeerInSecurityMode3() + { + iPeerInSecurityMode3 = ETrue; + + // We also now know that the remote cannot possibly do SSP, *and* the LMP will + // likely lock our finding if the remote does SSP anyway while we do SM3. + RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled); + } + // // TLowPowModeCmdController // diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/linkmgr/physicallinks.h --- a/bluetooth/btstack/linkmgr/physicallinks.h Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/linkmgr/physicallinks.h Fri Mar 12 15:49:00 2010 +0200 @@ -487,6 +487,12 @@ inline TBool IsAuthenticationPending() const; + void LinkKeyRequestResponseAttempt(TBool aForceResponse = EFalse); + void DoLinkKeyResponse(TBool aPositive); + + void RemoteSimplePairingModeDetermined(TPhysicalLinkSimplePairingMode aSimplePairingMode); + void SetPeerInSecurityMode3(); + private: // from MPINCodeResponseHandler TInt PINCodeRequestReply(const TBTDevAddr& aDevAddr,const TDesC8& aPin) const; TInt PINCodeRequestNegativeReply(const TBTDevAddr& aDevAddr) const; @@ -519,9 +525,11 @@ // the PHY's supported logical links... RPointerArray iACLLogicalLinks; CBTSynchronousLink* iSyncLogicalLink; // stack only supports a signal one per PHY - + + TBool iLinkKeyRequestOutstanding; // for if we have to wait for Registry or SSP support status - MPINCodeResponseHandler* iPinHandler; + MPINCodeResponseHandler* iPinHandler; // for forwarding responses to + TBTConnect iLastPendingConnection; // for if we have to wait for Registry to decide whether to rject or accept a connection TBool iPendingConnection; // is a connection request waiting for a reply TSglQue iProxySAPs; // the proxies bound to us @@ -571,8 +579,6 @@ TBool iNewPinCodeValid; TBTPinCode iNewPinCode; - TBool iWaitingForLinkKeyFromRegistry; - private: /** Enumeration to represent the current state of the physical links storage in the registry, diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/secman/pairingserver.cpp --- a/bluetooth/btstack/secman/pairingserver.cpp Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/secman/pairingserver.cpp Fri Mar 12 15:49:00 2010 +0200 @@ -775,12 +775,18 @@ iProxySap = CBTProxySAP::NewL(iPhysicalLinksManager, NULL); CleanupStack::Pop(this); // the start message cleaner - + + // Now we've entered the realm of not leaving with an error, since the connection + // process has started. Errors from now on must be via the Error() function call. iState = EInitialConnectionPending; iProxySap->SetNotify(this); iProxySap->SetRemName(addr); iProxySap->ActiveOpen(); - DoAccessRequestL(); + TRAPD(err, DoAccessRequestL()); + if(err != KErrNone) + { + Error(err); + } } void CDedicatedBondingSession::CleanupStartMessage(TAny* aPtr) @@ -816,7 +822,11 @@ addr.SetBTAddr(iProxySap->RemoteAddress()); iProxySap->SetRemName(addr); // triggers finding a link again. iProxySap->ActiveOpen(); - DoAccessRequestL(); + TRAPD(err, DoAccessRequestL()); + if(err != KErrNone) + { + Error(err); + } break; } // else not deferred so complete now.... @@ -864,7 +874,7 @@ __ASSERT_DEBUG(EFalse, PANIC(KPairingServerFaultCat, EPairingServerUnexpectedSocketCallback)); } -void CDedicatedBondingSession::ConnectCompleteL() +void CDedicatedBondingSession::ConnectComplete() { LOG_FUNC switch(iState) @@ -879,6 +889,11 @@ case EFinalConnection: // Apparently multiple connect completes are allowed by CSocket break; + case EShutdown: + // If an error occurred just after the connection request then we + // might receive a connection complete before the async shutdown request + // has been executed. + break; default: LOG1(_L("Unexpected Connect Complete in state %d"), iState); __ASSERT_DEBUG(EFalse, PANIC(KPairingServerFaultCat, EPairingServerUnexpectedSocketCallback)); @@ -886,16 +901,6 @@ } } -void CDedicatedBondingSession::ConnectComplete() - { - LOG_FUNC - TRAPD(err, ConnectCompleteL()); - if(err != KErrNone) - { - Error(err); - } - } - void CDedicatedBondingSession::ConnectComplete(const TDesC8& /*aConnectData*/) { LOG_FUNC diff -r 2b6718f05bdb -r 8a27654f7b62 bluetooth/btstack/secman/pairingserver.h --- a/bluetooth/btstack/secman/pairingserver.h Fri Feb 19 23:56:55 2010 +0200 +++ b/bluetooth/btstack/secman/pairingserver.h Fri Mar 12 15:49:00 2010 +0200 @@ -214,7 +214,6 @@ void StartBondingL(const RMessage2& aMessage); void DoAccessRequestL(); - void ConnectCompleteL(); void Shutdown(); void Complete(TInt aError); diff -r 2b6718f05bdb -r 8a27654f7b62 package_definition.xml --- a/package_definition.xml Fri Feb 19 23:56:55 2010 +0200 +++ b/package_definition.xml Fri Mar 12 15:49:00 2010 +0200 @@ -70,6 +70,11 @@ + + + + +