Skip to content

Commit

Permalink
Merge branch 'master' into sync-mcorefs
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Dec 11, 2024
2 parents 07cd4d3 + 7ceaf6f commit 37b8af4
Show file tree
Hide file tree
Showing 30 changed files with 1,777 additions and 4,342 deletions.
20 changes: 20 additions & 0 deletions docs/development_controllers/chip-tool/chip_tool_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ the setup payload or performing discovery actions.

<hr>

## Table of Contents

- [Installation](#installation)
- [Building from source](#building-from-source)
- [Running the CHIP Tool](#running-the-chip-tool)
- [CHIP Tool modes](#chip-tool-modes)
- [Single-command mode (default)](#single-command-mode-default)
- [Interactive mode](#interactive-mode)
- [Using CHIP Tool for Matter device testing](#using-chip-tool-for-matter-device-testing)
- [Supported commands and options](#supported-commands-and-options)
- [List all supported clusters](#printing-all-supported-clusters)
- [List all supported command for a cluster](#getting-the-list-of-commands-supported-for-a-specific-cluster)
- [List all supported attributes for a cluster](#getting-the-list-of-attributes-supported-for-a-specific-cluster)
- [Command options](#getting-the-list-of-command-options)
- [Testing and Interaction](#running-a-test-suite-against-a-paired-peer-device)
- [Multi-admin scenario](#multi-admin-scenario)
- [Subscribing to events or attributes](#subscribing-to-events-or-attributes)
- [Using wildcards](#using-wildcards)
- [Saving users and credentials for door lock device](#saving-users-and-credentials-on-door-lock-devices)

## Installation

On Linux distributions
Expand Down
64 changes: 57 additions & 7 deletions examples/chip-tool/commands/common/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

constexpr char kOptionalArgumentPrefix[] = "--";
constexpr size_t kOptionalArgumentPrefixLength = 2;
char kOptionalArgumentNullableDefault[] = "null";

bool Command::InitArguments(int argc, char ** argv)
{
Expand Down Expand Up @@ -81,10 +82,33 @@ bool Command::InitArguments(int argc, char ** argv)
}

// Initialize optional arguments
// Optional arguments expect a name and a value, so i is increased by 2 on every step.
for (size_t i = mandatoryArgsCount; i < (size_t) argc; i += 2)
//
// The optional arguments have a specific format and can also be "nullable":
// - Each optional argument is prefixed by `kOptionalArgumentPrefix` (e.g., "--").
// - Every optional argument name should be immediately followed by its corresponding value, unless it is nullable.
// - For nullable optional arguments, it is valid to have no subsequent value. In that case, the argument is set to a
// default null value. This allows such arguments to act as flags:
// - If the next token in `argv` starts with the optional prefix, or if this argument is the last one,
// we treat the optional argument as null (no specified value).
//
// The loop processes arguments starting at `mandatoryArgsCount` because all mandatory arguments are already processed.
// We iterate through `argv` and attempt to match each potential optional argument. The logic is as follows:
// 1. Check if the current argument (`argv[i]`) is indeed an optional argument by verifying it has the prefix
// `kOptionalArgumentPrefix`.
// 2. If it matches a known optional argument name, handle its value:
// - If the optional argument is nullable and the following conditions hold:
// a) There are no more arguments (`i + 1 >= argc`), or
// b) The next argument (`argv[i + 1]`) is also an optional argument (prefix check)
// then set the current optional argument to a null default.
// - Otherwise, expect the next argument (`argv[i + 1]`) to be the value. If no value is provided, log an error and exit.
// 3. Once processed, move the index `i` forward by 2 if a value was consumed (name + value), or by 1 if the argument was
// nullable and no value was consumed.
//
// If at any point an argument cannot be matched or initialized properly, an error is logged and we exit.
for (size_t i = mandatoryArgsCount; i < (size_t) argc;)
{
bool found = false;
bool found = false;
bool foundValue = false;
for (size_t j = mandatoryArgsCount; j < mandatoryArgsCount + optionalArgsCount; j++)
{
// optional arguments starts with kOptionalArgumentPrefix
Expand All @@ -98,14 +122,40 @@ bool Command::InitArguments(int argc, char ** argv)
{
found = true;

VerifyOrExit((size_t) argc > (i + 1),
ChipLogError(chipTool, "InitArgs: Optional argument %s missing value.", argv[i]));
if (!InitArgument(j, argv[i + 1]))
if (mArgs[j].isNullable())
{
ExitNow();
if ((size_t) argc <= (i + 1))
{
// This is the last argument, so set it to null.
VerifyOrDo(InitArgument(j, kOptionalArgumentNullableDefault), ExitNow());
continue;
}

if (strncmp(argv[i + 1], kOptionalArgumentPrefix, kOptionalArgumentPrefixLength) == 0)
{
// The argument is followed by an other optional argument, so set it to null.
VerifyOrDo(InitArgument(j, kOptionalArgumentNullableDefault), ExitNow());
continue;
}
}

VerifyOrExit((size_t) argc > (i + 1),
ChipLogError(chipTool, "InitArgs: Optional argument %s missing value.", argv[i]));

foundValue = true;
VerifyOrDo(InitArgument(j, argv[i + 1]), ExitNow());
}
}

if (foundValue)
{
i += 2;
}
else
{
i += 1;
}

VerifyOrExit(found, ChipLogError(chipTool, "InitArgs: Optional argument %s does not exist.", argv[i]));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ void FabricSyncAddBridgeCommand::OnCommissioningComplete(NodeId deviceId, CHIP_E
ChipLogValueX64(deviceId), err.Format());
}

PairingManager::Instance().ResetForNextCommand();
mBridgeNodeId = kUndefinedNodeId;
}

Expand Down Expand Up @@ -123,6 +124,7 @@ void FabricSyncRemoveBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_ERROR
ChipLogValueX64(deviceId), err.Format());
}

PairingManager::Instance().ResetForNextCommand();
mBridgeNodeId = kUndefinedNodeId;
}

Expand Down Expand Up @@ -174,6 +176,7 @@ void FabricSyncAddLocalBridgeCommand::OnCommissioningComplete(NodeId deviceId, C
ChipLogValueX64(deviceId), err.Format());
}

PairingManager::Instance().ResetForNextCommand();
mLocalBridgeNodeId = kUndefinedNodeId;
}

Expand Down Expand Up @@ -215,6 +218,7 @@ void FabricSyncRemoveLocalBridgeCommand::OnDeviceRemoved(NodeId deviceId, CHIP_E
ChipLogValueX64(deviceId), err.Format());
}

PairingManager::Instance().ResetForNextCommand();
mLocalBridgeNodeId = kUndefinedNodeId;
}

Expand Down Expand Up @@ -290,6 +294,8 @@ void FabricSyncDeviceCommand::OnCommissioningComplete(NodeId deviceId, CHIP_ERRO
ChipLogError(NotSpecified, "Failed to pair synced device (0x:" ChipLogFormatX64 ") with error: %" CHIP_ERROR_FORMAT,
ChipLogValueX64(deviceId), err.Format());
}

PairingManager::Instance().ResetForNextCommand();
}

CHIP_ERROR FabricSyncDeviceCommand::RunCommand(EndpointId remoteEndpointId)
Expand Down
31 changes: 31 additions & 0 deletions examples/fabric-admin/device_manager/PairingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,4 +661,35 @@ CHIP_ERROR PairingManager::UnpairDevice(NodeId nodeId)
});
}

void PairingManager::ResetForNextCommand()
{
mCommissioningWindowDelegate = nullptr;
mPairingDelegate = nullptr;
mNodeId = chip::kUndefinedNodeId;
mVerifier = chip::ByteSpan();
mSalt = chip::ByteSpan();
mDiscriminator = 0;
mSetupPINCode = 0;
mDeviceIsICD = false;

memset(mRandomGeneratedICDSymmetricKey, 0, sizeof(mRandomGeneratedICDSymmetricKey));
memset(mVerifierBuffer, 0, sizeof(mVerifierBuffer));
memset(mSaltBuffer, 0, sizeof(mSaltBuffer));
memset(mRemoteIpAddr, 0, sizeof(mRemoteIpAddr));
memset(mOnboardingPayload, 0, sizeof(mOnboardingPayload));

mICDRegistration.ClearValue();
mICDCheckInNodeId.ClearValue();
mICDClientType.ClearValue();
mICDSymmetricKey.ClearValue();
mICDMonitoredSubject.ClearValue();
mICDStayActiveDurationMsec.ClearValue();

mWindowOpener.reset();
mOnOpenCommissioningWindowCallback.Cancel();
mOnOpenCommissioningWindowVerifierCallback.Cancel();
mCurrentFabricRemover.reset();
mCurrentFabricRemoveCallback.Cancel();
}

} // namespace admin
6 changes: 6 additions & 0 deletions examples/fabric-admin/device_manager/PairingManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ class PairingManager : public chip::Controller::DevicePairingDelegate,
*/
CHIP_ERROR UnpairDevice(chip::NodeId nodeId);

/**
* Resets the PairingManager's internal state to a baseline, making it ready to handle a new command.
* This method clears all internal states and resets all members to their initial values.
*/
void ResetForNextCommand();

private:
// Constructors
PairingManager();
Expand Down
26 changes: 25 additions & 1 deletion examples/fabric-sync/admin/DeviceSynchronization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path,
}
}
break;
case Clusters::BasicInformation::Attributes::VendorID::Id: {
uint32_t vendorId;
if (SuccessOrLog(data->Get(vendorId), "VendorID"))
{
mCurrentDeviceData.vendorId = static_cast<chip::VendorId>(vendorId);
}
}
break;
case Clusters::BasicInformation::Attributes::VendorName::Id: {
char vendorNameBuffer[kBasicInformationAttributeBufSize];
if (SuccessOrLog(data->GetString(vendorNameBuffer, sizeof(vendorNameBuffer)), "VendorName"))
Expand All @@ -99,6 +107,14 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path,
}
}
break;
case Clusters::BasicInformation::Attributes::ProductID::Id: {
uint32_t productId;
if (SuccessOrLog(data->Get(productId), "ProductID"))
{
mCurrentDeviceData.productId = productId;
}
}
break;
case Clusters::BasicInformation::Attributes::ProductName::Id: {
char productNameBuffer[kBasicInformationAttributeBufSize];
if (SuccessOrLog(data->GetString(productNameBuffer, sizeof(productNameBuffer)), "ProductName"))
Expand All @@ -124,6 +140,14 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path,
}
}
break;
case Clusters::BasicInformation::Attributes::SoftwareVersion::Id: {
uint32_t softwareVersion;
if (SuccessOrLog(data->Get(softwareVersion), "SoftwareVersion"))
{
mCurrentDeviceData.softwareVersion = softwareVersion;
}
}
break;
case Clusters::BasicInformation::Attributes::SoftwareVersionString::Id: {
char softwareVersionStringBuffer[kBasicInformationAttributeBufSize];
if (SuccessOrLog(data->GetString(softwareVersionStringBuffer, sizeof(softwareVersionStringBuffer)),
Expand Down Expand Up @@ -274,7 +298,7 @@ void DeviceSynchronizer::SynchronizationCompleteAddDevice()
bridge::FabricBridge::Instance().AddSynchronizedDevice(mCurrentDeviceData);

// TODO(#35077) Figure out how we should reflect CADMIN values of ICD.
if (!mCurrentDeviceData.isIcd)
if (!mCurrentDeviceData.isIcd.value_or(false))
{
VerifyOrDie(mController);
ScopedNodeId scopedNodeId(mNodeId, mController->GetFabricIndex());
Expand Down
1 change: 1 addition & 0 deletions scripts/tools/check_includes_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
# Only uses <chrono> for zero-cost types.
'src/system/SystemClock.h': {'chrono'},
'src/platform/mbed/MbedEventTimeout.h': {'chrono'},
'src/lib/core/StringBuilderAdapters.h': {'chrono'},

'src/app/app-platform/ContentApp.h': {'list', 'string'},
'src/app/app-platform/ContentAppPlatform.cpp': {'string'},
Expand Down
2 changes: 1 addition & 1 deletion src/darwin/Framework/CHIP/MTRAttributeValueWaiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ MTR_AVAILABLE(ios(18.3), macos(15.3), watchos(11.3), tvos(18.3))
*/
- (void)cancel;

@property (readonly, nonatomic) NSUUID * UUID MTR_NEWLY_AVAILABLE;
@property (readonly, nonatomic) NSUUID * UUID MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4));

@end

Expand Down
4 changes: 2 additions & 2 deletions src/darwin/Framework/CHIP/MTRDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
/**
* Network commissioning features supported by the device.
*/
@property (nonatomic, readonly) MTRNetworkCommissioningFeature networkCommissioningFeatures MTR_NEWLY_AVAILABLE;
@property (nonatomic, readonly) MTRNetworkCommissioningFeature networkCommissioningFeatures MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4));

/**
* Set the delegate to receive asynchronous callbacks about the device.
Expand Down Expand Up @@ -228,7 +228,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
* data-values (as described in the documentation for
* MTRDeviceResponseHandler) as values.
*/
- (NSDictionary<MTRAttributePath *, NSDictionary<NSString *, id> *> *)descriptorClusters MTR_NEWLY_AVAILABLE;
- (NSDictionary<MTRAttributePath *, NSDictionary<NSString *, id> *> *)descriptorClusters MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4));

/**
* Invoke a command with a designated command path
Expand Down
5 changes: 3 additions & 2 deletions src/darwin/Framework/CHIP/MTRKeypair.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,19 @@ NS_ASSUME_NONNULL_BEGIN
* Implementations of the keypair methods must not call into any Matter
* framework APIs.
*/
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
@protocol MTRKeypair <NSObject>

@optional
/**
* @brief Returns a copy of the public key for the keypair.
*/
- (SecKeyRef)copyPublicKey MTR_NEWLY_AVAILABLE;
- (SecKeyRef)copyPublicKey MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4));

/**
* @brief Returns public key for the keypair without adding a reference. DEPRECATED - please use copyPublicKey, otherwise this will leak.
*/
- (SecKeyRef)publicKey MTR_NEWLY_DEPRECATED("Please implement copyPublicKey, this will leak otherwise");
- (SecKeyRef)publicKey MTR_DEPRECATED("Please implement copyPublicKey, this will leak otherwise", ios(16.1, 18.4), macos(13.0, 15.4), watchos(9.1, 11.4), tvos(16.1, 18.4));

/**
* @brief A function to sign a message using ECDSA
Expand Down
Loading

0 comments on commit 37b8af4

Please sign in to comment.