blob: 1acc685f117cac934227c00925ba993263001033 [file] [log] [blame]
/*
*
* Copyright (c) 2022 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 "CastingServer.h"
using namespace chip;
using namespace chip::Controller;
using namespace chip::Credentials;
using namespace chip::app::Clusters::ContentLauncher::Commands;
CastingServer * CastingServer::castingServer_ = nullptr;
CastingServer::CastingServer()
{
#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
// generate and set a random uniqueId for generating rotatingId
uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
for (size_t i = 0; i < sizeof(rotatingDeviceIdUniqueId); i++)
{
rotatingDeviceIdUniqueId[i] = chip::Crypto::GetRandU8();
}
ByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan);
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
}
CastingServer * CastingServer::GetInstance()
{
if (castingServer_ == nullptr)
{
castingServer_ = new CastingServer();
}
return castingServer_;
}
void CastingServer::Init()
{
if (mInited)
{
return;
}
// Initialize binding handlers
ReturnOnFailure(InitBindingHandlers());
// Add callback to send Content casting commands after commissioning completes
ReturnOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0));
mInited = true;
}
CHIP_ERROR CastingServer::InitBindingHandlers()
{
auto & server = chip::Server::GetInstance();
chip::BindingManager::GetInstance().Init(
{ &server.GetFabricTable(), server.GetCASESessionManager(), &server.GetPersistentStorage() });
return CHIP_NO_ERROR;
}
CHIP_ERROR CastingServer::TargetVideoPlayerInfoInit(NodeId nodeId, FabricIndex fabricIndex)
{
Init();
return mTargetVideoPlayerInfo.Initialize(nodeId, fabricIndex);
}
CHIP_ERROR CastingServer::DiscoverCommissioners()
{
// Send discover commissioners request
return mCommissionableNodeController.DiscoverCommissioners(
Dnssd::DiscoveryFilter(Dnssd::DiscoveryFilterType::kDeviceType, static_cast<uint16_t>(35)));
}
CHIP_ERROR CastingServer::OpenBasicCommissioningWindow(std::function<void(CHIP_ERROR)> commissioningCompleteCallback)
{
mCommissioningCompleteCallback = commissioningCompleteCallback;
return Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(kCommissioningWindowTimeout);
}
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
CHIP_ERROR CastingServer::SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner)
{
return Server::GetInstance().SendUserDirectedCommissioningRequest(commissioner);
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
const Dnssd::DiscoveredNodeData * CastingServer::GetDiscoveredCommissioner(int index)
{
return mCommissionableNodeController.GetDiscoveredCommissioner(index);
}
void CastingServer::ReadServerClustersForNode(NodeId nodeId)
{
ChipLogProgress(NotSpecified, "ReadServerClustersForNode nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId));
for (const auto & binding : BindingTable::GetInstance())
{
ChipLogProgress(NotSpecified,
"Binding type=%d fab=%d nodeId=0x" ChipLogFormatX64
" groupId=%d local endpoint=%d remote endpoint=%d cluster=" ChipLogFormatMEI,
binding.type, binding.fabricIndex, ChipLogValueX64(binding.nodeId), binding.groupId, binding.local,
binding.remote, ChipLogValueMEI(binding.clusterId.ValueOr(0)));
if (binding.type == EMBER_UNICAST_BINDING && nodeId == binding.nodeId)
{
if (!mTargetVideoPlayerInfo.HasEndpoint(binding.remote))
{
ReadServerClusters(binding.remote);
}
else
{
TargetEndpointInfo * endpointInfo = mTargetVideoPlayerInfo.GetEndpoint(binding.remote);
if (endpointInfo != nullptr && endpointInfo->IsInitialized())
{
endpointInfo->PrintInfo();
}
}
}
}
}
void CastingServer::ReadServerClusters(EndpointId endpointId)
{
const OperationalDeviceProxy * deviceProxy = mTargetVideoPlayerInfo.GetOperationalDeviceProxy();
if (deviceProxy == nullptr)
{
ChipLogError(AppServer, "Failed in getting an instance of DeviceProxy");
return;
}
// GetOperationalDeviceProxy only passes us a deviceProxy if we can get a SessionHandle.
chip::Controller::DescriptorCluster cluster(*deviceProxy->GetExchangeManager(), deviceProxy->GetSecureSession().Value(),
endpointId);
TargetEndpointInfo * endpointInfo = mTargetVideoPlayerInfo.GetOrAddEndpoint(endpointId);
if (cluster.ReadAttribute<app::Clusters::Descriptor::Attributes::ServerList::TypeInfo>(
endpointInfo, CastingServer::OnDescriptorReadSuccessResponse, CastingServer::OnDescriptorReadFailureResponse) !=
CHIP_NO_ERROR)
{
ChipLogError(Controller, "Could not read Descriptor cluster ServerList");
}
ChipLogProgress(Controller, "Sent descriptor read for remote endpoint=%d", endpointId);
}
void CastingServer::OnDescriptorReadSuccessResponse(void * context, const app::DataModel::DecodableList<ClusterId> & responseList)
{
TargetEndpointInfo * endpointInfo = static_cast<TargetEndpointInfo *>(context);
ChipLogProgress(AppServer, "Descriptor: Default Success Response endpoint=%d", endpointInfo->GetEndpointId());
auto iter = responseList.begin();
while (iter.Next())
{
auto & clusterId = iter.GetValue();
endpointInfo->AddCluster(clusterId);
}
// Always print the target info after handling descriptor read response
// Even when we get nothing back for any reasons
CastingServer::GetInstance()->mTargetVideoPlayerInfo.PrintInfo();
}
void CastingServer::OnDescriptorReadFailureResponse(void * context, CHIP_ERROR error)
{
ChipLogError(AppServer, "Descriptor: Default Failure Response: %" CHIP_ERROR_FORMAT, error.Format());
}
[[deprecated("Use ContentLauncher_LaunchURL(..) instead")]] CHIP_ERROR
CastingServer::ContentLauncherLaunchURL(const char * contentUrl, const char * contentDisplayStr,
std::function<void(CHIP_ERROR)> launchURLResponseCallback)
{
return ContentLauncher_LaunchURL(contentUrl, contentDisplayStr,
MakeOptional(chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type()),
launchURLResponseCallback);
}
void CastingServer::DeviceEventCallback(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
if (event->Type == DeviceLayer::DeviceEventType::kBindingsChangedViaCluster)
{
if (CastingServer::GetInstance()->GetTargetVideoPlayerInfo()->IsInitialized())
{
CastingServer::GetInstance()->ReadServerClustersForNode(
CastingServer::GetInstance()->GetTargetVideoPlayerInfo()->GetNodeId());
}
}
else if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete)
{
CHIP_ERROR err = CastingServer::GetInstance()->GetTargetVideoPlayerInfo()->Initialize(
event->CommissioningComplete.nodeId, event->CommissioningComplete.fabricIndex);
CastingServer::GetInstance()->mCommissioningCompleteCallback(err);
}
}
// given a fabric index, try to determine the video-player nodeId by searching the binding table
NodeId CastingServer::GetVideoPlayerNodeForFabricIndex(FabricIndex fabricIndex)
{
for (const auto & binding : BindingTable::GetInstance())
{
ChipLogProgress(NotSpecified,
"Binding type=%d fab=%d nodeId=0x" ChipLogFormatX64
" groupId=%d local endpoint=%d remote endpoint=%d cluster=" ChipLogFormatMEI,
binding.type, binding.fabricIndex, ChipLogValueX64(binding.nodeId), binding.groupId, binding.local,
binding.remote, ChipLogValueMEI(binding.clusterId.ValueOr(0)));
if (binding.type == EMBER_UNICAST_BINDING && fabricIndex == binding.fabricIndex)
{
ChipLogProgress(NotSpecified, "GetVideoPlayerNodeForFabricIndex nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(binding.nodeId));
return binding.nodeId;
}
}
ChipLogProgress(NotSpecified, "GetVideoPlayerNodeForFabricIndex no bindings found for fabricIndex=%d", fabricIndex);
return kUndefinedNodeId;
}
// given a nodeId, try to determine the video-player fabric index by searching the binding table
FabricIndex CastingServer::GetVideoPlayerFabricIndexForNode(NodeId nodeId)
{
for (const auto & binding : BindingTable::GetInstance())
{
ChipLogProgress(NotSpecified,
"Binding type=%d fab=%d nodeId=0x" ChipLogFormatX64
" groupId=%d local endpoint=%d remote endpoint=%d cluster=" ChipLogFormatMEI,
binding.type, binding.fabricIndex, ChipLogValueX64(binding.nodeId), binding.groupId, binding.local,
binding.remote, ChipLogValueMEI(binding.clusterId.ValueOr(0)));
if (binding.type == EMBER_UNICAST_BINDING && nodeId == binding.nodeId)
{
ChipLogProgress(NotSpecified, "GetVideoPlayerFabricIndexForNode fabricIndex=%d nodeId=0x" ChipLogFormatX64,
binding.fabricIndex, ChipLogValueX64(binding.nodeId));
return binding.fabricIndex;
}
}
ChipLogProgress(NotSpecified, "GetVideoPlayerFabricIndexForNode no bindings found for nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(nodeId));
return kUndefinedFabricIndex;
}
void CastingServer::SetDefaultFabricIndex()
{
Init();
// set fabric to be the first in the list
for (const auto & fb : chip::Server::GetInstance().GetFabricTable())
{
FabricIndex fabricIndex = fb.GetFabricIndex();
ChipLogError(AppServer, "Next Fabric index=%d", fabricIndex);
if (!fb.IsInitialized())
{
ChipLogError(AppServer, " -- Not initialized");
continue;
}
NodeId myNodeId = fb.GetNodeId();
ChipLogProgress(NotSpecified,
"---- Current Fabric nodeId=0x" ChipLogFormatX64 " fabricId=0x" ChipLogFormatX64 " fabricIndex=%d",
ChipLogValueX64(myNodeId), ChipLogValueX64(fb.GetFabricId()), fabricIndex);
NodeId videoPlayerNodeId = GetVideoPlayerNodeForFabricIndex(fabricIndex);
if (videoPlayerNodeId == kUndefinedNodeId)
{
// could not determine video player nodeid for this fabric
continue;
}
mTargetVideoPlayerInfo.Initialize(videoPlayerNodeId, fabricIndex);
return;
}
ChipLogError(AppServer, " -- No initialized fabrics with video players");
}
/**
* @brief Content Launcher cluster
*/
CHIP_ERROR CastingServer::ContentLauncher_LaunchURL(
const char * contentUrl, const char * contentDisplayStr,
chip::Optional<chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type> brandingInformation,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mLaunchURLCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mLaunchURLCommand.Invoke(contentUrl, contentDisplayStr, brandingInformation, responseCallback);
}
CHIP_ERROR CastingServer::ContentLauncher_LaunchContent(chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type search,
bool autoPlay, chip::Optional<chip::CharSpan> data,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mLaunchContentCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mLaunchContentCommand.Invoke(search, autoPlay, data, responseCallback);
}
/**
* @brief Level Control cluster
*/
CHIP_ERROR CastingServer::LevelControl_Step(chip::app::Clusters::LevelControl::StepMode stepMode, uint8_t stepSize,
uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mStepCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
app::DataModel::Nullable<uint16_t> nullableTransitionTime;
nullableTransitionTime.SetNonNull(transitionTime);
return mStepCommand.Invoke(stepMode, stepSize, nullableTransitionTime, optionMask, optionOverride, responseCallback);
}
CHIP_ERROR CastingServer::LevelControl_MoveToLevel(uint8_t level, uint16_t transitionTime, uint8_t optionMask,
uint8_t optionOverride, std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mMoveToLevelCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
app::DataModel::Nullable<uint16_t> nullableTransitionTime;
nullableTransitionTime.SetNonNull(transitionTime);
return mMoveToLevelCommand.Invoke(level, nullableTransitionTime, optionMask, optionOverride, responseCallback);
}
CHIP_ERROR CastingServer::LevelControl_SubscribeToCurrentLevel(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mCurrentLevelSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mCurrentLevelSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::LevelControl_SubscribeToMinLevel(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mMinLevelSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mMinLevelSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::LevelControl_SubscribeToMaxLevel(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mMaxLevelSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mMaxLevelSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
/**
* @brief Media Playback cluster
*/
CHIP_ERROR CastingServer::MediaPlayback_Play(std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mPlayCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mPlayCommand.Invoke(responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_Pause(std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mPauseCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mPauseCommand.Invoke(responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_StopPlayback(std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mStopPlaybackCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mStopPlaybackCommand.Invoke(responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_Next(std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mNextCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mNextCommand.Invoke(responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_Seek(uint64_t position, std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mSeekCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSeekCommand.Invoke(position, responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_SkipForward(uint64_t deltaPositionMilliseconds,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mSkipForwardCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSkipForwardCommand.Invoke(deltaPositionMilliseconds, responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_SkipBackward(uint64_t deltaPositionMilliseconds,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mSkipBackwardCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSkipBackwardCommand.Invoke(deltaPositionMilliseconds, responseCallback);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToCurrentState(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mCurrentStateSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mCurrentStateSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToStartTime(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mStartTimeSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mStartTimeSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToDuration(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mDurationSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mDurationSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToSampledPosition(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType>
successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mSampledPositionSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSampledPositionSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToPlaybackSpeed(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType>
successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mPlaybackSpeedSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mPlaybackSpeedSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToSeekRangeEnd(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mSeekRangeEndSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSeekRangeEndSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::MediaPlayback_SubscribeToSeekRangeStart(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::MediaPlayback::Attributes::SeekRangeStart::TypeInfo::DecodableArgType>
successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mSeekRangeStartSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSeekRangeStartSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
/**
* @brief Application Launcher cluster
*/
CHIP_ERROR
CastingServer::ApplicationLauncher_LaunchApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
chip::Optional<chip::ByteSpan> data, std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mLaunchAppCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mLaunchAppCommand.Invoke(application, data, responseCallback);
}
CHIP_ERROR
CastingServer::ApplicationLauncher_StopApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mStopAppCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mStopAppCommand.Invoke(application, responseCallback);
}
CHIP_ERROR
CastingServer::ApplicationLauncher_HideApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mHideAppCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mHideAppCommand.Invoke(application, responseCallback);
}
CHIP_ERROR CastingServer::ApplicationLauncher_SubscribeToCurrentApp(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::ApplicationLauncher::Attributes::CurrentApp::TypeInfo::DecodableArgType>
successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mCurrentAppSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mCurrentAppSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
/**
* @brief Target Navigator cluster
*/
CHIP_ERROR CastingServer::TargetNavigator_NavigateTarget(const uint8_t target, const chip::Optional<chip::CharSpan> data,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mNavigateTargetCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mNavigateTargetCommand.Invoke(target, data, responseCallback);
}
CHIP_ERROR CastingServer::TargetNavigator_SubscribeToTargetList(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType> successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mTargetListSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mTargetListSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
CHIP_ERROR CastingServer::TargetNavigator_SubscribeToCurrentTarget(
void * context,
ReadResponseSuccessCallback<chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType>
successFn,
ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mCurrentTargetSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mCurrentTargetSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval,
onSubscriptionEstablished);
}
/**
* @brief Keypad Input cluster
*/
CHIP_ERROR CastingServer::KeypadInput_SendKey(const chip::app::Clusters::KeypadInput::CecKeyCode keyCode,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mSendKeyCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mSendKeyCommand.Invoke(keyCode, responseCallback);
}
/**
* @brief Channel cluster
*/
CHIP_ERROR CastingServer::Channel_ChangeChannelCommand(const chip::CharSpan & match,
std::function<void(CHIP_ERROR)> responseCallback)
{
ReturnErrorOnFailure(mChangeChannelCommand.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mChangeChannelCommand.Invoke(match, responseCallback);
}
CHIP_ERROR CastingServer::Channel_SubscribeToLineup(
void * context,
chip::Controller::ReadResponseSuccessCallback<chip::app::Clusters::Channel::Attributes::Lineup::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished)
{
ReturnErrorOnFailure(mLineupSubscriber.SetTarget(mTargetVideoPlayerInfo, kTvEndpoint));
return mLineupSubscriber.SubscribeAttribute(context, successFn, failureFn, minInterval, maxInterval, onSubscriptionEstablished);
}