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 <commits@restyled.io>
* Fix CI
---------
Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/platform/linux/CommissionerMain.cpp b/examples/platform/linux/CommissionerMain.cpp
index d4155ac..3ffac89 100644
--- a/examples/platform/linux/CommissionerMain.cpp
+++ b/examples/platform/linux/CommissionerMain.cpp
@@ -277,6 +277,13 @@
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 bf20ccd..e82c049 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 <CommissionableInit.h>
#include <inttypes.h>
#include <lib/core/CHIPCore.h>
#include <lib/shell/Commands.h>
@@ -34,6 +35,13 @@
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>
+using namespace chip;
+using namespace chip::DeviceLayer;
+
+namespace {
+LinuxCommissionableDataProvider gCommissionableDataProvider;
+}
+
namespace chip {
namespace Shell {
@@ -120,6 +128,17 @@
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 @@
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 @@
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 d64f504..49eb65d 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 @@
* 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 @@
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<TargetVideoPlayerInfo *> & outAssociatedConnectableVideoPlayer);
@@ -470,6 +481,12 @@
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 b98647d..3c77048 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 <app/server/Dnssd.h>
using namespace chip;
using namespace chip::Controller;
@@ -67,6 +68,10 @@
// 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 @@
}
#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 a4d874f..4df133c 100644
--- a/src/controller/CommissionerDiscoveryController.cpp
+++ b/src/controller/CommissionerDiscoveryController.cpp
@@ -61,54 +61,99 @@
ResetState();
}
+void CommissionerDiscoveryController::OnCancel(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::OnCancel received when no current instance.");
+ return;
+ }
+
+ if (strncmp(mCurrentInstance, state.GetInstanceName(), sizeof(mCurrentInstance)) != 0)
+ {
+ // 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;
+ }
+
+ 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());
+ }
+ 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 (strncmp(mCurrentInstance, state.GetInstanceName(), sizeof(mCurrentInstance)) != 0)
+ {
+ // 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 (state.GetCdPort() == 0)
+ {
+ ChipLogDetail(Controller, "CommissionerDiscoveryController::OnCommissionerPasscodeReady no port");
+ return;
+ }
+
+ 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;
}
- // 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)
- {
- mUserPrompter->HidePromptsOnCancel(state.GetVendorId(), state.GetProductId(), state.GetDeviceName());
- }
- return;
- }
- if (state.GetCommissionerPasscodeReady() && state.GetCdPort() != 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 (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;
- }
- }
mReady = false;
Platform::CopyString(mCurrentInstance, state.GetInstanceName());
@@ -398,6 +443,7 @@
return;
}
client->SetCachedCommissionerPasscode(passcode);
+ client->SetUDCClientProcessingState(UDCClientProcessingState::kWaitingForCommissionerPasscodeReady);
CommissionerDeclaration cd;
cd.SetCommissionerPasscode(true);
@@ -482,7 +528,7 @@
if (!mPendingConsent)
{
- ChipLogError(AppServer, "UX Cancel: no current instance");
+ ChipLogError(AppServer, "UX CommissionWithPasscode: no current instance");
return;
}
if (mUdcServer == nullptr)
@@ -493,7 +539,7 @@
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 @@
}
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 c4c90c3..521fe5c 100644
--- a/src/controller/CommissionerDiscoveryController.h
+++ b/src/controller/CommissionerDiscoveryController.h
@@ -276,6 +276,24 @@
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 e87e303..259f6ee 100644
--- a/src/protocols/user_directed_commissioning/UDCClientState.h
+++ b/src/protocols/user_directed_commissioning/UDCClientState.h
@@ -37,6 +37,7 @@
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 7f22c92..86fd4d5 100644
--- a/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h
+++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioning.h
@@ -448,6 +448,30 @@
*/
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 @@
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<kMaxUDCClients> mUdcClients; // < Active UDC clients
diff --git a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp
index f63a10c..b96c456 100644
--- a/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp
+++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioningServer.cpp
@@ -61,9 +61,25 @@
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,10 +125,60 @@
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)
{
if (mTransportMgr == nullptr)
diff --git a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp
index 9c171b5..a62aa52 100644
--- a/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp
+++ b/src/protocols/user_directed_commissioning/tests/TestUdcMessages.cpp
@@ -37,6 +37,10 @@
mState = state;
}
+ void OnCancel(UDCClientState state) {}
+
+ void OnCommissionerPasscodeReady(UDCClientState state) {}
+
void FindCommissionableNode(char * instanceName)
{
mFindCommissionableNodeCalled = true;