blob: 4c61cf11a3a97da974379ff01fc0dff3c372f25e [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
* @brief Routines for the Application Basic plugin, the
*server implementation of the Application Basic cluster.
*******************************************************************************
******************************************************************************/
#include <app/clusters/application-basic-server/application-basic-delegate.h>
#include <app/clusters/application-basic-server/application-basic-server.h>
#include <app/AttributeAccessInterface.h>
#include <app/data-model/Encode.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <platform/CHIPDeviceConfig.h>
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
#include <app/app-platform/ContentAppPlatform.h>
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
#include <list>
using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::ApplicationBasic;
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
using namespace chip::AppPlatform;
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
static constexpr size_t kApplicationBasicDelegateTableSize =
EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
static_assert(kApplicationBasicDelegateTableSize <= kEmberInvalidEndpointIndex, "ApplicationBasic Delegate table size error");
// -----------------------------------------------------------------------------
// Delegate Implementation
using chip::app::Clusters::ApplicationBasic::Delegate;
namespace {
Delegate * gDelegateTable[kApplicationBasicDelegateTableSize] = { nullptr };
Delegate * GetDelegate(EndpointId endpoint)
{
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint);
if (app != nullptr)
{
ChipLogProgress(Zcl, "ApplicationBasic returning ContentApp delegate for endpoint:%u", endpoint);
return app->GetApplicationBasicDelegate();
}
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
ChipLogProgress(Zcl, "ApplicationBasic NOT returning ContentApp delegate for endpoint:%u", endpoint);
uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, chip::app::Clusters::ApplicationBasic::Id,
EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT);
return (ep >= kApplicationBasicDelegateTableSize ? nullptr : gDelegateTable[ep]);
}
bool isDelegateNull(Delegate * delegate, EndpointId endpoint)
{
if (delegate == nullptr)
{
ChipLogProgress(Zcl, "Application Basic has no delegate set for endpoint:%u", endpoint);
return true;
}
return false;
}
} // namespace
namespace chip {
namespace app {
namespace Clusters {
namespace ApplicationBasic {
void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
{
uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, ApplicationBasic::Id,
EMBER_AF_APPLICATION_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT);
// if endpoint is found
if (ep < kApplicationBasicDelegateTableSize)
{
gDelegateTable[ep] = delegate;
}
else
{
}
}
Delegate * GetDefaultDelegate(EndpointId endpoint)
{
return GetDelegate(endpoint);
}
CHIP_ERROR Delegate::HandleGetApplication(app::AttributeValueEncoder & aEncoder)
{
ApplicationBasicApplicationType application;
application.catalogVendorID = mCatalogVendorApp.catalogVendorId;
application.applicationID = CharSpan(mCatalogVendorApp.applicationId, strlen(mCatalogVendorApp.applicationId));
return aEncoder.Encode(application);
}
bool Delegate::Matches(const ApplicationBasicApplicationType & match)
{
std::string appId(match.applicationID.data(), match.applicationID.size());
CatalogVendorApp matchApp(match.catalogVendorID, appId.c_str());
return mCatalogVendorApp.Matches(&matchApp);
}
} // namespace ApplicationBasic
} // namespace Clusters
} // namespace app
} // namespace chip
// -----------------------------------------------------------------------------
// Attribute Accessor Implementation
namespace {
class ApplicationBasicAttrAccess : public app::AttributeAccessInterface
{
public:
ApplicationBasicAttrAccess() : app::AttributeAccessInterface(Optional<EndpointId>::Missing(), ApplicationBasic::Id) {}
CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override;
private:
CHIP_ERROR ReadVendorNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadVendorIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadApplicationNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadProductIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadApplicationAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadStatusAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadApplicationVersionAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
CHIP_ERROR ReadAllowedVendorListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
};
ApplicationBasicAttrAccess gApplicationBasicAttrAccess;
CHIP_ERROR ApplicationBasicAttrAccess::Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder)
{
EndpointId endpoint = aPath.mEndpointId;
Delegate * delegate = GetDelegate(endpoint);
if (isDelegateNull(delegate, endpoint))
{
if (aPath.mAttributeId == Attributes::AllowedVendorList::Id)
{
return aEncoder.EncodeEmptyList();
}
return CHIP_NO_ERROR;
}
switch (aPath.mAttributeId)
{
case chip::app::Clusters::ApplicationBasic::Attributes::VendorName::Id: {
return ReadVendorNameAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::VendorID::Id: {
return ReadVendorIdAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationName::Id: {
return ReadApplicationNameAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::ProductID::Id: {
return ReadProductIdAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::Application::Id: {
return ReadApplicationAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::Status::Id: {
return ReadStatusAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::Id: {
return ReadApplicationVersionAttribute(aEncoder, delegate);
}
case chip::app::Clusters::ApplicationBasic::Attributes::AllowedVendorList::Id: {
return ReadAllowedVendorListAttribute(aEncoder, delegate);
}
default: {
break;
}
}
return CHIP_NO_ERROR;
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadVendorNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
return delegate->HandleGetVendorName(aEncoder);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadVendorIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
uint16_t vendorId = delegate->HandleGetVendorId();
return aEncoder.Encode(vendorId);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationNameAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
return delegate->HandleGetApplicationName(aEncoder);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadProductIdAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
uint16_t vendorId = delegate->HandleGetProductId();
return aEncoder.Encode(vendorId);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
return delegate->HandleGetApplication(aEncoder);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadStatusAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
ApplicationStatusEnum status = delegate->HandleGetStatus();
return aEncoder.Encode(status);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationVersionAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
return delegate->HandleGetApplicationVersion(aEncoder);
}
CHIP_ERROR ApplicationBasicAttrAccess::ReadAllowedVendorListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
return delegate->HandleGetAllowedVendorList(aEncoder);
}
} // anonymous namespace
// -----------------------------------------------------------------------------
// Plugin initialization
void MatterApplicationBasicPluginServerInitCallback()
{
registerAttributeAccessOverride(&gApplicationBasicAttrAccess);
}