blob: 16f1d5cd132f817f0766bfb0ef8c46173a0bbdd9 [file] [log] [blame]
/*
* 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 <app-common/zap-generated/cluster-objects.h>
#include <app/ConcreteCommandPath.h>
#include <controller/InvokeInteraction.h>
#include <support/CHIPMem.h>
CHIP_ERROR StayActiveSender::SendStayActiveCommand(uint32_t stayActiveDurationMs, const chip::ScopedNodeId & peerNode,
chip::app::InteractionModelEngine * engine, OnDoneCallbackType onDone)
{
ConstructorOnlyInternallyCallable internal;
auto stayActiveSender = chip::Platform::New<StayActiveSender>(internal, stayActiveDurationMs, peerNode,
chip::app::InteractionModelEngine::GetInstance(), onDone);
VerifyOrReturnError(stayActiveSender != nullptr, CHIP_ERROR_NO_MEMORY);
CHIP_ERROR err = stayActiveSender->EstablishSessionToPeer();
if (CHIP_NO_ERROR != err)
{
chip::Platform::Delete(stayActiveSender);
}
return err;
}
StayActiveSender::StayActiveSender(const ConstructorOnlyInternallyCallable & _, uint32_t stayActiveDurationMs,
const chip::ScopedNodeId & peerNode, chip::app::InteractionModelEngine * engine,
OnDoneCallbackType onDone) :
mStayActiveDurationMs(stayActiveDurationMs),
mPeerNode(peerNode), mpImEngine(engine), mOnDone(onDone), 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 promisedActiveDurationMs = dataResponse.promisedActiveDuration;
ChipLogProgress(ICD, "StayActive command succeeded with promised duration %u", promisedActiveDurationMs);
mOnDone(promisedActiveDurationMs);
chip::Platform::Delete(this);
};
auto onFailure = [&](CHIP_ERROR error) {
ChipLogError(ICD, "StayActive command failed: %" CHIP_ERROR_FORMAT, error.Format());
chip::Platform::Delete(this);
};
chip::EndpointId endpointId = 0;
chip::app::Clusters::IcdManagement::Commands::StayActiveRequest::Type request;
request.stayActiveDuration = mStayActiveDurationMs;
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");
chip::Platform::Delete(_this);
}
}
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());
chip::Platform::Delete(_this);
}