Skip to content

Commit

Permalink
Merge branch 'master' into onboarding_payload_renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierGre authored Dec 13, 2024
2 parents 93d2adf + 9e203e2 commit 93b06db
Show file tree
Hide file tree
Showing 58 changed files with 2,390 additions and 4,629 deletions.
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 @@ -23,7 +23,6 @@
#include <EnergyEvseManager.h>
#include <EnergyTimeUtils.h>

#include <EnergyTimeUtils.h>
#include <FakeReadings.h>
#include <app/clusters/device-energy-management-server/DeviceEnergyManagementTestEventTriggerHandler.h>
#include <app/clusters/electrical-energy-measurement-server/EnergyReportingTestEventTriggerHandler.h>
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace admin {
namespace {

constexpr uint16_t kSubscribeMinInterval = 0;
constexpr uint16_t kSubscribeMaxInterval = 60;
constexpr uint16_t kSubscribeMaxInterval = 30;

void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
Expand Down
7 changes: 6 additions & 1 deletion examples/fabric-admin/device_manager/DeviceSubscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ namespace admin {

namespace {

constexpr uint16_t kSubscribeMinInterval = 0;
constexpr uint16_t kSubscribeMaxInterval = 10;

void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
reinterpret_cast<DeviceSubscription *>(context)->OnDeviceConnected(exchangeMgr, sessionHandle);
Expand Down Expand Up @@ -162,7 +165,9 @@ void DeviceSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchange

readParams.mpAttributePathParamsList = readPaths;
readParams.mAttributePathParamsListSize = 1;
readParams.mMaxIntervalCeilingSeconds = 5 * 60;
readParams.mMinIntervalFloorSeconds = kSubscribeMinInterval;
readParams.mMaxIntervalCeilingSeconds = kSubscribeMaxInterval;
readParams.mKeepSubscriptions = true;

CHIP_ERROR err = mClient->SendRequest(readParams);

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
2 changes: 1 addition & 1 deletion examples/fabric-sync/admin/BridgeSubscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace admin {
namespace {

constexpr uint16_t kSubscribeMinInterval = 0;
constexpr uint16_t kSubscribeMaxInterval = 60;
constexpr uint16_t kSubscribeMaxInterval = 30;

void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
Expand Down
7 changes: 6 additions & 1 deletion examples/fabric-sync/admin/DeviceSubscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ namespace admin {

namespace {

constexpr uint16_t kSubscribeMinInterval = 0;
constexpr uint16_t kSubscribeMaxInterval = 10;

void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
reinterpret_cast<DeviceSubscription *>(context)->OnDeviceConnected(exchangeMgr, sessionHandle);
Expand Down Expand Up @@ -160,7 +163,9 @@ void DeviceSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchange

readParams.mpAttributePathParamsList = readPaths;
readParams.mAttributePathParamsListSize = 1;
readParams.mMaxIntervalCeilingSeconds = 5 * 60;
readParams.mMinIntervalFloorSeconds = kSubscribeMinInterval;
readParams.mMaxIntervalCeilingSeconds = kSubscribeMaxInterval;
readParams.mKeepSubscriptions = true;

CHIP_ERROR err = mClient->SendRequest(readParams);

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
40 changes: 38 additions & 2 deletions integrations/appengine/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Deploy Static Website on App Engine
## Deploy Static Website on App Engine for The Matter SDK Coverage Report

### Setup google cloud integration

Expand Down Expand Up @@ -30,7 +30,43 @@ settings of your App Engine application.
Directory `out/coverage/coverage` contains the coverage report files, such as
HTML, CSS, images, and JavaScript.

Deploying your generated report:

```
cd out/coverage/coverage
gcloud app deploy ../../../integrations/appengine/webapp_config.yaml
gcloud app deploy webapp_config.yaml --project matter-build-automation
```

The output should look like:

```
Services to deploy:
descriptor: [/usr/local/google/home/<user>/connectedhomeip/out/coverage/coverage/webapp_config.yaml]
source: [/usr/local/google/home/<user>/connectedhomeip/out/coverage/coverage]
target project: [matter-build-automation]
target service: [default]
target version: [20241212t175429]
target url: [https://matter-build-automation.ue.r.appspot.com]
target service account: [[email protected]]
Do you want to continue (Y/n)? Y
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 0 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://matter-build-automation.ue.r.appspot.com]
You can stream logs from the command line by running:
$ gcloud app logs tail -s default
To view your application in the web browser run:
$ gcloud app browse --project=matter-build-automation
```

If you run into permission issues, reach out to a team member from Google.
4 changes: 1 addition & 3 deletions integrations/appengine/webapp_config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
runtime: python27
api_version: 1
threadsafe: true
runtime: python39
handlers:
- url: /
static_files: html/index.html
Expand Down
2 changes: 1 addition & 1 deletion scripts/build_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ mkdir -p "$COVERAGE_ROOT"
lcov --initial --capture --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_base.info"
lcov --capture --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_test.info"
lcov --add-tracefile "$COVERAGE_ROOT/lcov_base.info" --add-tracefile "$COVERAGE_ROOT/lcov_test.info" --output-file "$COVERAGE_ROOT/lcov_final.info"
genhtml "$COVERAGE_ROOT/lcov_final.info" --output-directory "$COVERAGE_ROOT/html"
genhtml "$COVERAGE_ROOT/lcov_final.info" --output-directory "$COVERAGE_ROOT/html" --title "SHA:$(git rev-parse HEAD)" --header-title "Matter SDK Coverage Report"

# Copy webapp's YAML file to the coverage output directory
cp "$CHIP_ROOT/integrations/appengine/webapp_config.yaml" "$COVERAGE_ROOT/webapp_config.yaml"
9 changes: 7 additions & 2 deletions scripts/tests/run_python_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ def forward_fifo(path: str, f_out: typing.BinaryIO, stop_event: threading.Event)
@click.option("--quiet/--no-quiet", default=None,
help="Do not print output from passing tests. Use this flag in CI to keep GitHub log size manageable.")
@click.option("--load-from-env", default=None, help="YAML file that contains values for environment variables.")
@click.option("--run", type=str, multiple=True, help="Run only the specified test run(s).")
def main(app: str, factory_reset: bool, factory_reset_app_only: bool, app_args: str,
app_ready_pattern: str, app_stdin_pipe: str, script: str, script_args: str,
script_gdb: bool, quiet: bool, load_from_env):
script_gdb: bool, quiet: bool, load_from_env, run):
if load_from_env:
reader = MetadataReader(load_from_env)
runs = reader.parse_script(script)
Expand All @@ -141,7 +142,11 @@ def main(app: str, factory_reset: bool, factory_reset_app_only: bool, app_args:
"No valid runs were found. Make sure you add runs to your file, see "
"https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md document for reference/example.")

# Override runs Metadata with the command line arguments
if run:
# Filter runs based on the command line arguments
runs = [r for r in runs if r.run in run]

# Override runs Metadata with the command line options
for run in runs:
if factory_reset is not None:
run.factory_reset = factory_reset
Expand Down
Loading

0 comments on commit 93b06db

Please sign in to comment.