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

Generated by: LCOV version 2.0-1