Skip to content

Commit

Permalink
THNETDIR and WIFINM: Align with latest spec and other small fixes (pr…
Browse files Browse the repository at this point in the history
…oject-chip#35191)

* YAML runner: Add support for EstablishPASESession command

* Enable python constraints in TC_THNETDIR_*

* THNETDIR: Align with latest spec

- Implement ActiveTimestamp check for updates
- Implement CASE session requirement for GetOperationalDataset
- Update / add certification YAML tests accordingly

* WIFINM: Implement CASE session requirement for NetworkPassphraseRequest

- Implement CASE session requirement for NetworkPassphraseRequest
- Add a corresponding YAML test

* Apply test script suggestions from code review

Co-authored-by: marchemi <[email protected]>

* Enable negative timed-invoke tests in TC_THNETDIR_2_2

Instead, disable the test in CI for darwin-framework-tool.

Fixes matter-test-scripts#359

---------

Co-authored-by: marchemi <[email protected]>
  • Loading branch information
ksperling-apple and marchemi authored Aug 28, 2024
1 parent c3a4675 commit 1d1319b
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@
'has_destination': False,
'has_endpoint': False,
},
'EstablishPASESession': {
'alias': 'code-paseonly',
'arguments': {
'nodeId': 'node-id'
},
'has_destination': False,
'has_endpoint': False,
},
'GetCommissionerNodeId': {
'has_destination': False,
'has_endpoint': False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
<arg name="IPK" type="octet_string"/>
</command>
<command source="client" code="5" name="EstablishPASESession">
<arg name="nodeId" type="node_id"/>
<arg name="payload" type="char_string"/>
</command>
</cluster>
</configurator>
'''
Expand Down
1 change: 1 addition & 0 deletions scripts/tests/chiptest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ def _GetDarwinFrameworkToolUnsupportedTests() -> Set[str]:
"Test_TC_SC_4_1", # darwin-framework-tool does not support dns-sd commands.
"Test_TC_SC_5_2", # darwin-framework-tool does not support group commands.
"Test_TC_S_2_3", # darwin-framework-tool does not support group commands.
"Test_TC_THNETDIR_2_2", # darwin-framework-tool does not support negative timed-invoke tests
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ void ThreadNetworkDirectoryServer::HandleAddNetworkRequest(HandlerContext & ctx,
{
OperationalDataset dataset;
ByteSpan extendedPanIdSpan;
uint64_t activeTimestamp;
union
{
uint64_t activeTimestamp;
uint16_t channel;
uint8_t masterKey[kSizeMasterKey];
uint8_t meshLocalPrefix[kSizeMeshLocalPrefix];
Expand All @@ -203,7 +203,7 @@ void ThreadNetworkDirectoryServer::HandleAddNetworkRequest(HandlerContext & ctx,
// TODO: An immutable OperationalDatasetView on top of a ByteSpan (without copying) would be useful here.
SuccessOrExitAction(err = dataset.Init(req.operationalDataset), context = "OperationalDataset");
SuccessOrExitAction(err = dataset.GetExtendedPanIdAsByteSpan(extendedPanIdSpan), context = "ExtendedPanID");
SuccessOrExitAction(err = dataset.GetActiveTimestamp(unused.activeTimestamp), context = "ActiveTimestamp");
SuccessOrExitAction(err = dataset.GetActiveTimestamp(activeTimestamp), context = "ActiveTimestamp");
SuccessOrExitAction(err = dataset.GetChannel(unused.channel), context = "Channel");
SuccessOrExitAction(err = dataset.GetChannelMask(unusedSpan), context = "ChannelMask");
SuccessOrExitAction(err = dataset.GetMasterKey(unused.masterKey), context = "NetworkKey");
Expand All @@ -214,6 +214,27 @@ void ThreadNetworkDirectoryServer::HandleAddNetworkRequest(HandlerContext & ctx,
SuccessOrExitAction(err = dataset.GetSecurityPolicy(unused.securityPolicy), context = "SecurityContext");

status = IMStatus::Failure;

// "If the received dataset has an Active Timestamp that is less than or equal to that of the existing entry,
// then the update SHALL be rejected with a status of INVALID_IN_STATE."
{
uint8_t datasetBuffer[kSizeOperationalDataset];
MutableByteSpan datasetSpan(datasetBuffer);
err = mStorage.GetNetworkDataset(ExtendedPanId(extendedPanIdSpan), datasetSpan);
if (err != CHIP_ERROR_NOT_FOUND)
{
SuccessOrExit(err);
SuccessOrExit(err = dataset.Init(datasetSpan));
uint64_t existingActiveTimestamp;
SuccessOrExit(err = dataset.GetActiveTimestamp(existingActiveTimestamp));
if (activeTimestamp <= existingActiveTimestamp)
{
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::InvalidInState, "ActiveTimestamp");
return;
}
}
}

SuccessOrExit(err = mStorage.AddOrUpdateNetwork(ExtendedPanId(extendedPanIdSpan), req.operationalDataset));

ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::Success);
Expand Down Expand Up @@ -266,6 +287,12 @@ void ThreadNetworkDirectoryServer::HandleOperationalDatasetRequest(
{
CHIP_ERROR err;

if (ctx.mCommandHandler.GetSubjectDescriptor().authMode != Access::AuthMode::kCase)
{
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::UnsupportedAccess);
return;
}

if (req.extendedPanID.size() != ExtendedPanId::size())
{
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::ConstraintError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::WiFiNetworkManagement::Attributes;
using namespace chip::app::Clusters::WiFiNetworkManagement::Commands;
using namespace std::placeholders;
using IMStatus = chip::Protocols::InteractionModel::Status;

namespace chip {
namespace app {
Expand Down Expand Up @@ -143,6 +143,12 @@ void WiFiNetworkManagementServer::InvokeCommand(HandlerContext & ctx)
void WiFiNetworkManagementServer::HandleNetworkPassphraseRequest(HandlerContext & ctx,
const NetworkPassphraseRequest::DecodableType & req)
{
if (ctx.mCommandHandler.GetSubjectDescriptor().authMode != Access::AuthMode::kCase)
{
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::UnsupportedAccess);
return;
}

if (HaveNetworkCredentials())
{
NetworkPassphraseResponse::Type response;
Expand All @@ -151,8 +157,7 @@ void WiFiNetworkManagementServer::HandleNetworkPassphraseRequest(HandlerContext
}
else
{
// TODO: Status code TBC: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/9234
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::InvalidInState);
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::InvalidInState);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/app/tests/suites/certification/Test_TC_THNETDIR_2_1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,4 @@ tests:
response:
constraints:
type: int8u
minValue: 10 # assume 5 supported fabrics
# python: value >= 2 * supportedFabrics
python: value >= 2 * supportedFabrics
147 changes: 111 additions & 36 deletions src/app/tests/suites/certification/Test_TC_THNETDIR_2_2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ config:
# Note: TestNetwork* values need to match what's encoded in TestNetworkDataset
TestNetworkDataset:
type: octet_string
defaultValue: "hex:0e080000000000000001000300000f350407fff800020839758ec8144b07fb0708fdf1f1add0797dc00510f366cec7a446bab978d90d27abe38f23030f4f70656e5468726561642d353933380102593804103ca67c969efb0d0c74a4d8ee923b576c0c0402a0f7f8"
defaultValue: "hex:0e0800000000000c0001000300000f350407fff800020839758ec8144b07fb0708fdf1f1add0797dc00510f366cec7a446bab978d90d27abe38f23030f4f70656e5468726561642d353933380102593804103ca67c969efb0d0c74a4d8ee923b576c0c0402a0f7f8"
TestNetworkExtendedPanId:
type: octet_string
defaultValue: "hex:39758ec8144b07fb"
TestNetworkName: "OpenThread-5938"
TestNetworkChannel: 15
TestNetworkActiveTimestamp: 1
TestNetworkActiveTimestamp: 0xc0001
TestNetworkUpdatedDataset:
type: octet_string
defaultValue: "hex:0e0800000000000d0001000300000f350407fff800020839758ec8144b07fb0708fdf1f1add0797dc00510f366cec7a446bab978d90d27abe38f23030f4f70656e5468726561642d353933380102593804103ca67c969efb0d0c74a4d8ee923b576c0c0402a0f7f8"

tests:
- label: "Wait for the commissioned device to be retrieved"
Expand Down Expand Up @@ -90,15 +93,15 @@ tests:
response:
error: NOT_FOUND

# TODO: Currently fails with darwin-framework-tool because it automatically performs a timed invoke
# - label: "TH sends AddNetwork command to DUT without a timed interaction"
# command: AddNetwork
# arguments:
# values:
# - name: OperationalDataset
# value: TestNetworkDataset
# response:
# error: NEEDS_TIMED_INTERACTION
# Note: Unsupported with darwin-framework-tool because it automatically performs a timed invoke
- label: "TH sends AddNetwork command to DUT without a timed interaction"
command: AddNetwork
arguments:
values:
- name: OperationalDataset
value: TestNetworkDataset
response:
error: NEEDS_TIMED_INTERACTION

- label: "TH sends AddNetwork command to DUT with TestNetwork dataset"
command: AddNetwork
Expand All @@ -116,18 +119,43 @@ tests:
response:
constraints:
type: list
# python: |
# # Split the list into test (our TestNetwork) and rest (everything else)
# test = next((n for n in value if n['ExtendedPanID'] == TestNetworkExtendedPanId), None)
# rest = [n for n in value if n != test]
# # Check test has the expected values and rest == initialNetworks (ignoring order)
# return (test is not None and
# test['NetworkName'] == TestNetworkName and
# test['Channel'] == TestNetworkChannel and
# test['ActiveTimestamp'] == TestNetworkActiveTimestamp and
# len(value) == len(initialNetworks) + 1 and
# len(rest) == len(initialNetworks) and
# all(n in initialNetworks for n in rest))
python: |
# Split the list into test (our TestNetwork) and rest (everything else)
test = next((n for n in value if n['ExtendedPanID'] == TestNetworkExtendedPanId), None)
rest = [n for n in value if n != test]
# Check test has the expected values and rest == initialNetworks (ignoring order)
return (test is not None and
test['NetworkName'] == TestNetworkName and
test['Channel'] == TestNetworkChannel and
test['ActiveTimestamp'] == TestNetworkActiveTimestamp and
len(value) == len(initialNetworks) + 1 and
len(rest) == len(initialNetworks) and
all(n in initialNetworks for n in rest))
- label:
"TH sends GetOperationalDataset command to DUT with ExtendedPanID from
TestNetwork"
command: GetOperationalDataset
arguments:
values:
- name: ExtendedPanID
value: TestNetworkExtendedPanId
response:
values:
- name: OperationalDataset
value: TestNetworkDataset

- label:
"TH sends AddNetwork command to DUT with TestNetwork dataset matching
existing Active Timestamp"
command: AddNetwork
timedInteractionTimeoutMs: 2000
arguments:
values:
- name: OperationalDataset
value: TestNetworkDataset
response:
error: INVALID_IN_STATE

- label:
"TH sends GetOperationalDataset command to DUT with ExtendedPanID from
Expand All @@ -142,6 +170,53 @@ tests:
- name: OperationalDataset
value: TestNetworkDataset

- label:
"TH sends AddNetwork command to DUT with updated TestNetwork dataset
with larger Active Timestamp"
command: AddNetwork
timedInteractionTimeoutMs: 2000
arguments:
values:
- name: OperationalDataset
value: TestNetworkUpdatedDataset

- label:
"TH sends GetOperationalDataset command to DUT with ExtendedPanID from
TestNetwork"
command: GetOperationalDataset
arguments:
values:
- name: ExtendedPanID
value: TestNetworkExtendedPanId
response:
values:
- name: OperationalDataset
value: TestNetworkUpdatedDataset

- label:
"TH sends AddNetwork command to DUT with original TestNetwork dataset"
command: AddNetwork
timedInteractionTimeoutMs: 2000
arguments:
values:
- name: OperationalDataset
value: TestNetworkDataset
response:
error: INVALID_IN_STATE

- label:
"TH sends GetOperationalDataset command to DUT with ExtendedPanID from
TestNetwork"
command: GetOperationalDataset
arguments:
values:
- name: ExtendedPanID
value: TestNetworkExtendedPanId
response:
values:
- name: OperationalDataset
value: TestNetworkUpdatedDataset

- label:
"TH writes ExtendedPanID from TestNetwork to PreferredExtendedPanID on
DUT"
Expand All @@ -158,15 +233,15 @@ tests:
response:
value: TestNetworkExtendedPanId

# TODO: Currently fails with darwin-framework-tool because it automatically performs a timed invoke
# - label: "TH sends RemoveNetwork command to DUT without a timed interaction"
# command: RemoveNetwork
# arguments:
# values:
# - name: ExtendedPanID
# value: TestNetworkExtendedPanId
# response:
# error: NEEDS_TIMED_INTERACTION
# Note: Unsupported with darwin-framework-tool because it automatically performs a timed invoke
- label: "TH sends RemoveNetwork command to DUT without a timed interaction"
command: RemoveNetwork
arguments:
values:
- name: ExtendedPanID
value: TestNetworkExtendedPanId
response:
error: NEEDS_TIMED_INTERACTION

- label:
"TH sends RemoveNetwork command to DUT with ExtendedPanID of
Expand Down Expand Up @@ -212,10 +287,10 @@ tests:
response:
constraints:
type: list
# python: |
# # value == initialNetworks (ignoring order)
# return (len(value) == len(initialNetworks) and
# all(n in initialNetworks for n in value))
python: |
# value == initialNetworks (ignoring order)
return (len(value) == len(initialNetworks) and
all(n in initialNetworks for n in value))
- label:
"TH writes PreferredExtendedPanID to DUT, restoring the initial value"
Expand Down
Loading

0 comments on commit 1d1319b

Please sign in to comment.