blob: f177d8358b67ba8e74e9894777aba4f499df3e9d [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.
*/
#pragma once
#include "lib/core/CHIPTLV.h"
#include "system/SystemPacketBuffer.h"
#include "system/TLVPacketBufferBackingStore.h"
#include <app/AttributePathParams.h>
#include <app/ReadClient.h>
#include <vector>
namespace chip {
namespace app {
/*
* This is an adapter that intercepts calls that deliver data from the ReadClient,
* selectively buffers up list chunks in TLV and reconstitutes them into a singular, contiguous TLV array
* upon completion of delivery of all chunks. This is then delivered to a compliant ReadClient::Callback
* without any awareness on their part that chunking happened.
*
*/
class BufferedReadCallback : public ReadClient::Callback
{
public:
BufferedReadCallback(Callback & callback) : mCallback(callback) {}
private:
/*
* Generates the reconsistuted TLV array from the stored individual list elements
*/
CHIP_ERROR GenerateListTLV(TLV::ScopedBufferTLVReader & reader);
/*
* Dispatch any buffered list data if we need to. Buffered data will only be dispatched if:
* 1. The path provided in aPath is different from the buffered path being tracked internally AND the type of data
* in the buffer is list data
*
* OR
*
* 2. The path provided in aPath is similar to what is buffered but we've hit the end of the report.
*
*/
CHIP_ERROR DispatchBufferedData(const ReadClient * apReadClient, const ConcreteAttributePath & aPath, const StatusIB & aStatus,
bool aEndOfReport = false);
/*
* Buffer up list data as they arrive.
*/
CHIP_ERROR BufferData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apReader);
private:
//
// ReadClient::Callback
//
void OnReportBegin(const ReadClient * apReadClient) override;
void OnReportEnd(const ReadClient * apReadClient) override;
void OnAttributeData(const ReadClient * apReadClient, const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData,
const StatusIB & aStatus) override;
void OnError(const ReadClient * apReadClient, CHIP_ERROR aError) override { return mCallback.OnError(apReadClient, aError); }
void OnEventData(const ReadClient * apReadClient, const EventHeader & aEventHeader, TLV::TLVReader * apData,
const StatusIB * apStatus) override
{
return mCallback.OnEventData(apReadClient, aEventHeader, apData, apStatus);
}
void OnDone(ReadClient * apReadClient) override { return mCallback.OnDone(apReadClient); }
void OnSubscriptionEstablished(const ReadClient * apReadClient) override { mCallback.OnSubscriptionEstablished(apReadClient); }
private:
/*
* Given a reader positioned at a list element, allocate a packet buffer, copy the list item where
* the reader is positioned into that buffer and add it to our buffered list for tracking.
*
* This should be called in list index order starting from the lowest index that needs to be buffered.
*
*/
CHIP_ERROR BufferListItem(TLV::TLVReader & reader);
ConcreteDataAttributePath mBufferedPath;
std::vector<System::PacketBufferHandle> mBufferedList;
Callback & mCallback;
};
} // namespace app
} // namespace chip