Skip to content

Commit

Permalink
[Fabric-Sync] Port 'add-bridge' and 'remove-bridge' commands (project…
Browse files Browse the repository at this point in the history
…-chip#36241)

* [Fabric-Sync] Implemenat 'add-bridge' command

* Address review comments
  • Loading branch information
yufengwangca authored Nov 5, 2024
1 parent 62a4a97 commit 9c389ba
Show file tree
Hide file tree
Showing 15 changed files with 1,524 additions and 1 deletion.
16 changes: 15 additions & 1 deletion examples/fabric-sync/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,35 @@ assert(chip_build_tools)
executable("fabric-sync") {
cflags = [ "-Wconversion" ]

defines = []

if (chip_build_libshell) {
defines += [ "ENABLE_CHIP_SHELL" ]
}

include_dirs = [
".",
"${chip_root}/src/lib",
]

if (chip_build_libshell) {
include_dirs += [ "shell" ]
}

sources = [ "main.cpp" ]

deps = [
"${chip_root}/examples/fabric-sync/admin:fabric-admin-lib",
"${chip_root}/examples/fabric-sync/bridge:fabric-bridge-lib",
"${chip_root}/examples/fabric-sync/bridge:fabric-bridge-zap",
"${chip_root}/examples/platform/linux:app-main",
"${chip_root}/src/lib",
"${chip_root}/third_party/inipp",
]

if (chip_build_libshell) {
deps += [ "${chip_root}/examples/fabric-sync/shell" ]
}

output_dir = root_out_dir
}

Expand Down
30 changes: 30 additions & 0 deletions examples/fabric-sync/admin/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2024 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import("//build_overrides/chip.gni")
import("${chip_root}/src/app/chip_data_model.gni")

source_set("fabric-admin-lib") {
sources = [
"DeviceManager.cpp",
"DeviceManager.h",
"PairingManager.cpp",
"PairingManager.h",
]

deps = [
"${chip_root}/examples/fabric-sync/bridge:fabric-bridge-lib",
"${chip_root}/src/lib",
]
}
111 changes: 111 additions & 0 deletions examples/fabric-sync/admin/DeviceManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "DeviceManager.h"

#include <crypto/RandUtils.h>
#include <lib/support/StringBuilder.h>

#include <cstdio>
#include <string>

using namespace chip;

// Define the static member
DeviceManager DeviceManager::sInstance;

void DeviceManager::Init()
{
// TODO: (#34113) Init mLastUsedNodeId from chip config file
mLastUsedNodeId = 1;
mInitialized = true;

ChipLogProgress(NotSpecified, "DeviceManager initialized: last used nodeId " ChipLogFormatX64,
ChipLogValueX64(mLastUsedNodeId));
}

NodeId DeviceManager::GetNextAvailableNodeId()
{
mLastUsedNodeId++;
VerifyOrDieWithMsg(mLastUsedNodeId < std::numeric_limits<NodeId>::max(), NotSpecified, "No more available NodeIds.");

return mLastUsedNodeId;
}

void DeviceManager::UpdateLastUsedNodeId(NodeId nodeId)
{
if (nodeId > mLastUsedNodeId)
{
mLastUsedNodeId = nodeId;
ChipLogProgress(NotSpecified, "Updating last used NodeId to " ChipLogFormatX64, ChipLogValueX64(mLastUsedNodeId));
}
}

void DeviceManager::SetRemoteBridgeNodeId(chip::NodeId nodeId)
{
mRemoteBridgeNodeId = nodeId;
}

CHIP_ERROR DeviceManager::PairRemoteFabricBridge(NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp,
uint16_t deviceRemotePort)
{
CHIP_ERROR err = PairingManager::Instance().PairDevice(nodeId, setupPINCode, deviceRemoteIp, deviceRemotePort);

if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified,
"Failed to pair remote fabric bridge: Node ID " ChipLogFormatX64 " with error: %" CHIP_ERROR_FORMAT,
ChipLogValueX64(nodeId), err.Format());
return err;
}

ChipLogProgress(NotSpecified, "Successfully paired remote fabric bridge: Node ID " ChipLogFormatX64, ChipLogValueX64(nodeId));
return CHIP_NO_ERROR;
}

CHIP_ERROR DeviceManager::UnpairRemoteFabricBridge()
{
if (mRemoteBridgeNodeId == kUndefinedNodeId)
{
ChipLogError(NotSpecified, "Remote bridge node ID is undefined; cannot unpair device.");
return CHIP_ERROR_INCORRECT_STATE;
}

CHIP_ERROR err = PairingManager::Instance().UnpairDevice(mRemoteBridgeNodeId);
if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "Failed to unpair remote bridge device " ChipLogFormatX64, ChipLogValueX64(mRemoteBridgeNodeId));
return err;
}

ChipLogProgress(NotSpecified, "Successfully unpaired remote fabric bridge: Node ID " ChipLogFormatX64,
ChipLogValueX64(mRemoteBridgeNodeId));
return CHIP_NO_ERROR;
}

void DeviceManager::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR err)
{
if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "Failed to remove synced device:(" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
ChipLogValueX64(deviceId), err.Format());
return;
}

ChipLogProgress(NotSpecified, "Synced device with NodeId:" ChipLogFormatX64 " has been removed.", ChipLogValueX64(deviceId));
}
99 changes: 99 additions & 0 deletions examples/fabric-sync/admin/DeviceManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "PairingManager.h"

#include <app-common/zap-generated/cluster-objects.h>
#include <platform/CHIPDeviceLayer.h>

class DeviceManager : public PairingDelegate
{
public:
DeviceManager() = default;

void Init();

chip::NodeId GetNextAvailableNodeId();

chip::NodeId GetRemoteBridgeNodeId() const { return mRemoteBridgeNodeId; }

void UpdateLastUsedNodeId(chip::NodeId nodeId);

void SetRemoteBridgeNodeId(chip::NodeId nodeId);

bool IsFabricSyncReady() const { return mRemoteBridgeNodeId != chip::kUndefinedNodeId; }

/**
* @brief Determines whether a given nodeId corresponds to the remote bridge device.
*
* @param nodeId The ID of the node being checked.
*
* @return true if the nodeId matches the remote bridge device; otherwise, false.
*/
bool IsCurrentBridgeDevice(chip::NodeId nodeId) const { return nodeId == mRemoteBridgeNodeId; }

/**
* @brief Pair a remote fabric bridge with a given node ID.
*
* This function initiates the pairing process for a remote fabric bridge using the specified parameters.
* @param nodeId The user-defined ID for the node being commissioned. It doesn’t need to be the same ID,
* as for the first fabric.
* @param setupPINCode The setup PIN code used to authenticate the pairing process.
* @param deviceRemoteIp The IP address of the remote device that is being paired as part of the fabric bridge.
* @param deviceRemotePort The secured device port of the remote device that is being paired as part of the fabric bridge.
*
* @return CHIP_ERROR Returns CHIP_NO_ERROR on success or an appropriate error code on failure.
*/
CHIP_ERROR PairRemoteFabricBridge(chip::NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp,
uint16_t deviceRemotePort);

CHIP_ERROR UnpairRemoteFabricBridge();

private:
friend DeviceManager & DeviceMgr();

void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) override;

static DeviceManager sInstance;

chip::NodeId mLastUsedNodeId = 0;

// The Node ID of the remote bridge used for Fabric-Sync
// This represents the bridge on the other ecosystem.
chip::NodeId mRemoteBridgeNodeId = chip::kUndefinedNodeId;

bool mInitialized = false;
};

/**
* Returns the public interface of the DeviceManager singleton object.
*
* Applications should use this to access features of the DeviceManager
* object.
*/
inline DeviceManager & DeviceMgr()
{
if (!DeviceManager::sInstance.mInitialized)
{
DeviceManager::sInstance.Init();
}
return DeviceManager::sInstance;
}
Loading

0 comments on commit 9c389ba

Please sign in to comment.