diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index a899179c85e545..3ddde11a931acb 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -239,7 +239,7 @@ CHIP_ERROR CommissioningWindowManager::AdvertiseAndListenForPASE() #endif ReturnErrorOnFailure(mServer->GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( - Protocols::SecureChannel::MsgType::PBKDFParamRequest, &mPairingSession)); + Protocols::SecureChannel::MsgType::PBKDFParamRequest, this)); mListeningForPASE = true; if (mUseECM) @@ -584,4 +584,32 @@ void CommissioningWindowManager::UpdateOpenerFabricIndex(Nullable a mOpenerFabricIndex = aNewOpenerFabricIndex; } +CHIP_ERROR CommissioningWindowManager::OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, + Messaging::ExchangeDelegate *& newDelegate) +{ + using Protocols::SecureChannel::MsgType; + + // Must be a PBKDFParamRequest message. Stop listening to new + // PBKDFParamRequest messages and hand it off to mPairingSession. If + // mPairingSession's OnMessageReceived fails, it will call our + // OnSessionEstablishmentError, and that will either start listening for a + // new PBKDFParamRequest or not, depending on how many failures we had seen. + // + // It's very important that we stop listening here, so that new incoming + // PASE establishment attempts don't interrupt our existing establishment. + mServer->GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(MsgType::PBKDFParamRequest); + newDelegate = &mPairingSession; + return CHIP_NO_ERROR; +} + +void CommissioningWindowManager::OnExchangeCreationFailed(Messaging::ExchangeDelegate * delegate) +{ + using Protocols::SecureChannel::MsgType; + + // We couldn't create an exchange, so didn't manage to call + // OnMessageReceived on mPairingSession. Just go back to listening for + // PBKDFParamRequest messages. + mServer->GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(MsgType::PBKDFParamRequest, this); +} + } // namespace chip diff --git a/src/app/server/CommissioningWindowManager.h b/src/app/server/CommissioningWindowManager.h index cfd13eecb06c11..cc2eda2ea29199 100644 --- a/src/app/server/CommissioningWindowManager.h +++ b/src/app/server/CommissioningWindowManager.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,8 @@ enum class CommissioningWindowAdvertisement class Server; -class CommissioningWindowManager : public SessionEstablishmentDelegate, +class CommissioningWindowManager : public Messaging::UnsolicitedMessageHandler, + public SessionEstablishmentDelegate, public app::CommissioningModeProvider, public SessionDelegate { @@ -104,6 +106,11 @@ class CommissioningWindowManager : public SessionEstablishmentDelegate, // CommissioningModeProvider implementation. Dnssd::CommissioningMode GetCommissioningMode() const override; + //// UnsolicitedMessageHandler Implementation //// + CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, + Messaging::ExchangeDelegate *& newDelegate) override; + void OnExchangeCreationFailed(Messaging::ExchangeDelegate * delegate) override; + //////////// SessionEstablishmentDelegate Implementation /////////////// void OnSessionEstablishmentError(CHIP_ERROR error) override; void OnSessionEstablishmentStarted() override; @@ -195,7 +202,8 @@ class CommissioningWindowManager : public SessionEstablishmentDelegate, Spake2pVerifier mECMPASEVerifier; uint16_t mECMDiscriminator = 0; // mListeningForPASE is true only when we are listening for - // PBKDFParamRequest messages. + // PBKDFParamRequest messages or when we're in the middle of a PASE + // handshake. bool mListeningForPASE = false; // Boolean that tracks whether we have a live commissioning timeout timer. bool mCommissioningTimeoutTimerArmed = false;