Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2021 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 : /** 20 : * @file 21 : * Defines an iterator for iterating all possible paths from a list of AttributePathParams-s according to spec section 8.9.2.2 22 : * (Valid Attribute Paths) 23 : */ 24 : 25 : #pragma once 26 : 27 : #include <app/AttributePathParams.h> 28 : #include <app/ConcreteAttributePath.h> 29 : #include <app/EventManagement.h> 30 : #include <lib/core/CHIPCore.h> 31 : #include <lib/core/TLVDebug.h> 32 : #include <lib/support/CodeUtils.h> 33 : #include <lib/support/DLLUtil.h> 34 : #include <lib/support/logging/CHIPLogging.h> 35 : #include <messaging/ExchangeContext.h> 36 : #include <messaging/ExchangeMgr.h> 37 : #include <messaging/Flags.h> 38 : #include <protocols/Protocols.h> 39 : #include <system/SystemPacketBuffer.h> 40 : 41 : namespace chip { 42 : namespace app { 43 : 44 : /** 45 : * AttributePathExpandIterator is used to iterate over a linked list of AttributePathParams-s. 46 : * The AttributePathExpandIterator is copiable, however, the given cluster info must be valid when calling Next(). 47 : * 48 : * AttributePathExpandIterator will expand attribute paths with wildcards, and only emit existing paths for AttributePathParams with 49 : * wildcards. For AttributePathParams with a concrete path (i.e. does not contain wildcards), AttributePathExpandIterator will emit 50 : * them as-is. 51 : * 52 : * The typical use of AttributePathExpandIterator may look like: 53 : * ConcreteAttributePath path; 54 : * for (AttributePathExpandIterator iterator(AttributePathParams); iterator.Get(path); iterator.Next()) {...} 55 : * 56 : * The iterator does not copy the given AttributePathParams, The given AttributePathParams must be valid when using the iterator. 57 : * If the set of endpoints, clusters, or attributes that are supported changes, AttributePathExpandIterator must be reinitialized. 58 : * 59 : * A initialized iterator will return the first valid path, no need to call Next() before calling Get() for the first time. 60 : * 61 : * Note: The Next() and Get() are two separate operations by design since a possible call of this iterator might be: 62 : * - Get() 63 : * - Chunk full, return 64 : * - In a new chunk, Get() 65 : * 66 : * TODO: The AttributePathParams may support a group id, the iterator should be able to call group data provider to expand the group 67 : * id. 68 : */ 69 : class AttributePathExpandIterator 70 : { 71 : public: 72 : AttributePathExpandIterator(ObjectList<AttributePathParams> * aAttributePath); 73 : 74 : /** 75 : * Proceed the iterator to the next attribute path in the given cluster info. 76 : * 77 : * Returns false if AttributePathExpandIterator has exhausted all paths in the given AttributePathParams list. 78 : */ 79 : bool Next(); 80 : 81 : /** 82 : * Fills the aPath with the path the iterator currently points to. 83 : * Returns false if the iterator is not pointing to a valid path (i.e. it has exhausted the cluster info). 84 : */ 85 5953 : bool Get(ConcreteAttributePath & aPath) 86 : { 87 5953 : aPath = mOutputPath; 88 5953 : return Valid(); 89 : } 90 : 91 : /** 92 : * Reset the iterator to the beginning of current cluster if we are in the middle of expanding a wildcard attribute id for some 93 : * cluster. 94 : * 95 : * When attributes are changed in the middle of expanding a wildcard attribute, we need to reset the iterator, to provide the 96 : * client with a consistent state of the cluster. 97 : */ 98 : void ResetCurrentCluster(); 99 : 100 : /** 101 : * Returns if the iterator is valid (not exhausted). An iterator is exhausted if and only if: 102 : * - Next() is called after iterating last path. 103 : * - Iterator is initialized with a null AttributePathParams. 104 : */ 105 5953 : inline bool Valid() const { return mpAttributePath != nullptr; } 106 : 107 : private: 108 : ObjectList<AttributePathParams> * mpAttributePath; 109 : 110 : ConcreteAttributePath mOutputPath; 111 : 112 : uint16_t mEndpointIndex, mEndEndpointIndex; 113 : uint16_t mAttributeIndex, mEndAttributeIndex; 114 : 115 : // Note: should use decltype(EmberAfEndpointType::clusterCount) here, but af-types is including app specific generated files. 116 : uint8_t mClusterIndex, mEndClusterIndex; 117 : // For dealing with global attributes that are not part of the attribute 118 : // metadata. 119 : uint8_t mGlobalAttributeIndex, mGlobalAttributeEndIndex; 120 : 121 : /** 122 : * Prepare*IndexRange will update mBegin*Index and mEnd*Index variables. 123 : * If AttributePathParams contains a wildcard field, it will set mBegin*Index to 0 and mEnd*Index to count. 124 : * Or it will set mBegin*Index to the index of the Endpoint/Cluster/Attribute, and mEnd*Index to mBegin*Index + 1. 125 : * 126 : * If the Endpoint/Cluster/Attribute does not exist, mBegin*Index will be UINT*_MAX, and mEnd*Inde will be 0. 127 : * 128 : * The index can be used with emberAfEndpointFromIndex, emberAfGetNthClusterId and emberAfGetServerAttributeIdByIndex. 129 : */ 130 : void PrepareEndpointIndexRange(const AttributePathParams & aAttributePath); 131 : void PrepareClusterIndexRange(const AttributePathParams & aAttributePath, EndpointId aEndpointId); 132 : void PrepareAttributeIndexRange(const AttributePathParams & aAttributePath, EndpointId aEndpointId, ClusterId aClusterId); 133 : }; 134 : } // namespace app 135 : } // namespace chip