Skip to content

Commit

Permalink
[net-comm] Check if failsafe is armed (#17103)
Browse files Browse the repository at this point in the history
* [net-comm] Check if failsafe is armed

Validate that commands that modify the network configuration
are called when the failsafe is armed.

Signed-off-by: Damian Krolik <[email protected]>

* Fix Cirque tests
  • Loading branch information
Damian-Nordic authored and pull[bot] committed Jan 25, 2024
1 parent 40b6fb4 commit 0d9c19e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/app/clusters/network-commissioning/network-commissioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,27 @@ void FillDebugTextAndNetworkIndex(Commands::NetworkConfigResponse::Type & respon
}
}

bool CheckFailSafeArmed(CommandHandlerInterface::HandlerContext & ctx)
{
DeviceLayer::FailSafeContext & failSafeContext = DeviceLayer::DeviceControlServer::DeviceControlSvr().GetFailSafeContext();

if (failSafeContext.IsFailSafeArmed(ctx.mCommandHandler.GetAccessingFabricIndex()))
{
return true;
}

ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::UnsupportedAccess);
return false;
}

} // namespace

void Instance::HandleAddOrUpdateWiFiNetwork(HandlerContext & ctx, const Commands::AddOrUpdateWiFiNetwork::DecodableType & req)
{
MATTER_TRACE_EVENT_SCOPE("HandleAddOrUpdateWiFiNetwork", "NetworkCommissioning");

VerifyOrReturn(CheckFailSafeArmed(ctx));

Commands::NetworkConfigResponse::Type response;
MutableCharSpan debugText;
#if CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE
Expand All @@ -354,6 +370,9 @@ void Instance::HandleAddOrUpdateWiFiNetwork(HandlerContext & ctx, const Commands
void Instance::HandleAddOrUpdateThreadNetwork(HandlerContext & ctx, const Commands::AddOrUpdateThreadNetwork::DecodableType & req)
{
MATTER_TRACE_EVENT_SCOPE("HandleAddOrUpdateThreadNetwork", "NetworkCommissioning");

VerifyOrReturn(CheckFailSafeArmed(ctx));

Commands::NetworkConfigResponse::Type response;
MutableCharSpan debugText;
#if CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE
Expand All @@ -370,6 +389,9 @@ void Instance::HandleAddOrUpdateThreadNetwork(HandlerContext & ctx, const Comman
void Instance::HandleRemoveNetwork(HandlerContext & ctx, const Commands::RemoveNetwork::DecodableType & req)
{
MATTER_TRACE_EVENT_SCOPE("HandleRemoveNetwork", "NetworkCommissioning");

VerifyOrReturn(CheckFailSafeArmed(ctx));

Commands::NetworkConfigResponse::Type response;
MutableCharSpan debugText;
#if CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE
Expand All @@ -391,6 +413,8 @@ void Instance::HandleConnectNetwork(HandlerContext & ctx, const Commands::Connec
return;
}

VerifyOrReturn(CheckFailSafeArmed(ctx));

mConnectingNetworkIDLen = static_cast<uint8_t>(req.networkID.size());
memcpy(mConnectingNetworkID, req.networkID.data(), mConnectingNetworkIDLen);

Expand Down
24 changes: 24 additions & 0 deletions src/controller/python/test/test_scripts/network_commissioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ async def test_wifi(self, endpointId):
if res.networkingStatus != Clusters.NetworkCommissioning.Enums.NetworkCommissioningStatus.kSuccess:
raise AssertionError(f"Unexpected result: {res.networkingStatus}")

# Arm the failsafe before making network config changes
logger.info(f"Arming the failsafe")
req = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900)
res = await self._devCtrl.SendCommand(nodeid=self._nodeid, endpoint=endpointId, payload=req)
logger.info(f"Received response: {res}")

# Remove existing network
logger.info(f"Check network list")
res = await self._devCtrl.ReadAttribute(nodeid=self._nodeid, attributes=[(endpointId, Clusters.NetworkCommissioning.Attributes.Networks)], returnClusterObject=True)
Expand Down Expand Up @@ -166,6 +172,12 @@ async def test_wifi(self, endpointId):
raise AssertionError(f"Unexpected result: {res.networkingStatus}")
logger.info(f"Device connected to a network.")

# Disarm the failsafe
logger.info(f"Disarming the failsafe")
req = Clusters.GeneralCommissioning.Commands.CommissioningComplete()
res = await self._devCtrl.SendCommand(nodeid=self._nodeid, endpoint=endpointId, payload=req)
logger.info(f"Received response: {res}")

# Note: On Linux, when connecting to a connected network, it will return immediately, however, it will try a reconnect. This will make the below attribute read return false negative values.
await asyncio.sleep(5)

Expand Down Expand Up @@ -220,6 +232,12 @@ async def test_thread(self, endpointId):
if res.networkingStatus != Clusters.NetworkCommissioning.Enums.NetworkCommissioningStatus.kSuccess:
raise AssertionError(f"Unexpected result: {res.networkingStatus}")

# Arm the failsafe before making network config changes
logger.info(f"Arming the failsafe")
req = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900)
res = await self._devCtrl.SendCommand(nodeid=self._nodeid, endpoint=endpointId, payload=req)
logger.info(f"Received response: {res}")

# Remove existing network
logger.info(f"Check network list")
res = await self._devCtrl.ReadAttribute(nodeid=self._nodeid, attributes=[(endpointId, Clusters.NetworkCommissioning.Attributes.Networks)], returnClusterObject=True)
Expand Down Expand Up @@ -267,6 +285,12 @@ async def test_thread(self, endpointId):
raise AssertionError(f"Unexpected result: {res.networkingStatus}")
logger.info(f"Device connected to a network.")

# Disarm the failsafe
logger.info(f"Disarming the failsafe")
req = Clusters.GeneralCommissioning.Commands.CommissioningComplete()
res = await self._devCtrl.SendCommand(nodeid=self._nodeid, endpoint=endpointId, payload=req)
logger.info(f"Received response: {res}")

# Verify Last* attributes
logger.info(f"Read Last* attributes")
res = await self.readLastNetworkingStateAttributes(endpointId=endpointId)
Expand Down

0 comments on commit 0d9c19e

Please sign in to comment.