Matter SDK Coverage Report
Current view: top level - data-model-providers/codegen - ClusterIntegration.cpp (source / functions) Coverage Total Hit
Test: SHA:7c9b1260e3daa86aae0d41b894469b295eee70e8 Lines: 0.0 % 37 0
Test Date: 2025-09-07 07:12:04 Functions: 0.0 % 4 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 fixedClusterServerEndpointCount,
      33              :                          uint16_t maxEndpointCount, uint16_t & emberEndpointIndex)
      34              : {
      35            0 :     emberEndpointIndex = emberAfGetClusterServerEndpointIndex(endpointId, clusterId, fixedClusterServerEndpointCount);
      36              : 
      37            0 :     if (emberEndpointIndex >= maxEndpointCount)
      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), emberEndpointIndex);
      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 emberEndpointIndex;
      76            0 :     if (!findEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterServerEndpointCount,
      77            0 :                              options.maxEndpointCount, emberEndpointIndex))
      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, emberEndpointIndex, 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 emberEndpointIndex;
     126            0 :     if (!findEndpointWithLog(options.endpointId, options.clusterId, options.fixedClusterServerEndpointCount,
     127            0 :                              options.maxEndpointCount, emberEndpointIndex))
     128              :     {
     129            0 :         return;
     130              :     }
     131              : 
     132            0 :     CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Unregister(&delegate.FindRegistration(emberEndpointIndex));
     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(emberEndpointIndex);
     148              : }
     149              : 
     150              : } // namespace chip::app
        

Generated by: LCOV version 2.0-1