From 03d2fa8f2b2f71aa7616f9fec96543ef4ce1595e Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:01:41 -0700 Subject: [PATCH] Fix 32957 : Matter TV: commissioner passcode flow does not accept CommissionerPasscodeReady flag (#32958) * Temp fix for 32875 * Clarify comments * Fix commissioner passcode flow * Make test shell commands for commissionerpasscode always trigger passcode dialog * Make commissioner passcode commissioning work for casting app using shell commands * Fix CI, address comments, wire CDC callback to CastingServer * Fix CI * Fix CI * Restyled by clang-format (#32968) Co-authored-by: Restyled.io * Fix CI --------- Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com> Co-authored-by: Restyled.io --- examples/platform/linux/CommissionerMain.cpp | 7 + .../linux/CastingShellCommands.cpp | 35 +++++ .../tv-casting-common/include/CastingServer.h | 17 +++ .../tv-casting-common/src/CastingServer.cpp | 35 +++++ .../CommissionerDiscoveryController.cpp | 129 ++++++++++++------ .../CommissionerDiscoveryController.h | 18 +++ .../UDCClientState.h | 1 + .../UserDirectedCommissioning.h | 27 ++++ .../UserDirectedCommissioningServer.cpp | 70 +++++++++- .../tests/TestUdcMessages.cpp | 4 + 10 files changed, 302 insertions(+), 41 deletions(-) diff --git a/examples/platform/linux/CommissionerMain.cpp b/examples/platform/linux/CommissionerMain.cpp index d4155ac5bc3f24..3ffac89a6e08e9 100644 --- a/examples/platform/linux/CommissionerMain.cpp +++ b/examples/platform/linux/CommissionerMain.cpp @@ -277,6 +277,13 @@ void PairingCommand::OnStatusUpdate(DevicePairingDelegate::Status status) break; case DevicePairingDelegate::Status::SecurePairingFailed: ChipLogError(AppServer, "Secure Pairing Failed"); +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController(); + if (cdc != nullptr) + { + cdc->CommissioningFailed(CHIP_ERROR_CONNECTION_ABORTED); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED break; } } diff --git a/examples/tv-casting-app/linux/CastingShellCommands.cpp b/examples/tv-casting-app/linux/CastingShellCommands.cpp index bf20ccdec73b7f..e82c0491a00c51 100644 --- a/examples/tv-casting-app/linux/CastingShellCommands.cpp +++ b/examples/tv-casting-app/linux/CastingShellCommands.cpp @@ -24,6 +24,7 @@ #include "CastingServer.h" #include "CastingUtils.h" #include "app/clusters/bindings/BindingManager.h" +#include #include #include #include @@ -34,6 +35,13 @@ #include #include +using namespace chip; +using namespace chip::DeviceLayer; + +namespace { +LinuxCommissionableDataProvider gCommissionableDataProvider; +} + namespace chip { namespace Shell { @@ -120,6 +128,17 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv) int index = (int) strtol(argv[1], &eptr, 10); return RequestCommissioning(index); } + if (strcmp(argv[0], "setusecommissionerpasscode") == 0) + { + ChipLogProgress(DeviceLayer, "setusecommissionerpasscode"); + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + int useCP = (int) strtol(argv[1], &eptr, 10); + CastingServer::GetInstance()->SetCommissionerPasscodeEnabled(useCP == 1); + } if (strcmp(argv[0], "launch") == 0) { ChipLogProgress(DeviceLayer, "launch"); @@ -179,6 +198,8 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv) Protocols::UserDirectedCommissioning::IdentificationDeclaration id; id.SetCommissionerPasscode(true); + id.SetVendorId(1244); // set non-standard vid-pid to prevent dummy content apps from returning a passcode + id.SetProductId(2234); if (argc > 3) { id.SetCommissionerPasscodeReady(strcmp(argv[3], "t") == 0); @@ -202,6 +223,20 @@ static CHIP_ERROR CastingHandler(int argc, char ** argv) return Server::GetInstance().SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP(commissioner, port), id); } + if (strcmp(argv[0], "setcommissionerpasscode") == 0) + { + + char * eptr; + uint32_t passcode = (uint32_t) strtol(argv[1], &eptr, 10); + LinuxDeviceOptions::GetInstance().payload.setUpPINCode = passcode; + + VerifyOrDie(chip::examples::InitCommissionableDataProvider(gCommissionableDataProvider, + LinuxDeviceOptions::GetInstance()) == CHIP_NO_ERROR); + + DeviceLayer::SetCommissionableDataProvider(&gCommissionableDataProvider); + + CastingServer::GetInstance()->SetCommissionerPasscodeReady(); + } if (strcmp(argv[0], "testudc") == 0) { char * eptr; diff --git a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h index d64f5049df1a8f..49eb65d13786fb 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h +++ b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h @@ -50,6 +50,10 @@ inline constexpr chip::System::Clock::Seconds16 kCommissioningWindowTimeout = ch * as a singleton and is to be used across Linux, Android and iOS. */ class CastingServer : public AppDelegate +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + , + chip::Protocols::UserDirectedCommissioning::CommissionerDeclarationHandler +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT { public: CastingServer(CastingServer & other) = delete; @@ -61,6 +65,13 @@ class CastingServer : public AppDelegate CHIP_ERROR InitBindingHandlers(); void InitAppDelegation(); +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + void SetCommissionerPasscodeEnabled(bool enabled) { mUdcCommissionerPasscodeEnabled = enabled; }; + void SetCommissionerPasscodeReady() { mUdcCommissionerPasscodeReady = true; }; + void OnCommissionerDeclarationMessage(const chip::Transport::PeerAddress & source, + chip::Protocols::UserDirectedCommissioning::CommissionerDeclaration cd) override; +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + CHIP_ERROR DiscoverCommissioners(chip::Controller::DeviceDiscoveryDelegate * deviceDiscoveryDelegate = nullptr); const chip::Dnssd::DiscoveredNodeData * GetDiscoveredCommissioner(int index, chip::Optional & outAssociatedConnectableVideoPlayer); @@ -470,6 +481,12 @@ class CastingServer : public AppDelegate PersistenceManager mPersistenceManager; bool mInited = false; bool mUdcInProgress = false; +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + bool mUdcCommissionerPasscodeEnabled = false; + bool mUdcCommissionerPasscodeReady = false; + char mUdcCommissionerPasscodeInstanceName[chip::Dnssd::Commission::kInstanceNameMaxLength + 1] = ""; +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + chip::Dnssd::DiscoveredNodeData mStrNodeDataList[kMaxCachedVideoPlayers]; TargetVideoPlayerInfo mActiveTargetVideoPlayerInfo; TargetVideoPlayerInfo mCachedTargetVideoPlayerInfo[kMaxCachedVideoPlayers]; diff --git a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp index b98647db802050..3c77048e67d551 100644 --- a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp @@ -20,6 +20,7 @@ #include "ConversionUtils.h" #include "app/clusters/bindings/BindingManager.h" +#include using namespace chip; using namespace chip::Controller; @@ -67,6 +68,10 @@ CHIP_ERROR CastingServer::Init(AppParams * AppParams) // Add callback to send Content casting commands after commissioning completes ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0)); +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + Server::GetInstance().GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler(this); +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + mInited = true; return CHIP_NO_ERROR; } @@ -189,10 +194,40 @@ void CastingServer::OnCommissioningSessionEstablishmentStarted() } #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +void CastingServer::OnCommissionerDeclarationMessage(const chip::Transport::PeerAddress & source, + chip::Protocols::UserDirectedCommissioning::CommissionerDeclaration cd) +{ + ChipLogProgress(AppServer, "CastingServer::OnCommissionerDeclarationMessage"); + // TODO: call a mCommissioningCallbacks +} + CHIP_ERROR CastingServer::SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner) { // TODO: expose options to the higher layer Protocols::UserDirectedCommissioning::IdentificationDeclaration id; + if (mUdcCommissionerPasscodeEnabled) + { + id.SetCommissionerPasscode(true); + if (mUdcCommissionerPasscodeReady) + { + id.SetCommissionerPasscodeReady(true); + id.SetInstanceName(mUdcCommissionerPasscodeInstanceName); + mUdcCommissionerPasscodeReady = false; + } + else + { + CHIP_ERROR err = app::DnssdServer::Instance().GetCommissionableInstanceName( + mUdcCommissionerPasscodeInstanceName, sizeof(mUdcCommissionerPasscodeInstanceName)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to get mdns instance name error: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + id.SetInstanceName(mUdcCommissionerPasscodeInstanceName); + } + } + } return Server::GetInstance().SendUserDirectedCommissioningRequest(commissioner, id); } diff --git a/src/controller/CommissionerDiscoveryController.cpp b/src/controller/CommissionerDiscoveryController.cpp index a4d874f0243b2f..4df133c59e99f3 100644 --- a/src/controller/CommissionerDiscoveryController.cpp +++ b/src/controller/CommissionerDiscoveryController.cpp @@ -61,53 +61,98 @@ void CommissionerDiscoveryController::ValidateSession() ResetState(); } -void CommissionerDiscoveryController::OnUserDirectedCommissioningRequest(UDCClientState state) +void CommissionerDiscoveryController::OnCancel(UDCClientState state) { - ValidateSession(); + if (mReady) + { + // if state was ready for a new session, + // then we have lost our discovery controller context and can't perform the commissioning request + ChipLogDetail(Controller, "CommissionerDiscoveryController::OnCancel received when no current instance."); + return; + } - if (!mReady) + if (strncmp(mCurrentInstance, state.GetInstanceName(), sizeof(mCurrentInstance)) != 0) { - ChipLogDetail(Controller, "CommissionerDiscoveryController not ready. Current instance=%s", mCurrentInstance); + // if the instance doesn't match the one in our discovery controller context, + // then we can't perform the commissioning request + ChipLogDetail(Controller, "CommissionerDiscoveryController::OnCancel received mismatched instance. Current instance=%s", + mCurrentInstance); return; } - // first check if this is a cancel - if (state.GetCancelPasscode()) + + ChipLogDetail(Controller, "------PROMPT USER: %s cancelled commissioning [" ChipLogFormatMEI "," ChipLogFormatMEI ",%s]", + state.GetDeviceName(), ChipLogValueMEI(state.GetVendorId()), ChipLogValueMEI(state.GetProductId()), + state.GetInstanceName()); + if (mUserPrompter != nullptr) { - ChipLogDetail(Controller, "------PROMPT USER: %s cancelled commissioning [" ChipLogFormatMEI "," ChipLogFormatMEI ",%s]", - state.GetDeviceName(), ChipLogValueMEI(state.GetVendorId()), ChipLogValueMEI(state.GetProductId()), - state.GetInstanceName()); - if (mUserPrompter != nullptr) - { - mUserPrompter->HidePromptsOnCancel(state.GetVendorId(), state.GetProductId(), state.GetDeviceName()); - } + mUserPrompter->HidePromptsOnCancel(state.GetVendorId(), state.GetProductId(), state.GetDeviceName()); + } + return; +} + +void CommissionerDiscoveryController::OnCommissionerPasscodeReady(UDCClientState state) +{ + if (mReady) + { + // if state was ready for a new session, + // then we have lost our discovery controller context and can't perform the commissioning request + ChipLogDetail(Controller, + "CommissionerDiscoveryController::OnCommissionerPasscodeReady received when no current instance."); return; } - if (state.GetCommissionerPasscodeReady() && state.GetCdPort() != 0) + + if (strncmp(mCurrentInstance, state.GetInstanceName(), sizeof(mCurrentInstance)) != 0) { - uint32_t passcode = state.GetCachedCommissionerPasscode(); - if (!mReady || passcode == 0) - { - ChipLogError(AppServer, "On UDC: commissioner passcode ready but no passcode"); - CommissionerDeclaration cd; - cd.SetErrorCode(CommissionerDeclaration::CdError::kUnexpectedCommissionerPasscodeReady); + // if the instance doesn't match the one in our discovery controller context, + // then we can't perform the commissioning request + ChipLogDetail( + Controller, + "CommissionerDiscoveryController::OnCommissionerPasscodeReady received mismatched instance. Current instance=%s", + mCurrentInstance); + return; + } - if (mUdcServer == nullptr) - { - ChipLogError(AppServer, "On UDC: no udc server"); - return; - } - mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(state.GetPeerAddress().GetIPAddress(), state.GetCdPort())); - return; - } - else - { - // can only get here is ok() has already been called - ChipLogDetail(AppServer, "On UDC: commissioner passcode ready with passcode - commissioning"); + if (state.GetCdPort() == 0) + { + ChipLogDetail(Controller, "CommissionerDiscoveryController::OnCommissionerPasscodeReady no port"); + return; + } - // start commissioning using the cached passcode - CommissionWithPasscode(passcode); + uint32_t passcode = state.GetCachedCommissionerPasscode(); + if (passcode == 0) + { + ChipLogError(AppServer, "On UDC: commissioner passcode ready but no passcode"); + CommissionerDeclaration cd; + cd.SetErrorCode(CommissionerDeclaration::CdError::kUnexpectedCommissionerPasscodeReady); + + if (mUdcServer == nullptr) + { + ChipLogError(AppServer, "On UDC: no udc server"); return; } + mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(state.GetPeerAddress().GetIPAddress(), state.GetCdPort())); + return; + } + else + { + // can only get here is ok() has already been called + ChipLogDetail(AppServer, "On UDC: commissioner passcode ready with passcode - commissioning"); + + // start commissioning using the cached passcode + CommissionWithPasscode(passcode); + return; + } +} + +void CommissionerDiscoveryController::OnUserDirectedCommissioningRequest(UDCClientState state) +{ + ValidateSession(); + + if (!mReady) + { + // we must currently have discovery controller context (a UDC prompt under way) + ChipLogDetail(Controller, "CommissionerDiscoveryController not ready. Current instance=%s", mCurrentInstance); + return; } mReady = false; @@ -398,6 +443,7 @@ void CommissionerDiscoveryController::InternalHandleContentAppPasscodeResponse() return; } client->SetCachedCommissionerPasscode(passcode); + client->SetUDCClientProcessingState(UDCClientProcessingState::kWaitingForCommissionerPasscodeReady); CommissionerDeclaration cd; cd.SetCommissionerPasscode(true); @@ -482,7 +528,7 @@ void CommissionerDiscoveryController::InternalCommissionWithPasscode() if (!mPendingConsent) { - ChipLogError(AppServer, "UX Cancel: no current instance"); + ChipLogError(AppServer, "UX CommissionWithPasscode: no current instance"); return; } if (mUdcServer == nullptr) @@ -493,7 +539,7 @@ void CommissionerDiscoveryController::InternalCommissionWithPasscode() UDCClientState * client = mUdcServer->GetUDCClients().FindUDCClientState(mCurrentInstance); if (client == nullptr) { - ChipLogError(AppServer, "UX Ok: could not find instance=%s", mCurrentInstance); + ChipLogError(AppServer, "UX CommissionWithPasscode: could not find instance=%s", mCurrentInstance); return; } // state needs to be either kPromptingUser or kObtainingOnboardingPayload @@ -566,13 +612,18 @@ void CommissionerDiscoveryController::CommissioningFailed(CHIP_ERROR error) } if (mUdcServer == nullptr) { - ChipLogError(AppServer, "UX Cancel: no udc server"); + ChipLogError(AppServer, "UX CommissioningFailed: no udc server"); return; } UDCClientState * client = mUdcServer->GetUDCClients().FindUDCClientState(mCurrentInstance); - if (client == nullptr || client->GetUDCClientProcessingState() != UDCClientProcessingState::kCommissioningNode) + if (client == nullptr) { - ChipLogError(AppServer, "UX Cancel: invalid state for cancel"); + ChipLogError(AppServer, "UX CommissioningFailed: no client"); + return; + } + if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kCommissioningNode) + { + ChipLogError(AppServer, "UX CommissioningFailed: invalid state"); return; } client->SetUDCClientProcessingState(UDCClientProcessingState::kCommissioningFailed); diff --git a/src/controller/CommissionerDiscoveryController.h b/src/controller/CommissionerDiscoveryController.h index c4c90c32342bc1..521fe5c611dc3c 100644 --- a/src/controller/CommissionerDiscoveryController.h +++ b/src/controller/CommissionerDiscoveryController.h @@ -275,6 +275,24 @@ class CommissionerDiscoveryController : public chip::Protocols::UserDirectedComm */ void OnUserDirectedCommissioningRequest(UDCClientState state) override; + /** + * UserConfirmationProvider callback. + * + * Notification that a Cancel UDC protocol message was received. + * + * This code will call the registered UserPrompter's HidePromptsOnCancel + */ + void OnCancel(UDCClientState state) override; + + /** + * UserConfirmationProvider callback. + * + * Notification that a CommissionerPasscodeReady UDC protocol message was received. + * + * This code will trigger the Commissioner to begin commissioning + */ + void OnCommissionerPasscodeReady(UDCClientState state) override; + /** * This method should be called after the user has given consent for commissioning of the client * indicated in the UserPrompter's PromptForCommissionOKPermission callback diff --git a/src/protocols/user_directed_commissioning/UDCClientState.h b/src/protocols/user_directed_commissioning/UDCClientState.h index e87e303340560c..259f6eedf1c0dc 100644 --- a/src/protocols/user_directed_commissioning/UDCClientState.h +++ b/src/protocols/user_directed_commissioning/UDCClientState.h @@ -37,6 +37,7 @@ enum class UDCClientProcessingState : uint8_t kPromptingUser, kUserDeclined, kObtainingOnboardingPayload, + kWaitingForCommissionerPasscodeReady, kCommissioningNode, kCommissioningFailed, }; diff --git a/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h b/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h index 7f22c92be0b71c..86fd4d51ed4e48 100644 --- a/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h +++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h @@ -448,6 +448,30 @@ class DLL_EXPORT UserConfirmationProvider */ virtual void OnUserDirectedCommissioningRequest(UDCClientState state) = 0; + /** + * @brief + * Called when an Identification Declaration UDC message has been received + * with the cancel flag set. + * It is expected that the implementer will tear down any dialog prompts for the + * commissionee instance (identified in the UDC client state argument). + * + * @param[in] state The state for the UDC Client. + * + */ + virtual void OnCancel(UDCClientState state) = 0; + + /** + * @brief + * Called when an Identification Declaration UDC message has been received + * with the commissioner passcode ready flag set. + * It is expected that the implementer will invoke commissioning on the + * commissionee instance (identified in the UDC client state argument). + * + * @param[in] state The state for the UDC Client. + * + */ + virtual void OnCommissionerPasscodeReady(UDCClientState state) = 0; + virtual ~UserConfirmationProvider() = default; }; @@ -625,6 +649,9 @@ class DLL_EXPORT UserDirectedCommissioningServer : public TransportMgrDelegate InstanceNameResolver * mInstanceNameResolver = nullptr; UserConfirmationProvider * mUserConfirmationProvider = nullptr; + void HandleNewUDC(const Transport::PeerAddress & source, IdentificationDeclaration & id); + void HandleUDCCancel(IdentificationDeclaration & id); + void HandleUDCCommissionerPasscodeReady(IdentificationDeclaration & id); void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf) override; UDCClients mUdcClients; // < Active UDC clients diff --git a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp index f63a10c94965f5..b96c45630166fa 100644 --- a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp +++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp @@ -61,9 +61,25 @@ void UserDirectedCommissioningServer::OnMessageReceived(const Transport::PeerAdd IdentificationDeclaration id; id.ReadPayload(udcPayload, sizeof(udcPayload)); - char * instanceName = (char *) id.GetInstanceName(); + if (id.GetCancelPasscode()) + { + HandleUDCCancel(id); + return; + } - ChipLogProgress(AppServer, "UDC instance=%s ", id.GetInstanceName()); + if (id.GetCommissionerPasscodeReady()) + { + HandleUDCCommissionerPasscodeReady(id); + return; + } + + HandleNewUDC(source, id); +} + +void UserDirectedCommissioningServer::HandleNewUDC(const Transport::PeerAddress & source, IdentificationDeclaration & id) +{ + char * instanceName = (char *) id.GetInstanceName(); + ChipLogProgress(AppServer, "HandleNewUDC instance=%s ", id.GetInstanceName()); UDCClientState * client = mUdcClients.FindUDCClientState(instanceName); if (client == nullptr) @@ -109,8 +125,58 @@ void UserDirectedCommissioningServer::OnMessageReceived(const Transport::PeerAdd ChipLogError(AppServer, "UserDirectedCommissioningServer::OnMessageReceived no mInstanceNameResolver registered"); } } + mUdcClients.MarkUDCClientActive(client); +} + +void UserDirectedCommissioningServer::HandleUDCCancel(IdentificationDeclaration & id) +{ + char * instanceName = (char *) id.GetInstanceName(); + ChipLogProgress(AppServer, "HandleUDCCancel instance=%s ", id.GetInstanceName()); + UDCClientState * client = mUdcClients.FindUDCClientState(instanceName); + if (client == nullptr) + { + ChipLogProgress(AppServer, "UDC no matching instance found"); + return; + } + id.DebugLog(); mUdcClients.MarkUDCClientActive(client); + + // Call the registered mUserConfirmationProvider, if any. + if (mUserConfirmationProvider != nullptr) + { + mUserConfirmationProvider->OnCancel(*client); + } + + // reset this entry so that the client can try again without waiting an hour + client->Reset(); +} + +void UserDirectedCommissioningServer::HandleUDCCommissionerPasscodeReady(IdentificationDeclaration & id) +{ + char * instanceName = (char *) id.GetInstanceName(); + ChipLogProgress(AppServer, "HandleUDCCommissionerPasscodeReady instance=%s ", id.GetInstanceName()); + + UDCClientState * client = mUdcClients.FindUDCClientState(instanceName); + if (client == nullptr) + { + ChipLogProgress(AppServer, "UDC no matching instance found"); + return; + } + if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kWaitingForCommissionerPasscodeReady) + { + ChipLogProgress(AppServer, "UDC instance not in waiting for passcode ready state"); + return; + } + id.DebugLog(); + mUdcClients.MarkUDCClientActive(client); + client->SetUDCClientProcessingState(UDCClientProcessingState::kObtainingOnboardingPayload); + + // Call the registered mUserConfirmationProvider, if any. + if (mUserConfirmationProvider != nullptr) + { + mUserConfirmationProvider->OnCommissionerPasscodeReady(*client); + } } CHIP_ERROR UserDirectedCommissioningServer::SendCDCMessage(CommissionerDeclaration cd, chip::Transport::PeerAddress peerAddress) diff --git a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp index 9c171b5efad5b8..a62aa52b94a2e3 100644 --- a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp +++ b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp @@ -37,6 +37,10 @@ class DLL_EXPORT TestCallback : public UserConfirmationProvider, public Instance mState = state; } + void OnCancel(UDCClientState state) {} + + void OnCommissionerPasscodeReady(UDCClientState state) {} + void FindCommissionableNode(char * instanceName) { mFindCommissionableNodeCalled = true;