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 : #pragma once 20 : 21 : #include "lib/core/TLV.h" 22 : #include "system/SystemPacketBuffer.h" 23 : #include "system/TLVPacketBufferBackingStore.h" 24 : #include <app/AppConfig.h> 25 : #include <app/AttributePathParams.h> 26 : #include <app/ReadClient.h> 27 : #include <vector> 28 : 29 : #if CHIP_CONFIG_ENABLE_READ_CLIENT 30 : namespace chip { 31 : namespace app { 32 : 33 : /* 34 : * This is an adapter that intercepts calls that deliver data from the ReadClient, 35 : * selectively buffers up list chunks in TLV and reconstitutes them into a singular, contiguous TLV array 36 : * upon completion of delivery of all chunks. This is then delivered to a compliant ReadClient::Callback 37 : * without any awareness on their part that chunking happened. 38 : * 39 : */ 40 : class BufferedReadCallback : public ReadClient::Callback 41 : { 42 : public: 43 0 : BufferedReadCallback(Callback & callback) : mCallback(callback) {} 44 : 45 : private: 46 : /* 47 : * Generates the reconsistuted TLV array from the stored individual list elements 48 : */ 49 : CHIP_ERROR GenerateListTLV(TLV::ScopedBufferTLVReader & reader); 50 : 51 : /* 52 : * Dispatch any buffered list data if we need to. Buffered data will only be dispatched if: 53 : * 1. The path provided in aPath is different from the buffered path being tracked internally AND the type of data 54 : * in the buffer is list data 55 : * 56 : * OR 57 : * 58 : * 2. The path provided in aPath is similar to what is buffered but we've hit the end of the report. 59 : * 60 : */ 61 : CHIP_ERROR DispatchBufferedData(const ConcreteAttributePath & aPath, const StatusIB & aStatus, bool aEndOfReport = false); 62 : 63 : /* 64 : * Buffer up list data as they arrive. 65 : */ 66 : CHIP_ERROR BufferData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apReader); 67 : 68 : // 69 : // ReadClient::Callback 70 : // 71 : void OnReportBegin() override; 72 : void OnReportEnd() override; 73 : void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override; 74 33 : void OnError(CHIP_ERROR aError) override 75 : { 76 33 : mBufferedList.clear(); 77 33 : return mCallback.OnError(aError); 78 : } 79 : 80 1532 : void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) override 81 : { 82 1532 : return mCallback.OnEventData(aEventHeader, apData, apStatus); 83 : } 84 : 85 757 : void OnDone(ReadClient * apReadClient) override { return mCallback.OnDone(apReadClient); } 86 142 : void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override 87 : { 88 142 : mCallback.OnSubscriptionEstablished(aSubscriptionId); 89 142 : } 90 : 91 6 : CHIP_ERROR OnResubscriptionNeeded(ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override 92 : { 93 6 : return mCallback.OnResubscriptionNeeded(apReadClient, aTerminationCause); 94 : } 95 : 96 143 : void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override 97 : { 98 143 : return mCallback.OnDeallocatePaths(std::move(aReadPrepareParams)); 99 : } 100 : 101 1123 : virtual CHIP_ERROR OnUpdateDataVersionFilterList(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, 102 : const Span<AttributePathParams> & aAttributePaths, 103 : bool & aEncodedDataVersionList) override 104 : { 105 1123 : return mCallback.OnUpdateDataVersionFilterList(aDataVersionFilterIBsBuilder, aAttributePaths, aEncodedDataVersionList); 106 : } 107 : 108 4 : virtual CHIP_ERROR GetHighestReceivedEventNumber(Optional<EventNumber> & aEventNumber) override 109 : { 110 4 : return mCallback.GetHighestReceivedEventNumber(aEventNumber); 111 : } 112 : 113 9 : void OnUnsolicitedMessageFromPublisher(ReadClient * apReadClient) override 114 : { 115 9 : return mCallback.OnUnsolicitedMessageFromPublisher(apReadClient); 116 : } 117 : 118 0 : void OnCASESessionEstablished(const SessionHandle & aSession, ReadPrepareParams & aSubscriptionParams) override 119 : { 120 0 : return mCallback.OnCASESessionEstablished(aSession, aSubscriptionParams); 121 : } 122 : 123 : /* 124 : * Given a reader positioned at a list element, allocate a packet buffer, copy the list item where 125 : * the reader is positioned into that buffer and add it to our buffered list for tracking. 126 : * 127 : * This should be called in list index order starting from the lowest index that needs to be buffered. 128 : * 129 : */ 130 : CHIP_ERROR BufferListItem(TLV::TLVReader & reader); 131 : ConcreteDataAttributePath mBufferedPath; 132 : std::vector<System::PacketBufferHandle> mBufferedList; 133 : Callback & mCallback; 134 : }; 135 : 136 : } // namespace app 137 : } // namespace chip 138 : #endif // CHIP_CONFIG_ENABLE_READ_CLIENT