diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 717f8ca95628fa..383a98583bd9fc 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -62,7 +62,7 @@ jobs: - name: Generate all run: ./scripts/run_in_build_env.sh scripts/tools/zap_regen_all.py - name: Generate script-maintained items (ERROR_CODES.md) - run: ./scripts/run_in_build_env.sh "scripts/error_table.py > docs/ERROR_CODES.md" + run: ./scripts/run_in_build_env.sh "scripts/error_table.py > docs/ids_and_codes/ERROR_CODES.md" - name: Ensure git works in current working directory run: git config --global --add safe.directory `pwd` - name: Check for uncommited changes diff --git a/.restyled.yaml b/.restyled.yaml index c201729d30e41a..446dad740b96a5 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -83,9 +83,7 @@ exclude: - "scripts/setup/bootstrap.sh" # tries to quote loop variable - "integrations/docker/build-all.sh" # tries to quote loop variable - "scripts/setup/pigweed.json" # TODO(#29547). This file is temporary copy from pigweed repo that has minor edits. No restyle help in diff. - - "docs/ERROR_CODES.md" # generated by scripts, not easy to align tables - - "docs/zap_clusters.md" # generated by scripts, not easy to align tables - - "docs/spec_clusters.md" # generated by scripts, not easy to align tables + - "docs/ids_and_codes/**" # generated by scripts, not easy to align tables - "docs/testing/yaml_pseudocluster.md" # generated by scripts, restyler makes the tables render improperly - "docs/testing/yaml_schema.md" # generated by scripts, restyler makes the tables render improperly diff --git a/.spellcheck.yml b/.spellcheck.yml index 757034586b9bd0..36461334c881ee 100644 --- a/.spellcheck.yml +++ b/.spellcheck.yml @@ -65,7 +65,7 @@ matrix: # converts markdown to HTML - pyspelling.filters.markdown: sources: - - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md|!docs/testing/python.md|!docs/testing/ChipDeviceCtrlAPI.md|!docs/issue_triage.md' + - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ids_and_codes/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md|!docs/testing/python.md|!docs/testing/ChipDeviceCtrlAPI.md|!docs/issue_triage.md' aspell: ignore-case: true camel-case: true diff --git a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md index a19336a5939b73..ad509ea57a418b 100644 --- a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md +++ b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md @@ -48,11 +48,11 @@ Note that the output should also be verified against the spec using the - Goal: get zap to understand the new cluster so it can be used on devices (XML and glue) -![](../getting_started/img/zap_compiler.png) +![](../zap_and_codegen/img/zap_compiler.png) ### Cluster definitions and ZAP -Please see [ZAP](../getting_started/zap.md) for an introduction to ZAP. +Please see [ZAP](../zap_and_codegen/zap_intro.md) for an introduction to ZAP. After implementing the changes outlined in the wiki article, your cluster and device type should show up in zap. you can check this by running zaptool with @@ -64,17 +64,17 @@ To ensure the cluster and device type are correctly implemented for ZAP, open the endpoint configuration and ensure the device type appears in the device type list. -![](../getting_started/img/zap3.png) +![](../zap_and_codegen/img/zap3.png) Next, check your cluster. The "domain" parameter in the XML controls which group the cluster is in. It should have all the expected attributes, commands and events. -![](../getting_started/img/zap4.png) +![](../zap_and_codegen/img/zap4.png) Last, ensure that your attributes have the storage option set appropriately. -![](../getting_started/img/zap5.png) +![](../zap_and_codegen/img/zap5.png) ### Cluster implementation - Ember and overrides diff --git a/docs/getting_started/changing_examples.md b/docs/getting_started/changing_examples.md index 611610ce43fb59..02ba357d861300 100644 --- a/docs/getting_started/changing_examples.md +++ b/docs/getting_started/changing_examples.md @@ -4,10 +4,10 @@ The composition of most examples in the SDK is static and code generated. The tool used to describe and change the composition of an example is called ZAP. More information about ZAP and a walk-through of the tool can be found in -the [ZAP introduction](./zap.md). The composition of the device is captured in a -.zap file, which is readable by the ZAP tool. This is then compiled into a -human-readable .matter file, which is used to build the static features of the -example. +the [ZAP introduction](../zap_and_codegen/zap_intro.md). The composition of the +device is captured in a .zap file, which is readable by the ZAP tool. This is +then compiled into a human-readable .matter file, which is used to build the +static features of the example. To change the composition of a device example, you need to @@ -35,7 +35,8 @@ This will open the ZAP GUI tool, which can be used to change the endpoint composition, clusters, features, attributes, commands and events exposed by the device. -Details of how to use the tool can be found in the [ZAP Introduction](./zap.md). +Details of how to use the tool can be found in the +[ZAP Introduction](../zap_and_codegen/zap_intro.md). ## Running code generation @@ -62,3 +63,16 @@ recompile the .zap files for all the examples and the controller. After generating the .matter file, re-build the example. Instructions for building examples are given in [Building your first example](./first_example.md) + +## Ensuring device conformance + +After changing the examples, it is important to ensure they remain spec +compliant. Although there are numerous certification tests to check the various +parts of the device, the tests most likely to be affected by changes to ZAP are +the conformance tests, which ensure that the device included meets the +conformance requirements for clusters and device types. To run conformance tests +against the example app, see [Testing](../testing/index.md). The tests that +ensure the device composition is spec compliant are found in +[Device Basic Composition Test](../../src/python_testing/TC_DeviceBasicComposition.py) +and +[Device Conformance Tests](../../src/python_testing/TC_DeviceConformance.py). diff --git a/docs/getting_started/first_example.md b/docs/getting_started/first_example.md index d75d9e7b1a4fee..7b005f3adc63db 100644 --- a/docs/getting_started/first_example.md +++ b/docs/getting_started/first_example.md @@ -37,7 +37,7 @@ for testing. More information about the python controller can be found in the The examples directory contains a set of apps using an example device composition \.zap file. For more information about device composition and zap, -see [ZAP documentation](./zap.md). +see [ZAP documentation](../zap_and_codegen/zap_intro.md). This quick start guide will walk you through diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index 1bfbe3f57cc333..fc8b9bd1713085 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -10,11 +10,9 @@ The following docs are a brief introduction to SDK development. first_example changing_examples SDKBasics -zap ``` - [Running your first example](./first_example.md) - [Changing examples](./changing_examples.md) - [SDK Architecture Overview](./SDKBasics.md) -- [ZAP Introduction](./zap.md) diff --git a/docs/guides/simulated_device_linux.md b/docs/guides/simulated_device_linux.md index db7e6bc4ef55ad..eb4d6d7564c0c6 100644 --- a/docs/guides/simulated_device_linux.md +++ b/docs/guides/simulated_device_linux.md @@ -19,8 +19,8 @@ is defined by a ZAP config file and tests can be added with a - [Building Prerequisites](./BUILDING.md#prerequisites) - [Prepare For Building](./BUILDING.md#prepare-for-building) -- [Code Generate](../code_generation.md) -- [ZAP Installed](../code_generation.md#installing-zap-and-environment-variables) +- [Code Generate](../zap_and_codegen/code_generation.md) +- [ZAP Installed](../zap_and_codegen/code_generation.md#installing-zap-and-environment-variables) ## Building the default Simulated App with Script diff --git a/docs/ERROR_CODES.md b/docs/ids_and_codes/ERROR_CODES.md similarity index 100% rename from docs/ERROR_CODES.md rename to docs/ids_and_codes/ERROR_CODES.md diff --git a/docs/ids_and_codes/index.md b/docs/ids_and_codes/index.md new file mode 100644 index 00000000000000..ef87b9ca01c569 --- /dev/null +++ b/docs/ids_and_codes/index.md @@ -0,0 +1,10 @@ +# IDs and Codes + + +```{toctree} +:glob: +:maxdepth: 1 + +* + +``` diff --git a/docs/spec_clusters.md b/docs/ids_and_codes/spec_clusters.md similarity index 100% rename from docs/spec_clusters.md rename to docs/ids_and_codes/spec_clusters.md diff --git a/docs/zap_clusters.md b/docs/ids_and_codes/zap_clusters.md similarity index 100% rename from docs/zap_clusters.md rename to docs/ids_and_codes/zap_clusters.md diff --git a/docs/index.md b/docs/index.md index 89e4661e2a0e1e..cd5fe17d102fd4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,6 +10,7 @@ VSCODE_DEVELOPMENT ci-cd/index development_controllers/index getting_started/index +ids_and_codes/index cluster_and_device_type_dev/index guides/index platforms/index @@ -19,14 +20,10 @@ product_considerations/index testing/index tips_and_troubleshooting/index tools/index +zap_and_codegen/index BUG_REPORT -code_generation -zap_clusters -spec_clusters upgrading -ERROR_CODES issue_triage - ``` ```{include} README.md diff --git a/docs/code_generation.md b/docs/zap_and_codegen/code_generation.md similarity index 98% rename from docs/code_generation.md rename to docs/zap_and_codegen/code_generation.md index bf5b6f3036963a..e6ff51b3182e77 100644 --- a/docs/code_generation.md +++ b/docs/zap_and_codegen/code_generation.md @@ -197,6 +197,11 @@ via `-o/--output-dir`. ./scripts/tools/zap/generate.py $PATH_TO_ZAP_FILE ``` +Rebuild the application. + +It is also recommended to run device composition tests to ensure the selected +composition is spec compliant (see [Testing](../testing)) + ### Compile-time code generation / pre-generated code A subset of code generation (both `codegen.py` and `zap-cli`) is done at compile diff --git a/docs/getting_started/img/zap1.png b/docs/zap_and_codegen/img/zap1.png similarity index 100% rename from docs/getting_started/img/zap1.png rename to docs/zap_and_codegen/img/zap1.png diff --git a/docs/getting_started/img/zap2.png b/docs/zap_and_codegen/img/zap2.png similarity index 100% rename from docs/getting_started/img/zap2.png rename to docs/zap_and_codegen/img/zap2.png diff --git a/docs/getting_started/img/zap3.png b/docs/zap_and_codegen/img/zap3.png similarity index 100% rename from docs/getting_started/img/zap3.png rename to docs/zap_and_codegen/img/zap3.png diff --git a/docs/getting_started/img/zap4.png b/docs/zap_and_codegen/img/zap4.png similarity index 100% rename from docs/getting_started/img/zap4.png rename to docs/zap_and_codegen/img/zap4.png diff --git a/docs/getting_started/img/zap5.png b/docs/zap_and_codegen/img/zap5.png similarity index 100% rename from docs/getting_started/img/zap5.png rename to docs/zap_and_codegen/img/zap5.png diff --git a/docs/getting_started/img/zap6.png b/docs/zap_and_codegen/img/zap6.png similarity index 100% rename from docs/getting_started/img/zap6.png rename to docs/zap_and_codegen/img/zap6.png diff --git a/docs/getting_started/img/zap_compiler.png b/docs/zap_and_codegen/img/zap_compiler.png similarity index 100% rename from docs/getting_started/img/zap_compiler.png rename to docs/zap_and_codegen/img/zap_compiler.png diff --git a/docs/zap_and_codegen/index.md b/docs/zap_and_codegen/index.md new file mode 100644 index 00000000000000..7301f03b2147d7 --- /dev/null +++ b/docs/zap_and_codegen/index.md @@ -0,0 +1,8 @@ +# ZAP and Codegen + +```{toctree} +:glob: +:maxdepth: 1 + +* +``` diff --git a/docs/getting_started/zap.md b/docs/zap_and_codegen/zap_intro.md similarity index 100% rename from docs/getting_started/zap.md rename to docs/zap_and_codegen/zap_intro.md diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn index 0d1e142f1074df..1c492ba10a1241 100644 --- a/examples/darwin-framework-tool/BUILD.gn +++ b/examples/darwin-framework-tool/BUILD.gn @@ -194,6 +194,8 @@ executable("darwin-framework-tool") { "commands/common/CertificateIssuer.mm", "commands/common/ControllerStorage.h", "commands/common/ControllerStorage.mm", + "commands/common/DeviceDelegate.h", + "commands/common/DeviceDelegate.mm", "commands/common/MTRDevice_Externs.h", "commands/common/MTRError.mm", "commands/common/MTRError_Utils.h", diff --git a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h index cd8125e3b12273..ba3428341ec8e8 100644 --- a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h @@ -105,9 +105,7 @@ class ReadAttribute : public ModelCommand { LogNSError("Error reading attribute", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(endpoint, cluster, attribute, error); } else { - for (id item in values) { - NSLog(@"Response Item: %@", [item description]); - } + NSLog(@"cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u: %@", mClusterId, mAttributeId, endpointId, values); RemoteDataModelLogger::LogAttributeAsJSON(endpoint, cluster, attribute, values); } diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 90f3a6c56415f6..2f53c0dd7bc4db 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -52,6 +52,7 @@ class CHIPCommandBridge : public Command { AddArgument("commissioner-vendor-id", 0, UINT16_MAX, &mCommissionerVendorId, "The vendor id to use for darwin-framework-tool. If not provided, chip::VendorId::TestVendor1 (65521, 0xFFF1) will be " "used."); + AddArgument("pretend-thread-enabled", 0, 1, &mPretendThreadEnabled, "When the command is issued using an MTRDevice (via -use-mtr-device), instructs the MTRDevice to treat the target device as a Thread device."); } /////////// Command Interface ///////// @@ -164,4 +165,5 @@ class CHIPCommandBridge : public Command { chip::Optional mPaaTrustStorePath; chip::Optional mCommissionerVendorId; std::string mCurrentIdentity; + chip::Optional mPretendThreadEnabled; }; diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index b237acaa5b7132..2eba24c84ad44c 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -28,12 +28,15 @@ #import "CHIPCommandStorageDelegate.h" #import "CertificateIssuer.h" #import "ControllerStorage.h" +#import "DeviceDelegate.h" #include "MTRError_Utils.h" #include #include static CHIPToolPersistentStorageDelegate * storage = nil; +static DeviceDelegate * sDeviceDelegate = nil; +static dispatch_queue_t sDeviceDelegateDispatchQueue = nil; std::set CHIPCommandBridge::sDeferredCleanups; std::map CHIPCommandBridge::mControllers; dispatch_queue_t CHIPCommandBridge::mOTAProviderCallbackQueue; @@ -302,6 +305,18 @@ __auto_type * device = [MTRDevice deviceWithNodeID:@(nodeId) controller:controller]; VerifyOrReturnValue(nil != device, nil); + // The device delegate is initialized only once, when the first MTRDevice is created. + // As a result, subsequent commands using --use-mtr-device don’t need to specify the + // `--pretend-thread-enabled 1` argument again. Any further attempts to set it to `0` will also be ignored. + if (sDeviceDelegate == nil) { + sDeviceDelegate = [[DeviceDelegate alloc] init]; + sDeviceDelegateDispatchQueue = dispatch_queue_create("com.chip.devicedelegate", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + if (mPretendThreadEnabled.ValueOr(false)) { + [sDeviceDelegate setPretendThreadEnabled:YES]; + } + } + [device addDelegate:sDeviceDelegate queue:sDeviceDelegateDispatchQueue]; + return device; } diff --git a/examples/darwin-framework-tool/commands/common/DeviceDelegate.h b/examples/darwin-framework-tool/commands/common/DeviceDelegate.h new file mode 100644 index 00000000000000..a3f5cf427f191c --- /dev/null +++ b/examples/darwin-framework-tool/commands/common/DeviceDelegate.h @@ -0,0 +1,23 @@ +/* + * 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. + * + */ + +#import + +@interface DeviceDelegate : NSObject +- (void)setPretendThreadEnabled:(BOOL)threadEnabled; +@end diff --git a/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm b/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm new file mode 100644 index 00000000000000..ecf8e708e26ff3 --- /dev/null +++ b/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm @@ -0,0 +1,69 @@ +/* + * 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. + * + */ + +#import "DeviceDelegate.h" + +#include + +NS_ASSUME_NONNULL_BEGIN + +@interface DeviceDelegate () +@property (nonatomic, readwrite) BOOL threadEnabled; +@end + +@implementation DeviceDelegate +- (instancetype)init +{ + if (self = [super init]) { + _threadEnabled = NO; + } + return self; +} + +- (void)device:(MTRDevice *)device stateChanged:(MTRDeviceState)state +{ +} + +- (void)device:(MTRDevice *)device receivedAttributeReport:(NSArray *> *)attributeReport +{ +} + +- (void)device:(MTRDevice *)device receivedEventReport:(NSArray *> *)eventReport +{ +} + +- (void)deviceCachePrimed:(MTRDevice *)device +{ +} + +- (void)deviceConfigurationChanged:(MTRDevice *)device +{ +} + +- (void)setPretendThreadEnabled:(BOOL)threadEnabled +{ + _threadEnabled = threadEnabled; +} + +- (BOOL)unitTestPretendThreadEnabled:(MTRDevice *)device +{ + return _threadEnabled; +} +@end + +NS_ASSUME_NONNULL_END diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 6f8afea5bb496b..30732ae7e0a034 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -46,6 +46,10 @@ #include #endif +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST +#include +#endif + using namespace chip; using namespace chip::ArgParser; using namespace chip::Platform; @@ -112,6 +116,9 @@ enum kDeviceOption_WiFiSupports5g, #if CONFIG_BUILD_FOR_HOST_UNIT_TEST kDeviceOption_SubscriptionResumptionRetryIntervalSec, + kDeviceOption_IdleRetransmitTimeout, + kDeviceOption_ActiveRetransmitTimeout, + kDeviceOption_ActiveThresholdTime, #endif #if CHIP_WITH_NLFAULTINJECTION kDeviceOption_FaultInjection, @@ -187,6 +194,9 @@ OptionDef sDeviceOptionDefs[] = { #if CONFIG_BUILD_FOR_HOST_UNIT_TEST { "subscription-capacity", kArgumentRequired, kDeviceOption_SubscriptionCapacity }, { "subscription-resumption-retry-interval", kArgumentRequired, kDeviceOption_SubscriptionResumptionRetryIntervalSec }, + { "idle-retransmit-timeout", kArgumentRequired, kDeviceOption_IdleRetransmitTimeout }, + { "active-retransmit-timeout", kArgumentRequired, kDeviceOption_ActiveRetransmitTimeout }, + { "active-threshold-time", kArgumentRequired, kDeviceOption_ActiveThresholdTime }, #endif #if CHIP_WITH_NLFAULTINJECTION { "faults", kArgumentRequired, kDeviceOption_FaultInjection }, @@ -335,6 +345,19 @@ const char * sDeviceOptionHelp = " Max number of subscriptions the device will allow\n" " --subscription-resumption-retry-interval\n" " subscription timeout resumption retry interval in seconds\n" + " --idle-retransmit-timeout \n" + " Sets the MRP idle retry interval (in milliseconds).\n" + " This interval is used by the peer to calculate the retransmission timeout when the current device is considered idle.\n" + "\n" + " --active-retransmit-timeout \n" + " Sets the MRP active retry interval (in milliseconds).\n" + " This interval is used by the peer to calculate the retransmission timeout when the current device is considered " + "active.\n" + "\n" + " --active-threshold-time