blob: 544dbb8509e8f6fb321cae5faa843c9d3597365a [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 Implementation of the ContentApp and the ContentAppPlatform.
*/
#include "AppImpl.h"
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/CommandHandler.h>
#include <app/server/Dnssd.h>
#include <app/server/Server.h>
#include <app/util/af.h>
#include <cstdio>
#include <inttypes.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/DataModelTypes.h>
#include <lib/shell/Commands.h>
#include <lib/shell/Engine.h>
#include <lib/shell/commands/Help.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 <zap-generated/CHIPClusters.h>
using namespace chip;
using namespace chip::AppPlatform;
using namespace chip::app::Clusters;
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
class MyUserPrompter : public UserPrompter
{
// tv should override this with a dialog prompt
inline void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override
{
return;
}
// tv should override this with a dialog prompt
inline void PromptForCommissionPincode(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override
{
return;
}
// tv should override this with a dialog prompt
inline void PromptCommissioningSucceeded(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override
{
return;
}
// tv should override this with a dialog prompt
inline void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) override { return; }
};
MyUserPrompter gMyUserPrompter;
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
class MyPincodeService : public PincodeService
{
uint32_t FetchCommissionPincodeFromContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId) override
{
return ContentAppPlatform::GetInstance().GetPincodeFromContentApp(vendorId, productId, rotatingId);
}
};
MyPincodeService gMyPincodeService;
class MyPostCommissioningListener : public PostCommissioningListener
{
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle) override
{
// read current binding list
chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
CHIP_ERROR err =
cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err));
clearContext();
}
}
/* Callback when command results in success */
static void
OnReadSuccessResponse(void * context,
const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseData)
{
ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully");
MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->finishTargetConfiguration(responseData);
}
/* Callback when command results in failure */
static void OnReadFailureResponse(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed");
MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
listener->clearContext();
CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->PostCommissioningFailed(error);
}
}
/* Callback when command results in success */
static void OnSuccessResponse(void * context)
{
ChipLogProgress(Controller, "OnSuccessResponse - Binding Add Successfully");
CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->PostCommissioningSucceeded();
}
}
/* Callback when command results in failure */
static void OnFailureResponse(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "OnFailureResponse - Binding Add Failed");
CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->PostCommissioningFailed(error);
}
}
void
finishTargetConfiguration(const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseList)
{
std::vector<app::Clusters::Binding::Structs::TargetStruct::Type> bindings;
NodeId localNodeId = GetDeviceCommissioner()->GetNodeId();
auto iter = responseList.begin();
while (iter.Next())
{
auto & binding = iter.GetValue();
ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId));
if (binding.node.ValueOr(0) != localNodeId)
{
ChipLogProgress(Controller, "Found a binding for a different node, preserving");
bindings.push_back(binding);
}
else
{
ChipLogProgress(Controller, "Found a binding for a matching node, dropping");
}
}
Optional<SessionHandle> opt = mSecureSession.Get();
SessionHandle & sessionHandle = opt.Value();
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId,
bindings, OnSuccessResponse, OnFailureResponse);
clearContext();
}
void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
SessionHandle & sessionHandle)
{
mVendorId = vendorId;
mProductId = productId;
mNodeId = nodeId;
mExchangeMgr = &exchangeMgr;
mSecureSession.ShiftToSession(sessionHandle);
}
void clearContext()
{
mVendorId = 0;
mProductId = 0;
mNodeId = 0;
mExchangeMgr = nullptr;
mSecureSession.SessionReleased();
}
uint16_t mVendorId = 0;
uint16_t mProductId = 0;
NodeId mNodeId = 0;
Messaging::ExchangeManager * mExchangeMgr = nullptr;
SessionHolder mSecureSession;
};
MyPostCommissioningListener gMyPostCommissioningListener;
ContentAppFactoryImpl gFactory;
ContentAppFactoryImpl * GetContentAppFactoryImpl()
{
return &gFactory;
}
namespace chip {
namespace AppPlatform {
// BEGIN DYNAMIC ENDPOINTS
// =================================================================================
static const int kNameSize = 32;
// Current ZCL implementation of Struct uses a max-size array of 254 bytes
static const int kDescriptorAttributeArraySize = 254;
// Device types for dynamic endpoints: TODO Need a generated file from ZAP to define these!
// (taken from chip-devices.xml)
#define DEVICE_TYPE_CONTENT_APP 0x0024
// ---------------------------------------------------------------------------
//
// CONTENT APP ENDPOINT: contains the following clusters:
// - Descriptor
// - Application Basic
// - Keypad Input
// - Application Launcher
// - Account Login
// - Content Launcher
// - Target Navigator
// - Channel
// Declare Descriptor cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_DEVICE_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_SERVER_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CLIENT_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_PARTS_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Application Basic information cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationBasicAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_VENDOR_NAME_ATTRIBUTE_ID, CHAR_STRING, kNameSize, 0), /* VendorName */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_VENDOR_ID_ATTRIBUTE_ID, INT16U, 1, 0), /* VendorID */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_NAME_ATTRIBUTE_ID, CHAR_STRING, kNameSize, 0), /* ApplicationName */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_PRODUCT_ID_ATTRIBUTE_ID, INT16U, 1, 0), /* ProductID */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_STATUS_ATTRIBUTE_ID, INT8U, 1, 0), /* ApplicationStatus */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_VERSION_ATTRIBUTE_ID, CHAR_STRING, kNameSize, 0), /* ApplicationVersion */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_ALLOWED_VENDOR_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize,
0), /* AllowedVendorList */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Keypad Input cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(keypadInputAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, BITMAP32, 4, 0), /* FeatureMap */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Application Launcher cluster attributes
// NOTE: Does not make sense for content app to be able to set the AP feature flag
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationLauncherAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_LAUNCHER_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* catalog list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_APPLICATION_LAUNCHER_CURRENT_APP_ATTRIBUTE_ID, STRUCT, 1, 0), /* current app */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Account Login cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(accountLoginAttrs)
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Content Launcher cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(contentLauncherAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CONTENT_LAUNCHER_ACCEPT_HEADER_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize,
0), /* accept header list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CONTENT_LAUNCHER_SUPPORTED_STREAMING_PROTOCOLS_ATTRIBUTE_ID, BITMAP32, 1,
0), /* streaming protocols */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, BITMAP32, 4, 0), /* FeatureMap */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Media Playback cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(mediaPlaybackAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_STATE_ATTRIBUTE_ID, ENUM8, 1, 0), /* current state */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_START_TIME_ATTRIBUTE_ID, EPOCH_US, 1, 0), /* start time */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_DURATION_ATTRIBUTE_ID, INT64U, 1, 0), /* duration */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_POSITION_ATTRIBUTE_ID, STRUCT, 1, 0), /* playback speed */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SPEED_ATTRIBUTE_ID, SINGLE, 1, 0), /* playback speed */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SEEK_RANGE_END_ATTRIBUTE_ID, INT64U, 1, 0), /* seek range end */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_MEDIA_PLAYBACK_PLAYBACK_SEEK_RANGE_START_ATTRIBUTE_ID, INT64U, 1, 0), /* seek range start */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, BITMAP32, 4, 0), /* FeatureMap */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Target Navigator cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(targetNavigatorAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_TARGET_NAVIGATOR_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* target list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_TARGET_NAVIGATOR_CURRENT_TARGET_ATTRIBUTE_ID, INT8U, 1, 0), /* current target */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
// Declare Channel cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(channelAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_LIST_ATTRIBUTE_ID, ARRAY, kDescriptorAttributeArraySize, 0), /* channel list */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_LINEUP_ATTRIBUTE_ID, STRUCT, 1, 0), /* lineup */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_CHANNEL_CURRENT_CHANNEL_ATTRIBUTE_ID, STRUCT, 1, 0), /* current channel */
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_FEATURE_MAP_SERVER_ATTRIBUTE_ID, BITMAP32, 4, 0), /* FeatureMap */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
constexpr CommandId keypadInputIncomingCommands[] = {
app::Clusters::KeypadInput::Commands::SendKey::Id,
kInvalidCommandId,
};
constexpr CommandId keypadInputOutgoingCommands[] = {
app::Clusters::KeypadInput::Commands::SendKeyResponse::Id,
kInvalidCommandId,
};
constexpr CommandId applicationLauncherIncomingCommands[] = {
app::Clusters::ApplicationLauncher::Commands::LaunchApp::Id,
app::Clusters::ApplicationLauncher::Commands::StopApp::Id,
app::Clusters::ApplicationLauncher::Commands::HideApp::Id,
kInvalidCommandId,
};
constexpr CommandId applicationLauncherOutgoingCommands[] = {
app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Id,
kInvalidCommandId,
};
constexpr CommandId accountLoginIncomingCommands[] = {
app::Clusters::AccountLogin::Commands::GetSetupPIN::Id,
app::Clusters::AccountLogin::Commands::Login::Id,
app::Clusters::AccountLogin::Commands::Logout::Id,
kInvalidCommandId,
};
constexpr CommandId accountLoginOutgoingCommands[] = {
app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Id,
kInvalidCommandId,
};
// TODO: Sort out when the optional commands here should be listed.
constexpr CommandId contentLauncherIncomingCommands[] = {
app::Clusters::ContentLauncher::Commands::LaunchContent::Id,
app::Clusters::ContentLauncher::Commands::LaunchURL::Id,
kInvalidCommandId,
};
constexpr CommandId contentLauncherOutgoingCommands[] = {
app::Clusters::ContentLauncher::Commands::LaunchResponse::Id,
kInvalidCommandId,
};
// TODO: Sort out when the optional commands here should be listed.
constexpr CommandId mediaPlaybackIncomingCommands[] = {
app::Clusters::MediaPlayback::Commands::Play::Id, app::Clusters::MediaPlayback::Commands::Pause::Id,
app::Clusters::MediaPlayback::Commands::StopPlayback::Id, app::Clusters::MediaPlayback::Commands::StartOver::Id,
app::Clusters::MediaPlayback::Commands::Previous::Id, app::Clusters::MediaPlayback::Commands::Next::Id,
app::Clusters::MediaPlayback::Commands::Rewind::Id, app::Clusters::MediaPlayback::Commands::FastForward::Id,
app::Clusters::MediaPlayback::Commands::SkipForward::Id, app::Clusters::MediaPlayback::Commands::SkipBackward::Id,
app::Clusters::MediaPlayback::Commands::Seek::Id, kInvalidCommandId,
};
constexpr CommandId mediaPlaybackOutgoingCommands[] = {
app::Clusters::MediaPlayback::Commands::PlaybackResponse::Id,
kInvalidCommandId,
};
constexpr CommandId targetNavigatorIncomingCommands[] = {
app::Clusters::TargetNavigator::Commands::NavigateTarget::Id,
kInvalidCommandId,
};
constexpr CommandId targetNavigatorOutgoingCommands[] = {
app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Id,
kInvalidCommandId,
};
// TODO: Sort out when the optional commands here should be listed.
constexpr CommandId channelIncomingCommands[] = {
app::Clusters::Channel::Commands::ChangeChannel::Id,
app::Clusters::Channel::Commands::ChangeChannelByNumber::Id,
app::Clusters::Channel::Commands::SkipChannel::Id,
kInvalidCommandId,
};
constexpr CommandId channelOutgoingCommands[] = {
app::Clusters::Channel::Commands::ChangeChannelResponse::Id,
kInvalidCommandId,
};
// Declare Cluster List for Content App endpoint
DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(contentAppClusters)
DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_BASIC_CLUSTER_ID, applicationBasicAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_KEYPAD_INPUT_CLUSTER_ID, keypadInputAttrs, keypadInputIncomingCommands,
keypadInputOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_APPLICATION_LAUNCHER_CLUSTER_ID, applicationLauncherAttrs, applicationLauncherIncomingCommands,
applicationLauncherOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_ACCOUNT_LOGIN_CLUSTER_ID, accountLoginAttrs, accountLoginIncomingCommands,
accountLoginOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_CONTENT_LAUNCHER_CLUSTER_ID, contentLauncherAttrs, contentLauncherIncomingCommands,
contentLauncherOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_MEDIA_PLAYBACK_CLUSTER_ID, mediaPlaybackAttrs, mediaPlaybackIncomingCommands,
mediaPlaybackOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_TARGET_NAVIGATOR_CLUSTER_ID, targetNavigatorAttrs, targetNavigatorIncomingCommands,
targetNavigatorOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER(ZCL_CHANNEL_CLUSTER_ID, channelAttrs, channelIncomingCommands, channelOutgoingCommands),
DECLARE_DYNAMIC_CLUSTER_LIST_END;
// Declare Content App endpoint
DECLARE_DYNAMIC_ENDPOINT(contentAppEndpoint, contentAppClusters);
namespace {
DataVersion gDataVersions[APP_LIBRARY_SIZE][ArraySize(contentAppClusters)];
EmberAfDeviceType gContentAppDeviceType[] = { { DEVICE_TYPE_CONTENT_APP, 1 } };
} // anonymous namespace
ContentAppFactoryImpl::ContentAppFactoryImpl() {}
uint16_t ContentAppFactoryImpl::GetPlatformCatalogVendorId()
{
return kCatalogVendorId;
}
CHIP_ERROR ContentAppFactoryImpl::LookupCatalogVendorApp(uint16_t vendorId, uint16_t productId, CatalogVendorApp * destinationApp)
{
std::string appId = BuildAppId(vendorId);
destinationApp->catalogVendorId = GetPlatformCatalogVendorId();
Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), appId.c_str());
return CHIP_NO_ERROR;
}
CHIP_ERROR ContentAppFactoryImpl::ConvertToPlatformCatalogVendorApp(const CatalogVendorApp & sourceApp,
CatalogVendorApp * destinationApp)
{
destinationApp->catalogVendorId = GetPlatformCatalogVendorId();
std::string appId(sourceApp.applicationId);
if (appId == "applicationId")
{
// regression test case passes "applicationId", map this to our test suite app
Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "1111");
}
else if (appId == "exampleid")
{
// cert test case passes "exampleid", map this to our test suite app
Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "1");
}
else if (appId == "exampleString")
{
// cert test case passes "exampleString", map this to our test suite app
Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "65521");
}
else
{
// for now, just return the applicationId passed in
Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), sourceApp.applicationId);
}
return CHIP_NO_ERROR;
}
ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vendorApp)
{
ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: LoadContentAppByAppId catalogVendorId=%d applicationId=%s ",
vendorApp.catalogVendorId, vendorApp.applicationId);
for (size_t i = 0; i < ArraySize(mContentApps); ++i)
{
auto & app = mContentApps[i];
ChipLogProgress(DeviceLayer, " Looking next=%s ", app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->applicationId);
if (app.GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp))
{
ContentAppPlatform::GetInstance().AddContentApp(&app, &contentAppEndpoint, Span<DataVersion>(gDataVersions[i]),
Span<const EmberAfDeviceType>(gContentAppDeviceType));
return &app;
}
}
ChipLogProgress(DeviceLayer, "LoadContentAppByAppId NOT FOUND catalogVendorId=%d applicationId=%s ", vendorApp.catalogVendorId,
vendorApp.applicationId);
return nullptr;
}
void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId)
{
mAdminVendorIds.push_back(vendorId);
}
Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
{
for (size_t i = 0; i < mAdminVendorIds.size(); ++i)
{
auto & vendor = mAdminVendorIds.at(i);
if (vendorId == vendor)
{
return Access::Privilege::kAdminister;
}
}
return Access::Privilege::kOperate;
}
std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId,
uint16_t productId)
{
if (endpointId == kLocalVideoPlayerEndpointId)
{
return { chip::app::Clusters::Descriptor::Id, chip::app::Clusters::OnOff::Id,
chip::app::Clusters::WakeOnLan::Id, chip::app::Clusters::MediaPlayback::Id,
chip::app::Clusters::LowPower::Id, chip::app::Clusters::KeypadInput::Id,
chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::AudioOutput::Id };
}
return {};
}
} // namespace AppPlatform
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
CHIP_ERROR InitVideoPlayerPlatform()
{
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
ContentAppPlatform::GetInstance().SetupAppPlatform();
ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory);
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
if (cdc != nullptr)
{
cdc->SetPincodeService(&gMyPincodeService);
cdc->SetUserPrompter(&gMyUserPrompter);
cdc->SetPostCommissioningListener(&gMyPostCommissioningListener);
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
return CHIP_NO_ERROR;
}