Matter SDK Coverage Report
Current view: top level - app - AttributeAccessInterface.h (source / functions) Coverage Total Hit
Test: SHA:a3f00eecfccfb30133c3bcd3c5c7d0ea4a2c71a4 Lines: 82.4 % 17 14
Test Date: 2025-07-31 07:11:52 Functions: 66.7 % 12 8

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021-2022 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : #pragma once
      20              : 
      21              : #include <app/AttributeReportBuilder.h>
      22              : #include <app/AttributeValueDecoder.h>
      23              : #include <app/AttributeValueEncoder.h>
      24              : #include <app/data-model-provider/OperationTypes.h>
      25              : #include <lib/core/CHIPError.h>
      26              : 
      27              : /**
      28              :  * Callback class that clusters can implement in order to interpose custom
      29              :  * attribute-handling logic.  An AttributeAccessInterface instance is associated
      30              :  * with some specific cluster.  A single instance may be used for a specific
      31              :  * endpoint or for all endpoints.
      32              :  *
      33              :  * Instances of AttributeAccessInterface that are registered via
      34              :  * AttributeAccessInterfaceRegistry::Instance().Register will be consulted before taking the
      35              :  * normal attribute access codepath and can use that codepath as a fallback if desired.
      36              :  */
      37              : namespace chip {
      38              : namespace app {
      39              : 
      40              : class AttributeAccessInterface
      41              : {
      42              : public:
      43              :     /**
      44              :      * aEndpointId can be Missing to indicate that this object is meant to be
      45              :      * used with all endpoints.
      46              :      */
      47          139 :     AttributeAccessInterface(Optional<EndpointId> aEndpointId, ClusterId aClusterId) :
      48          139 :         mEndpointId(aEndpointId), mClusterId(aClusterId)
      49          139 :     {}
      50          139 :     virtual ~AttributeAccessInterface() {}
      51              : 
      52              :     /**
      53              :      * Callback for reading attributes.
      54              :      *
      55              :      * @param [in] aRequest indicates which exact data is being read along with attributes of how data is being read.
      56              :      * @param [in] aEncoder the AttributeValueEncoder to use for encoding the
      57              :      *             data.
      58              :      *
      59              :      * The implementation can do one of three things:
      60              :      *
      61              :      * 1) Return a failure.  This is treated as a failed read and the error is
      62              :      *    returned to the client, by converting it to a StatusIB.
      63              :      * 2) Return success and attempt to encode data using aEncoder.  The data is
      64              :      *    returned to the client.
      65              :      * 3) Return success and not attempt to encode any data using aEncoder.  In
      66              :      *    this case, Ember attribute access will happen for the read. This may
      67              :      *    involve reading from the attribute store or external attribute
      68              :      *    callbacks.
      69              :      */
      70         1762 :     virtual CHIP_ERROR Read(const DataModel::ReadAttributeRequest & aRequest, AttributeValueEncoder & aEncoder)
      71              :     {
      72         1762 :         return Read(aRequest.path, aEncoder);
      73              :     }
      74              : 
      75              :     /**
      76              :      * A simpler version of Read(const ReadAttributeRequest & request, AttributeValueEncoder & aEncoder)
      77              :      * which takes simply the path being read, for backwards compatibility.
      78              :      *
      79              :      * @param [in] aPath indicates which exact data is being read.
      80              :      */
      81              :     virtual CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) = 0;
      82              : 
      83              :     /**
      84              :      * Callback for writing attributes.
      85              :      *
      86              :      * @param [in] aPath indicates which exact data is being written.
      87              :      * @param [in] aDecoder the AttributeValueDecoder to use for decoding the
      88              :      *             data.
      89              :      *
      90              :      * The implementation can do one of three things:
      91              :      *
      92              :      * 1) Return a failure.  This is treated as a failed write and the error is
      93              :      *    sent to the client, by converting it to a StatusIB.
      94              :      * 2) Return success and attempt to decode from aDecoder.  This is
      95              :      *    treated as a successful write.
      96              :      * 3) Return success and not attempt to decode from aDecoder.  In
      97              :      *    this case, Ember attribute access will happen for the write. This may
      98              :      *    involve writing to the attribute store or external attribute
      99              :      *    callbacks.
     100              :      */
     101            0 :     virtual CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) { return CHIP_NO_ERROR; }
     102              : 
     103              :     /**
     104              :      * Indicates the start of a series of list operations. This function will be called before the first Write operation of a series
     105              :      * of consequence attribute data of the same attribute.
     106              :      *
     107              :      * 1) This function will be called if the client tries to set a nullable list attribute to null.
     108              :      * 2) This function will only be called once for a series of consequent attribute data (regardless the kind of list operation)
     109              :      * of the same attribute.
     110              :      *
     111              :      * @param [in] aPath indicates the path of the modified list.
     112              :      */
     113            0 :     virtual void OnListWriteBegin(const ConcreteAttributePath & aPath) {}
     114              : 
     115              :     /**
     116              :      * Indicates the end of a series of list operations. This function will be called after the last Write operation of a series
     117              :      * of consequence attribute data of the same attribute.
     118              :      *
     119              :      * 1) This function will be called if the client tries to set a nullable list attribute to null.
     120              :      * 2) This function will only be called once for a series of consequent attribute data (regardless the kind of list operation)
     121              :      * of the same attribute.
     122              :      * 3) When aWriteWasSuccessful is true, the data written must be consistent or the list is untouched.
     123              :      *
     124              :      * @param [in] aPath indicates the path of the modified list
     125              :      * @param [in] aWriteWasSuccessful indicates whether the delivered list is complete.
     126              :      *
     127              :      */
     128            0 :     virtual void OnListWriteEnd(const ConcreteAttributePath & aPath, bool aWriteWasSuccessful) {}
     129              : 
     130              :     /**
     131              :      * Mechanism for keeping track of a chain of AttributeAccessInterfaces.
     132              :      */
     133           22 :     void SetNext(AttributeAccessInterface * aNext) { mNext = aNext; }
     134           47 :     AttributeAccessInterface * GetNext() const { return mNext; }
     135              : 
     136              :     /**
     137              :      * Check whether a this AttributeAccessInterface is relevant for a
     138              :      * particular endpoint+cluster.  An AttributeAccessInterface will be used
     139              :      * for a read from a particular cluster only when this function returns
     140              :      * true.
     141              :      */
     142           34 :     bool Matches(EndpointId aEndpointId, ClusterId aClusterId) const
     143              :     {
     144           34 :         return (!mEndpointId.HasValue() || mEndpointId.Value() == aEndpointId) && mClusterId == aClusterId;
     145              :     }
     146              : 
     147              :     /**
     148              :      * Check whether an AttributeAccessInterface is relevant for a particular
     149              :      * specific endpoint.  This is used to clean up overrides registered for an
     150              :      * endpoint that becomes disabled.
     151              :      */
     152           29 :     bool MatchesEndpoint(EndpointId aEndpointId) const { return mEndpointId.HasValue() && mEndpointId.Value() == aEndpointId; }
     153              : 
     154              :     /**
     155              :      * Check whether another AttributeAccessInterface wants to handle the same set of
     156              :      * attributes as we do.
     157              :      */
     158           13 :     bool Matches(const AttributeAccessInterface & aOther) const
     159              :     {
     160           21 :         return mClusterId == aOther.mClusterId &&
     161           21 :             (!mEndpointId.HasValue() || !aOther.mEndpointId.HasValue() || mEndpointId.Value() == aOther.mEndpointId.Value());
     162              :     }
     163              : 
     164              : protected:
     165              :     Optional<EndpointId> GetEndpointId() { return mEndpointId; }
     166              : 
     167              : private:
     168              :     Optional<EndpointId> mEndpointId;
     169              :     ClusterId mClusterId;
     170              :     AttributeAccessInterface * mNext = nullptr;
     171              : };
     172              : 
     173              : } // namespace app
     174              : } // namespace chip
        

Generated by: LCOV version 2.0-1