Skip to content

Commit

Permalink
Update RPC, pass OCW params between fabric bridge and admin
Browse files Browse the repository at this point in the history
  • Loading branch information
samadDotDev committed Jul 5, 2024
1 parent 1699db0 commit d55aa40
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 20 deletions.
1 change: 1 addition & 0 deletions examples/common/pigweed/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pw_proto_library("button_service") {

pw_proto_library("fabric_admin_service") {
sources = [ "protos/fabric_admin_service.proto" ]
inputs = [ "protos/fabric_admin_service.options" ]
deps = [ "$dir_pw_protobuf:common_protos" ]
strip_prefix = "protos"
prefix = "fabric_admin_service"
Expand Down
2 changes: 2 additions & 0 deletions examples/common/pigweed/protos/fabric_admin_service.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
chip.rpc.DeviceCommissioningWindowInfo.verifier max_size:97 // kSpake2p_VerifierSerialized_Length
chip.rpc.DeviceCommissioningWindowInfo.salt max_size:32 // kSpake2p_Max_PBKDF_Salt_Length
10 changes: 7 additions & 3 deletions examples/common/pigweed/protos/fabric_admin_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import 'pw_protobuf_protos/common.proto';
package chip.rpc;

// Define the message for a synchronized end device with necessary fields
message DeviceInfo {
message DeviceCommissioningWindowInfo {
uint64 node_id = 1;
uint32 commissioning_timeout = 2;
uint32 discriminator = 3;
uint32 iterations = 4;
bytes salt = 5;
bytes verifier = 6;
}

// Define the response message to convey the status of the operation
Expand All @@ -15,6 +20,5 @@ message OperationStatus {
}

service FabricAdmin {
rpc OpenCommissioningWindow(DeviceInfo) returns (OperationStatus){}
rpc OpenCommissioningWindow(DeviceCommissioningWindowInfo) returns (OperationStatus){}
}

3 changes: 2 additions & 1 deletion examples/common/pigweed/rpc_services/FabricAdmin.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class FabricAdmin : public pw_rpc::nanopb::FabricAdmin::Service<FabricAdmin>
public:
virtual ~FabricAdmin() = default;

virtual pw::Status OpenCommissioningWindow(const chip_rpc_DeviceInfo & request, chip_rpc_OperationStatus & response)
virtual pw::Status OpenCommissioningWindow(const chip_rpc_DeviceCommissioningWindowInfo & request,
chip_rpc_OperationStatus & response)
{
return pw::Status::Unimplemented();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ CHIP_ERROR OpenCommissioningWindowCommand::RunCommand()
{
SetupPayload ignored;
return mWindowOpener->OpenCommissioningWindow(mNodeId, System::Clock::Seconds16(mCommissioningWindowTimeout), mIteration,
mDiscriminator, NullOptional, NullOptional, NullOptional,
mDiscriminator, NullOptional, mSalt, mVerifier,
&mOnOpenCommissioningWindowCallback, ignored,
/* readVIDPIDAttributes */ true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class OpenCommissioningWindowCommand : public CHIPCommand
&mIteration, "Number of PBKDF iterations to use to derive the verifier. Ignored if 'option' is 0.");
AddArgument("discriminator", 0, 4096, &mDiscriminator, "Discriminator to use for advertising. Ignored if 'option' is 0.");
AddArgument("timeout", 0, UINT16_MAX, &mTimeout, "Time, in seconds, before this command is considered to have timed out.");
AddArgument("salt", &mSalt, "Salt payload encoded in hexadecimal. Random salt will be generated if absent");
AddArgument("verifier", &mVerifier,
"PAKE Passcode verifier encoded in hexadecimal format. Will be generated from random setup pin and other "
"params if absent");
}

void RegisterDelegate(CommissioningWindowDelegate * delegate) { mDelegate = delegate; }
Expand All @@ -69,6 +73,8 @@ class OpenCommissioningWindowCommand : public CHIPCommand
uint16_t mDiscriminator;

chip::Optional<uint16_t> mTimeout;
chip::Optional<chip::ByteSpan> mSalt;
chip::Optional<chip::ByteSpan> mVerifier;

chip::Platform::UniquePtr<chip::Controller::CommissioningWindowOpener> mWindowOpener;

Expand Down
23 changes: 18 additions & 5 deletions examples/fabric-admin/rpc/RpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,27 @@ namespace {
class FabricAdmin final : public rpc::FabricAdmin
{
public:
pw::Status OpenCommissioningWindow(const chip_rpc_DeviceInfo & request, chip_rpc_OperationStatus & response) override
pw::Status OpenCommissioningWindow(const chip_rpc_DeviceCommissioningWindowInfo & request,
chip_rpc_OperationStatus & response) override
{
NodeId nodeId = request.node_id;
NodeId nodeId = request.node_id;
uint32_t commissioningTimeout = request.commissioning_timeout;
uint32_t iterations = request.iterations;
uint32_t discriminator = request.discriminator;

char saltHex[Crypto::kSpake2p_Max_PBKDF_Salt_Length * 2 + 1];
Encoding::BytesToHex(request.salt.bytes, request.salt.size, saltHex, sizeof(saltHex), Encoding::HexFlags::kNullTerminate);

char verifierHex[Crypto::kSpake2p_VerifierSerialized_Length * 2 + 1];
Encoding::BytesToHex(request.verifier.bytes, request.verifier.size, verifierHex, sizeof(verifierHex),
Encoding::HexFlags::kNullTerminate);

ChipLogProgress(NotSpecified, "Received OpenCommissioningWindow request: 0x%lx", nodeId);

char command[64];
snprintf(command, sizeof(command), "pairing open-commissioning-window %ld %d %d %d %d %d", nodeId, kRootEndpointId,
kEnhancedCommissioningMethod, kWindowTimeout, kIteration, kDiscriminator);
char command[512];
snprintf(command, sizeof(command), "pairing open-commissioning-window %ld %d %d %d %d %d --salt hex:%s --verifier hex:%s",
nodeId, kRootEndpointId, kEnhancedCommissioningMethod, commissioningTimeout, iterations, discriminator, saltHex,
verifierHex);

PushCommand(command);

Expand Down
30 changes: 27 additions & 3 deletions examples/fabric-bridge-app/linux/RpcClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort)
return rpc::client::StartPacketProcessing();
}

CHIP_ERROR OpenCommissioningWindow(NodeId nodeId)
CHIP_ERROR OpenCommissioningWindow(NodeId nodeId, uint16_t commissioningTimeout, uint16_t discriminator, uint32_t iterations,
chip::Optional<chip::ByteSpan> salt, chip::Optional<chip::ByteSpan> verifier)
{
ChipLogProgress(NotSpecified, "OpenCommissioningWindow with Node Id 0x:" ChipLogFormatX64, ChipLogValueX64(nodeId));

Expand All @@ -73,8 +74,31 @@ CHIP_ERROR OpenCommissioningWindow(NodeId nodeId)
return CHIP_ERROR_BUSY;
}

chip_rpc_DeviceInfo device;
device.node_id = nodeId;
chip_rpc_DeviceCommissioningWindowInfo device;
device.node_id = nodeId;
device.commissioning_timeout = commissioningTimeout;
device.discriminator = discriminator;
device.iterations = iterations;

if (salt.HasValue())
{
if (salt.Value().size() > sizeof(device.salt.bytes))
{
return CHIP_ERROR_INTERNAL;
}
memcpy(device.salt.bytes, salt.Value().data(), salt.Value().size());
device.salt.size = static_cast<pb_size_t>(salt.Value().size());
}

if (verifier.HasValue())
{
if (verifier.Value().size() > sizeof(device.verifier.bytes))
{
return CHIP_ERROR_INTERNAL;
}
memcpy(device.verifier.bytes, verifier.Value().data(), verifier.Value().size());
device.verifier.size = static_cast<pb_size_t>(verifier.Value().size());
}

// The RPC will remain active as long as `openCommissioningWindowCall` is alive.
openCommissioningWindowCall = fabricAdminClient.OpenCommissioningWindow(device, OnOpenCommissioningWindowCompleted);
Expand Down
3 changes: 2 additions & 1 deletion examples/fabric-bridge-app/linux/include/RpcClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort);
* - CHIP_ERROR_BUSY: Another commissioning window is currently in progress.
* - CHIP_ERROR_INTERNAL: An internal error occurred.
*/
CHIP_ERROR OpenCommissioningWindow(chip::NodeId nodeId);
CHIP_ERROR OpenCommissioningWindow(chip::NodeId nodeId, uint16_t commissioningTimeout, uint16_t discriminator, uint32_t iterations,
chip::Optional<chip::ByteSpan> salt, chip::Optional<chip::ByteSpan> verifier);
31 changes: 25 additions & 6 deletions examples/fabric-bridge-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ void BridgePollingThread()
#if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE
else if (ch == 'o')
{
CHIP_ERROR err = OpenCommissioningWindow(0x1234);
CHIP_ERROR err = OpenCommissioningWindow(0x1234, 300, 3840, 1000, chip::NullOptional, chip::NullOptional);
if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "Failed to call OpenCommissioningWindow RPC: %" CHIP_ERROR_FORMAT, err.Format());
Expand Down Expand Up @@ -129,26 +129,45 @@ void AdministratorCommissioningCommandHandler::InvokeCommand(HandlerContext & ha
}

handlerContext.SetCommandHandled();
Status status = Status::Success;

uint16_t commissioningTimeout;
uint16_t discriminator;
uint32_t iterations;
chip::Optional<chip::ByteSpan> salt;
chip::Optional<chip::ByteSpan> verifier;
Device * device = nullptr;
Status status = Status::Failure;

Commands::OpenCommissioningWindow::DecodableType commandData;
CHIP_ERROR tlvError = DataModel::Decode(handlerContext.mPayload, commandData);
SuccessOrExit(tlvError);

commissioningTimeout = commandData.commissioningTimeout;
discriminator = commandData.discriminator;
iterations = commandData.iterations;
salt = chip::Optional<chip::ByteSpan>(commandData.salt);
verifier = chip::Optional<chip::ByteSpan>(commandData.PAKEPasscodeVerifier);

#if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE
Device * device = DeviceMgr().GetDevice(endpointId);
device = DeviceMgr().GetDevice(endpointId);

// TODO: issues:#33784, need to make OpenCommissioningWindow synchronous
if (device != nullptr && OpenCommissioningWindow(device->GetNodeId()) == CHIP_NO_ERROR)
if (device != nullptr &&
OpenCommissioningWindow(device->GetNodeId(), commissioningTimeout, discriminator, iterations, salt, verifier) ==
CHIP_NO_ERROR)
{
ChipLogProgress(NotSpecified, "Commissioning window is now open");
status = Status::Success;
}
else
{
status = Status::Failure;
ChipLogProgress(NotSpecified, "Commissioning window is failed to open");
}
#else
status = Status::Failure;
ChipLogProgress(NotSpecified, "Commissioning window failed to open: PW_RPC_FABRIC_BRIDGE_SERVICE not defined");
#endif // defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE

exit:
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, status);
}

Expand Down

0 comments on commit d55aa40

Please sign in to comment.