/*
 *
 *    Copyright (c) 2025 Project CHIP Authors
 *
 *    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 implements a WiFiPAF endpoint abstraction for CHIP over WiFiPAF (CHIPoPAF)
 *      Public Action Frame Transport Protocol (PAFTP).
 *
 */

#include "WiFiPAFEndPoint.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <utility>

#include <lib/support/BitFlags.h>
#include <lib/support/BufferReader.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <system/SystemClock.h>
#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>

#include "WiFiPAFConfig.h"
#include "WiFiPAFError.h"
#include "WiFiPAFLayer.h"
#include "WiFiPAFTP.h"

// Define below to enable extremely verbose, WiFiPAF end point-specific debug logging.
#undef CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_ENABLED
#define CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_LEVEL 0

#ifdef CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_ENABLED
#define ChipLogDebugWiFiPAFEndPoint_L0(MOD, MSG, ...) ChipLogDetail(MOD, MSG, ##__VA_ARGS__)
#if (CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_LEVEL == 0)
#define ChipLogDebugWiFiPAFEndPoint(MOD, MSG, ...)
#else
#define ChipLogDebugWiFiPAFEndPoint(MOD, MSG, ...) ChipLogDetail(MOD, MSG, ##__VA_ARGS__)
#endif // CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_LEVEL
#define ChipLogDebugBufferWiFiPAFEndPoint(MOD, BUF)                                                                                \
    ChipLogByteSpan(MOD, ByteSpan((BUF)->Start(), ((BUF)->DataLength() < 8 ? (BUF)->DataLength() : 8u)))
#else
#define ChipLogDebugWiFiPAFEndPoint(MOD, MSG, ...)
#define ChipLogDebugBufferWiFiPAFEndPoint(MOD, BUF)
#endif

/**
 *  @def WIFIPAF_CONFIG_IMMEDIATE_ACK_WINDOW_THRESHOLD
 *
 *  @brief
 *    If an end point's receive window drops equal to or below this value, it will send an immediate acknowledgement
 *    packet to re-open its window instead of waiting for the send-ack timer to expire.
 *
 */
#define WIFIPAF_CONFIG_IMMEDIATE_ACK_WINDOW_THRESHOLD 1

#define WIFIPAF_ACK_SEND_TIMEOUT_MS 2500
#define WIFIPAF_WAIT_RES_TIMEOUT_MS 1000
// Drop the connection if network resources remain unavailable for the period.
#define WIFIPAF_MAX_RESOURCE_BLOCK_COUNT (PAFTP_CONN_IDLE_TIMEOUT_MS / WIFIPAF_WAIT_RES_TIMEOUT_MS)

/**
 *  @def WIFIPAF_WINDOW_NO_ACK_SEND_THRESHOLD
 *
 *  @brief
 *    Data fragments may only be sent without piggybacked acks if receiver's window size is above this threshold.
 *
 */
#define WIFIPAF_WINDOW_NO_ACK_SEND_THRESHOLD 1

namespace chip {
namespace WiFiPAF {

CHIP_ERROR WiFiPAFEndPoint::StartConnect()
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    PAFTransportCapabilitiesRequestMessage req;
    PacketBufferHandle buf;
    constexpr uint8_t numVersions =
        CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION - CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION + 1;
    static_assert(numVersions <= NUM_PAFTP_SUPPORTED_PROTOCOL_VERSIONS, "Incompatibly protocol versions");

    // Ensure we're in the correct state.
    VerifyOrExit(mState == kState_Ready, err = CHIP_ERROR_INCORRECT_STATE);
    mState = kState_Connecting;

    // Build PAF transport protocol capabilities request.
    buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
    VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);

    // Zero-initialize PAF transport capabilities request.
    memset(&req, 0, sizeof(req));
    req.mMtu        = CHIP_PAF_DEFAULT_MTU;
    req.mWindowSize = PAF_MAX_RECEIVE_WINDOW_SIZE;

    // Populate request with highest supported protocol versions
    for (uint8_t i = 0; i < numVersions; i++)
    {
        req.SetSupportedProtocolVersion(i, static_cast<uint8_t>(CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION - i));
    }

    err = req.Encode(buf);
    SuccessOrExit(err);

    // Start connect timer. Canceled when end point freed or connection established.
    err = StartConnectTimer();
    SuccessOrExit(err);

    // Send PAF transport capabilities request to peripheral.
    // Add reference to message fragment. CHIP retains partial ownership of message fragment's packet buffer,
    // since this is the same buffer as that of the whole message, just with a fragmenter-modified payload offset
    // and data length, by a Retain() on the handle when calling this function.
    err = SendWrite(buf.Retain());
    SuccessOrExit(err);
    // Free request buffer on write confirmation. Stash a reference to it in mSendQueue, which we don't use anyway
    // until the connection has been set up.
    QueueTx(std::move(buf), kType_Data);

exit:
    // If we failed to initiate the connection, close the end point.
    if (err != CHIP_NO_ERROR)
    {
        StopConnectTimer();
        DoClose(kWiFiPAFCloseFlag_AbortTransmission, err);
    }

    return err;
}

CHIP_ERROR WiFiPAFEndPoint::HandleConnectComplete()
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    mState = kState_Connected;
    // Cancel connect and receive-connection timers.
    if (mRole == kWiFiPafRole_Subscriber)
    {
        StopConnectTimer();
    }
    else
    {
        StopReceiveConnectionTimer();
    }

    // Arm ongoing idle session supervision to ensure upper-layer commissioning
    // (Phase 2 PASE handshake) initiates within a reasonable deadline.
    LogErrorOnFailure(StartAckReceivedTimer());

    // We've successfully completed the PAF transport protocol handshake, so let the application know we're open for business.

    if (mWiFiPafLayer != nullptr)
    {
        // Indicate connect complete to next-higher layer.
        mWiFiPafLayer->OnEndPointConnectComplete(this, CHIP_NO_ERROR);
    }
    else
    {
        // If no connect complete callback has been set up, close the end point.
        err = WIFIPAF_ERROR_NO_CONNECT_COMPLETE_CALLBACK;
    }
    return err;
}

bool WiFiPAFEndPoint::IsConnected(uint8_t state) const
{
    return (state == kState_Connected || state == kState_Closing);
}

void WiFiPAFEndPoint::DoClose(uint8_t flags, CHIP_ERROR err)
{
    uint8_t oldState = mState;

    // If end point is not closed or closing, OR end point was closing gracefully, but tx abort has been specified...
    if ((mState != kState_Closed && mState != kState_Closing) ||
        (mState == kState_Closing && (flags & kWiFiPAFCloseFlag_AbortTransmission)))
    {
        // Cancel Connect and ReceiveConnect timers if they are running.
        // Check role first to avoid needless iteration over timer pool.
        if (mRole == kWiFiPafRole_Subscriber)
        {
            StopConnectTimer();
        }
        else
        {
            StopReceiveConnectionTimer();
        }

        // Free the packets in re-order queue if ones exist
        for (uint8_t qidx = 0; qidx < PAFTP_REORDER_QUEUE_SIZE; qidx++)
        {
            if (!ReorderQueue[qidx].IsNull())
            {
                ReorderQueue[qidx] = nullptr;
            }
        }
        ItemsInReorderQueue = 0;

        // If transmit buffer is empty or a transmission abort was specified...
        if (mPafTP.TxState() == WiFiPAFTP::kState_Idle || (flags & kWiFiPAFCloseFlag_AbortTransmission))
        {
            FinalizeClose(oldState, flags, err);
        }
        else
        {
            // Wait for send queue and fragmenter's tx buffer to become empty, to ensure all pending messages have been
            // sent. Only free end point and tell platform it can throw away the underlying connection once all
            // pending messages have been sent and acknowledged by the remote CHIPoPAF stack, or once the remote stack
            // closes the CHIPoPAF connection.
            //
            // In so doing, WiFiPAFEndPoint attempts to emulate the level of reliability afforded by TCPEndPoint and TCP
            // sockets in general with a typical default SO_LINGER option. That said, there is no hard guarantee that
            // pending messages will be sent once (Do)Close() is called, so developers should use application-level
            // messages to confirm the receipt of all data sent prior to a Close() call.
            mState = kState_Closing;

            if ((flags & kWiFiPAFCloseFlag_SuppressCallback) == 0)
            {
                DoCloseCallback(oldState, flags, err);
            }
        }
    }
}

void WiFiPAFEndPoint::FinalizeClose(uint8_t oldState, uint8_t flags, CHIP_ERROR err)
{
    mState = kState_Closed;

    // Ensure transmit queue is empty and set to NULL.
    mSendQueue = nullptr;
    // Clear the session information
    ChipLogProgress(WiFiPAF, "Shutdown PAF session (%u, %u)", mSessionInfo.id, mSessionInfo.role);
    TEMPORARY_RETURN_IGNORED mWiFiPafLayer->mWiFiPAFTransport->WiFiPAFCloseSession(mSessionInfo);
    memset(&mSessionInfo, 0, sizeof(mSessionInfo));
    // Fire application's close callback if we haven't already, and it's not suppressed.
    if (oldState != kState_Closing && (flags & kWiFiPAFCloseFlag_SuppressCallback) == 0)
    {
        DoCloseCallback(oldState, flags, err);
    }

    // If underlying WiFiPAF connection has closed, connection object is invalid, so just free the end point and return.
    if (err == WIFIPAF_ERROR_REMOTE_DEVICE_DISCONNECTED || err == WIFIPAF_ERROR_APP_CLOSED_CONNECTION)
    {
        Free();
    }
    else // Otherwise, try to signal close to remote device before end point releases WiFiPAF connection and frees itself.
    {
        if (mRole == kWiFiPafRole_Subscriber)
        {
            // Cancel send and receive-ack timers, if running.
            StopAckReceivedTimer();
            StopSendAckTimer();
            StopWaitResourceTimer();
            mConnStateFlags.Set(ConnectionStateFlag::kOperationInFlight);
        }
        else
        {
            Free();
        }
    }
    ClearAll();
}

void WiFiPAFEndPoint::DoCloseCallback(uint8_t state, uint8_t flags, CHIP_ERROR err)
{
    // Callback fires once per end point lifetime.
    mOnPafSubscribeComplete = nullptr;
    mOnPafSubscribeError    = nullptr;
    OnConnectionClosed      = nullptr;
}

void WiFiPAFEndPoint::Free()
{
    // Clear fragmentation and reassembly engine's Tx and Rx buffers. Counters will be reset by next engine init.
    FreePAFtpEngine();

    // Clear pending ack buffer, if any.
    mAckToSend = nullptr;

    // Cancel all timers.
    StopConnectTimer();
    StopReceiveConnectionTimer();
    StopAckReceivedTimer();

    StopSendAckTimer();
    StopWaitResourceTimer();

    // Clear callbacks.
    mOnPafSubscribeComplete = nullptr;
    mOnPafSubscribeError    = nullptr;
    OnMessageReceived       = nullptr;
    OnConnectionClosed      = nullptr;
}

void WiFiPAFEndPoint::FreePAFtpEngine()
{
    // Free transmit disassembly buffer
    mPafTP.ClearTxPacket();

    // Free receive reassembly buffer
    mPafTP.ClearRxPacket();
}

CHIP_ERROR WiFiPAFEndPoint::Init(WiFiPAFLayer * WiFiPafLayer, WiFiPAFSession & SessionInfo)
{
    // Fail if already initialized.
    VerifyOrReturnError(mWiFiPafLayer == nullptr, CHIP_ERROR_INCORRECT_STATE);

    // Validate args.
    VerifyOrReturnError(WiFiPafLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    // If end point plays subscriber role, expect ack as last step of PAFTP handshake.
    // If being publisher, subscriber's handshake indication 'ack's write sent by publisher to kick off the PAFTP handshake.
    bool expectInitialAck = (SessionInfo.role == kWiFiPafRole_Publisher);

    CHIP_ERROR err = mPafTP.Init(this, expectInitialAck);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(WiFiPAF, "WiFiPAFTP init failed");
        return err;
    }

    mWiFiPafLayer = WiFiPafLayer;

    // WiFiPAF EndPoint data members:
    memcpy(&mSessionInfo, &SessionInfo, sizeof(mSessionInfo));
    mRole = SessionInfo.role;
    mTimerStateFlags.ClearAll();
    mLocalReceiveWindowSize  = 0;
    mRemoteReceiveWindowSize = 0;
    mReceiveWindowMaxSize    = 0;
    mSendQueue               = nullptr;
    mAckToSend               = nullptr;

    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "initialized local rx window, size = %u", mLocalReceiveWindowSize);

    // End point is ready.
    mState = kState_Ready;

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::SendCharacteristic(PacketBufferHandle && buf)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    SuccessOrExit(err = SendWrite(std::move(buf)));
    // Write succeeded, so shrink remote receive window counter by 1.
    mRemoteReceiveWindowSize = static_cast<SequenceNumber_t>(mRemoteReceiveWindowSize - 1);
    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "decremented remote rx window, new size = %u", mRemoteReceiveWindowSize);
exit:
    return err;
}

/*
 *  Routine to queue the Tx packet with a packet type
 *  kType_Data(0)       - data packet
 *  kType_Control(1)    - control packet
 */
void WiFiPAFEndPoint::QueueTx(PacketBufferHandle && data, PacketType_t type)
{
    if (mSendQueue.IsNull())
    {
        mSendQueue = std::move(data);
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "%s: Set data as new mSendQueue %p, type %d", __FUNCTION__, mSendQueue->Start(), type);
    }
    else
    {
        mSendQueue->AddToEnd(std::move(data));
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "%s: Append data to mSendQueue %p, type %d", __FUNCTION__, mSendQueue->Start(), type);
    }
}

CHIP_ERROR WiFiPAFEndPoint::Send(PacketBufferHandle && data)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    VerifyOrExit(!data.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrExit(IsConnected(mState), err = CHIP_ERROR_INCORRECT_STATE);

    // Ensure outgoing message fits in a single contiguous packet buffer, as currently required by the
    // message fragmentation and reassembly engine.
    if (data->HasChainedBuffer())
    {
        data->CompactHead();

        if (data->HasChainedBuffer())
        {
            err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG;
            ExitNow();
        }
    }

    // Add new message to send queue.
    QueueTx(std::move(data), kType_Data);

    // Send first fragment of new message, if we can.
    err = DriveSending();
    SuccessOrExit(err);
exit:
    if (err != CHIP_NO_ERROR)
    {
        DoClose(kWiFiPAFCloseFlag_AbortTransmission, err);
    }

    return err;
}

bool WiFiPAFEndPoint::PrepareNextFragment(PacketBufferHandle && data, bool & sentAck)
{
    // If we have a pending fragment acknowledgement to send, piggyback it on the fragment we're about to transmit.
    if (mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning))
    {
        // Reset local receive window counter.
        mLocalReceiveWindowSize = mReceiveWindowMaxSize;
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "reset local rx window on piggyback ack tx, size = %u", mLocalReceiveWindowSize);

        // Tell caller AND fragmenter we have an ack to piggyback.
        sentAck = true;
    }
    else
    {
        // No ack to piggyback.
        sentAck = false;
    }

    return mPafTP.HandleCharacteristicSend(std::move(data), sentAck);
}

CHIP_ERROR WiFiPAFEndPoint::SendNextMessage()
{
    // Get the first queued packet to send
    PacketBufferHandle data = mSendQueue.PopHead();

    // Hand whole message payload to the fragmenter.
    bool sentAck;
    VerifyOrReturnError(PrepareNextFragment(std::move(data), sentAck), WIFIPAF_ERROR_CHIPPAF_PROTOCOL_ABORT);

    ReturnErrorOnFailure(SendCharacteristic(mPafTP.BorrowTxPacket()));

    if (sentAck)
    {
        // If sent piggybacked ack, stop send-ack timer.
        StopSendAckTimer();
    }

    // Start ack received timer, if it's not already running.
    return StartAckReceivedTimer();
}

CHIP_ERROR WiFiPAFEndPoint::ContinueMessageSend()
{
    bool sentAck;

    if (!PrepareNextFragment(nullptr, sentAck))
    {
        // Log PAFTP error
        ChipLogError(WiFiPAF, "paftp fragmenter error on send!");
        mPafTP.LogState();

        return WIFIPAF_ERROR_CHIPPAF_PROTOCOL_ABORT;
    }

    ReturnErrorOnFailure(SendCharacteristic(mPafTP.BorrowTxPacket()));

    if (sentAck)
    {
        // If sent piggybacked ack, stop send-ack timer.
        StopSendAckTimer();
    }

    // Start ack received timer, if it's not already running.
    return StartAckReceivedTimer();
}

CHIP_ERROR WiFiPAFEndPoint::HandleHandshakeConfirmationReceived()
{
    // Free capabilities request/response payload.
    mSendQueue.FreeHead();

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::HandleFragmentConfirmationReceived(bool result)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    // Ensure we're in correct state to receive confirmation of non-handshake GATT send.
    VerifyOrExit(IsConnected(mState), err = CHIP_ERROR_INCORRECT_STATE);

    if (mConnStateFlags.Has(ConnectionStateFlag::kStandAloneAckInFlight))
    {
        // If confirmation was received for stand-alone ack, free its tx buffer.
        mAckToSend = nullptr;
        mConnStateFlags.Clear(ConnectionStateFlag::kStandAloneAckInFlight);
    }

    if (result != true)
    {
        // Something wrong in writing packets
        ChipLogError(WiFiPAF, "Failed to send PAF packet");
        err = CHIP_ERROR_SENDING_BLOCKED;
        StopAckReceivedTimer();
        SuccessOrExit(err);
    }

    // If local receive window size has shrunk to or below immediate ack threshold, AND a message fragment is not
    // pending on which to piggyback an ack, send immediate stand-alone ack.
    //
    // This check covers the case where the local receive window has shrunk between transmission and confirmation of
    // the stand-alone ack, and also the case where a window size < the immediate ack threshold was detected in
    // Receive(), but the stand-alone ack was deferred due to a pending outbound message fragment.
    if (mLocalReceiveWindowSize <= WIFIPAF_CONFIG_IMMEDIATE_ACK_WINDOW_THRESHOLD && mSendQueue.IsNull() &&
        mPafTP.TxState() != WiFiPAFTP::kState_InProgress)
    {
        err = DriveStandAloneAck(); // Encode stand-alone ack and drive sending.
        SuccessOrExit(err);
    }
    else
    {
        err = DriveSending();
        SuccessOrExit(err);
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        DoClose(kWiFiPAFCloseFlag_AbortTransmission, err);
    }

    return err;
}

CHIP_ERROR WiFiPAFEndPoint::HandleSendConfirmationReceived(bool result)
{
    // Mark outstanding operation as finished.
    mConnStateFlags.Clear(ConnectionStateFlag::kOperationInFlight);

    // If confirmation was for outbound portion of PAFTP connect handshake...
    if (!mConnStateFlags.Has(ConnectionStateFlag::kCapabilitiesConfReceived))
    {
        mConnStateFlags.Set(ConnectionStateFlag::kCapabilitiesConfReceived);
        return HandleHandshakeConfirmationReceived();
    }

    return HandleFragmentConfirmationReceived(result);
}

CHIP_ERROR WiFiPAFEndPoint::DriveStandAloneAck()
{
    // Stop send-ack timer if running.
    StopSendAckTimer();

    // If stand-alone ack not already pending, allocate new payload buffer here.
    if (mAckToSend.IsNull())
    {
        mAckToSend = System::PacketBufferHandle::New(kTransferProtocolStandaloneAckHeaderSize);
        VerifyOrReturnError(!mAckToSend.IsNull(), CHIP_ERROR_NO_MEMORY);
    }

    // Attempt to send stand-alone ack.
    return DriveSending();
}

CHIP_ERROR WiFiPAFEndPoint::DoSendStandAloneAck()
{
    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "sending stand-alone ack");

    // Encode and transmit stand-alone ack.
    ReturnErrorOnFailure(mPafTP.EncodeStandAloneAck(mAckToSend));
    ReturnErrorOnFailure(SendCharacteristic(mAckToSend.Retain()));

    // Reset local receive window counter.
    mLocalReceiveWindowSize = mReceiveWindowMaxSize;
    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "reset local rx window on stand-alone ack tx, size = %u", mLocalReceiveWindowSize);

    mConnStateFlags.Set(ConnectionStateFlag::kStandAloneAckInFlight);

    // Start ack received timer, if it's not already running.
    return StartAckReceivedTimer();
}

CHIP_ERROR WiFiPAFEndPoint::DriveSending()
{
    // If receiver's window is almost closed and we don't have an ack to send, OR we do have an ack to send but
    // receiver's window is completely empty, OR another operation is in flight, awaiting confirmation...
    if ((mRemoteReceiveWindowSize <= WIFIPAF_WINDOW_NO_ACK_SEND_THRESHOLD &&
         !mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning) && mAckToSend.IsNull()) ||
        (mRemoteReceiveWindowSize == 0) || (mConnStateFlags.Has(ConnectionStateFlag::kOperationInFlight)))
    {
        if (mRemoteReceiveWindowSize <= WIFIPAF_WINDOW_NO_ACK_SEND_THRESHOLD &&
            !mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning) && mAckToSend.IsNull())
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "NO SEND: receive window almost closed, and no ack to send");
        }

        if (mRemoteReceiveWindowSize == 0)
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "NO SEND: remote receive window closed");
        }

        if (mConnStateFlags.Has(ConnectionStateFlag::kOperationInFlight))
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "NO SEND: Operation in flight");
        }
        // Can't send anything.
        return CHIP_NO_ERROR;
    }

    if (!mWiFiPafLayer->mWiFiPAFTransport->WiFiPAFResourceAvailable() && (!mAckToSend.IsNull() || !mSendQueue.IsNull()))
    {
        // Resource is currently unavailable, send packets later
        return StartWaitResourceTimer();
    }
    mResourceWaitCount = 0;

    // Otherwise, let's see what we can send.
    if ((!mAckToSend.IsNull()) && !mConnStateFlags.Has(ConnectionStateFlag::kStandAloneAckInFlight))
    {
        // If immediate, stand-alone ack is pending, send it.
        ChipLogProgress(WiFiPAF, "Send the pending stand-alone ack");
        ReturnErrorOnFailure(DoSendStandAloneAck());
    }
    else if (mPafTP.TxState() == WiFiPAFTP::kState_Idle) // Else send next message fragment, if any.
    {
        // Fragmenter's idle, let's see what's in the send queue...
        if (!mSendQueue.IsNull())
        {
            // Transmit first fragment of next whole message in send queue.
            ReturnErrorOnFailure(SendNextMessage());
        }
        else
        {
            // Nothing to send!
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "=> No pending packets, nothing to send!");
        }
    }
    else if (mPafTP.TxState() == WiFiPAFTP::kState_InProgress)
    {
        // Send next fragment of message currently held by fragmenter.
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "Send the next fragment");
        ReturnErrorOnFailure(ContinueMessageSend());
    }
    else if (mPafTP.TxState() == WiFiPAFTP::kState_Complete)
    {
        // Clear fragmenter's pointer to sent message buffer and reset its Tx state.
        // Buffer will be freed at scope exit.
        PacketBufferHandle sentBuf = mPafTP.TakeTxPacket();

        if (!mSendQueue.IsNull())
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "Send the next pkt");
            // Transmit first fragment of next whole message in send queue.
            ReturnErrorOnFailure(SendNextMessage());
        }
        else if (mState == kState_Closing && !mPafTP.ExpectingAck()) // and mSendQueue is NULL, per above...
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "Closing and no expect ack!");
            // If end point closing, got last ack, and got out-of-order confirmation for last send, finalize close.
            FinalizeClose(mState, kWiFiPAFCloseFlag_SuppressCallback, CHIP_NO_ERROR);
        }
        else
        {
            // Nothing to send!
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "No more packets to send");
        }
    }
    else
    {
        ChipLogError(WiFiPAF, "Unknown TxState: %u", mPafTP.TxState());
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::HandleCapabilitiesRequestReceived(PacketBufferHandle && data)
{
    PAFTransportCapabilitiesRequestMessage req;
    PAFTransportCapabilitiesResponseMessage resp;
    uint16_t mtu;

    VerifyOrReturnError(!data.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);

    mState = kState_Connecting;

    // Decode PAFTP capabilities request.
    ReturnErrorOnFailure(PAFTransportCapabilitiesRequestMessage::Decode(data, req));

    PacketBufferHandle responseBuf = System::PacketBufferHandle::New(kCapabilitiesResponseLength);
    VerifyOrReturnError(!responseBuf.IsNull(), CHIP_ERROR_NO_MEMORY);

    if (req.mMtu > 0) // If MTU was observed and provided by central...
    {
        mtu = req.mMtu; // Accept central's observation of the MTU.
    }
    else
    {
        mtu = CHIP_PAF_DEFAULT_MTU;
    }

    // Select fragment size for connection based on MTU.
    VerifyOrReturnError(mtu >= WiFiPAFTP::sMinFragmentSize, WIFIPAF_ERROR_INVALID_FRAGMENT_SIZE);
    resp.mFragmentSize = std::min(static_cast<uint16_t>(mtu), WiFiPAFTP::sMaxFragmentSize);

    // Select local and remote max receive window size based on local resources available for both incoming writes
    auto windowSize = std::min(req.mWindowSize, static_cast<uint8_t>(PAF_MAX_RECEIVE_WINDOW_SIZE));
    if (windowSize < PAF_MIN_RECEIVE_WINDOW_SIZE)
    {
        // The Window size should be at least PAF_MIN_RECEIVE_WINDOW_SIZE to ensure PAF stability and avoid underflow problems.
        ChipLogError(WiFiPAF, "Small window size: %u, reject due to stability requirement", windowSize);
        mState = kState_Aborting;
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    mRemoteReceiveWindowSize = mLocalReceiveWindowSize = mReceiveWindowMaxSize = windowSize;
    resp.mWindowSize                                                           = mReceiveWindowMaxSize;
    ChipLogProgress(WiFiPAF, "local and remote recv window sizes = %u", resp.mWindowSize);

    // Select PAF transport protocol version from those supported by central, or none if no supported version found.
    resp.mSelectedProtocolVersion = WiFiPAFLayer::GetHighestSupportedProtocolVersion(req);
    ChipLogProgress(WiFiPAF, "selected PAFTP version %d", resp.mSelectedProtocolVersion);

    if (resp.mSelectedProtocolVersion == kWiFiPAFTransportProtocolVersion_None)
    {
        // If WiFiPAF transport protocol versions incompatible, prepare to close connection after capabilities response
        // has been sent.
        ChipLogError(WiFiPAF, "incompatible PAFTP versions; peripheral expected between %d and %d",
                     CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION, CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION);
        mState = kState_Aborting;
    }
    else
    {
        // Set Rx and Tx fragment sizes to the same value
        mPafTP.SetRxFragmentSize(resp.mFragmentSize);
        mPafTP.SetTxFragmentSize(resp.mFragmentSize);
    }

    ChipLogProgress(WiFiPAF, "using PAFTP fragment sizes rx %d / tx %d.", mPafTP.GetRxFragmentSize(), mPafTP.GetTxFragmentSize());
    ReturnErrorOnFailure(resp.Encode(responseBuf));

    CHIP_ERROR err;
    err = SendWrite(responseBuf.Retain());
    SuccessOrExit(err);

    // Stash capabilities response payload
    QueueTx(std::move(responseBuf), kType_Data);

    // Response has been sent
    return HandleConnectComplete();
exit:
    return err;
}

CHIP_ERROR WiFiPAFEndPoint::HandleCapabilitiesResponseReceived(PacketBufferHandle && data)
{
    PAFTransportCapabilitiesResponseMessage resp;

    VerifyOrReturnError(!data.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);

    // Decode PAFTP capabilities response.
    ReturnErrorOnFailure(PAFTransportCapabilitiesResponseMessage::Decode(data, resp));

    VerifyOrReturnError(resp.mFragmentSize >= WiFiPAFTP::sMinFragmentSize, WIFIPAF_ERROR_INVALID_FRAGMENT_SIZE);

    ChipLogProgress(WiFiPAF, "Publisher chose PAFTP version %d; subscriber expected between %d and %d",
                    resp.mSelectedProtocolVersion, CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION,
                    CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION);

    if ((resp.mSelectedProtocolVersion < CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) ||
        (resp.mSelectedProtocolVersion > CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION))
    {
        return WIFIPAF_ERROR_INCOMPATIBLE_PROTOCOL_VERSIONS;
    }

    // Set fragment size as minimum of (reported ATT MTU, BTP characteristic size)
    resp.mFragmentSize = std::min(resp.mFragmentSize, WiFiPAFTP::sMaxFragmentSize);

    mPafTP.SetRxFragmentSize(resp.mFragmentSize);
    mPafTP.SetTxFragmentSize(resp.mFragmentSize);

    ChipLogProgress(WiFiPAF, "using PAFTP fragment sizes rx %d / tx %d.", mPafTP.GetRxFragmentSize(), mPafTP.GetTxFragmentSize());

    // Select local and remote max receive window size based on local resources available for both incoming indications
    if (resp.mWindowSize < PAF_MIN_RECEIVE_WINDOW_SIZE)
    {
        // The Window size should be at least PAF_MIN_RECEIVE_WINDOW_SIZE to ensure PAF stability and avoid underflow problems.
        ChipLogError(WiFiPAF, "Small window size: %u, reject due to stability requirement", resp.mWindowSize);
        mState = kState_Aborting;
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    mRemoteReceiveWindowSize = mLocalReceiveWindowSize = mReceiveWindowMaxSize =
        std::min(resp.mWindowSize, static_cast<uint8_t>(PAF_MAX_RECEIVE_WINDOW_SIZE));
    ChipLogProgress(WiFiPAF, "local and remote recv window size = %u", mReceiveWindowMaxSize);

    // Shrink local receive window counter by 1, since connect handshake indication requires acknowledgement.
    mLocalReceiveWindowSize = static_cast<SequenceNumber_t>(mLocalReceiveWindowSize - 1);
    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "decremented local rx window, new size = %u", mLocalReceiveWindowSize);

    // Send ack for connection handshake indication when timer expires. Sequence numbers always start at 0,
    // and the reassembler's "last received seq num" is initialized to 0 and updated when new fragments are
    // received from the peripheral, so we don't need to explicitly mark the ack num to send here.
    ReturnErrorOnFailure(StartSendAckTimer());

    // We've sent a capabilities request write and received a compatible response, so the connect
    // operation has completed successfully.
    return HandleConnectComplete();
}

// Returns number of open slots in remote receive window given the input values.
SequenceNumber_t WiFiPAFEndPoint::AdjustRemoteReceiveWindow(SequenceNumber_t lastReceivedAck, SequenceNumber_t maxRemoteWindowSize,
                                                            SequenceNumber_t newestUnackedSentSeqNum)
{
    // Assumption: SequenceNumber_t is uint8_t.
    // Assumption: Maximum possible sequence number value is UINT8_MAX.
    // Assumption: Sequence numbers incremented past maximum value wrap to 0.
    // Assumption: newest unacked sent sequence number never exceeds current (and by extension, new and un-wrapped)
    //             window boundary, so it never wraps relative to last received ack, if new window boundary would not
    //             also wrap.

    // Define new window boundary (inclusive) as uint16_t, so its value can temporarily exceed UINT8_MAX.
    uint16_t newRemoteWindowBoundary = static_cast<uint16_t>(lastReceivedAck + maxRemoteWindowSize);

    if (newRemoteWindowBoundary > UINT8_MAX && newestUnackedSentSeqNum < lastReceivedAck)
    {
        // New window boundary WOULD wrap, and latest unacked seq num already HAS wrapped, so add offset to difference.
        return static_cast<uint8_t>(newRemoteWindowBoundary - (newestUnackedSentSeqNum + UINT8_MAX));
    }

    // Neither values would or have wrapped, OR new boundary WOULD wrap but latest unacked seq num does not, so no
    // offset required.
    return static_cast<uint8_t>(newRemoteWindowBoundary - newestUnackedSentSeqNum);
}

CHIP_ERROR WiFiPAFEndPoint::GetPktSn(Encoding::LittleEndian::Reader & reader, uint8_t * pHead, SequenceNumber_t & seqNum)
{
    BitFlags<WiFiPAFTP::HeaderFlags> rx_flags;
    size_t SnOffset = 0;
    SequenceNumber_t * pSn;
    ReturnErrorOnFailure(reader.Read8(rx_flags.RawStorage()).StatusCode());
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kHankshake))
    {
        // Handkshake message => No ack/sn
        return CHIP_ERROR_INTERNAL;
    }
    // Always has header flag
    SnOffset += kTransferProtocolHeaderFlagsSize;
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kManagementOpcode)) // Has Mgmt_Op
    {
        SnOffset += kTransferProtocolMgmtOpSize;
    }
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kFragmentAck)) // Has ack
    {
        SnOffset += kTransferProtocolAckSize;
    }
    VerifyOrReturnError(SnOffset + sizeof(seqNum) <= reader.OctetsRead() + reader.Remaining(), CHIP_ERROR_MESSAGE_INCOMPLETE);
    pSn    = pHead + SnOffset;
    seqNum = *pSn;

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::DebugPktAckSn(const PktDirect_t PktDirect, Encoding::LittleEndian::Reader & reader, uint8_t * pHead)
{
#ifdef CHIP_WIFIPAF_END_POINT_DEBUG_LOGGING_ENABLED
    BitFlags<WiFiPAFTP::HeaderFlags> rx_flags;
    CHIP_ERROR err;
    uint8_t * pAct = nullptr;
    char AckBuff[4];
    uint8_t * pSn;
    size_t SnOffset = 0;

    err = reader.Read8(rx_flags.RawStorage()).StatusCode();
    SuccessOrExit(err);
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kHankshake))
    {
        // Handkshake message => No ack/sn
        return CHIP_NO_ERROR;
    }
    // Always has header flag
    SnOffset += kTransferProtocolHeaderFlagsSize;
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kManagementOpcode)) // Has Mgmt_Op
    {
        SnOffset += kTransferProtocolMgmtOpSize;
    }
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kFragmentAck)) // Has ack
    {
        pAct = pHead + kTransferProtocolHeaderFlagsSize;
        SnOffset += kTransferProtocolAckSize;
    }
    VerifyOrExit(SnOffset + sizeof(*pSn) <= reader.OctetsRead() + reader.Remaining(), err = CHIP_ERROR_MESSAGE_INCOMPLETE);
    pSn = pHead + SnOffset;
    if (pAct == nullptr)
    {
        strcpy(AckBuff, "  ");
    }
    else
    {
        snprintf(AckBuff, sizeof(AckBuff), "%02hhu", *pAct);
    }
    if (PktDirect == PktDirect_t::kTx)
    {
        ChipLogDebugWiFiPAFEndPoint_L0(WiFiPAF, "==>[tx] [Sn, Ack] = [   %02u, -- %s]", *pSn, AckBuff);
    }
    else if (PktDirect == PktDirect_t::kRx)
    {
        ChipLogDebugWiFiPAFEndPoint_L0(WiFiPAF, "<==[rx] [Ack, Sn] = [-- %s,    %02u]", AckBuff, *pSn);
    }
exit:
    return err;
#else
    return CHIP_NO_ERROR;
#endif
}

CHIP_ERROR WiFiPAFEndPoint::Receive(PacketBufferHandle && data)
{
    SequenceNumber_t ExpRxNextSeqNum = mPafTP.GetRxNextSeqNum();
    SequenceNumber_t seqNum;
    Encoding::LittleEndian::Reader reader(data->Start(), data->DataLength());
    CHIP_ERROR err = CHIP_NO_ERROR;

    err = GetPktSn(reader, data->Start(), seqNum);
    if (err != CHIP_NO_ERROR)
    {
        // Failed to get SeqNum. => Pass down to PAFTP engine directly
        return RxPacketProcess(std::move(data));
    }
    /*
        If reorder-queue is not empty => Need to queue the packet whose SeqNum is the next one at
        offset 0 to fill the hole.
    */
    if ((ExpRxNextSeqNum == seqNum) && (ItemsInReorderQueue == 0))
        return RxPacketProcess(std::move(data));

    ChipLogError(WiFiPAF, "Reorder the packet: [%u, %u]", ExpRxNextSeqNum, seqNum);
    // Start reordering packets
    SequenceNumber_t offset = OffsetSeqNum(seqNum, ExpRxNextSeqNum);
    if (offset >= PAFTP_REORDER_QUEUE_SIZE)
    {
        // Offset is too big
        // => It may be the unexpected packet or duplicate packet => drop it
        ChipLogError(WiFiPAF, "Offset (%u) is too big => drop the packet", offset);
        ChipLogDebugBufferWiFiPAFEndPoint(WiFiPAF, data);
        return CHIP_NO_ERROR;
    }

    // Save the packet to the reorder-queue
    if (ReorderQueue[offset].IsNull())
    {
        ReorderQueue[offset] = std::move(data);
        ItemsInReorderQueue++;
    }

    // Consume the packets in the reorder queue if no hole exists
    if (ReorderQueue[0].IsNull())
    {
        // The hole still exists => Can't continue
        ChipLogError(WiFiPAF, "The hole still exists. Packets in reorder-queue: %u", ItemsInReorderQueue);
        return CHIP_NO_ERROR;
    }
    uint8_t qidx;
    for (qidx = 0; qidx < PAFTP_REORDER_QUEUE_SIZE; qidx++)
    {
        // The head slots should have been filled. => Do rx processing
        if (ReorderQueue[qidx].IsNull())
        {
            // Stop consuming packets until the hole or no packets
            break;
        }
        // Consume the saved packets
        ChipLogProgress(WiFiPAF, "Rx processing from the re-order queue [%u]", qidx);
        err = RxPacketProcess(std::move(ReorderQueue[qidx]));
        ItemsInReorderQueue--;
    }
    // Has reached the 1st hole in the queue => move the rest items forward
    // Note: It's to continue => No need to reinit "i"
    for (uint8_t newId = 0; qidx < PAFTP_REORDER_QUEUE_SIZE; qidx++, newId++)
    {
        if (!ReorderQueue[qidx].IsNull())
        {
            ReorderQueue[newId] = std::move(ReorderQueue[qidx]);
            ReorderQueue[qidx]  = nullptr;
        }
    }
    return err;
}

CHIP_ERROR WiFiPAFEndPoint::RxPacketProcess(PacketBufferHandle && data)
{
    ChipLogDebugBufferWiFiPAFEndPoint(WiFiPAF, data);

    CHIP_ERROR err               = CHIP_NO_ERROR;
    SequenceNumber_t receivedAck = 0;
    uint8_t closeFlags           = kWiFiPAFCloseFlag_AbortTransmission;
    bool didReceiveAck           = false;
    BitFlags<WiFiPAFTP::HeaderFlags> rx_flags;
    Encoding::LittleEndian::Reader reader(data->Start(), data->DataLength());
    TEMPORARY_RETURN_IGNORED DebugPktAckSn(PktDirect_t::kRx, reader, data->Start());

    { // This is a special handling on the first CHIPoPAF data packet, the CapabilitiesRequest.
        // If we're receiving the first inbound packet of a PAF transport connection handshake...
        if (!mConnStateFlags.Has(ConnectionStateFlag::kCapabilitiesMsgReceived))
        {
            if (mRole == kWiFiPafRole_Subscriber) // If we're a central receiving a capabilities response indication...
            {
                // Ensure end point's in the right state before continuing.
                VerifyOrExit(mState == kState_Connecting, err = CHIP_ERROR_INCORRECT_STATE);
                mConnStateFlags.Set(ConnectionStateFlag::kCapabilitiesMsgReceived);
                err = HandleCapabilitiesResponseReceived(std::move(data));
                SuccessOrExit(err);
            }
            else // Or, a peripheral receiving a capabilities request write...
            {
                // Ensure end point's in the right state before continuing.
                VerifyOrExit(mState == kState_Ready, err = CHIP_ERROR_INCORRECT_STATE);
                mConnStateFlags.Set(ConnectionStateFlag::kCapabilitiesMsgReceived);
                err = HandleCapabilitiesRequestReceived(std::move(data));
                if (err != CHIP_NO_ERROR)
                {
                    // If an error occurred decoding and handling the capabilities request, release the BLE connection.
                    // Central's connect attempt will time out if peripheral's application decides to keep the BLE
                    // connection open, or fail immediately if the application closes the connection.
                    closeFlags = closeFlags | kWiFiPAFCloseFlag_SuppressCallback;
                    ExitNow();
                }
            }
            // If received data was handshake packet, don't feed it to message reassembler.
            ExitNow();
        }
    } // End handling the CapabilitiesRequest

    err = reader.Read8(rx_flags.RawStorage()).StatusCode();
    SuccessOrExit(err);
    if (rx_flags.Has(WiFiPAFTP::HeaderFlags::kHankshake))
    {
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "Unexpected handshake packet => drop");
        ExitNow();
    }

    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "PAFTP about to rx characteristic, state before:");
    mPafTP.LogStateDebug();

    // Pass received packet into PAFTP protocol engine.
    err = mPafTP.HandleCharacteristicReceived(std::move(data), receivedAck, didReceiveAck);

    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "PAFTP rx'd characteristic, state after:");
    mPafTP.LogStateDebug();
    SuccessOrExit(err);

    // Protocol engine accepted the fragment, so shrink local receive window counter by 1.
    mLocalReceiveWindowSize = static_cast<SequenceNumber_t>(mLocalReceiveWindowSize - 1);
    ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "decremented local rx window, new size = %u", mLocalReceiveWindowSize);

    // Respond to received ack, if any.
    if (didReceiveAck)
    {
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "got paftp ack = %u", receivedAck);

        // If ack was rx'd for newest unacked sent fragment, stop ack received timer.
        if (!mPafTP.ExpectingAck())
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "got ack for last outstanding fragment");
            StopAckReceivedTimer();

            if (mState == kState_Closing && mSendQueue.IsNull() && mPafTP.TxState() == WiFiPAFTP::kState_Idle)
            {
                // If end point closing, got confirmation for last send, and waiting for last ack, finalize close.
                FinalizeClose(mState, kWiFiPAFCloseFlag_SuppressCallback, CHIP_NO_ERROR);
                ExitNow();
            }
        }
        else // Else there are still sent fragments for which acks are expected, so restart ack received timer.
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "still expecting ack(s), restarting timer...");
            err = RestartAckReceivedTimer();
            SuccessOrExit(err);
        }

        ChipLogDebugWiFiPAFEndPoint(
            WiFiPAF, "about to adjust remote rx window; got ack num = %u, newest unacked sent seq num = %u, \
                old window size = %u, max window size = %u",
            receivedAck, mPafTP.GetNewestUnackedSentSequenceNumber(), mRemoteReceiveWindowSize, mReceiveWindowMaxSize);

        // Open remote device's receive window according to sequence number it just acknowledged.
        mRemoteReceiveWindowSize =
            AdjustRemoteReceiveWindow(receivedAck, mReceiveWindowMaxSize, mPafTP.GetNewestUnackedSentSequenceNumber());

        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "adjusted remote rx window, new size = %u", mRemoteReceiveWindowSize);

        // Restart message transmission if it was previously paused due to window exhaustion.
        err = DriveSending();
        SuccessOrExit(err);
    }

    // The previous DriveSending() might have generated a piggyback acknowledgement if there was
    // previously un-acked data.  Otherwise, prepare to send acknowledgement for newly received fragment.
    //
    // If local receive window is below immediate ack threshold, AND there is no previous stand-alone ack in
    // flight, AND there is no pending outbound message fragment on which the ack can and will be piggybacked,
    // send immediate stand-alone ack to reopen window for sender.
    //
    // The "operation in flight" check below covers "pending outbound message fragment" by extension, as when
    // a message has been passed to the end point via Send(), its next outbound fragment must either be in flight
    // itself, or awaiting the completion of another in-flight operation.
    //
    // If any operation is in flight that is NOT a stand-alone ack, the window size will be checked against
    // this threshold again when the operation is confirmed.
    if (mPafTP.HasUnackedData())
    {
        if (mLocalReceiveWindowSize <= WIFIPAF_CONFIG_IMMEDIATE_ACK_WINDOW_THRESHOLD &&
            !mConnStateFlags.Has(ConnectionStateFlag::kOperationInFlight))
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "sending immediate ack");
            err = DriveStandAloneAck();
            SuccessOrExit(err);
        }
        else
        {
            ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "starting send-ack timer");
            // Send ack when timer expires.
            err = StartSendAckTimer();
            SuccessOrExit(err);
        }
    }

    // If we've reassembled a whole message...
    if (mPafTP.RxState() == WiFiPAFTP::kState_Complete)
    {
        // Take ownership of message buffer
        System::PacketBufferHandle full_packet = mPafTP.TakeRxPacket();

        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "reassembled whole msg, len = %u", static_cast<unsigned>(full_packet->DataLength()));

        // If we have a message received callback, and end point is not closing...
        if (mWiFiPafLayer != nullptr && mState != kState_Closing)
        {
            // Pass received message up the stack.
            err = mWiFiPafLayer->OnWiFiPAFMsgRxComplete(mSessionInfo, std::move(full_packet));
        }
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        DoClose(closeFlags, err);
    }

    return err;
}

CHIP_ERROR WiFiPAFEndPoint::SendWrite(PacketBufferHandle && buf)
{
    mConnStateFlags.Set(ConnectionStateFlag::kOperationInFlight);

    ChipLogDebugBufferWiFiPAFEndPoint(WiFiPAF, buf);
    Encoding::LittleEndian::Reader reader(buf->Start(), buf->DataLength());
    TEMPORARY_RETURN_IGNORED DebugPktAckSn(PktDirect_t::kTx, reader, buf->Start());
    return mWiFiPafLayer->mWiFiPAFTransport->WiFiPAFMessageSend(mSessionInfo, std::move(buf));
}

CHIP_ERROR WiFiPAFEndPoint::StartConnectTimer()
{
    const CHIP_ERROR timerErr = mWiFiPafLayer->mSystemLayer->StartTimer(System::Clock::Milliseconds32(PAFTP_CONN_RSP_TIMEOUT_MS),
                                                                        HandleConnectTimeout, this);
    ReturnErrorOnFailure(timerErr);
    mTimerStateFlags.Set(TimerStateFlag::kConnectTimerRunning);

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::StartReceiveConnectionTimer()
{
    const CHIP_ERROR timerErr = mWiFiPafLayer->mSystemLayer->StartTimer(System::Clock::Milliseconds32(PAFTP_CONN_RSP_TIMEOUT_MS),
                                                                        HandleReceiveConnectionTimeout, this);
    ReturnErrorOnFailure(timerErr);
    mTimerStateFlags.Set(TimerStateFlag::kReceiveConnectionTimerRunning);

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::StartAckReceivedTimer()
{
    if (!mTimerStateFlags.Has(TimerStateFlag::kAckReceivedTimerRunning))
    {
        const CHIP_ERROR timerErr = mWiFiPafLayer->mSystemLayer->StartTimer(System::Clock::Milliseconds32(PAFTP_ACK_TIMEOUT_MS),
                                                                            HandleAckReceivedTimeout, this);
        ReturnErrorOnFailure(timerErr);

        mTimerStateFlags.Set(TimerStateFlag::kAckReceivedTimerRunning);
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::RestartAckReceivedTimer()
{
    VerifyOrReturnError(mTimerStateFlags.Has(TimerStateFlag::kAckReceivedTimerRunning), CHIP_ERROR_INCORRECT_STATE);

    StopAckReceivedTimer();

    return StartAckReceivedTimer();
}

CHIP_ERROR WiFiPAFEndPoint::StartSendAckTimer()
{
    if (!mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning))
    {
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "starting new SendAckTimer");
        const CHIP_ERROR timerErr = mWiFiPafLayer->mSystemLayer->StartTimer(
            System::Clock::Milliseconds32(WIFIPAF_ACK_SEND_TIMEOUT_MS), HandleSendAckTimeout, this);
        ReturnErrorOnFailure(timerErr);

        mTimerStateFlags.Set(TimerStateFlag::kSendAckTimerRunning);
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR WiFiPAFEndPoint::StartWaitResourceTimer()
{
    mResourceWaitCount++;
    if (mResourceWaitCount >= WIFIPAF_MAX_RESOURCE_BLOCK_COUNT)
    {
        ChipLogError(WiFiPAF, "Network resource has been unavailable for a long time");
        mResourceWaitCount = 0;
        DoClose(kWiFiPAFCloseFlag_AbortTransmission, CHIP_ERROR_NOT_CONNECTED);
        return CHIP_NO_ERROR;
    }
    if (!mTimerStateFlags.Has(TimerStateFlag::kWaitResTimerRunning))
    {
        ChipLogDebugWiFiPAFEndPoint(WiFiPAF, "starting new WaitResTimer");
        const CHIP_ERROR timerErr = mWiFiPafLayer->mSystemLayer->StartTimer(
            System::Clock::Milliseconds32(WIFIPAF_WAIT_RES_TIMEOUT_MS), HandleWaitResourceTimeout, this);
        ReturnErrorOnFailure(timerErr);
        mTimerStateFlags.Set(TimerStateFlag::kWaitResTimerRunning);
    }
    return CHIP_NO_ERROR;
}

void WiFiPAFEndPoint::StopConnectTimer()
{
    // Cancel any existing connect timer.
    mWiFiPafLayer->mSystemLayer->CancelTimer(HandleConnectTimeout, this);
    mTimerStateFlags.Clear(TimerStateFlag::kConnectTimerRunning);
}

void WiFiPAFEndPoint::StopReceiveConnectionTimer()
{
    // Cancel any existing receive-connection timer.
    mWiFiPafLayer->mSystemLayer->CancelTimer(HandleReceiveConnectionTimeout, this);
    mTimerStateFlags.Clear(TimerStateFlag::kReceiveConnectionTimerRunning);
}

void WiFiPAFEndPoint::StopAckReceivedTimer()
{
    // Cancel any existing ack-received timer.
    mWiFiPafLayer->mSystemLayer->CancelTimer(HandleAckReceivedTimeout, this);
    mTimerStateFlags.Clear(TimerStateFlag::kAckReceivedTimerRunning);
}

void WiFiPAFEndPoint::StopSendAckTimer()
{
    // Cancel any existing send-ack timer.
    mWiFiPafLayer->mSystemLayer->CancelTimer(HandleSendAckTimeout, this);
    mTimerStateFlags.Clear(TimerStateFlag::kSendAckTimerRunning);
}

void WiFiPAFEndPoint::StopWaitResourceTimer()
{
    // Cancel any existing wait-resource timer.
    mWiFiPafLayer->mSystemLayer->CancelTimer(HandleWaitResourceTimeout, this);
    mTimerStateFlags.Clear(TimerStateFlag::kWaitResTimerRunning);
}

void WiFiPAFEndPoint::HandleConnectTimeout(chip::System::Layer * systemLayer, void * appState)
{
    WiFiPAFEndPoint * ep = static_cast<WiFiPAFEndPoint *>(appState);

    // Check for event-based timer race condition.
    if (ep->mTimerStateFlags.Has(TimerStateFlag::kConnectTimerRunning))
    {
        ChipLogError(WiFiPAF, "connect handshake timed out, closing ep %p", ep);
        ep->mTimerStateFlags.Clear(TimerStateFlag::kConnectTimerRunning);
        ep->DoClose(kWiFiPAFCloseFlag_AbortTransmission, WIFIPAF_ERROR_CONNECT_TIMED_OUT);
    }
}

void WiFiPAFEndPoint::HandleReceiveConnectionTimeout(chip::System::Layer * systemLayer, void * appState)
{
    WiFiPAFEndPoint * ep = static_cast<WiFiPAFEndPoint *>(appState);

    // Check for event-based timer race condition.
    if (ep->mTimerStateFlags.Has(TimerStateFlag::kReceiveConnectionTimerRunning))
    {
        ChipLogError(WiFiPAF, "receive handshake timed out, closing ep %p", ep);
        ep->mTimerStateFlags.Clear(TimerStateFlag::kReceiveConnectionTimerRunning);
        ep->DoClose(kWiFiPAFCloseFlag_SuppressCallback | kWiFiPAFCloseFlag_AbortTransmission, WIFIPAF_ERROR_RECEIVE_TIMED_OUT);
    }
}

void WiFiPAFEndPoint::HandleAckReceivedTimeout(chip::System::Layer * systemLayer, void * appState)
{
    WiFiPAFEndPoint * ep = static_cast<WiFiPAFEndPoint *>(appState);

    // Check for event-based timer race condition.
    if (ep->mTimerStateFlags.Has(TimerStateFlag::kAckReceivedTimerRunning))
    {
        ChipLogError(WiFiPAF, "ack recv timeout, closing ep %p", ep);
        ep->mPafTP.LogStateDebug();
        ep->mTimerStateFlags.Clear(TimerStateFlag::kAckReceivedTimerRunning);
        ep->DoClose(kWiFiPAFCloseFlag_AbortTransmission, WIFIPAF_ERROR_FRAGMENT_ACK_TIMED_OUT);
    }
}

void WiFiPAFEndPoint::HandleSendAckTimeout(chip::System::Layer * systemLayer, void * appState)
{
    WiFiPAFEndPoint * ep = static_cast<WiFiPAFEndPoint *>(appState);

    // Check for event-based timer race condition.
    if (ep->mTimerStateFlags.Has(TimerStateFlag::kSendAckTimerRunning))
    {
        ep->mTimerStateFlags.Clear(TimerStateFlag::kSendAckTimerRunning);

        // If previous stand-alone ack isn't still in flight...
        if (!ep->mConnStateFlags.Has(ConnectionStateFlag::kStandAloneAckInFlight))
        {
            CHIP_ERROR sendErr = ep->DriveStandAloneAck();

            if (sendErr != CHIP_NO_ERROR)
            {
                ep->DoClose(kWiFiPAFCloseFlag_AbortTransmission, sendErr);
            }
        }
    }
}

void WiFiPAFEndPoint::HandleWaitResourceTimeout(chip::System::Layer * systemLayer, void * appState)
{
    WiFiPAFEndPoint * ep = static_cast<WiFiPAFEndPoint *>(appState);

    // Check for event-based timer race condition.
    if (ep->mTimerStateFlags.Has(TimerStateFlag::kWaitResTimerRunning))
    {
        ep->mTimerStateFlags.Clear(TimerStateFlag::kWaitResTimerRunning);
        CHIP_ERROR sendErr = ep->DriveSending();
        if (sendErr != CHIP_NO_ERROR)
        {
            ep->DoClose(kWiFiPAFCloseFlag_AbortTransmission, sendErr);
        }
    }
}

void WiFiPAFEndPoint::ClearAll()
{
    // Return the end point to the free state the pool relies on (GetFree()/Find() key off
    // mWiFiPafLayer == nullptr). The endpoint owns ref-counted PacketBufferHandles (mSendQueue,
    // mAckToSend, ReorderQueue and buffers inside mPafTP); release those explicitly, then reset
    // the trivially-copyable state. Any owning member added here later must be released too.
    mSendQueue = nullptr;
    mAckToSend = nullptr;
    for (auto & queued : ReorderQueue)
    {
        queued = nullptr;
    }
    ItemsInReorderQueue = 0;
    mPafTP.ClearRxPacket();
    mPafTP.ClearTxPacket();

    mWiFiPafLayer           = nullptr;
    mOnPafSubscribeComplete = nullptr;
    mOnPafSubscribeError    = nullptr;
    mAppState               = nullptr;
    OnMessageReceived       = nullptr;
    OnConnectionClosed      = nullptr;

    mState = kState_Closed;
    mRole  = kWiFiPafRole_Publisher;
    mRxAck = 0;
    mConnStateFlags.ClearAll();
    mTimerStateFlags.ClearAll();
    mLocalReceiveWindowSize  = 0;
    mRemoteReceiveWindowSize = 0;
    mReceiveWindowMaxSize    = 0;
    mResourceWaitCount       = 0;
    mSessionInfo             = WiFiPAFSession{};
}

} /* namespace WiFiPAF */
} /* namespace chip */
