/*
 *
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    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.
 */

/**
 *    @file
 *      This file defines the member functions and private data for
 *      the nl::Weave::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 <SystemLayer/SystemPacketBuffer.h>

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

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

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

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

#include <Weave/Support/logging/WeaveLogging.h>
#include <Weave/Support/CodeUtils.h>

#include <SystemLayer/SystemStats.h>

namespace nl {
namespace Weave {
namespace System {

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

static BufferPoolElement sBufferPool[WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC];

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

static Mutex sBufferPoolMutex;

#define LOCK_BUF_POOL()     do { sBufferPoolMutex.Lock(); } while (0)
#define UNLOCK_BUF_POOL()   do { sBufferPoolMutex.Unlock(); } while (0)

#endif // WEAVE_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 // !WEAVE_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) + WEAVE_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) + WEAVE_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 - WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_LWIP
    pbuf_cat(this, aPacket);
#else // !WEAVE_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 // !WEAVE_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) + WEAVE_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, WeaveSystemLayer, "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] consumeLen - 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] alignBytes - 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 WEAVE_SYSTEM_CONFIG_USE_LWIP
    pbuf_ref(this);
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
    LOCK_BUF_POOL();
    ++this->ref;
    UNLOCK_BUF_POOL();
#endif // !WEAVE_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 = WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE + lAllocSize;
    PacketBuffer* lPacket;

    WEAVE_SYSTEM_FAULT_INJECT(FaultInjection::kFault_PacketBufferNew, return NULL);

    if (lAllocSize > WEAVE_SYSTEM_PACKETBUFFER_ALLOCSIZE_MAX)
    {
        WeaveLogError(WeaveSystemLayer, "PacketBuffer: allocation too large.");
        return NULL;
    }

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

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

#if LWIP_STATS
    if (lPacket != NULL)
    {
        SYSTEM_STATS_SET(nl::Weave::System::Stats::kSystemLayer_NumPacketBufs, MEMP_STATS_GET(used, MEMP_PBUF_POOL));
    }
#endif

#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
#if WEAVE_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(nl::Weave::System::Stats::kSystemLayer_NumPacketBufs);
    }

    UNLOCK_BUF_POOL();

#else // !WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

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

#endif // !WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC
#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP

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

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

    return lPacket;
}

/**
 * Allocates a PacketBuffer with default reserved size (#WEAVE_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(WEAVE_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 #WEAVE_SYSTEM_PACKETBUFFER_ALLOCSIZE_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 < WEAVE_SYSTEM_PACKETBUFFER_ALLOCSIZE_MAX ? WEAVE_SYSTEM_PACKETBUFFER_ALLOCSIZE_MAX - lReservedSize : 0;

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

/**
 * Allocates a single PacketBuffer of default max size (#WEAVE_SYSTEM_PACKETBUFFER_ALLOCSIZE_MAX) with default reserved size
 * (#WEAVE_SYSTEM_CONFIG_HEADER_RESERVE_SIZE) in the payload.
 *
 * The reserved size (#WEAVE_SYSTEM_CONFIG_HEADER_RESERVE_SIZE) is large enough to hold transport layer headers as well as headers required by
 * \c WeaveMessageLayer and \c WeaveExchangeLayer.
 */
PacketBuffer* PacketBuffer::New(void)
{
    return PacketBuffer::New(WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_LWIP

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

#if LWIP_STATS
        SYSTEM_STATS_SET(nl::Weave::System::Stats::kSystemLayer_NumPacketBufs, MEMP_STATS_GET(used, MEMP_PBUF_POOL));
#endif
    }

#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP

    LOCK_BUF_POOL();

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

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

    UNLOCK_BUF_POOL();

#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP
}

/**
 * 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] buf - 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 WEAVE_SYSTEM_CONFIG_USE_LWIP
    lNewPacket =  static_cast<PacketBuffer *>(pbuf_rightsize((struct pbuf *)aPacket, -1));
    if (lNewPacket != aPacket)
    {
#if LWIP_STATS
        using namespace nl::Weave::System::Stats;

        const size_t system_index = kSystemLayer_NumPacketBufs;
        const size_t lwip_index = MEMP_PBUF_POOL;

        GetResourcesInUse()[system_index] = MEMP_STATS_GET(used, lwip_index);
        GetHighWatermarks()[system_index] = MEMP_STATS_GET(max, lwip_index);
#endif

        WeaveLogProgress(WeaveSystemLayer, "PacketBuffer: RightSize Copied");
    }
#endif
    return lNewPacket;
}

#if !WEAVE_SYSTEM_CONFIG_USE_LWIP && WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

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

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

    Mutex::Init(sBufferPoolMutex);

    return lHead;
}

#endif //  !WEAVE_SYSTEM_CONFIG_USE_LWIP && WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC

} // namespace System
} // namespace Weave
} // namespace nl
