| /** |
| * |
| * 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/AttributeAccessInterfaceRegistry.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> |
| #include <string> |
| |
| 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 = |
| MATTER_DM_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, |
| MATTER_DM_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, |
| MATTER_DM_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() |
| { |
| app::AttributeAccessInterfaceRegistry::Instance().Register(&gApplicationBasicAttrAccess); |
| } |