Matter SDK Coverage Report
Current view: top level - data-model-providers/codegen - ClusterIntegration.cpp (source / functions) Coverage Total Hit
Test: SHA:3108862db59e5fa02f4a254cea1d5089c60155eb Lines: 0.0 % 45 0
Test Date: 2025-10-12 07:08:15 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2025 Project CHIP Authors
       3              :  *    All rights reserved.
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : #include <data-model-providers/codegen/ClusterIntegration.h>
      18              : 
      19              : #include <app/util/attribute-storage-null-handling.h>
      20              : #include <app/util/attribute-storage.h>
      21              : #include <app/util/attribute-table.h>
      22              : #include <app/util/endpoint-config-api.h>
      23              : #include <data-model-providers/codegen/CodegenDataModelProvider.h>
      24              : #include <data-model-providers/codegen/CodegenProcessingConfig.h>
      25              : 
      26              : #include <limits>
      27              : 
      28              : namespace chip::app {
      29              : 
      30              : namespace {
      31              : 
      32            0 : bool FindEndpointWithLog(EndpointId endpointId, ClusterId clusterId, uint16_t fixedClusterInstanceCount,
      33              :                          uint16_t maxClusterInstanceCount, uint16_t & clusterInstanceIndex)
      34              : {
      35            0 :     clusterInstanceIndex = emberAfGetClusterServerEndpointIndex(endpointId, clusterId, fixedClusterInstanceCount);
      36              : 
      37            0 :     if (clusterInstanceIndex >= maxClusterInstanceCount)
      38              :     {
      39              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      40            0 :         ChipLogError(AppServer,
      41              :                      "Could not find a valid endpoint index for endpoint %u/" ChipLogFormatMEI " (Index %u was not valid)",
      42              :                      endpointId, ChipLogValueMEI(clusterId), clusterInstanceIndex);
      43              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      44            0 :         return false;
      45              :     }
      46            0 :     return true;
      47              : }
      48              : 
      49              : /// Fetch the featuremap from ember for the given endpoint/cluster
      50              : ///
      51              : /// on error 0 is returned
      52            0 : uint32_t LoadFeatureMap(EndpointId endpointId, ClusterId clusterId)
      53              : {
      54              :     using Traits = NumericAttributeTraits<uint32_t>;
      55              :     Traits::StorageType temp;
      56            0 :     uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
      57              :     Protocols::InteractionModel::Status status =
      58            0 :         emberAfReadAttribute(endpointId, clusterId, Clusters::Globals::Attributes::FeatureMap::Id, readable, sizeof(temp));
      59            0 :     if (status != Protocols::InteractionModel::Status::Success)
      60              :     {
      61              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      62            0 :         ChipLogError(AppServer, "Failed to load feature map for %u/" ChipLogFormatMEI " (Status %d)", endpointId,
      63              :                      ChipLogValueMEI(clusterId), static_cast<int>(status));
      64              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      65            0 :         return 0;
      66              :     }
      67              :     // note: we do not try to check if value is representable: all the uint32_t values are representable
      68            0 :     return Traits::StorageToWorking(temp);
      69              : }
      70              : 
      71              : } // namespace
      72              : 
      73            0 : void CodegenClusterIntegration::RegisterServer(const RegisterServerOptions & options, Delegate & delegate)
      74              : {
      75              :     uint16_t clusterInstanceIndex;
      76            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
      77            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
      78              :     {
      79            0 :         return;
      80              :     }
      81              : 
      82            0 :     uint32_t featureMap = 0;
      83            0 :     if (options.fetchFeatureMap)
      84              :     {
      85            0 :         featureMap = LoadFeatureMap(options.endpointId, options.clusterId);
      86              :     }
      87              : 
      88              :     // NOTE: we fetch low ID attributes only here as a convenience/speedup for the very frequent cluster case
      89              :     //       where attributes are few and with low IDS.
      90              :     //
      91              :     // This is NOT a general rule. Specific examples are:
      92              :     //   - LevelControl::StartupCurrentLevel has ID 0x4000
      93              :     //   - OnOff has several: GlobalSceneControl, OnTime, OffWaitTime, StartupOnOff with id >= 0x4000
      94              :     //   - Thermostat and DoorLock have more than 32 attributes in general
      95              :     //   - ColorControl has a lot of high-ID attributes
      96              :     //
      97              :     // The above examples however are few compared to the large number of clusters that Matter supports,
      98              :     // so this optimization is considered worth it at this time.
      99            0 :     uint32_t optionalAttributes = 0;
     100            0 :     if (options.fetchOptionalAttributes)
     101              :     {
     102            0 :         for (AttributeId attributeId = 0; attributeId < std::numeric_limits<uint32_t>::digits; attributeId++)
     103              :         {
     104            0 :             if (emberAfContainsAttribute(options.endpointId, options.clusterId, attributeId))
     105              :             {
     106            0 :                 optionalAttributes |= 1u << attributeId;
     107              :             }
     108              :         }
     109              :     }
     110              : 
     111            0 :     CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Register(
     112            0 :         delegate.CreateRegistration(options.endpointId, clusterInstanceIndex, optionalAttributes, featureMap));
     113              : 
     114            0 :     if (err != CHIP_NO_ERROR)
     115              :     {
     116              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     117            0 :         ChipLogError(AppServer, "Failed to register cluster %u/" ChipLogFormatMEI ":   %" CHIP_ERROR_FORMAT, options.endpointId,
     118              :                      ChipLogValueMEI(options.clusterId), err.Format());
     119              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     120              :     }
     121              : }
     122              : 
     123            0 : void CodegenClusterIntegration::UnregisterServer(const UnregisterServerOptions & options, Delegate & delegate)
     124              : {
     125              :     uint16_t clusterInstanceIndex;
     126            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
     127            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
     128              :     {
     129            0 :         return;
     130              :     }
     131              : 
     132            0 :     CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Unregister(delegate.FindRegistration(clusterInstanceIndex));
     133            0 :     if (err != CHIP_NO_ERROR)
     134              :     {
     135              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     136            0 :         ChipLogError(AppServer, "Failed to unregister cluster %u/" ChipLogFormatMEI ":   %" CHIP_ERROR_FORMAT, options.endpointId,
     137              :                      ChipLogValueMEI(options.clusterId), err.Format());
     138              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     139              :        // NOTE: There is no sane way to handle this failure:
     140              :        //   - Returning here means we never free resources and a future registration will fail.
     141              :        //   - Not returning (as we do now) will free resources, but it is unclear why unregistration failed (is it still in use?).
     142              :        //
     143              :        // For now, assume that unregistration failed due to "already missing", so it is safe to delete.
     144              :        // However, this should never happen in practice.
     145              :     }
     146              : 
     147            0 :     delegate.ReleaseRegistration(clusterInstanceIndex);
     148              : }
     149              : 
     150            0 : ServerClusterInterface * CodegenClusterIntegration::FindClusterOnEndpoint(const FindClusterOnEndpointOptions & options,
     151              :                                                                           Delegate & delegate)
     152              : {
     153              :     uint16_t clusterInstanceIndex;
     154            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
     155            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
     156              :     {
     157            0 :         return nullptr;
     158              :     }
     159              : 
     160            0 :     ServerClusterInterface * interface = delegate.FindRegistration(clusterInstanceIndex);
     161              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     162            0 :     if (interface == nullptr)
     163              :     {
     164            0 :         ChipLogError(AppServer,
     165              :                      "No endpoint interface available on %u/" ChipLogFormatMEI ". Code may try to use an uninitialized cluster",
     166              :                      options.endpointId, ChipLogValueMEI(options.clusterId));
     167              :     }
     168              : #endif
     169              : 
     170            0 :     return interface;
     171              : }
     172              : 
     173              : } // namespace chip::app
        

Generated by: LCOV version 2.0-1