/* * * Copyright (c) 2021 Project CHIP Authors * Copyright (c) 2013-2017 Nest Labs, Inc. * * 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 contains an implementation of TLVBackingStore using PacketBuffers. */ #include #include namespace chip { namespace System { CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen) { bufStart = mHeadBuffer->Start(); VerifyOrReturnError(CanCastTo(mHeadBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT); bufLen = static_cast(mHeadBuffer->DataLength()); return CHIP_NO_ERROR; } CHIP_ERROR TLVPacketBufferBackingStore::GetNextBuffer(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen) { if (mUseChainedBuffers) { mCurrentBuffer.Advance(); } else { mCurrentBuffer = nullptr; } if (mCurrentBuffer.IsNull()) { bufStart = nullptr; bufLen = 0; } else { bufStart = mCurrentBuffer->Start(); VerifyOrReturnError(CanCastTo(mCurrentBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT); bufLen = static_cast(mCurrentBuffer->DataLength()); } return CHIP_NO_ERROR; } CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) { bufStart = mHeadBuffer->Start() + mHeadBuffer->DataLength(); VerifyOrReturnError(CanCastTo(mHeadBuffer->AvailableDataLength()), CHIP_ERROR_INVALID_ARGUMENT); bufLen = static_cast(mHeadBuffer->AvailableDataLength()); return CHIP_NO_ERROR; } CHIP_ERROR TLVPacketBufferBackingStore::FinalizeBuffer(chip::TLV::TLVWriter & writer, uint8_t * bufStart, uint32_t dataLen) { uint8_t * endPtr = bufStart + dataLen; intptr_t length = endPtr - mCurrentBuffer->Start(); if (!CanCastTo(length)) { return CHIP_ERROR_INVALID_ARGUMENT; } mCurrentBuffer->SetDataLength(static_cast(length), mHeadBuffer); return CHIP_NO_ERROR; } CHIP_ERROR TLVPacketBufferBackingStore::GetNewBuffer(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) { if (!mUseChainedBuffers) { return CHIP_ERROR_NO_MEMORY; } mCurrentBuffer.Advance(); if (mCurrentBuffer.IsNull()) { mCurrentBuffer = PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (mCurrentBuffer.IsNull()) { return CHIP_ERROR_NO_MEMORY; } mHeadBuffer->AddToEnd(mCurrentBuffer.Retain()); } if (mCurrentBuffer.IsNull()) { bufStart = nullptr; bufLen = 0; } else { bufStart = mCurrentBuffer->Start(); VerifyOrReturnError(CanCastTo(mCurrentBuffer->MaxDataLength()), CHIP_ERROR_INVALID_ARGUMENT); bufLen = static_cast(mCurrentBuffer->MaxDataLength()); } return CHIP_NO_ERROR; } } // namespace System } // namespace chip