/* * Copyright (c) 2023 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 * This file defines a basic implementation of SubscriptionResumptionStorage that * persists subscriptions in a flat list in TLV. */ #pragma once #include #include #include #include namespace chip { namespace app { /** * An example SubscriptionResumptionStorage using PersistentStorageDelegate as it backend. */ class SimpleSubscriptionResumptionStorage : public SubscriptionResumptionStorage { public: static constexpr size_t kIteratorsMax = CHIP_CONFIG_MAX_SUBSCRIPTION_RESUMPTION_STORAGE_CONCURRENT_ITERATORS; CHIP_ERROR Init(PersistentStorageDelegate * storage); SubscriptionInfoIterator * IterateSubscriptions() override; CHIP_ERROR Save(SubscriptionInfo & subscriptionInfo) override; CHIP_ERROR Delete(NodeId nodeId, FabricIndex fabricIndex, SubscriptionId subscriptionId) override; CHIP_ERROR DeleteAll(FabricIndex fabricIndex) override; protected: CHIP_ERROR Save(TLV::TLVWriter & writer, SubscriptionInfo & subscriptionInfo); CHIP_ERROR Load(uint16_t subscriptionIndex, SubscriptionInfo & subscriptionInfo); CHIP_ERROR Delete(uint16_t subscriptionIndex); uint16_t Count(); CHIP_ERROR DeleteMaxCount(); class SimpleSubscriptionInfoIterator : public SubscriptionInfoIterator { public: SimpleSubscriptionInfoIterator(SimpleSubscriptionResumptionStorage & storage); size_t Count() override; bool Next(SubscriptionInfo & output) override; void Release() override; private: SimpleSubscriptionResumptionStorage & mStorage; uint16_t mNextIndex; }; static constexpr size_t MaxScopedNodeIdSize() { return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex)); } static constexpr size_t MaxSubscriptionPathsSize() { // IM engine declares an attribute path pool and an event path pool, and each pool // includes CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS for subscriptions return 2 * TLV::EstimateStructOverhead( TLV::EstimateStructOverhead(sizeof(uint8_t), sizeof(EndpointId), sizeof(ClusterId), sizeof(AttributeId)) * CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS); } static constexpr size_t MaxSubscriptionSize() { // All the fields added together return TLV::EstimateStructOverhead(MaxScopedNodeIdSize(), sizeof(SubscriptionId), sizeof(uint16_t), sizeof(uint16_t), sizeof(bool), MaxSubscriptionPathsSize()); } enum class EventPathType : uint8_t { kUrgent = 0x1, kNonUrgent = 0x2, }; // Flat list of subscriptions indexed from from 0 to CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS-1 // // Each entry in list is a Subscription TLV structure: // Structure of: (Subscription info) // Node ID // Fabric Index // Subscription ID // Min interval // Max interval // Fabric filtered boolean // List of: // Structure of: (Attribute path) // Endpoint ID // Cluster ID // Attribute ID // List of: // Structure of: (Event path) // Event subscription type (urgent / non-urgent) // Endpoint ID // Cluster ID // Event ID static constexpr TLV::Tag kPeerNodeIdTag = TLV::ContextTag(1); static constexpr TLV::Tag kFabricIndexTag = TLV::ContextTag(2); static constexpr TLV::Tag kSubscriptionIdTag = TLV::ContextTag(3); static constexpr TLV::Tag kMinIntervalTag = TLV::ContextTag(4); static constexpr TLV::Tag kMaxIntervalTag = TLV::ContextTag(5); static constexpr TLV::Tag kFabricFilteredTag = TLV::ContextTag(6); static constexpr TLV::Tag kAttributePathsListTag = TLV::ContextTag(7); static constexpr TLV::Tag kEventPathsListTag = TLV::ContextTag(8); static constexpr TLV::Tag kAttributePathTag = TLV::ContextTag(9); static constexpr TLV::Tag kEventPathTag = TLV::ContextTag(10); static constexpr TLV::Tag kEndpointIdTag = TLV::ContextTag(11); static constexpr TLV::Tag kClusterIdTag = TLV::ContextTag(12); static constexpr TLV::Tag kAttributeIdTag = TLV::ContextTag(13); static constexpr TLV::Tag kEventIdTag = TLV::ContextTag(14); static constexpr TLV::Tag kEventPathTypeTag = TLV::ContextTag(16); static constexpr TLV::Tag kResumptionRetriesTag = TLV::ContextTag(17); PersistentStorageDelegate * mStorage; ObjectPool mSubscriptionInfoIterators; }; } // namespace app } // namespace chip