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

Create new ICD Manager in fabric-admin to service KeepActive Command #34894

Merged
merged 21 commits into from
Aug 14, 2024
Merged
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions examples/fabric-admin/BUILD.gn
Original file line number Diff line number Diff line change
@@ -73,6 +73,8 @@ static_library("fabric-admin-utils") {
"commands/common/IcdManager.h",
"commands/common/RemoteDataModelLogger.cpp",
"commands/common/RemoteDataModelLogger.h",
"commands/common/StayActiveSender.cpp",
"commands/common/StayActiveSender.h",
"commands/fabric-sync/FabricSyncCommand.cpp",
"commands/pairing/DeviceSynchronization.cpp",
"commands/pairing/DeviceSynchronization.h",
16 changes: 16 additions & 0 deletions examples/fabric-admin/commands/common/IcdManager.cpp
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@
*/

#include "IcdManager.h"
#include <app/InteractionModelEngine.h>


IcdManager IcdManager::sInstance;

@@ -32,6 +34,20 @@ void IcdManager::OnCheckInComplete(const chip::app::ICDClientInfo & clientInfo)
{
mDelegate->OnCheckInCompleted(clientInfo);
}

uint32_t activeDurationMs = 30000;
auto stayActiveSender = chip::Platform::New<StayActiveSender>(activeDurationMs, clientInfo.peer_node, chip::app::InteractionModelEngine::GetInstance());
if (stayActiveSender == nullptr)
{
ChipLogProgress(ICD, "Fail to allocate stayActiveSender");
return;
}
CHIP_ERROR err = stayActiveSender->EstablishSessionToPeer();
if (CHIP_NO_ERROR != err)
{
ChipLogError(ICD, "CASE session establishment failed with error : %" CHIP_ERROR_FORMAT, err.Format());
return;
}
}

void IcdManager::SetDelegate(Delegate * delegate)
3 changes: 3 additions & 0 deletions examples/fabric-admin/commands/common/IcdManager.h
Original file line number Diff line number Diff line change
@@ -22,6 +22,9 @@

#include <app/icd/client/DefaultCheckInDelegate.h>

#include "StayActiveSender.h"


class IcdManager : public chip::app::DefaultCheckInDelegate
{
public:
81 changes: 81 additions & 0 deletions examples/fabric-admin/commands/common/StayActiveSender.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "StayActiveSender.h"
#include <controller/InvokeInteraction.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/AppConfig.h>
#include <app/CommandPathParams.h>
#include <app/OperationalSessionSetup.h>
#include <memory>

StayActiveSender::StayActiveSender(uint32_t stayActiveDuration, const chip::ScopedNodeId & peerNode,
chip::app::InteractionModelEngine * engine) :
mStayActiveDuration(stayActiveDuration), mPeerNode(peerNode), mpImEngine(engine),
mOnConnectedCallback(HandleDeviceConnected, this), mOnConnectionFailureCallback(HandleDeviceConnectionFailure, this)
{}

CHIP_ERROR StayActiveSender::SendStayActiveCommand(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle)
{
auto onSuccess = [&](const chip::app::ConcreteCommandPath & commandPath, const chip::app::StatusIB & status, const auto & dataResponse) {
uint32_t promisedActiveDuration = dataResponse.promisedActiveDuration;
ChipLogProgress(ICD, "StayActive command succeeded with promised duration %u", promisedActiveDuration);
// TODO: please send multiple stayActive request with 30 seconds up to x min since active duration in server side is upper bound to 30 seconds
if (mStayActiveDuration > dataResponse.promisedActiveDuration)
{
mStayActiveDuration -= dataResponse.promisedActiveDuration;
}
};

auto onFailure = [&](CHIP_ERROR error) {
ChipLogError(ICD, "StayActive command failed: %" CHIP_ERROR_FORMAT, error.Format());
};

chip::EndpointId endpointId = 0;
chip::app::Clusters::IcdManagement::Commands::StayActiveRequest::Type request;
request.stayActiveDuration = mStayActiveDuration;
return chip::Controller::InvokeCommandRequest(&exchangeMgr, sessionHandle, endpointId, request, onSuccess, onFailure);
}

CHIP_ERROR StayActiveSender::EstablishSessionToPeer()
{
ChipLogProgress(ICD, "Trying to establish a CASE session to extend the active period for lit icd device");
auto * caseSessionManager = mpImEngine->GetCASESessionManager();
VerifyOrReturnError(caseSessionManager != nullptr, CHIP_ERROR_INVALID_CASE_PARAMETER);
caseSessionManager->FindOrEstablishSession(mPeerNode, &mOnConnectedCallback, &mOnConnectionFailureCallback);
return CHIP_NO_ERROR;
}

void StayActiveSender::HandleDeviceConnected(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
const chip::SessionHandle & sessionHandle)
{
StayActiveSender * const _this = static_cast<StayActiveSender *>(context);
VerifyOrDie(_this != nullptr);

CHIP_ERROR err = _this->SendStayActiveCommand(exchangeMgr, sessionHandle);
if (CHIP_NO_ERROR != err)
{
ChipLogError(ICD, "Failed to send stay active command");
}
}

void StayActiveSender::HandleDeviceConnectionFailure(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR err)
{
StayActiveSender * const _this = static_cast<StayActiveSender *>(context);
VerifyOrDie(_this != nullptr);
ChipLogError(ICD, "Failed to establish CASE for stay active command with error '%" CHIP_ERROR_FORMAT "'", err.Format());;
}
93 changes: 93 additions & 0 deletions examples/fabric-admin/commands/common/StayActiveSender.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPEncoding.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandSender.h>
#include <app/OperationalSessionSetup.h>

#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPConfig.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/ScopedNodeId.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/ExchangeContext.h>
#include <lib/support/CodeUtils.h>
#include <stddef.h>
#include <app/InteractionModelEngine.h>

namespace chip
{
namespace app
{
class InteractionModelEngine;
}
}

/**
* @brief StayActiveSender contains all the data and methods needed for active period extension of an ICD client.
*/
class StayActiveSender
{
public:
StayActiveSender(uint32_t stayActiveDuration, const chip::ScopedNodeId & peerNode,
chip::app::InteractionModelEngine * engine);

/**
* @brief Sets up a CASE session to the peer for extend a client active period with the peer.
* Returns error if we did not even manage to kick off a CASE attempt.
*/
CHIP_ERROR EstablishSessionToPeer();

private:
// CASE session callbacks
/**
*@brief Callback received on successfully establishing a CASE session in order to keep the 'lit icd device' active
*
* @param[in] context - context of the client establishing the CASE session
* @param[in] exchangeMgr - exchange manager to use for the re-registration
* @param[in] sessionHandle - session handle to use for the re-registration
*/
static void HandleDeviceConnected(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
const chip::SessionHandle & sessionHandle);
/**
* @brief Callback received on failure to establish a CASE session
*
* @param[in] context - context of the client establishing the CASE session
* @param[in] peerId - Scoped Node ID of the peer node
* @param[in] err - failure reason
*/
static void HandleDeviceConnectionFailure(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR err);

/**
* @brief Used to send a stayActive command to the peer
*
* @param[in] exchangeMgr - exchange manager to use for the re-registration
* @param[in] sessionHandle - session handle to use for the re-registration
*/
CHIP_ERROR SendStayActiveCommand(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle);

uint32_t mStayActiveDuration = 0;
chip::ScopedNodeId mPeerNode;
chip::app::InteractionModelEngine * mpImEngine = nullptr;

chip::Callback::Callback<chip::OnDeviceConnected> mOnConnectedCallback;
chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnConnectionFailureCallback;
};