blob: 23e5e63237d2683b08a32f24aa36a983d1e3e501 [file] [log] [blame]
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* Defines an iterator for iterating all possible paths from a list of ClusterInfo-s according to spec section 8.9.2.2 (Valid
* Attribute Paths)
*/
#pragma once
#include <app/ClusterInfo.h>
#include <app/ConcreteAttributePath.h>
#include <app/EventManagement.h>
#include <app/InteractionModelDelegate.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPTLVDebug.hpp>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <system/SystemPacketBuffer.h>
namespace chip {
namespace app {
/**
* AttributePathExpandIterator is used to iterate over a linked list of ClusterInfo-s.
* The AttributePathExpandIterator is copiable, however, the given cluster info must be valid when calling Next().
*
* AttributePathExpandIterator will expand attribute paths with wildcards, and only emit existing paths for ClusterInfo with
* wildcards. For ClusterInfo with a concrete path (i.e. does not contain wildcards), AttributePathExpandIterator will emit them
* as-is.
*
* The typical use of AttributePathExpandIterator may look like:
* ConcreteAttributePath path;
* for (AttributePathExpandIterator iterator(clusterInfo); iterator.Get(path); iterator.Next()) {...}
*
* The iterator does not copy the given ClusterInfo, The given ClusterInfo must be valid when using the iterator.
* If the set of endpoints, clusters, or attributes that are supported changes, AttributePathExpandIterator must be reinitialized.
*
* A initialized iterator will return the first valid path, no need to call Next() before calling Get() for the first time.
*
* Note: The Next() and Get() are two separate operations by design since a possible call of this iterator might be:
* - Get()
* - Chunk full, return
* - In a new chunk, Get()
*
* TODO: The ClusterInfo may support a group id, the iterator should be able to call group data provider to expand the group id.
*/
class AttributePathExpandIterator
{
public:
AttributePathExpandIterator(ClusterInfo * aClusterInfo);
/**
* Proceed the iterator to the next attribute path in the given cluster info.
*
* Returns false if AttributePathExpandIterator has exhausted all paths in the given ClusterInfo list.
*/
bool Next();
/**
* Fills the aPath with the path the iterator currently points to.
* Returns false if the iterator is not pointing to a valid path (i.e. it has exhausted the cluster info).
*/
bool Get(ConcreteAttributePath & aPath)
{
aPath = mOutputPath;
return Valid();
}
/**
* Returns if the iterator is valid (not exhausted). An iterator is exhausted if and only if:
* - Next() is called after iterating last path.
* - Iterator is initialized with a null ClusterInfo.
*/
inline bool Valid() const { return mpClusterInfo != nullptr; }
private:
ClusterInfo * mpClusterInfo;
uint16_t mEndpointIndex, mEndEndpointIndex;
// Note: should use decltype(EmberAfEndpointType::clusterCount) here, but af-types is including app specific generated files.
uint8_t mClusterIndex, mEndClusterIndex;
uint16_t mAttributeIndex, mEndAttributeIndex;
ConcreteAttributePath mOutputPath;
/**
* Prepare*IndexRange will update mBegin*Index and mEnd*Index variables.
* If ClusterInfo contains a wildcard field, it will set mBegin*Index to 0 and mEnd*Index to count.
* Or it will set mBegin*Index to the index of the Endpoint/Cluster/Attribute, and mEnd*Index to mBegin*Index + 1.
*
* If the Endpoint/Cluster/Attribute does not exist, mBegin*Index will be UINT*_MAX, and mEnd*Inde will be 0.
*
* The index can be used with emberAfEndpointFromIndex, emberAfGetNthClusterId and emberAfGetServerAttributeIdByIndex.
*/
void PrepareEndpointIndexRange(const ClusterInfo & aClusterInfo);
void PrepareClusterIndexRange(const ClusterInfo & aClusterInfo, EndpointId aEndpointId);
void PrepareAttributeIndexRange(const ClusterInfo & aClusterInfo, EndpointId aEndpointId, ClusterId aClusterId);
};
} // namespace app
} // namespace chip