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 1188 : virtual CHIP_ERROR OnUpdateDataVersionFilterList(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder,
102 : const Span<AttributePathParams> & aAttributePaths,
103 : bool & aEncodedDataVersionList) override
104 : {
105 1188 : 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
|