blob: 4d9268e586dc2c3b0dcdcd249fc4f0f562bfc05f [file] [log] [blame]
/*
*
* Copyright (c) 2021 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.
*/
/**
* @file Contains functions relating to Content App of the Video Player.
*/
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/app-platform/ContentAppPlatform.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/ZclString.h>
#include <platform/CHIPDeviceLayer.h>
#include <protocols/interaction_model/StatusCode.h>
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
using namespace chip;
using namespace chip::AppPlatform;
using chip::Protocols::InteractionModel::Status;
namespace chip {
namespace AppPlatform {
#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u)
#define ZCL_APPLICATION_BASIC_CLUSTER_REVISION (1u)
inline constexpr EndpointId kCastingVideoPlayerEndpointId = 1;
Status ContentApp::HandleReadAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength)
{
ChipLogProgress(DeviceLayer,
"Read Attribute for endpoint " ChipLogFormatMEI " cluster " ChipLogFormatMEI " attribute " ChipLogFormatMEI,
ChipLogValueMEI(mEndpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId));
return Status::Failure;
}
Status ContentApp::HandleWriteAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t * buffer)
{
ChipLogProgress(DeviceLayer,
"Read Attribute for endpoint " ChipLogFormatMEI " cluster " ChipLogFormatMEI " attribute " ChipLogFormatMEI,
ChipLogValueMEI(mEndpointId), ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId));
return Status::Failure;
}
bool ContentApp::AddClientNode(NodeId subjectNodeId)
{
for (int i = 0; i < kMaxClientNodes; ++i)
{
if (mClientNodes[i] == subjectNodeId)
{
// avoid storing duplicate nodes
return false;
}
}
mClientNodes[mNextClientNodeIndex++] = subjectNodeId;
if (mClientNodeCount < kMaxClientNodes)
{
mClientNodeCount++;
}
if (mNextClientNodeIndex >= kMaxClientNodes)
{
// if we exceed the max number, then overwrite the oldest entry
mNextClientNodeIndex = 0;
}
return true;
}
void ContentApp::SendAppObserverCommand(chip::Controller::DeviceCommissioner * commissioner, NodeId clientNodeId, char * data,
char * encodingHint)
{
ChipLogProgress(Controller, "Attempting to send AppObserver command");
if (mContentAppClientCommandSender.IsBusy())
{
ChipLogProgress(Controller, "SendAppObserverCommand busy");
return;
}
mContentAppClientCommandSender.SendContentAppMessage(commissioner, clientNodeId, kCastingVideoPlayerEndpointId, data,
encodingHint);
ChipLogProgress(Controller, "Completed send of AppObserver command");
}
bool ContentApp::HasSupportedCluster(chip::ClusterId clusterId) const
{
for (const auto & supportedCluster : mSupportedClusters)
{
if (clusterId == supportedCluster.mClusterIdentifier)
{
return true;
}
}
return false;
}
CHIP_ERROR ContentAppClientCommandSender::SendContentAppMessage(chip::Controller::DeviceCommissioner * commissioner,
chip::NodeId destinationId, chip::EndpointId endPointId,
char * data, char * encodingHint)
{
if (mIsBusy)
{
return CHIP_ERROR_INCORRECT_STATE;
}
mIsBusy = true;
mDestinationId = destinationId;
mEndPointId = endPointId;
mData = std::string(data);
mEncodingHint = std::string(encodingHint);
ChipLogProgress(Controller, "Sending command to node 0x" ChipLogFormatX64, ChipLogValueX64(mDestinationId));
return commissioner->GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback);
}
void ContentAppClientCommandSender::OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
const chip::SessionHandle & sessionHandle)
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::OnDeviceConnectedFn");
ContentAppClientCommandSender * sender = reinterpret_cast<ContentAppClientCommandSender *>(context);
VerifyOrReturn(sender != nullptr, ChipLogError(chipTool, "OnDeviceConnectedFn: context is null"));
sender->SendMessage(exchangeMgr, sessionHandle);
}
CHIP_ERROR ContentAppClientCommandSender::SendMessage(chip::Messaging::ExchangeManager & exchangeMgr,
const chip::SessionHandle & sessionHandle)
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::SendMessage");
chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, mEndPointId);
chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::Type request;
request.data = Optional<CharSpan>(CharSpan::fromCharString(mData.c_str()));
request.encodingHint = CharSpan::fromCharString(mEncodingHint.c_str());
CHIP_ERROR err = cluster.InvokeCommand(request, nullptr, OnCommandResponse, OnCommandFailure);
if (err != CHIP_NO_ERROR)
{
ChipLogDetail(Controller, "ContentAppClientCommandSender SendMessage error err %s", ErrorStr(err));
}
mIsBusy = false;
ChipLogProgress(Controller, "ContentAppClientCommandSender: Completed send of AppObserver command");
return CHIP_NO_ERROR;
}
void ContentAppClientCommandSender::OnDeviceConnectionFailureFn(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR err)
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::OnDeviceConnectedFn error err %s", ErrorStr(err));
ContentAppClientCommandSender * sender = reinterpret_cast<ContentAppClientCommandSender *>(context);
VerifyOrReturn(sender != nullptr, ChipLogError(chipTool, "OnDeviceConnectionFailureFn: context is null"));
sender->Cleanup();
}
void ContentAppClientCommandSender::Cleanup()
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::Cleanup");
mIsBusy = false;
}
void ContentAppClientCommandSender::OnCommandResponse(void * context, const ContentAppMessageResponseDecodableType & response)
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::OnCommandResponse");
}
void ContentAppClientCommandSender::OnCommandFailure(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "ContentAppClientCommandSender::OnCommandFailure error err %s", ErrorStr(error));
}
} // namespace AppPlatform
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED