Skip to content

Commit e8fb908

Browse files
THNETDIR / WIFINM: Test scripts and small fixes (#34469)
* Thread Network Directory GetOperationalDataset does not required timed invoke See CHIP-Specifications/connectedhomeip-spec#10106 * Actually return the dataset in GetOperationalDataset * Add test scripts for THNETDIR cluster Base on CHIP-Specifications/chip-test-plans#4322 but contains some additional steps which will be added to the test plan. Some validations depend on PR #34487 and are commented out. * Darwin: Avoid linker issues with pigweed clang * Prefix network-manager binary name with matter- * Run THNETDIR tests against network-manager app in CI * Add test script for WIFINM cluster and include in CI * Add network-manager app to darwin-tests.yaml * Update WIFINM cluster definition and test to match latest spec Based on CHIP-Specifications/connectedhomeip-spec#10025 * zap_regen_all * Disable tests for NEEDS_TIMED_INTERACTION for now These currently fail when run with darwin-framework-tool because Matter.framework automatically defaults to using a timed interaction when the cluster command requires it, defeating the test. * Fix network-manager-app zap/matter files * Add apiMaturity attributes * Add missing attribute read step and improve step names
1 parent ea94b7d commit e8fb908

File tree

48 files changed

+886
-56
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+886
-56
lines changed

.github/workflows/darwin-tests.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ jobs:
9595
--target darwin-x64-lit-icd-${BUILD_VARIANT} \
9696
--target darwin-x64-microwave-oven-${BUILD_VARIANT} \
9797
--target darwin-x64-rvc-${BUILD_VARIANT} \
98+
--target darwin-x64-network-manager-${BUILD_VARIANT} \
9899
build \
99100
--copy-artifacts-to objdir-clone \
100101
"
@@ -116,6 +117,7 @@ jobs:
116117
--bridge-app ./out/darwin-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \
117118
--microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \
118119
--rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \
120+
--network-manager-app ./out/darwin-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \
119121
"
120122
- name: Run OTA Test
121123
run: |

.github/workflows/tests.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ jobs:
186186
src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml \
187187
src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml \
188188
src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml \
189+
src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml \
189190
src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml \
190191
src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml \
191192
src/app/zap-templates/zcl/data-model/chip/timer-cluster.xml \
@@ -223,6 +224,7 @@ jobs:
223224
--target linux-x64-lit-icd-${BUILD_VARIANT} \
224225
--target linux-x64-microwave-oven-${BUILD_VARIANT} \
225226
--target linux-x64-rvc-${BUILD_VARIANT} \
227+
--target linux-x64-network-manager-${BUILD_VARIANT} \
226228
build \
227229
--copy-artifacts-to objdir-clone \
228230
"
@@ -245,6 +247,7 @@ jobs:
245247
--lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \
246248
--microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \
247249
--rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \
250+
--network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \
248251
"
249252
250253
- name: Run purposeful failure tests using the python parser sending commands to chip-tool
@@ -286,6 +289,7 @@ jobs:
286289
--lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \
287290
--microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \
288291
--rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \
292+
--network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \
289293
"
290294
- name: Run Tests using chip-repl (including slow)
291295
if: github.event_name == 'push'
@@ -305,6 +309,7 @@ jobs:
305309
--lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \
306310
--microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \
307311
--rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \
312+
--network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \
308313
"
309314
- name: Uploading core files
310315
uses: actions/upload-artifact@v4
@@ -373,6 +378,7 @@ jobs:
373378
--target darwin-x64-lit-icd-${BUILD_VARIANT} \
374379
--target darwin-x64-microwave-oven-${BUILD_VARIANT} \
375380
--target darwin-x64-rvc-${BUILD_VARIANT} \
381+
--target darwin-x64-network-manager-${BUILD_VARIANT} \
376382
build \
377383
--copy-artifacts-to objdir-clone \
378384
"
@@ -396,6 +402,7 @@ jobs:
396402
--lit-icd-app ./out/darwin-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \
397403
--microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \
398404
--rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \
405+
--network-manager-app ./out/darwin-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \
399406
"
400407
401408
- name: Run purposeful failure tests using the python parser sending commands to chip-tool

build/config/compiler/BUILD.gn

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import("//build_overrides/build.gni")
1616
import("//build_overrides/pigweed.gni")
17+
import("//build_overrides/pigweed_environment.gni")
1718
import("${build_root}/chip/java/config.gni")
1819
import("${build_root}/config/compiler/compiler.gni")
1920
import("${build_root}/config/sysroot.gni")
@@ -348,7 +349,14 @@ config("cosmetic_default") {
348349
}
349350

350351
config("runtime_default") {
351-
if (is_clang) { # Using Pigweed clang instead of Darwin host clang
352+
if (is_clang &&
353+
current_os == "mac") { # Using Pigweed clang instead of Darwin host clang
354+
# Without pw_env_setup_CIPD_PIGWEED defined the hostclang:no_system_libcpp
355+
# config silently uses the system libc++, usually resulting in linker errors.
356+
assert(
357+
defined(pw_env_setup_CIPD_PIGWEED),
358+
"//build_overrides/pigweed_environment.gni must define pw_env_setup_CIPD_PIGWEED when using pigweed clang")
359+
352360
configs = [
353361
"$dir_pw_toolchain/host_clang:no_system_libcpp",
354362
"$dir_pw_toolchain/host_clang:xcode_sysroot",

examples/network-manager-app/linux/BUILD.gn

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import("//build_overrides/build.gni")
1616
import("//build_overrides/chip.gni")
1717

18-
executable("network-manager-app") {
18+
executable("matter-network-manager-app") {
1919
sources = [
2020
"include/CHIPProjectAppConfig.h",
2121
"main.cpp",
@@ -32,7 +32,7 @@ executable("network-manager-app") {
3232
}
3333

3434
group("linux") {
35-
deps = [ ":network-manager-app" ]
35+
deps = [ ":matter-network-manager-app" ]
3636
}
3737

3838
group("default") {

examples/network-manager-app/network-manager-common/network-manager-app.matter

+7-5
Original file line numberDiff line numberDiff line change
@@ -1193,10 +1193,11 @@ cluster GroupKeyManagement = 63 {
11931193
}
11941194

11951195
/** Functionality to retrieve operational information about a managed Wi-Fi network. */
1196-
cluster WiFiNetworkManagement = 1105 {
1196+
provisional cluster WiFiNetworkManagement = 1105 {
11971197
revision 1;
11981198

1199-
readonly attribute nullable octet_string<32> ssid = 1;
1199+
readonly attribute nullable octet_string<32> ssid = 0;
1200+
readonly attribute access(read: manage) nullable int64u passphraseSurrogate = 1;
12001201
readonly attribute command_id generatedCommandList[] = 65528;
12011202
readonly attribute command_id acceptedCommandList[] = 65529;
12021203
readonly attribute event_id eventList[] = 65530;
@@ -1209,11 +1210,11 @@ cluster WiFiNetworkManagement = 1105 {
12091210
}
12101211

12111212
/** Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. */
1212-
command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0;
1213+
command access(invoke: manage) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0;
12131214
}
12141215

12151216
/** Manages the names and credentials of Thread networks visible to the user. */
1216-
cluster ThreadNetworkDirectory = 1107 {
1217+
provisional cluster ThreadNetworkDirectory = 1107 {
12171218
revision 1;
12181219

12191220
struct ThreadNetworkStruct {
@@ -1254,7 +1255,7 @@ cluster ThreadNetworkDirectory = 1107 {
12541255
/** Removes an entry from the ThreadNetworks list. */
12551256
timed command access(invoke: manage) RemoveNetwork(RemoveNetworkRequest): DefaultSuccess = 1;
12561257
/** Retrieves a Thread Operational Dataset from the ThreadNetworks list. */
1257-
timed command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2;
1258+
command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2;
12581259
}
12591260

12601261
endpoint 0 {
@@ -1525,6 +1526,7 @@ endpoint 1 {
15251526

15261527
server cluster WiFiNetworkManagement {
15271528
callback attribute ssid;
1529+
callback attribute passphraseSurrogate;
15281530
callback attribute generatedCommandList;
15291531
callback attribute acceptedCommandList;
15301532
callback attribute eventList;

examples/network-manager-app/network-manager-common/network-manager-app.zap

+17-1
Original file line numberDiff line numberDiff line change
@@ -3238,7 +3238,7 @@
32383238
"attributes": [
32393239
{
32403240
"name": "SSID",
3241-
"code": 1,
3241+
"code": 0,
32423242
"mfgCode": null,
32433243
"side": "server",
32443244
"type": "octet_string",
@@ -3252,6 +3252,22 @@
32523252
"maxInterval": 65534,
32533253
"reportableChange": 0
32543254
},
3255+
{
3256+
"name": "PassphraseSurrogate",
3257+
"code": 1,
3258+
"mfgCode": null,
3259+
"side": "server",
3260+
"type": "int64u",
3261+
"included": 1,
3262+
"storageOption": "External",
3263+
"singleton": 0,
3264+
"bounded": 0,
3265+
"defaultValue": null,
3266+
"reportable": 1,
3267+
"minInterval": 1,
3268+
"maxInterval": 65534,
3269+
"reportableChange": 0
3270+
},
32553271
{
32563272
"name": "GeneratedCommandList",
32573273
"code": 65528,

scripts/build/builders/host.py

+3
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ def OutputNames(self):
256256
elif self == HostApp.LIT_ICD:
257257
yield 'lit-icd-app'
258258
yield 'lit-icd-app.map'
259+
elif self == HostApp.NETWORK_MANAGER:
260+
yield 'matter-network-manager-app'
261+
yield 'matter-network-manager-app.map'
259262
elif self == HostApp.ENERGY_MANAGEMENT:
260263
yield 'chip-energy-management-app'
261264
yield 'chip-energy-management-app.map'

scripts/tests/chiptest/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ def target_for_name(name: str):
286286
return TestTarget.MWO
287287
if name.startswith("Test_TC_RVCRUNM_") or name.startswith("Test_TC_RVCCLEANM_") or name.startswith("Test_TC_RVCOPSTATE_"):
288288
return TestTarget.RVC
289+
if name.startswith("Test_TC_THNETDIR_") or name.startswith("Test_TC_WIFINM_"):
290+
return TestTarget.NETWORK_MANAGER
289291
return TestTarget.ALL_CLUSTERS
290292

291293

scripts/tests/chiptest/linux.py

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ def PathsWithNetworkNamespaces(paths: ApplicationPaths) -> ApplicationPaths:
184184
lit_icd_app='ip netns exec app'.split() + paths.lit_icd_app,
185185
microwave_oven_app='ip netns exec app'.split() + paths.microwave_oven_app,
186186
rvc_app='ip netns exec app'.split() + paths.rvc_app,
187+
network_manager_app='ip netns exec app'.split() + paths.network_manager_app,
187188
bridge_app='ip netns exec app'.split() + paths.bridge_app,
188189
chip_repl_yaml_tester_cmd='ip netns exec tool'.split() + paths.chip_repl_yaml_tester_cmd,
189190
chip_tool_with_python_cmd='ip netns exec tool'.split() + paths.chip_tool_with_python_cmd,

scripts/tests/chiptest/test_definition.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ class TestTarget(Enum):
177177
LIT_ICD = auto()
178178
MWO = auto()
179179
RVC = auto()
180+
NETWORK_MANAGER = auto()
180181

181182

182183
@dataclass
@@ -193,10 +194,11 @@ class ApplicationPaths:
193194
chip_repl_yaml_tester_cmd: typing.List[str]
194195
chip_tool_with_python_cmd: typing.List[str]
195196
rvc_app: typing.List[str]
197+
network_manager_app: typing.List[str]
196198

197199
def items(self):
198200
return [self.chip_tool, self.all_clusters_app, self.lock_app, self.ota_provider_app, self.ota_requestor_app,
199-
self.tv_app, self.bridge_app, self.lit_icd_app, self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, self.chip_tool_with_python_cmd, self.rvc_app]
201+
self.tv_app, self.bridge_app, self.lit_icd_app, self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, self.chip_tool_with_python_cmd, self.rvc_app, self.network_manager_app]
200202

201203

202204
@dataclass
@@ -309,6 +311,8 @@ def Run(self, runner, apps_register, paths: ApplicationPaths, pics_file: str,
309311
target_app = paths.microwave_oven_app
310312
elif self.target == TestTarget.RVC:
311313
target_app = paths.rvc_app
314+
elif self.target == TestTarget.NETWORK_MANAGER:
315+
target_app = paths.network_manager_app
312316
else:
313317
raise Exception("Unknown test target - "
314318
"don't know which application to run")

scripts/tests/run_test_suite.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ def cmd_list(context):
260260
@click.option(
261261
'--rvc-app',
262262
help='what rvc app to use')
263+
@click.option(
264+
'--network-manager-app',
265+
help='what network-manager app to use')
263266
@click.option(
264267
'--chip-repl-yaml-tester',
265268
help='what python script to use for running yaml tests using chip-repl as controller')
@@ -291,7 +294,7 @@ def cmd_list(context):
291294
help='Number of tests that are expected to fail in each iteration. Overall test will pass if the number of failures matches this. Nonzero values require --keep-going')
292295
@click.pass_context
293296
def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, ota_requestor_app,
294-
tv_app, bridge_app, lit_icd_app, microwave_oven_app, rvc_app, chip_repl_yaml_tester, chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures):
297+
tv_app, bridge_app, lit_icd_app, microwave_oven_app, rvc_app, network_manager_app, chip_repl_yaml_tester, chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures):
295298
if expected_failures != 0 and not keep_going:
296299
logging.exception(f"'--expected-failures {expected_failures}' used without '--keep-going'")
297300
sys.exit(2)
@@ -327,6 +330,9 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o
327330
if rvc_app is None:
328331
rvc_app = paths_finder.get('chip-rvc-app')
329332

333+
if network_manager_app is None:
334+
network_manager_app = paths_finder.get('matter-network-manager-app')
335+
330336
if chip_repl_yaml_tester is None:
331337
chip_repl_yaml_tester = paths_finder.get('yamltest_with_chip_repl_tester.py')
332338

@@ -348,6 +354,7 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o
348354
lit_icd_app=[lit_icd_app],
349355
microwave_oven_app=[microwave_oven_app],
350356
rvc_app=[rvc_app],
357+
network_manager_app=[network_manager_app],
351358
chip_repl_yaml_tester_cmd=['python3'] + [chip_repl_yaml_tester],
352359
chip_tool_with_python_cmd=['python3'] + [chip_tool_with_python],
353360
)

src/app/clusters/thread-network-directory-server/thread-network-directory-server.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,10 @@ void ThreadNetworkDirectoryServer::HandleOperationalDatasetRequest(
274274

275275
uint8_t datasetBuffer[kSizeOperationalDataset];
276276
MutableByteSpan datasetSpan(datasetBuffer);
277+
OperationalDatasetResponse::Type response;
277278
SuccessOrExit(err = mStorage.GetNetworkDataset(ExtendedPanId(req.extendedPanID), datasetSpan));
278-
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::Success);
279+
response.operationalDataset = datasetSpan;
280+
ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response);
279281
return;
280282
exit:
281283
ChipLogError(Zcl, "GetOperationalDataset: %" CHIP_ERROR_FORMAT, err.Format());

src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <app/InteractionModelEngine.h>
2323
#include <app/reporting/reporting.h>
2424
#include <lib/support/CodeUtils.h>
25+
#include <system/SystemClock.h>
2526

2627
#include <algorithm>
2728
#include <cctype>
@@ -99,11 +100,20 @@ CHIP_ERROR WiFiNetworkManagementServer::SetNetworkCredentials(ByteSpan ssid, Byt
99100
VerifyOrDie(mPassphrase.SetLength(passphrase.size()) == CHIP_NO_ERROR);
100101
memcpy(mPassphrase.Bytes(), passphrase.data(), passphrase.size());
101102

102-
// Note: The spec currently defines no way to signal a passphrase change
103103
if (ssidChanged)
104104
{
105105
MatterReportingAttributeChangeCallback(GetEndpointId(), WiFiNetworkManagement::Id, Ssid::Id);
106106
}
107+
if (passphraseChanged)
108+
{
109+
mPassphraseSurrogate++;
110+
System::Clock::Milliseconds64 realtime;
111+
if (System::SystemClock().GetClock_RealTimeMS(realtime) == CHIP_NO_ERROR)
112+
{
113+
mPassphraseSurrogate = std::max(mPassphraseSurrogate, realtime.count());
114+
}
115+
MatterReportingAttributeChangeCallback(GetEndpointId(), WiFiNetworkManagement::Id, PassphraseSurrogate::Id);
116+
}
107117
return CHIP_NO_ERROR;
108118
}
109119

@@ -113,6 +123,8 @@ CHIP_ERROR WiFiNetworkManagementServer::Read(const ConcreteReadAttributePath & a
113123
{
114124
case Ssid::Id:
115125
return HaveNetworkCredentials() ? aEncoder.Encode(SsidSpan()) : aEncoder.EncodeNull();
126+
case PassphraseSurrogate::Id:
127+
return HaveNetworkCredentials() ? aEncoder.Encode(mPassphraseSurrogate) : aEncoder.EncodeNull();
116128
}
117129
return CHIP_NO_ERROR;
118130
}

src/app/clusters/wifi-network-management-server/wifi-network-management-server.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class WiFiNetworkManagementServer : private AttributeAccessInterface, private Co
5757
static_assert(std::numeric_limits<decltype(mSsidLen)>::max() >= sizeof(mSsid));
5858
ByteSpan SsidSpan() const { return ByteSpan(mSsid, mSsidLen); }
5959

60+
uint64_t mPassphraseSurrogate = 0;
6061
Crypto::SensitiveDataBuffer<64> mPassphrase;
6162
ByteSpan PassphraseSpan() const { return mPassphrase.Span(); }
6263

src/app/tests/suites/certification/PICS.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -10199,3 +10199,19 @@ PICS:
1019910199

1020010200
- label: "Does the device implement the ActiveEndpoints attribute?"
1020110201
id: PWRTL.S.A0001
10202+
10203+
#
10204+
# Thread Network Directory Cluster
10205+
#
10206+
- label:
10207+
"Does the device implement the Thread Network Directory cluster as a
10208+
server"
10209+
id: THNETDIR.S
10210+
10211+
#
10212+
# Wi-Fi Network Management Cluster
10213+
#
10214+
- label:
10215+
"Does the device implement the Wi-Fi Network Management cluster as a
10216+
server"
10217+
id: WIFINM.S

0 commit comments

Comments
 (0)