/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2016-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 defines the member functions and private data for
 *      the chip::System::PacketBuffer class, which provides the
 *      mechanisms for manipulating packets of octet-serialized
 *      data.
 */

// Include standard C library limit macros
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>

// Include module header
#include <system/SystemPacketBuffer.h>

// Include common private header
#include "SystemLayerPrivate.h"

// Include local headers
#include <system/SystemMutex.h>
#include <system/SystemFaultInjection.h>

#include <string.h>
#include <stdlib.h>
#include <stddef.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/pbuf.h>
#include <lwip/mem.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#include <support/logging/CHIPLogging.h>
#include <support/CodeUtils.h>

#include <system/SystemStats.h>

namespace chip {
namespace System {

//
// Pool allocation for PacketBuffer objects (toll-free bridged with LwIP pbuf allocator if CHIP_SYSTEM_CONFIG_USE_LWIP)
//
#if !CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

static BufferPoolElement sBufferPool[CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC];

PacketBuffer * PacketBuffer::sFreeList = PacketBuffer::BuildFreeList();

#if !CHIP_SYSTEM_CONFIG_NO_LOCKING
static Mutex sBufferPoolMutex;

#define LOCK_BUF_POOL()                                                                                                            \
    do                                                                                                                             \
    {                                                                                                                              \
        sBufferPoolMutex.Lock();                                                                                                   \
    } while (0)
#define UNLOCK_BUF_POOL()                                                                                                          \
    do                                                                                                                             \
    {                                                                                                                              \
        sBufferPoolMutex.Unlock();                                                                                                 \
    } while (0)
#endif // !CHIP_SYSTEM_CONFIG_NO_LOCKING

#endif // CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

#ifndef LOCK_BUF_POOL
#define LOCK_BUF_POOL()                                                                                                            \
    do                                                                                                                             \
    {                                                                                                                              \
    } while (0)
#endif // !defined(LOCK_BUF_POOL)

#ifndef UNLOCK_BUF_POOL
#define UNLOCK_BUF_POOL()                                                                                                          \
    do                                                                                                                             \
    {                                                                                                                              \
    } while (0)
#endif // !defined(UNLOCK_BUF_POOL)

#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP

/**
 * Get pointer to start of data in buffer.
 *
 *  @return pointer to the start of data.
 */
uint8_t * PacketBuffer::Start() const
{
    return static_cast<uint8_t *>(this->payload);
}

/**
 *  Set the start data in buffer, adjusting length and total length accordingly.
 *
 *  @note The data within the buffer is not moved, only accounting information is changed.  The function is commonly used to either
 *  strip or prepend protocol headers in a zero-copy way.
 *
 *  @note This call should not be used on any buffer that is not the head of a buffer chain, as it only alters the current buffer.
 *
 *  @param[in] aNewStart - A pointer to where the new payload should start.  newStart will be adjusted internally to fall within
 *      the boundaries of the first buffer in the PacketBuffer chain.
 */
void PacketBuffer::SetStart(uint8_t * aNewStart)
{
    uint8_t * const kStart = reinterpret_cast<uint8_t *>(this) + CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE;
    uint8_t * const kEnd   = kStart + this->AllocSize();

    if (aNewStart < kStart)
        aNewStart = kStart;
    else if (aNewStart > kEnd)
        aNewStart = kEnd;

    ptrdiff_t lDelta = aNewStart - static_cast<uint8_t *>(this->payload);
    if (lDelta > this->len)
        lDelta = this->len;

    this->len     = static_cast<uint16_t>(static_cast<ptrdiff_t>(this->len) - lDelta);
    this->tot_len = static_cast<uint16_t>(static_cast<ptrdiff_t>(this->tot_len) - lDelta);
    this->payload = aNewStart;
}

/**
 * Get length, in bytes, of data in packet buffer.
 *
 *  @return length, in bytes (current payload length).
 */
uint16_t PacketBuffer::DataLength() const
{
    return this->len;
}

/**
 * Set length, in bytes, of data in buffer, adjusting total length accordingly.
 *
 *  The function sets the length, in bytes, of the data in the buffer, adjusting the total length appropriately.  When the buffer
 *  is not the head of the buffer chain (common case: the caller adds data to the last buffer in the PacketBuffer chain prior to
 *  calling higher layers), the aChainHead __must__ be passed in to properly adjust the total lengths of each buffer ahead of the
 *  current buffer.
 *
 *  @param[in] aNewLen - new length, in bytes, of this buffer.
 *
 *  @param[inout] aChainHead - the head of the buffer chain the current buffer belongs to.  May be NULL if the current buffer is
 *      the head of the buffer chain.
 */
void PacketBuffer::SetDataLength(uint16_t aNewLen, PacketBuffer * aChainHead)
{
    const uint16_t kMaxDataLen = this->MaxDataLength();

    if (aNewLen > kMaxDataLen)
        aNewLen = kMaxDataLen;

    ptrdiff_t lDelta = static_cast<ptrdiff_t>(aNewLen) - static_cast<ptrdiff_t>(this->len);

    this->len     = aNewLen;
    this->tot_len = (uint16_t)(this->tot_len + lDelta);

    while (aChainHead != NULL && aChainHead != this)
    {
        aChainHead->tot_len = static_cast<uint16_t>(aChainHead->tot_len + lDelta);
        aChainHead          = static_cast<PacketBuffer *>(aChainHead->next);
    }
}

/**
 * Get total length of packet data in the buffer chain.
 *
 * @return total length, in octets.
 */
uint16_t PacketBuffer::TotalLength() const
{
    return this->tot_len;
}

/**
 * Get the maximum amount, in bytes, of data that will fit in the buffer given the current start position and buffer size.
 *
 * @return number of bytes that fits in the buffer given the current start position.
 */
uint16_t PacketBuffer::MaxDataLength() const
{
    const uint8_t * const kStart = reinterpret_cast<const uint8_t *>(this) + CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE;
    const ptrdiff_t kDelta       = static_cast<uint8_t *>(this->payload) - kStart;
    return static_cast<uint16_t>(this->AllocSize() - kDelta);
}

/**
 * Get the number of bytes of data that can be added to the current buffer given the current start position and data length.
 *
 * @return the length, in bytes, of data that will fit in the current buffer given the current start position and data length.
 */
uint16_t PacketBuffer::AvailableDataLength() const
{
    return this->MaxDataLength() - this->len;
}

/**
 * Get the number of bytes within the current buffer between the start of the buffer and the current data start position.
 *
 * @return the amount, in bytes, of space between the start of the buffer and the current data start position.
 */
uint16_t PacketBuffer::ReservedSize() const
{
    const ptrdiff_t kDelta = static_cast<uint8_t *>(this->payload) - reinterpret_cast<const uint8_t *>(this);
    return static_cast<uint16_t>(kDelta - CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE);
}

/**
 *
 * Add the given packet buffer to the end of the buffer chain, adjusting the total length of each buffer in the chain accordingly.
 *
 *  @note The current packet buffer must be the head of the buffer chain for the lengths to be adjusted properly. The caller MUST
 *  NOT reference the given packet buffer afterwards.
 *
 * @param[in] aPacket - the packet buffer to be added to the end of the current chain.
 */
void PacketBuffer::AddToEnd(PacketBuffer * aPacket)
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    pbuf_cat(this, aPacket);
#else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
    PacketBuffer * lCursor = this;

    while (true)
    {
        lCursor->tot_len += aPacket->tot_len;
        if (lCursor->next == NULL)
        {
            lCursor->next = aPacket;
            break;
        }

        lCursor = static_cast<PacketBuffer *>(lCursor->next);
    }
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 *  Detach the current buffer from its chain and return a pointer to the remaining buffers.  The current buffer must be the head of
 *  the chain.
 *
 *  @return the tail of the current buffer chain or NULL if the current buffer is the only buffer in the chain.
 */
PacketBuffer * PacketBuffer::DetachTail()
{
    PacketBuffer & lReturn = *static_cast<PacketBuffer *>(this->next);

    this->next    = NULL;
    this->tot_len = this->len;

    return &lReturn;
}

/**
 * Move data from subsequent buffers in the chain into the current buffer until it is full.
 *
 *  Only the current buffer is compacted: the data within the current buffer is moved to the front of the buffer, eliminating any
 *  reserved space.  The remaining available space is filled with data moved from subsequent buffers in the chain, until the
 *  current buffer is full.  If a subsequent buffer in the chain is moved into the current buffer in its entirety, it is removed
 *  from the chain and freed.  The method takes no parameters, returns no results and cannot fail.
 */
void PacketBuffer::CompactHead()
{
    uint8_t * const kStart = reinterpret_cast<uint8_t *>(this) + CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE;

    if (this->payload != kStart)
    {
        memmove(kStart, this->payload, this->len);
        this->payload = kStart;
    }

    uint16_t lAvailLength = this->AvailableDataLength();

    while (lAvailLength > 0 && this->next != NULL)
    {
        PacketBuffer & lNextPacket = *static_cast<PacketBuffer *>(this->next);
        VerifyOrDieWithMsg(lNextPacket.ref == 1, chipSystemLayer, "next buffer %p is not exclusive to this chain", &lNextPacket);

        uint16_t lMoveLength = lNextPacket.len;
        if (lMoveLength > lAvailLength)
            lMoveLength = lAvailLength;

        memcpy(static_cast<uint8_t *>(this->payload) + this->len, lNextPacket.payload, lMoveLength);

        lNextPacket.payload = (uint8_t *) lNextPacket.payload + lMoveLength;
        this->len += lMoveLength;
        lAvailLength -= lMoveLength;
        lNextPacket.len -= lMoveLength;
        lNextPacket.tot_len -= lMoveLength;

        if (lNextPacket.len == 0)
            this->next = this->FreeHead(&lNextPacket);
    }
}

/**
 * Adjust the current buffer to indicate the amount of data consumed.
 *
 *  Advance the data start position in the current buffer by the specified amount, in bytes, up to the length of data in the
 *  buffer. Decrease the length and total length by the amount consumed.
 *
 *  @param[in] aConsumeLen - number of bytes to consume from the current buffer.
 */
void PacketBuffer::ConsumeHead(uint16_t aConsumeLength)
{
    if (aConsumeLength > this->len)
        aConsumeLength = this->len;
    this->payload = static_cast<uint8_t *>(this->payload) + aConsumeLength;
    this->len -= aConsumeLength;
    this->tot_len -= aConsumeLength;
}

/**
 * Consume data in a chain of buffers.
 *
 *  Consume data in a chain of buffers starting with the current buffer and proceeding through the remaining buffers in the chain.
 *  Each buffer that is completely consumed is freed and the function returns the first buffer (if any) containing the remaining
 *  data. The current buffer must be the head of the buffer chain.
 *
 *  @param[in] aConsumeLength - number of bytes to consume from the current chain.
 *
 *  @return the first buffer from the current chain that contains any remaining data.  If no data remains, a NULL is returned.
 */
PacketBuffer * PacketBuffer::Consume(uint16_t aConsumeLength)
{
    PacketBuffer * lPacket = this;

    while (lPacket != NULL && aConsumeLength > 0)
    {
        const uint16_t kLength = lPacket->DataLength();

        if (aConsumeLength >= kLength)
        {
            lPacket = PacketBuffer::FreeHead(lPacket);
            aConsumeLength -= kLength;
        }
        else
        {
            lPacket->ConsumeHead(aConsumeLength);
            break;
        }
    }

    return lPacket;
}

/**
 * Ensure the buffer has at least the specified amount of reserved space.
 *
 *  Ensure the buffer has at least the specified amount of reserved space moving the data in the buffer forward to make room if
 *  necessary.
 *
 *  @param[in] aReservedSize - number of bytes desired for the headers.
 *
 *  @return \c true if the requested reserved size is available, \c false if there's not enough room in the buffer.
 */
bool PacketBuffer::EnsureReservedSize(uint16_t aReservedSize)
{
    const uint16_t kCurrentReservedSize = this->ReservedSize();
    if (aReservedSize <= kCurrentReservedSize)
        return true;

    if ((aReservedSize + this->len) > this->AllocSize())
        return false;

    const uint16_t kMoveLength = aReservedSize - kCurrentReservedSize;
    memmove(static_cast<uint8_t *>(this->payload) + kMoveLength, this->payload, this->len);
    payload = static_cast<uint8_t *>(this->payload) + kMoveLength;

    return true;
}

/**
 * Align the buffer payload on the specified bytes boundary.
 *
 *  Moving the payload in the buffer forward if necessary.
 *
 *  @param[in] aAlignBytes - specifies number of bytes alignment for the payload start pointer.
 *
 *  @return \c true if alignment is successful, \c false if there's not enough room in the buffer.
 */
bool PacketBuffer::AlignPayload(uint16_t aAlignBytes)
{
    if (aAlignBytes == 0)
        return false;

    const uint16_t kPayloadOffset = reinterpret_cast<uintptr_t>(this->payload) % aAlignBytes;

    if (kPayloadOffset == 0)
        return true;

    const uint16_t kPayloadShift = aAlignBytes - kPayloadOffset;

    return (this->EnsureReservedSize(this->ReservedSize() + kPayloadShift));
}

/**
 * Get pointer to next buffer in chain.
 *
 *  @return a pointer to the next buffer in the chain.  \c NULL is returned when there is no buffers in the chain.
 */
PacketBuffer * PacketBuffer::Next() const
{
    return static_cast<PacketBuffer *>(this->next);
}

/**
 * Increment the reference count of the current buffer.
 */
void PacketBuffer::AddRef()
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    pbuf_ref(this);
#else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
    LOCK_BUF_POOL();
    ++this->ref;
    UNLOCK_BUF_POOL();
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * Allocates a PacketBuffer object with at least \c aReservedSize bytes reserved in the payload for headers, and at least
 *  \c aAllocSize bytes of space for additional data after the initial cursor pointer.
 *
 *  @param[in]  aReservedSize   Number of octets to reserve behind the cursor.
 *  @param[in]  aAvailableSize  Number of octets to allocate after the cursor.
 *
 *  @return     On success, a pointer to the PacketBuffer in the allocated block. On fail, \c NULL.
 */
PacketBuffer * PacketBuffer::NewWithAvailableSize(uint16_t aReservedSize, size_t aAvailableSize)
{
    const size_t lReservedSize = static_cast<size_t>(aReservedSize);
    const size_t lAllocSize    = lReservedSize + aAvailableSize;
    const size_t lBlockSize    = CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE + lAllocSize;
    PacketBuffer * lPacket;

    CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_PacketBufferNew, return NULL);

    if (lAllocSize > CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX)
    {
        ChipLogError(chipSystemLayer, "PacketBuffer: allocation too large.");
        return NULL;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    lPacket = static_cast<PacketBuffer *>(pbuf_alloc(PBUF_RAW, lBlockSize, PBUF_POOL));

    SYSTEM_STATS_UPDATE_LWIP_PBUF_COUNTS();

#else // !CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

    static_cast<void>(lBlockSize);

    LOCK_BUF_POOL();

    lPacket = sFreeList;
    if (lPacket != NULL)
    {
        sFreeList = static_cast<PacketBuffer *>(lPacket->next);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kSystemLayer_NumPacketBufs);
    }

    UNLOCK_BUF_POOL();

#else // !CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

    lPacket = reinterpret_cast<PacketBuffer *>(malloc(lBlockSize));
    SYSTEM_STATS_INCREMENT(chip::System::Stats::kSystemLayer_NumPacketBufs);

#endif // !CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP

    if (lPacket == NULL)
    {
        ChipLogError(chipSystemLayer, "PacketBuffer: pool EMPTY.");
        return NULL;
    }

    lPacket->payload = reinterpret_cast<uint8_t *>(lPacket) + CHIP_SYSTEM_PACKETBUFFER_HEADER_SIZE + lReservedSize;
    lPacket->len = lPacket->tot_len = 0;
    lPacket->next                   = NULL;
    lPacket->ref                    = 1;
#if CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0
    lPacket->alloc_size = lAllocSize;
#endif // CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0

    return lPacket;
}

/**
 * Allocates a PacketBuffer with default reserved size (#CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE) in the payload for headers,
 * and at least \c aAllocSize bytes of space for additional data after the initial cursor pointer.
 *
 * This usage is most appropriate when allocating a PacketBuffer for an application-layer message.
 *
 *  @param[in]  aAvailableSize  Number of octets to allocate after the cursor.
 *
 *  @return     On success, a pointer to the PacketBuffer in the allocated block. On fail, \c NULL. *
 */
PacketBuffer * PacketBuffer::NewWithAvailableSize(size_t aAvailableSize)
{
    return PacketBuffer::NewWithAvailableSize(CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE, aAvailableSize);
}

/**
 * Allocates a single PacketBuffer of maximum total size with a specific header reserve size.
 *
 *  The parameter passed in is the size reserved prior to the payload to accomodate packet headers from different stack layers,
 *  __not__ the overall size of the buffer to allocate. The size of the buffer #CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX
 *  and not, specified in the call.
 *
 * - `PacketBuffer::New(0)` : when called in this fashion, the buffer will be returned without any header reserved, consequently
 *      the entire payload is usable by the caller. This pattern is particularly useful at the lower layers of networking stacks,
 *      in cases where the user knows the payload will be copied out into the final message with appropriate header reserves or in
 *      creating PacketBuffer that are appended to a chain of PacketBuffer via `PacketBuffer::AddToEnd()`.
 *
 *  @param[in] aReservedSize  amount of header space to reserve.
 *
 *  @return On success, a pointer to the PacketBuffer, on failure \c NULL.
 */
PacketBuffer * PacketBuffer::New(uint16_t aReservedSize)
{
    const size_t lReservedSize = static_cast<size_t>(aReservedSize);

    const size_t lAvailableSize = lReservedSize < CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX
        ? CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX - lReservedSize
        : 0;

    return PacketBuffer::NewWithAvailableSize(aReservedSize, lAvailableSize);
}

/**
 * Allocates a single PacketBuffer of default max size (#CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX) with default reserved size
 * (#CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE) in the payload.
 *
 * The reserved size (#CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE) is large enough to hold transport layer headers as well as headers
 * required by \c chipMessageLayer and \c chipExchangeLayer.
 */
PacketBuffer * PacketBuffer::New(void)
{
    return PacketBuffer::New(CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE);
}

/**
 * Free all packet buffers in a chain.
 *
 *  Decrement the reference count to all the buffers in the current chain. If the reference count reaches 0, the respective buffers
 *  are freed or returned to allocation pools as appropriate. As a rule, users should treat this method as an equivalent of
 *  `free()` function and not use the argument after the call.
 *
 *  @param[in] aPacket - packet buffer to be freed.
 */
void PacketBuffer::Free(PacketBuffer * aPacket)
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP

    if (aPacket != NULL)
    {
        pbuf_free(aPacket);

        SYSTEM_STATS_UPDATE_LWIP_PBUF_COUNTS();
    }

#else // !CHIP_SYSTEM_CONFIG_USE_LWIP

    LOCK_BUF_POOL();

    while (aPacket != NULL)
    {
        PacketBuffer * lNextPacket = static_cast<PacketBuffer *>(aPacket->next);

        VerifyOrDieWithMsg(aPacket->ref > 0, chipSystemLayer, "SystemPacketBuffer::Free: aPacket->ref = 0");

        aPacket->ref--;
        if (aPacket->ref == 0)
        {
            SYSTEM_STATS_DECREMENT(chip::System::Stats::kSystemLayer_NumPacketBufs);
            aPacket->Clear();
#if CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC
            aPacket->next = sFreeList;
            sFreeList     = aPacket;
#else  // !CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC
            free(aPacket);
#endif // !CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC
            aPacket       = lNextPacket;
        }
        else
        {
            aPacket = NULL;
        }
    }

    UNLOCK_BUF_POOL();

#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * Clear content of the packet buffer.
 *
 * This method is called by Free(), before the buffer is released to the free buffer pool.
 */
void PacketBuffer::Clear(void)
{
    tot_len = 0;
    len     = 0;
#if CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0
    alloc_size = 0;
#endif // CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0
}

/**
 * Free the first buffer in a chain, returning a pointer to the remaining buffers.
 `*
 *  @note When the buffer chain is referenced by multiple callers, `FreeHead()` will detach the head, but will not forcibly
 *  deallocate the head buffer.
 *
 *  @param[in] aPacket - buffer chain.
 *
 *  @return packet buffer chain consisting of the tail of the input buffer (may be \c NULL).
 */
PacketBuffer * PacketBuffer::FreeHead(PacketBuffer * aPacket)
{
    PacketBuffer * lNextPacket = static_cast<PacketBuffer *>(aPacket->next);
    aPacket->next              = NULL;
    PacketBuffer::Free(aPacket);
    return lNextPacket;
}

/**
 * Copy the given buffer to a right-sized buffer if applicable.
 * This function is a no-op for sockets.
 *
 *  @param[in] aPacket - buffer or buffer chain.
 *
 *  @return new packet buffer or the original buffer
 */
PacketBuffer * PacketBuffer::RightSize(PacketBuffer * aPacket)
{
    PacketBuffer * lNewPacket = aPacket;
#if CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_PBUF_FROM_CUSTOM_POOLS
    lNewPacket = static_cast<PacketBuffer *>(pbuf_rightsize((struct pbuf *) aPacket, -1));
    if (lNewPacket != aPacket)
    {
        SYSTEM_STATS_UPDATE_LWIP_PBUF_COUNTS();

        ChipLogProgress(chipSystemLayer, "PacketBuffer: RightSize Copied");
    }
#endif
    return lNewPacket;
}

#if !CHIP_SYSTEM_CONFIG_USE_LWIP && CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

PacketBuffer * PacketBuffer::BuildFreeList()
{
    PacketBuffer * lHead = NULL;

    for (int i = 0; i < CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC; i++)
    {
        PacketBuffer * lCursor = &sBufferPool[i].Header;
        lCursor->next          = lHead;
        lCursor->ref           = 0;
        lHead                  = lCursor;
    }

    Mutex::Init(sBufferPoolMutex);

    return lHead;
}

#endif //  !CHIP_SYSTEM_CONFIG_USE_LWIP && CHIP_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

} // namespace System
} // namespace chip
