3939#include < lib/core/CHIPError.h>
4040#include < lib/core/DataModelTypes.h>
4141#include < lib/support/AutoRelease.h>
42+ #include < lib/support/BytesToHex.h>
4243#include < lib/support/CodeUtils.h>
4344#include < lib/support/SafeInt.h>
4445#include < lib/support/SortUtils.h>
4950#include < platform/internal/DeviceNetworkInfo.h>
5051#include < protocols/interaction_model/StatusCode.h>
5152#include < tracing/macros.h>
53+ #include < transport/SecureSession.h>
5254
5355namespace chip {
5456namespace app {
@@ -61,6 +63,17 @@ using namespace chip::app::Clusters::NetworkCommissioning;
6163
6264namespace {
6365
66+ #if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
67+
68+ bool IsConnectNetworkRequestOverPASE (CommandHandler & handler)
69+ {
70+ Messaging::ExchangeContext * exchangeCtx = handler.GetExchangeContext ();
71+ return exchangeCtx && exchangeCtx->HasSessionHandle () && exchangeCtx->GetSessionHandle ()->IsSecureSession () &&
72+ exchangeCtx->GetSessionHandle ()->AsSecureSession ()->GetSecureSessionType () == Transport::SecureSession::Type::kPASE ;
73+ }
74+
75+ #endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
76+
6477// Note: CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE can be 0, this disables debug text
6578using DebugTextStorage = std::array<char , CHIP_CONFIG_NETWORK_COMMISSIONING_DEBUG_TEXT_BUFFER_SIZE>;
6679
@@ -638,20 +651,49 @@ NetworkCommissioningCluster::HandleConnectNetwork(CommandHandler & handler, cons
638651
639652 mpWirelessDriver->ConnectNetwork (req.networkID , this );
640653#else
641- // In Non-concurrent mode postpone the final execution of ConnectNetwork until the operational
642- // network has been fully brought up and kOperationalNetworkStarted is delivered.
643- // mConnectingNetworkIDLen and mConnectingNetworkID contain the received SSID
644- // As per spec, send the ConnectNetworkResponse(Success) prior to releasing the commissioning channel
645- SendNonConcurrentConnectNetworkResponse ();
654+ mConnectNetworkResponseSentEarly = false ;
655+ // In non-concurrent mode there are two execution paths:
656+ // 1) PASE/BLE: send ConnectNetworkResponse early before tearing down the commissioning
657+ // transport; actual connect is started later from OnPlatformEventHandler.
658+ // 2) CASE: start connect immediately here and send ConnectNetworkResponse from OnResult
659+ // after attach finishes.
660+ if (IsConnectNetworkRequestOverPASE (handler))
661+ {
662+ // PASE path must respond before commissioning transport is torn down.
663+ mConnectNetworkResponseSentEarly = true ;
664+ SendNonConcurrentConnectNetworkResponse ();
665+ }
666+ else
667+ {
668+ HandleNonConcurrentConnectNetwork ();
669+ }
646670#endif
647671 return std::nullopt ;
648672}
649673
650674std::optional<ActionReturnStatus> NetworkCommissioningCluster::HandleNonConcurrentConnectNetwork ()
651675{
652676 ByteSpan nonConcurrentNetworkID = ByteSpan (mConnectingNetworkID , mConnectingNetworkIDLen );
653- ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, Connect to Network SSID=%s" ,
654- NullTerminated (mConnectingNetworkID , mConnectingNetworkIDLen ).c_str ());
677+ if (mFeatureFlags .Has (Feature::kThreadNetworkInterface ))
678+ {
679+ constexpr size_t kThreadNetworkIdHexMax = (2 * kMaxNetworkIDLen ) + 1 ;
680+ char threadNetworkIdHex[kThreadNetworkIdHexMax ];
681+ if (Encoding::BytesToUppercaseHexString (nonConcurrentNetworkID.data (), nonConcurrentNetworkID.size (), threadNetworkIdHex,
682+ sizeof (threadNetworkIdHex)) == CHIP_NO_ERROR)
683+ {
684+ ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, Connect to Thread Network ID=%s" , threadNetworkIdHex);
685+ }
686+ else
687+ {
688+ ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, Connect to Thread Network ID (len=%u)" ,
689+ static_cast <unsigned >(nonConcurrentNetworkID.size ()));
690+ }
691+ }
692+ else
693+ {
694+ ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, Connect to Wi-Fi SSID=%s" ,
695+ NullTerminated (mConnectingNetworkID , mConnectingNetworkIDLen ).c_str ());
696+ }
655697 mpWirelessDriver->ConnectNetwork (nonConcurrentNetworkID, this );
656698 return std::nullopt ;
657699}
@@ -790,12 +832,11 @@ void NetworkCommissioningCluster::DisconnectLingeringConnection()
790832void NetworkCommissioningCluster::OnResult (Status commissioningError, CharSpan debugText, int32_t interfaceStatus)
791833{
792834 auto commandHandleRef = std::move (mAsyncCommandHandle );
793-
835+ auto commandHandle = commandHandleRef. Get ();
794836 // In Non-concurrent mode the commandHandle will be null here, the ConnectNetworkResponse
795837 // has already been sent and the BLE will have been stopped, however the other functionality
796838 // is still required
797839#if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
798- auto commandHandle = commandHandleRef.Get ();
799840 if (commandHandle == nullptr )
800841 {
801842 // When the platform shut down, interaction model engine will invalidate all commandHandle to avoid dangling references.
@@ -825,14 +866,23 @@ void NetworkCommissioningCluster::OnResult(Status commissioningError, CharSpan d
825866 SetLastNetworkId (ByteSpan{ mConnectingNetworkID , mConnectingNetworkIDLen });
826867 SetLastNetworkingStatusValue (MakeNullable (commissioningError));
827868
869+ bool shouldSendConnectNetworkResponse = true ;
828870#if (CONFIG_NETWORK_LAYER_BLE || CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP) && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
829- ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, ConnectNetworkResponse will NOT be sent" );
830- // Do not send the ConnectNetworkResponse if in non-concurrent mode
831- // TODO(#30576) raised to modify CommandHandler to notify it if no response required
832- // -----> Is this required here: commandHandle->FinishCommand();
833- #else
834- commandHandle->AddResponse (mAsyncCommandPath , response);
835- #endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
871+ if (mConnectNetworkResponseSentEarly )
872+ {
873+ ChipLogProgress (NetworkProvisioning, " Non-concurrent mode, ConnectNetworkResponse was already sent" );
874+ shouldSendConnectNetworkResponse = false ;
875+ }
876+ #endif
877+
878+ if (shouldSendConnectNetworkResponse && commandHandle != nullptr )
879+ {
880+ commandHandle->AddResponse (mAsyncCommandPath , response);
881+ }
882+
883+ #if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
884+ mConnectNetworkResponseSentEarly = false ;
885+ #endif
836886
837887 if (commissioningError == Status::kSuccess )
838888 {
@@ -932,6 +982,10 @@ void NetworkCommissioningCluster::OnFailSafeTimerExpired()
932982{
933983 VerifyOrReturn (mpWirelessDriver != nullptr );
934984
985+ #if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION
986+ mConnectNetworkResponseSentEarly = false ;
987+ #endif
988+
935989 ChipLogDetail (Zcl, " Failsafe timeout, tell platform driver to revert network credentials." );
936990 TEMPORARY_RETURN_IGNORED mpWirelessDriver->RevertConfiguration ();
937991 mAsyncCommandHandle .Release ();
0 commit comments