Matter SDK Coverage Report
Current view: top level - data-model-providers/codegen - ClusterIntegration.cpp (source / functions) Coverage Total Hit
Test: SHA:2a48c1efeab1c0f76f3adb3a0940b0f7de706453 Lines: 0.0 % 52 0
Test Date: 2026-01-31 08:14:20 Functions: 0.0 % 6 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.h>
      20              : #include <app/util/attribute-table.h>
      21              : #include <app/util/endpoint-config-api.h>
      22              : #include <data-model-providers/codegen/CodegenDataModelProvider.h>
      23              : #include <data-model-providers/codegen/CodegenProcessingConfig.h>
      24              : 
      25              : #include <limits>
      26              : 
      27              : namespace chip::app {
      28              : 
      29              : namespace {
      30              : 
      31            0 : bool FindEndpointWithLog(EndpointId endpointId, ClusterId clusterId, uint16_t fixedClusterInstanceCount,
      32              :                          uint16_t maxClusterInstanceCount, uint16_t & clusterInstanceIndex)
      33              : {
      34            0 :     clusterInstanceIndex = emberAfGetClusterServerEndpointIndex(endpointId, clusterId, fixedClusterInstanceCount);
      35              : 
      36            0 :     if (clusterInstanceIndex >= maxClusterInstanceCount)
      37              :     {
      38              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      39            0 :         ChipLogError(AppServer,
      40              :                      "Could not find a valid endpoint index for endpoint %u/" ChipLogFormatMEI " (Index %u was not valid)",
      41              :                      endpointId, ChipLogValueMEI(clusterId), clusterInstanceIndex);
      42              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      43            0 :         return false;
      44              :     }
      45            0 :     return true;
      46              : }
      47              : 
      48              : /// Fetch the featuremap from ember for the given endpoint/cluster
      49              : ///
      50              : /// on error 0 is returned
      51            0 : uint32_t LoadFeatureMap(EndpointId endpointId, ClusterId clusterId)
      52              : {
      53              :     using Traits = NumericAttributeTraits<uint32_t>;
      54              :     Traits::StorageType temp;
      55            0 :     uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
      56              :     Protocols::InteractionModel::Status status =
      57            0 :         emberAfReadAttribute(endpointId, clusterId, Clusters::Globals::Attributes::FeatureMap::Id, readable, sizeof(temp));
      58            0 :     if (status != Protocols::InteractionModel::Status::Success)
      59              :     {
      60              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      61            0 :         ChipLogError(AppServer, "Failed to load feature map for %u/" ChipLogFormatMEI " (Status %d)", endpointId,
      62              :                      ChipLogValueMEI(clusterId), static_cast<int>(status));
      63              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
      64            0 :         return 0;
      65              :     }
      66              :     // note: we do not try to check if value is representable: all the uint32_t values are representable
      67            0 :     return Traits::StorageToWorking(temp);
      68              : }
      69              : 
      70            0 : ClusterShutdownType ToServerClusterInterfaceShutdown(MatterClusterShutdownType t)
      71              : {
      72            0 :     switch (t)
      73              :     {
      74            0 :     case MatterClusterShutdownType::kPermanentRemove:
      75            0 :         return ClusterShutdownType::kPermanentRemove;
      76            0 :     case MatterClusterShutdownType::kClusterShutdown:
      77            0 :         return ClusterShutdownType::kClusterShutdown;
      78              :     }
      79              :     // we are handling all cases above, but compiler does not seem to detect this...
      80            0 :     return ClusterShutdownType::kClusterShutdown;
      81              : }
      82              : 
      83              : } // namespace
      84              : 
      85            0 : void CodegenClusterIntegration::RegisterServer(const RegisterServerOptions & options, Delegate & delegate)
      86              : {
      87              :     uint16_t clusterInstanceIndex;
      88            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
      89            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
      90              :     {
      91            0 :         return;
      92              :     }
      93              : 
      94            0 :     uint32_t featureMap = 0;
      95            0 :     if (options.fetchFeatureMap)
      96              :     {
      97            0 :         featureMap = LoadFeatureMap(options.endpointId, options.clusterId);
      98              :     }
      99              : 
     100              :     // NOTE: we fetch low ID attributes only here as a convenience/speedup for the very frequent cluster case
     101              :     //       where attributes are few and with low IDS.
     102              :     //
     103              :     // This is NOT a general rule. Specific examples are:
     104              :     //   - LevelControl::StartupCurrentLevel has ID 0x4000
     105              :     //   - OnOff has several: GlobalSceneControl, OnTime, OffWaitTime, StartupOnOff with id >= 0x4000
     106              :     //   - Thermostat and DoorLock have more than 32 attributes in general
     107              :     //   - ColorControl has a lot of high-ID attributes
     108              :     //
     109              :     // The above examples however are few compared to the large number of clusters that Matter supports,
     110              :     // so this optimization is considered worth it at this time.
     111            0 :     uint32_t optionalAttributes = 0;
     112            0 :     if (options.fetchOptionalAttributes)
     113              :     {
     114            0 :         for (AttributeId attributeId = 0; attributeId < std::numeric_limits<uint32_t>::digits; attributeId++)
     115              :         {
     116            0 :             if (emberAfContainsAttribute(options.endpointId, options.clusterId, attributeId))
     117              :             {
     118            0 :                 optionalAttributes |= 1u << attributeId;
     119              :             }
     120              :         }
     121              :     }
     122              : 
     123            0 :     CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Register(
     124            0 :         delegate.CreateRegistration(options.endpointId, clusterInstanceIndex, optionalAttributes, featureMap));
     125              : 
     126            0 :     if (err != CHIP_NO_ERROR)
     127              :     {
     128              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     129            0 :         ChipLogError(AppServer, "Failed to register cluster %u/" ChipLogFormatMEI ":   %" CHIP_ERROR_FORMAT, options.endpointId,
     130              :                      ChipLogValueMEI(options.clusterId), err.Format());
     131              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     132              :     }
     133              : }
     134              : 
     135            0 : void CodegenClusterIntegration::UnregisterServer(const UnregisterServerOptions & options, Delegate & delegate,
     136              :                                                  MatterClusterShutdownType shutdownType)
     137              : {
     138              :     uint16_t clusterInstanceIndex;
     139            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
     140            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
     141              :     {
     142            0 :         return;
     143              :     }
     144              : 
     145            0 :     CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Unregister(delegate.FindRegistration(clusterInstanceIndex),
     146              :                                                                                 ToServerClusterInterfaceShutdown(shutdownType));
     147            0 :     if (err != CHIP_NO_ERROR)
     148              :     {
     149              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     150            0 :         ChipLogError(AppServer, "Failed to unregister cluster %u/" ChipLogFormatMEI ":   %" CHIP_ERROR_FORMAT, options.endpointId,
     151              :                      ChipLogValueMEI(options.clusterId), err.Format());
     152              : #endif // CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     153              :        // NOTE: There is no sane way to handle this failure:
     154              :        //   - Returning here means we never free resources and a future registration will fail.
     155              :        //   - Not returning (as we do now) will free resources, but it is unclear why unregistration failed (is it still in use?).
     156              :        //
     157              :        // For now, assume that unregistration failed due to "already missing", so it is safe to delete.
     158              :        // However, this should never happen in practice.
     159              :     }
     160              : 
     161            0 :     delegate.ReleaseRegistration(clusterInstanceIndex);
     162              : }
     163              : 
     164            0 : ServerClusterInterface * CodegenClusterIntegration::FindClusterOnEndpoint(const FindClusterOnEndpointOptions & options,
     165              :                                                                           Delegate & delegate)
     166              : {
     167              :     uint16_t clusterInstanceIndex;
     168            0 :     if (!FindEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterInstanceCount,
     169            0 :                              options.maxClusterInstanceCount, clusterInstanceIndex))
     170              :     {
     171            0 :         return nullptr;
     172              :     }
     173              : 
     174            0 :     ServerClusterInterface * interface = delegate.FindRegistration(clusterInstanceIndex);
     175              : #if CHIP_CODEGEN_CONFIG_ENABLE_CODEGEN_INTEGRATION_LOOKUP_ERRORS
     176            0 :     if (interface == nullptr)
     177              :     {
     178            0 :         ChipLogError(AppServer,
     179              :                      "No endpoint interface available on %u/" ChipLogFormatMEI ". Code may try to use an uninitialized cluster",
     180              :                      options.endpointId, ChipLogValueMEI(options.clusterId));
     181              :     }
     182              : #endif
     183              : 
     184            0 :     return interface;
     185              : }
     186              : 
     187              : } // namespace chip::app
        

Generated by: LCOV version 2.0-1