Skip to content

Commit

Permalink
Allows opening a commissioning window on a bridged node that is not o…
Browse files Browse the repository at this point in the history
…n Endpoint 0.
  • Loading branch information
yufengwangca committed Jun 7, 2024
1 parent 72450e4 commit e3f11f7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(
auto & iterations = commandData.iterations;
auto & salt = commandData.salt;

EndpointId endpointId = commandPath.mEndpointId;

Optional<StatusCode> status = Optional<StatusCode>::Missing();
InteractionModel::Status globalStatus = InteractionModel::Status::Success;
Spake2pVerifier verifier;
Expand All @@ -106,6 +108,7 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(
VerifyOrExit(failSafeContext.IsFailSafeFullyDisarmed(), status.Emplace(StatusCode::kBusy));

VerifyOrExit(!commissionMgr.IsCommissioningWindowOpen(), status.Emplace(StatusCode::kBusy));
VerifyOrExit(endpointId == kRootEndpointId, status.Emplace(StatusCode::kPAKEParameterError));
VerifyOrExit(iterations >= kSpake2p_Min_PBKDF_Iterations, status.Emplace(StatusCode::kPAKEParameterError));
VerifyOrExit(iterations <= kSpake2p_Max_PBKDF_Iterations, status.Emplace(StatusCode::kPAKEParameterError));
VerifyOrExit(salt.size() >= kSpake2p_Min_PBKDF_Salt_Length, status.Emplace(StatusCode::kPAKEParameterError));
Expand Down
28 changes: 25 additions & 3 deletions src/controller/CommissioningWindowOpener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenBasicCommissioningWindow(NodeId device
mBasicCommissioningWindowCallback = callback;
mCommissioningWindowCallback = nullptr;
mNodeId = deviceId;
mEndpointId = kRootEndpointId;
mCommissioningWindowTimeout = timeout;

mNextStep = Step::kOpenCommissioningWindow;
Expand All @@ -58,6 +59,28 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindow(NodeId deviceId, S
Optional<ByteSpan> salt,
Callback::Callback<OnOpenCommissioningWindow> * callback,
SetupPayload & payload, bool readVIDPIDAttributes)
{
return OpenCommissioningWindowImpl(deviceId, kRootEndpointId, timeout, iteration, discriminator, setupPIN, salt, callback,
payload, readVIDPIDAttributes);
}

CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindow(NodeId deviceId, EndpointId endpointId, Seconds16 timeout,
uint32_t iteration, uint16_t discriminator,
Optional<uint32_t> setupPIN, Optional<ByteSpan> salt,
Callback::Callback<OnOpenCommissioningWindow> * callback,
SetupPayload & payload)
{

VerifyOrReturnError(endpointId != kRootEndpointId, CHIP_ERROR_INVALID_ARGUMENT);
return OpenCommissioningWindowImpl(deviceId, endpointId, timeout, iteration, discriminator, setupPIN, salt, callback, payload,
false);
}

CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindowImpl(NodeId deviceId, EndpointId endpointId, Seconds16 timeout,
uint32_t iteration, uint16_t discriminator,
Optional<uint32_t> setupPIN, Optional<ByteSpan> salt,
Callback::Callback<OnOpenCommissioningWindow> * callback,
SetupPayload & payload, bool readVIDPIDAttributes)
{
VerifyOrReturnError(mNextStep == Step::kAcceptCommissioningStart, CHIP_ERROR_INCORRECT_STATE);

Expand Down Expand Up @@ -103,6 +126,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindow(NodeId deviceId, S
mCommissioningWindowCallback = callback;
mBasicCommissioningWindowCallback = nullptr;
mNodeId = deviceId;
mEndpointId = endpointId;
mCommissioningWindowTimeout = timeout;
mPBKDFIterations = iteration;

Expand All @@ -129,9 +153,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindowInternal(Messaging:
{
ChipLogProgress(Controller, "OpenCommissioningWindow for device ID 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId));

constexpr EndpointId kAdministratorCommissioningClusterEndpoint = 0;

ClusterBase cluster(exchangeMgr, sessionHandle, kAdministratorCommissioningClusterEndpoint);
ClusterBase cluster(exchangeMgr, sessionHandle, mEndpointId);

if (mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode)
{
Expand Down
38 changes: 38 additions & 0 deletions src/controller/CommissioningWindowOpener.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,39 @@ class CommissioningWindowOpener
Callback::Callback<OnOpenCommissioningWindow> * callback, SetupPayload & payload,
bool readVIDPIDAttributes = false);

/**
* @brief
* Try to look up the bridged device on the bridge with the given node id
* of the bridge and endpoint id of the bridged device and ask it to re-enter
* commissioning mode with a PASE verifier derived from the given information
* and the given discriminator. The bridged device will exit commissioning mode
* after a successful commissioning, or after the given `timeout` time.
*
* @param[in] deviceId The device Id of the bridge.
* @param[in] endpoinId The endpoint Id of the bridged node on the bridge.*
* @param[in] timeout The commissioning mode should terminate after this much time.
* @param[in] iteration The PAKE iteration count associated with the PAKE Passcode ID and ephemeral
* PAKE passcode verifier to be used for this commissioning.
* @param[in] discriminator The long discriminator for the DNS-SD advertisement.
* @param[in] setupPIN The setup PIN to use, or NullOptional to use a randomly-generated one.
* @param[in] salt The salt to use, or NullOptional to use a
* randomly-generated one. If provided, must be at
* least kSpake2p_Min_PBKDF_Salt_Length bytes and
* at most kSpake2p_Max_PBKDF_Salt_Length bytes in
* length.
* @param[in] callback The function to be called on success or failure of opening of commissioning window.
* @param[out] payload The setup payload, not including the VID/PID bits,
* even if those were asked for, that is generated
* based on the passed-in information. The payload
* provided to the callback function, unlike this
* out parameter, will include the VID/PID bits if
* readVIDPIDAttributes is true.
*
*/
CHIP_ERROR OpenCommissioningWindow(NodeId deviceId, EndpointId endpointId, System::Clock::Seconds16 timeout, uint32_t iteration,
uint16_t discriminator, Optional<uint32_t> setupPIN, Optional<ByteSpan> salt,
Callback::Callback<OnOpenCommissioningWindow> * callback, SetupPayload & payload);

private:
enum class Step : uint8_t
{
Expand All @@ -120,6 +153,10 @@ class CommissioningWindowOpener
kOpenCommissioningWindow,
};

CHIP_ERROR OpenCommissioningWindowImpl(NodeId deviceId, EndpointId endpointId, System::Clock::Seconds16 timeout,
uint32_t iteration, uint16_t discriminator, Optional<uint32_t> setupPIN,
Optional<ByteSpan> salt, Callback::Callback<OnOpenCommissioningWindow> * callback,
SetupPayload & payload, bool readVIDPIDAttributes);
CHIP_ERROR OpenCommissioningWindowInternal(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnPIDReadResponse(void * context, uint16_t value);
static void OnVIDReadResponse(void * context, VendorId value);
Expand All @@ -137,6 +174,7 @@ class CommissioningWindowOpener
Callback::Callback<OnOpenBasicCommissioningWindow> * mBasicCommissioningWindowCallback = nullptr;
SetupPayload mSetupPayload;
NodeId mNodeId = kUndefinedNodeId;
EndpointId mEndpointId = kInvalidEndpointId;
System::Clock::Seconds16 mCommissioningWindowTimeout = System::Clock::kZero;
CommissioningWindowOption mCommissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode;
Crypto::Spake2pVerifier mVerifier; // Used for non-basic commissioning.
Expand Down

0 comments on commit e3f11f7

Please sign in to comment.