Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
7 changes: 7 additions & 0 deletions config/telink/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,10 @@ endif
config TFLM_FEATURE
bool "Enable the TFLM micro speech feature"
default n

config CHIP_OPENTHREAD_NETWORK_SWITCH_PATH
bool "Keep Thread enabled when switching between commissioned datasets"
help
Keep Thread enabled while switching between commissioned
datasets to reduce detached window during fail-safe rollback/connect.
default y
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <app/reporting/reporting.h>
#include <app/server-cluster/AttributeListBuilder.h>
#include <app/server-cluster/DefaultServerCluster.h>
#include <app/server/Server.h>
#include <clusters/NetworkCommissioning/AttributeIds.h>
#include <clusters/NetworkCommissioning/CommandIds.h>
#include <clusters/NetworkCommissioning/Commands.h>
Expand All @@ -39,6 +40,7 @@
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/AutoRelease.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <lib/support/SortUtils.h>
Expand All @@ -49,6 +51,7 @@
#include <platform/internal/DeviceNetworkInfo.h>
#include <protocols/interaction_model/StatusCode.h>
#include <tracing/macros.h>
#include <transport/SecureSession.h>

namespace chip {
namespace app {
Expand All @@ -61,6 +64,17 @@ using namespace chip::app::Clusters::NetworkCommissioning;

namespace {

#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION

bool IsConnectNetworkRequestOverPASE(CommandHandler & handler)
{
Messaging::ExchangeContext * exchangeCtx = handler.GetExchangeContext();
return exchangeCtx && exchangeCtx->HasSessionHandle() && exchangeCtx->GetSessionHandle()->IsSecureSession() &&
exchangeCtx->GetSessionHandle()->AsSecureSession()->GetSecureSessionType() == Transport::SecureSession::Type::kPASE;
}

#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION

// Note: CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE can be 0, this disables debug text
using DebugTextStorage = std::array<char, CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE>;

Expand Down Expand Up @@ -638,20 +652,48 @@ NetworkCommissioningCluster::HandleConnectNetwork(CommandHandler & handler, cons

mpWirelessDriver->ConnectNetwork(req.networkID, this);
#else
mConnectNetworkResponseSentEarly = false;
// In Non-concurrent mode postpone the final execution of ConnectNetwork until the operational
// network has been fully brought up and kOperationalNetworkStarted is delivered.
// mConnectingNetworkIDLen and mConnectingNetworkID contain the received SSID
// As per spec, send the ConnectNetworkResponse(Success) prior to releasing the commissioning channel
SendNonConcurrentConnectNetworkResponse();

// For PASE/BLE requests, reply before tearing down the commissioning transport.
// For CASE requests, keep the command open and reply from OnResult after attach finishes.
if (IsConnectNetworkRequestOverPASE(handler))
{
mConnectNetworkResponseSentEarly = true;
SendNonConcurrentConnectNetworkResponse();
}
else
{
HandleNonConcurrentConnectNetwork();
}
#endif
return std::nullopt;
}

std::optional<ActionReturnStatus> NetworkCommissioningCluster::HandleNonConcurrentConnectNetwork()
{
ByteSpan nonConcurrentNetworkID = ByteSpan(mConnectingNetworkID, mConnectingNetworkIDLen);
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, Connect to Network SSID=%s",
NullTerminated(mConnectingNetworkID, mConnectingNetworkIDLen).c_str());
if (mFeatureFlags.Has(Feature::kThreadNetworkInterface))
{
constexpr size_t kThreadNetworkIdHexMax = (2 * kMaxNetworkIDLen) + 1;
char threadNetworkIdHex[kThreadNetworkIdHexMax];
if (Encoding::BytesToUppercaseHexString(nonConcurrentNetworkID.data(), nonConcurrentNetworkID.size(), threadNetworkIdHex,
sizeof(threadNetworkIdHex)) == CHIP_NO_ERROR)
{
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, Connect to Thread Network ID=%s", threadNetworkIdHex);
}
else
{
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, Connect to Thread Network ID (len=%u)",
static_cast<unsigned>(nonConcurrentNetworkID.size()));
}
}
else
{
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, Connect to Wi-Fi SSID=%s",
NullTerminated(mConnectingNetworkID, mConnectingNetworkIDLen).c_str());
}
mpWirelessDriver->ConnectNetwork(nonConcurrentNetworkID, this);
return std::nullopt;
}
Expand Down Expand Up @@ -790,12 +832,11 @@ void NetworkCommissioningCluster::DisconnectLingeringConnection()
void NetworkCommissioningCluster::OnResult(Status commissioningError, CharSpan debugText, int32_t interfaceStatus)
{
auto commandHandleRef = std::move(mAsyncCommandHandle);

auto commandHandle = commandHandleRef.Get();
// In Non-concurrent mode the commandHandle will be null here, the ConnectNetworkResponse
// has already been sent and the BLE will have been stopped, however the other functionality
// is still required
#if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
auto commandHandle = commandHandleRef.Get();
if (commandHandle == nullptr)
{
// When the platform shut down, interaction model engine will invalidate all commandHandle to avoid dangling references.
Expand Down Expand Up @@ -825,14 +866,23 @@ void NetworkCommissioningCluster::OnResult(Status commissioningError, CharSpan d
SetLastNetworkId(ByteSpan{ mConnectingNetworkID, mConnectingNetworkIDLen });
SetLastNetworkingStatusValue(MakeNullable(commissioningError));

bool shouldSendConnectNetworkResponse = true;
#if (CONFIG_NETWORK_LAYER_BLE || CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP) && !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
// TODO(#30576) raised to modify CommandHandler to notify it if no response required
// -----> Is this required here: commandHandle->FinishCommand();
#else
commandHandle->AddResponse(mAsyncCommandPath, response);
#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
if (mConnectNetworkResponseSentEarly)
{
ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, ConnectNetworkResponse was already sent");
shouldSendConnectNetworkResponse = false;
}
#endif

if (shouldSendConnectNetworkResponse && commandHandle != nullptr)
{
commandHandle->AddResponse(mAsyncCommandPath, response);
}

#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
mConnectNetworkResponseSentEarly = false;
#endif

if (commissioningError == Status::kSuccess)
{
Expand Down Expand Up @@ -932,6 +982,10 @@ void NetworkCommissioningCluster::OnFailSafeTimerExpired()
{
VerifyOrReturn(mpWirelessDriver != nullptr);

#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
mConnectNetworkResponseSentEarly = false;
#endif

ChipLogDetail(Zcl, "Failsafe timeout, tell platform driver to revert network credentials.");
TEMPORARY_RETURN_IGNORED mpWirelessDriver->RevertConfiguration();
mAsyncCommandHandle.Release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ class NetworkCommissioningCluster : private NetworkCommissioningLogicListNode,
uint8_t mLastNetworkIDLen = 0;
Optional<uint64_t> mCurrentOperationBreadcrumb;
bool mScanningWasDirected = false;
#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
bool mConnectNetworkResponseSentEarly = false;
#endif
Context mClusterContext;

void SetLastNetworkingStatusValue(NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo::Type networkingStatusValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,17 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_AttachToThreadN

// Reset the previously set callback since it will never be called in case incorrect dataset was supplied.
mpConnectCallback = nullptr;

#if defined(CONFIG_CHIP_OPENTHREAD_NETWORK_SWITCH_PATH) && CONFIG_CHIP_OPENTHREAD_NETWORK_SWITCH_PATH
if (callback == nullptr && dataset.IsCommissioned() && current_dataset.IsCommissioned() &&
!dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && Impl()->IsThreadEnabled())
{
ReturnErrorOnFailure(Impl()->SetThreadProvision(dataset.AsByteSpan()));
mpConnectCallback = callback;
return CHIP_NO_ERROR;
}
#endif

ReturnErrorOnFailure(Impl()->SetThreadEnabled(false));
ReturnErrorOnFailure(Impl()->SetThreadProvision(dataset.AsByteSpan()));

Expand Down
Loading