From dca27977f6adac57098e50c5ee77101fdb69efe6 Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Wed, 16 Jun 2021 08:56:44 -0700 Subject: [PATCH] enable CASE sessions for chip-tool --- .../commands/clusters/ModelCommand.cpp | 26 +++++++++++++++++++ src/controller/CHIPDevice.cpp | 2 ++ src/controller/CHIPDevice.h | 2 ++ src/protocols/secure_channel/CASEServer.cpp | 2 ++ src/transport/SecureSessionMgr.cpp | 18 +++++++++++++ src/transport/SecureSessionMgr.h | 1 + 6 files changed, 51 insertions(+) diff --git a/examples/chip-tool/commands/clusters/ModelCommand.cpp b/examples/chip-tool/commands/clusters/ModelCommand.cpp index 632304580563aa..0655b79192ef51 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.cpp +++ b/examples/chip-tool/commands/clusters/ModelCommand.cpp @@ -37,6 +37,25 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC "Default DispatchSingleClusterCommand is called, this should be replaced by actual dispatched for cluster commands"); } +CHIP_ERROR WaitForSessionSetup(chip::Controller::Device * device) +{ + constexpr time_t kWaitPerIteration = 1; + constexpr uint16_t kIterationCount = 5; + + struct timespec sleep_time; + sleep_time.tv_sec = kWaitPerIteration; + sleep_time.tv_nsec = 0; + + for (uint32_t i = 0; i < kIterationCount && device->IsSessionSetupInProgress(); i++) + { + nanosleep(&sleep_time, nullptr); + } + + ReturnErrorCodeIf(!device->IsSecureConnected(), CHIP_ERROR_TIMEOUT); + + return CHIP_NO_ERROR; +} + CHIP_ERROR ModelCommand::Run(NodeId localId, NodeId remoteId) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -54,6 +73,13 @@ CHIP_ERROR ModelCommand::Run(NodeId localId, NodeId remoteId) err = GetExecContext()->commissioner->GetDevice(remoteId, &mDevice); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(chipTool, "Init failure! No pairing for device: %" PRIu64, localId)); + if (mDevice->IsSessionSetupInProgress()) + { + err = WaitForSessionSetup(mDevice); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(chipTool, "Timed out while waiting for session setup for device: %" PRIu64, localId)); + } + err = SendCommand(mDevice, mEndPointId); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(chipTool, "Failed to send message: %s", ErrorStr(err))); } diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index 82caefdb39f3a2..5c21cf2df8b13c 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -499,6 +499,8 @@ void Device::OperationalCertProvisioned() ChipLogDetail(Controller, "Enabling CASE session establishment for the device"); mDeviceOperationalCertProvisioned = true; + Persist(); + if (mState == ConnectionState::SecureConnected) { mSessionManager->ExpirePairing(mSecureSession); diff --git a/src/controller/CHIPDevice.h b/src/controller/CHIPDevice.h index 2df354c015ef93..21324826c41c57 100644 --- a/src/controller/CHIPDevice.h +++ b/src/controller/CHIPDevice.h @@ -312,6 +312,8 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta bool IsSecureConnected() const { return IsActive() && mState == ConnectionState::SecureConnected; } + bool IsSessionSetupInProgress() const { return IsActive() && mState == ConnectionState::Connecting; } + void Reset(); NodeId GetDeviceId() const { return mDeviceId; } diff --git a/src/protocols/secure_channel/CASEServer.cpp b/src/protocols/secure_channel/CASEServer.cpp index 00c3a01a7960db..e3368e4f5a58e6 100644 --- a/src/protocols/secure_channel/CASEServer.cpp +++ b/src/protocols/secure_channel/CASEServer.cpp @@ -112,6 +112,8 @@ void CASEServer::OnSessionEstablishmentError(CHIP_ERROR err) void CASEServer::OnSessionEstablished() { ChipLogProgress(Inet, "CASE Session established. Setting up the secure channel."); + mSessionMgr->ExpireAllPairings(mPairingSession.PeerConnection().GetPeerNodeId(), mAdminId); + CHIP_ERROR err = mSessionMgr->NewPairing(Optional::Value(mPairingSession.PeerConnection().GetPeerAddress()), mPairingSession.PeerConnection().GetPeerNodeId(), &mPairingSession, diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index 2fd51491665d64..f3ed4d6649c88b 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -241,6 +241,24 @@ void SecureSessionMgr::ExpirePairing(SecureSessionHandle session) } } +void SecureSessionMgr::ExpireAllPairings(NodeId peerNodeId, Transport::AdminId admin) +{ + PeerConnectionState * state = mPeerConnections.FindPeerConnectionState(peerNodeId, nullptr); + while (state != nullptr) + { + if (admin == state->GetAdminId()) + { + mPeerConnections.MarkConnectionExpired( + state, [this](const Transport::PeerConnectionState & state1) { HandleConnectionExpired(state1); }); + state = mPeerConnections.FindPeerConnectionState(peerNodeId, nullptr); + } + else + { + state = mPeerConnections.FindPeerConnectionState(peerNodeId, state); + } + } +} + CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & peerAddr, NodeId peerNodeId, PairingSession * pairing, SecureSession::SessionRole direction, Transport::AdminId admin, Transport::Base * transport) diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 5a6870cc5a4db7..e7a848815eec2c 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -218,6 +218,7 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate SecureSession::SessionRole direction, Transport::AdminId admin, Transport::Base * transport = nullptr); void ExpirePairing(SecureSessionHandle session); + void ExpireAllPairings(NodeId peerNodeId, Transport::AdminId admin); /** * @brief