Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Non concurrent mode #30201

Merged
merged 41 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e789b29
Add non-concurrent SupportsConcurrentConnection
simonhmorris1 Oct 18, 2023
64a945f
Address CI build issues (#29865)
simonhmorris1 Oct 19, 2023
a963753
Fix style issue (#29865)
simonhmorris1 Oct 23, 2023
cb88ea3
Fix read of SupportsConcurrentConnection (#29865)
simonhmorris1 Oct 24, 2023
ae8682d
Correct intermittent missing SSID(#29865)
simonhmorris1 Oct 27, 2023
3a188d3
ConnectNetworkResponse Supression (#29865)
simonhmorris1 Oct 30, 2023
4df8d64
Add non-concurrent SupportsConcurrentConnection
simonhmorris1 Oct 18, 2023
a0ef929
Address CI build issues (#29865)
simonhmorris1 Oct 19, 2023
3c6db92
Fix style issue (#29865)
simonhmorris1 Oct 23, 2023
619d5ae
Fix read of SupportsConcurrentConnection (#29865)
simonhmorris1 Oct 24, 2023
21b583d
Merged head to Non-Concurrent branch(#29865)
simonhmorris1 Oct 31, 2023
f8af80c
Fix merge issue with ICD attributes(#29865)
simonhmorris1 Nov 1, 2023
7f819f6
Fix darwin-tests workflow file syntax. (#30162)
bzbarsky-apple Nov 2, 2023
f62501a
Add non-concurrent SupportsConcurrentConnection
simonhmorris1 Oct 18, 2023
a8bf10b
Address CI build issues (#29865)
simonhmorris1 Oct 19, 2023
1d7432f
Fix style issue (#29865)
simonhmorris1 Oct 23, 2023
c10f547
Fix read of SupportsConcurrentConnection (#29865)
simonhmorris1 Oct 24, 2023
5c8659b
Fix merge issue with ICD attributes(#29865)
simonhmorris1 Nov 1, 2023
fd20dd7
Only start WiFi on BLE Commissioning pass(#29865)
simonhmorris1 Nov 2, 2023
68ca86d
Address merge conflcits (#29865)
simonhmorris1 Nov 2, 2023
3f0226b
Remove use of Breadcrumb::Get from BLE (#29865)
simonhmorris1 Nov 2, 2023
b86ebea
Add non-concurrent SupportsConcurrentConnection
simonhmorris1 Oct 18, 2023
c041f4f
Address CI build issues (#29865)
simonhmorris1 Oct 19, 2023
1609850
Fix style issue (#29865)
simonhmorris1 Oct 23, 2023
226ada6
Fix read of SupportsConcurrentConnection (#29865)
simonhmorris1 Oct 24, 2023
38afa81
Fix merge issue with ICD attributes(#29865)
simonhmorris1 Nov 1, 2023
d4bb7bb
Only start WiFi on BLE Commissioning pass(#29865)
simonhmorris1 Nov 2, 2023
1813b94
Remove use of Breadcrumb::Get from BLE (#29865)
simonhmorris1 Nov 2, 2023
e2759e9
Merge head (#29865)
simonhmorris1 Nov 3, 2023
cc6f964
Tidy comments (#29865)
simonhmorris1 Nov 3, 2023
c76a116
Default on error, check timeout, tidy up (#29865)
simonhmorris1 Nov 6, 2023
2ebc2e3
Make log messages user friendly (#29865)
simonhmorris1 Nov 6, 2023
ff8fa6e
Change to compile time non-concurrent mode(#29865)
simonhmorris1 Nov 7, 2023
60a0f66
Merge branch 'master' into non-concurrent-mode
simonhmorris1 Nov 7, 2023
94a1006
Restyled by whitespace
restyled-commits Nov 7, 2023
a8ce91b
Restyled by clang-format
restyled-commits Nov 7, 2023
ba5ede5
Improve code style (#29865)
simonhmorris1 Nov 17, 2023
58986eb
Restyled by clang-format
restyled-commits Nov 17, 2023
ac54512
Merge head (#29865)
simonhmorris1 Nov 21, 2023
f285b38
Add CommandHandler issue reference 30576 (#29865)
simonhmorris1 Nov 21, 2023
050d0b3
Merge branch 'master' into non-concurrent-mode
simonhmorris1 Nov 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <platform/PlatformManager.h>

#include "app/clusters/network-commissioning/network-commissioning.h"
#include <app/server/Dnssd.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <app/util/endpoint-config-api.h>
Expand Down Expand Up @@ -238,15 +239,15 @@ void InitNetworkCommissioning()
using chip::Shell::Engine;
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#if CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
/*
* The device shall check every kWiFiStartCheckTimeUsec whether Wi-Fi management
* has been fully initialized. If after kWiFiStartCheckAttempts Wi-Fi management
* still hasn't been initialized, the device configuration is reset, and device
* needs to be paired again.
*/
static constexpr useconds_t kWiFiStartCheckTimeUsec = 100 * 1000; // 100 ms
static constexpr uint8_t kWiFiStartCheckAttempts = 5;
static constexpr useconds_t kWiFiStartCheckTimeUsec = WIFI_START_CHECK_TIME_USEC;
static constexpr uint8_t kWiFiStartCheckAttempts = WIFI_START_CHECK_ATTEMPTS;
#endif

namespace {
Expand All @@ -264,6 +265,11 @@ void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished");
}
else if ((event->Type == chip::DeviceLayer::DeviceEventType::kInternetConnectivityChange))
{
// Restart the server on connectivity change
app::DnssdServer::Instance().StartServer();
}
}

void Cleanup()
Expand Down Expand Up @@ -298,7 +304,7 @@ void StopSignalHandler(int signal)

} // namespace

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#if CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
static bool EnsureWiFiIsStarted()
{
for (int cnt = 0; cnt < kWiFiStartCheckAttempts; cnt++)
Expand Down Expand Up @@ -462,9 +468,10 @@ int ChipLinuxAppInit(int argc, char * const argv[], OptionSet * customOptions,
DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true);
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
#if CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
if (LinuxDeviceOptions::GetInstance().mWiFi)
{
// Start WiFi management in Concurrent mode
DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement();
if (!EnsureWiFiIsStarted())
{
Expand Down
32 changes: 31 additions & 1 deletion src/app/clusters/network-commissioning/network-commissioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,18 @@ void Instance::InvokeCommand(HandlerContext & ctxt)
ctxt, [this](HandlerContext & ctx, const auto & req) { HandleRemoveNetwork(ctx, req); });
return;

case Commands::ConnectNetwork::Id:
case Commands::ConnectNetwork::Id: {
VerifyOrReturn(mFeatureFlags.Has(Feature::kWiFiNetworkInterface) || mFeatureFlags.Has(Feature::kThreadNetworkInterface));
#if CONFIG_NETWORK_LAYER_BLE && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
// If commissionee does not support Concurrent Connections, request the BLE to be stopped.
// Start the ConnectNetwork, but this will not complete until the BLE is off.
ChipLogProgress(NetworkProvisioning, "Closing BLE connections due to non-concurrent mode");
DeviceLayer::DeviceControlServer::DeviceControlSvr().PostCloseAllBLEConnectionsToOperationalNetworkEvent();
#endif
HandleCommand<Commands::ConnectNetwork::DecodableType>(
ctxt, [this](HandlerContext & ctx, const auto & req) { HandleConnectNetwork(ctx, req); });
return;
}

case Commands::ReorderNetwork::Id:
VerifyOrReturn(mFeatureFlags.Has(Feature::kWiFiNetworkInterface) || mFeatureFlags.Has(Feature::kThreadNetworkInterface));
Expand Down Expand Up @@ -623,7 +630,20 @@ void Instance::HandleConnectNetwork(HandlerContext & ctx, const Commands::Connec
memcpy(mConnectingNetworkID, req.networkID.data(), mConnectingNetworkIDLen);
mAsyncCommandHandle = CommandHandler::Handle(&ctx.mCommandHandler);
mCurrentOperationBreadcrumb = req.breadcrumb;

// In Non-concurrent mode postpone the final execution of ConnectNetwork until the operational
// network has been fully brought up and kWiFiDeviceAvailable is delivered.
// mConnectingNetworkIDLen and mConnectingNetworkID contains the received SSID
#if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
mpWirelessDriver->ConnectNetwork(req.networkID, this);
#endif
}

void Instance::HandleNonConcurrentConnectNetwork()
{
ByteSpan nonConcurrentNetworkID = ByteSpan(mConnectingNetworkID, mConnectingNetworkIDLen);
ChipLogProgress(NetworkProvisioning, "HandleNonConcurrentConnectNetwork() SSID=%s", mConnectingNetworkID);
mpWirelessDriver->ConnectNetwork(nonConcurrentNetworkID, this);
}

void Instance::HandleReorderNetwork(HandlerContext & ctx, const Commands::ReorderNetwork::DecodableType & req)
Expand Down Expand Up @@ -759,7 +779,13 @@ void Instance::OnResult(Status commissioningError, CharSpan debugText, int32_t i
memcpy(mLastNetworkID, mConnectingNetworkID, mLastNetworkIDLen);
mLastNetworkingStatusValue.SetNonNull(commissioningError);

#if CONFIG_NETWORK_LAYER_BLE && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, ConnectNetworkResponse will NOT be sent");
// Do not send the ConnectNetworkResponse if in non-concurrent mode
// Issue #30576 raised to modify CommandHandler to notify it if no response required
#else
commandHandle->AddResponse(mPath, response);
#endif
if (commissioningError == Status::kSuccess)
{
CommitSavedBreadcrumb();
Expand Down Expand Up @@ -956,6 +982,10 @@ void Instance::OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event
{
this_->OnFailSafeTimerExpired();
}
else if (event->Type == DeviceLayer::DeviceEventType::kWiFiDeviceAvailable)
{
this_->HandleNonConcurrentConnectNetwork();
}
}

void Instance::OnCommissioningComplete()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class Instance : public CommandHandlerInterface,
void HandleRemoveNetwork(HandlerContext & ctx, const Commands::RemoveNetwork::DecodableType & req);
void HandleConnectNetwork(HandlerContext & ctx, const Commands::ConnectNetwork::DecodableType & req);
void HandleReorderNetwork(HandlerContext & ctx, const Commands::ReorderNetwork::DecodableType & req);
void HandleNonConcurrentConnectNetwork(void);
void HandleQueryIdentity(HandlerContext & ctx, const Commands::QueryIdentity::DecodableType & req);

public:
Expand Down
10 changes: 9 additions & 1 deletion src/app/server/CommissioningWindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ void CommissioningWindowManager::OnPlatformEvent(const DeviceLayer::ChipDeviceEv
Cleanup();
mServer->GetSecureSessionManager().ExpireAllPASESessions();
// That should have cleared out mPASESession.
#if CONFIG_NETWORK_LAYER_BLE
#if CONFIG_NETWORK_LAYER_BLE && CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
// If in NonConcurrentConnection, this will already have been completed
mServer->GetBleLayerObject()->CloseAllBleConnections();
#endif
}
Expand All @@ -82,6 +83,13 @@ void CommissioningWindowManager::OnPlatformEvent(const DeviceLayer::ChipDeviceEv
app::DnssdServer::Instance().AdvertiseOperational();
ChipLogProgress(AppServer, "Operational advertising enabled");
}
#if CONFIG_NETWORK_LAYER_BLE
else if (event->Type == DeviceLayer::DeviceEventType::kCloseAllBleConnections)
{
ChipLogProgress(AppServer, "Received kCloseAllBleConnections");
mServer->GetBleLayerObject()->CloseAllBleConnections();
}
#endif
}

void CommissioningWindowManager::Shutdown()
Expand Down
41 changes: 19 additions & 22 deletions src/controller/AutoCommissioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,35 +687,32 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
mNeedsDST = false;
break;
case CommissioningStage::kReadCommissioningInfo2: {
bool shouldReadCommissioningInfo2 =
mParams.GetCheckForMatchingFabric() || (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore);
if (shouldReadCommissioningInfo2)

if (!report.Is<ReadCommissioningInfo2>())
{
if (!report.Is<ReadCommissioningInfo2>())
{
ChipLogError(
Controller,
"[BUG] Should read commissioning info (part 2), but report is not ReadCommissioningInfo2. THIS IS A BUG.");
}
ChipLogError(
Controller,
"[BUG] Should read commissioning info (part 2), but report is not ReadCommissioningInfo2. THIS IS A BUG.");
}

ReadCommissioningInfo2 commissioningInfo = report.Get<ReadCommissioningInfo2>();
ReadCommissioningInfo2 commissioningInfo = report.Get<ReadCommissioningInfo2>();
mParams.SetSupportsConcurrentConnection(commissioningInfo.supportsConcurrentConnection);

if (mParams.GetCheckForMatchingFabric())
if (mParams.GetCheckForMatchingFabric())
{
chip::NodeId nodeId = commissioningInfo.nodeId;
if (nodeId != kUndefinedNodeId)
{
chip::NodeId nodeId = commissioningInfo.nodeId;
if (nodeId != kUndefinedNodeId)
{
mParams.SetRemoteNodeId(nodeId);
}
mParams.SetRemoteNodeId(nodeId);
}
}

if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore)
if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore)
{
if (commissioningInfo.isIcd)
{
if (commissioningInfo.isIcd)
{
mNeedIcdRegistraion = true;
ChipLogDetail(Controller, "AutoCommissioner: Device is ICD");
}
mNeedIcdRegistraion = true;
ChipLogDetail(Controller, "AutoCommissioner: Device is ICD");
}
}
break;
Expand Down
81 changes: 67 additions & 14 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,27 @@ void OnBasicFailure(void * context, CHIP_ERROR error)
commissioner->CommissioningStageComplete(error);
}

static void NonConcurrentTimeout(void * context, CHIP_ERROR error)
{
if (error == CHIP_ERROR_TIMEOUT)
{
ChipLogProgress(Controller, "Non-concurrent mode: Expected NetworkResponse Timeout, do nothing");
}
else
{
ChipLogProgress(Controller, "Non-concurrent mode: Received failure response %" CHIP_ERROR_FORMAT, error.Format());
}
}

static void NonConcurrentNetworkResponse(void * context,
const NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data)
{
// In Non Concurrent mode the commissioning network should have been shut down and not sent the
// ConnectNetworkResponse. In case it does send it this handles the message
ChipLogError(Controller, "Non-concurrent Mode : Received Unexpected ConnectNetwork response, ignoring. Status=%u",
to_underlying(data.networkingStatus));
}

void DeviceCommissioner::CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus)
{
commissioningCompletionStatus = completionStatus;
Expand Down Expand Up @@ -2111,6 +2132,16 @@ void DeviceCommissioner::ParseCommissioningInfo2()
ReadCommissioningInfo2 info;
CHIP_ERROR return_err = CHIP_NO_ERROR;

using namespace chip::app::Clusters::GeneralCommissioning::Attributes;
CHIP_ERROR err =
mAttributeCache->Get<SupportsConcurrentConnection::TypeInfo>(kRootEndpointId, info.supportsConcurrentConnection);
if (err != CHIP_NO_ERROR)
{
// May not be present so don't return the error code, non fatal, default concurrent
simonhmorris1 marked this conversation as resolved.
Show resolved Hide resolved
ChipLogError(Controller, "Failed to read SupportsConcurrentConnection: %" CHIP_ERROR_FORMAT, err.Format());
info.supportsConcurrentConnection = true;
}

return_err = ParseFabrics(info);

if (return_err == CHIP_NO_ERROR)
Expand Down Expand Up @@ -2206,6 +2237,8 @@ CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo2 & info)
}
else if (err == CHIP_ERROR_KEY_NOT_FOUND)
{
// This key is optional so not an error
err = CHIP_NO_ERROR;
info.isIcd = false;
}
else if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED)
Expand Down Expand Up @@ -2440,6 +2473,7 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
case CommissioningStage::kReadCommissioningInfo: {
ChipLogProgress(Controller, "Sending read request for commissioning information");
// NOTE: this array cannot have more than 9 entries, since the spec mandates that server only needs to support 9
// See R1.1, 2.11.2 Interaction Model Limits
app::AttributePathParams readPaths[9];
// Read all the feature maps for all the networking clusters on any endpoint to determine what is supported
readPaths[0] = app::AttributePathParams(app::Clusters::NetworkCommissioning::Id,
Expand Down Expand Up @@ -2471,7 +2505,14 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
case CommissioningStage::kReadCommissioningInfo2: {
size_t numberOfAttributes = 0;
// This is done in a separate step since we've already used up all the available read paths in the previous read step
app::AttributePathParams readPaths[9];
// NOTE: this array cannot have more than 9 entries, since the spec mandates that server only needs to support 9
// See R1.1, 2.11.2 Interaction Model Limits
app::AttributePathParams readPaths[3];
simonhmorris1 marked this conversation as resolved.
Show resolved Hide resolved

// Mandatory attribute
readPaths[numberOfAttributes++] =
app::AttributePathParams(endpoint, app::Clusters::GeneralCommissioning::Id,
app::Clusters::GeneralCommissioning::Attributes::SupportsConcurrentConnection::Id);

// Read the current fabrics
if (params.GetCheckForMatchingFabric())
Expand All @@ -2486,18 +2527,6 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::FeatureMap::Id);
}

// Current implementation makes sense when we only have a few attributes to read with conditions. Should revisit this if we
// are adding more attributes here.

if (numberOfAttributes == 0)
{
// We don't actually want to do this step, so just bypass it
ChipLogProgress(Controller, "kReadCommissioningInfo2 step called without parameter set, skipping");
CommissioningStageComplete(CHIP_NO_ERROR);
return;
}

ChipLogProgress(Controller, "Sending request for commissioning information -- Part 2");
SendCommissioningReadRequest(proxy, timeout, readPaths, numberOfAttributes);
}
break;
Expand Down Expand Up @@ -2918,7 +2947,31 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
NetworkCommissioning::Commands::ConnectNetwork::Type request;
request.networkID = params.GetWiFiCredentials().Value().ssid;
request.breadcrumb.Emplace(breadcrumb);
CHIP_ERROR err = SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure, endpoint, timeout);

CHIP_ERROR err = CHIP_NO_ERROR;
GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo::Type supportsConcurrentConnection;
supportsConcurrentConnection = params.GetSupportsConcurrentConnection().Value();
ChipLogProgress(Controller, "SendCommand kWiFiNetworkEnable, supportsConcurrentConnection=%d",
supportsConcurrentConnection);
if (supportsConcurrentConnection)
{
err = SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure, endpoint, timeout);
}
else
{
// Concurrent Connections not allowed. Send the ConnectNetwork command but do not wait for the
// ConnectNetworkResponse on the Commissioning network as it will not be present. Log the expected timeout
// and run what would have been in the onConnectNetworkResponse callback.
err = SendCommand(proxy, request, NonConcurrentNetworkResponse, NonConcurrentTimeout, endpoint, NullOptional);
if (err == CHIP_NO_ERROR)
{
// As there will be no ConnectNetworkResponse, it is an implicit kSuccess so a default report is fine
CommissioningDelegate::CommissioningReport report;
CommissioningStageComplete(CHIP_NO_ERROR, report);
return;
}
}

if (err != CHIP_NO_ERROR)
{
// We won't get any async callbacks here, so just complete our stage.
Expand Down
Loading
Loading