/*
 *
 *    Copyright (c) 2013-2018 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 implements the <tt>nl::Inet::TCPEndPoint</tt> class,
 *      where the Nest Inet Layer encapsulates methods for interacting
 *      with TCP transport endpoints (SOCK_DGRAM sockets on Linux and
 *      BSD-derived systems) or LwIP TCP protocol control blocks, as
 *      the system is configured accordingly.
 *
 */

#define __APPLE_USE_RFC_3542

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <string.h>
#include <stdio.h>

#include <SystemLayer/SystemFaultInjection.h>

#include <InetLayer/TCPEndPoint.h>
#include <InetLayer/InetLayer.h>
#include <InetLayer/InetFaultInjection.h>

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

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include <lwip/tcp.h>
#include <lwip/tcpip.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#include <sys/socket.h>
#include <sys/select.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/tcp.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#include "arpa-inet-compatibility.h"

// SOCK_CLOEXEC not defined on all platforms, e.g. iOS/MacOS:
#ifdef SOCK_CLOEXEC
#define SOCK_FLAGS SOCK_CLOEXEC
#else
#define SOCK_FLAGS 0
#endif

#if defined(SOL_TCP)
// socket option level for Linux and BSD systems.
#define TCP_SOCKOPT_LEVEL SOL_TCP
#else
// socket option level for MacOS & iOS systems.
#define TCP_SOCKOPT_LEVEL IPPROTO_TCP
#endif

#if defined(TCP_KEEPIDLE)
// socket option for Linux and BSD systems.
#define TCP_IDLE_INTERVAL_OPT_NAME TCP_KEEPIDLE
#else
// socket option for MacOS & iOS systems.
#define TCP_IDLE_INTERVAL_OPT_NAME TCP_KEEPALIVE
#endif

/*
 * This logic to register a null operation callback with the LwIP TCP/IP task
 * ensures that the TCP timer loop is started when a connection is established,
 * which is necessary to ensure that initial SYN and SYN-ACK packets are
 * retransmitted during the 3-way handshake.
 */
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
namespace {

void nil_tcpip_callback(void * _aContext)
{ }

err_t start_tcp_timers(void)
{
    return tcpip_callback(nil_tcpip_callback, NULL);
}

} // anonymous namespace
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

namespace nl {
namespace Inet {

using Weave::System::PacketBuffer;

Weave::System::ObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> TCPEndPoint::sPool;

INET_ERROR TCPEndPoint::Bind(IPAddressType addrType, IPAddress addr, uint16_t port, bool reuseAddr)
{
    INET_ERROR res = INET_NO_ERROR;

    if (State != kState_Ready)
        return INET_ERROR_INCORRECT_STATE;

    if (addr != IPAddress::Any && addr.Type() != kIPAddressType_Any && addr.Type() != addrType)
        return INET_ERROR_WRONG_ADDRESS_TYPE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Get the appropriate type of PCB.
    res = GetPCB(addrType);

    // Bind the PCB to the specified address/port.
    if (res == INET_NO_ERROR)
    {
        if (reuseAddr)
        {
            ip_set_option(mTCP, SOF_REUSEADDR);
        }

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5

        ip_addr_t ipAddr;
        if (addr != IPAddress::Any)
        {
            ipAddr = addr.ToLwIPAddr();
        }
        else if (addrType == kIPAddressType_IPv6)
        {
            ipAddr = ip6_addr_any;
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            ipAddr = ip_addr_any;
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            res = INET_ERROR_WRONG_ADDRESS_TYPE;
        res = Weave::System::MapErrorLwIP(tcp_bind(mTCP, &ipAddr, port));

#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

        if (addrType == kIPAddressType_IPv6)
        {
            ip6_addr_t ipv6Addr = addr.ToIPv6();
            res = Weave::System::MapErrorLwIP(tcp_bind_ip6(mTCP, &ipv6Addr, port));
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            ip_addr_t ipv4Addr = addr.ToIPv4();
            res = Weave::System::MapErrorLwIP(tcp_bind(mTCP, &ipv4Addr, port));
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            res = INET_ERROR_WRONG_ADDRESS_TYPE;

#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    res = GetSocket(addrType);

    if (res == INET_NO_ERROR && reuseAddr)
    {
        int n = 1;
        setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));

#ifdef SO_REUSEPORT
        // Enable SO_REUSEPORT.  This permits coexistence between an
        // untargetted Weave client and other services that listen on
        // a Weave port on a specific address (such as a Weave client
        // with TARGETTED_LISTEN or TCP proxying services).  Note that
        // one of the costs of this implementation is the
        // non-deterministic connection dispatch when multple clients
        // listen on the address wih the same degreee of selectivity,
        // e.g. two untargetted-listen Weave clients, or two
        // targetted-listen Weave clients with the same node id.

        if (setsockopt(mSocket, SOL_SOCKET, SO_REUSEPORT, &n, sizeof(n)) != 0)
        {
            WeaveLogError(Inet, "SO_REUSEPORT: %d", errno);
        }
#endif // defined(SO_REUSEPORT)

    }

    if (res == INET_NO_ERROR)
    {
        if (addrType == kIPAddressType_IPv6)
        {
            struct sockaddr_in6 sa;
            memset(&sa, 0, sizeof(sa));
            sa.sin6_family = AF_INET6;
            sa.sin6_port = htons(port);
            sa.sin6_flowinfo = 0;
            sa.sin6_addr = addr.ToIPv6();
            sa.sin6_scope_id = 0;

            if (bind(mSocket, (const sockaddr *) &sa, (unsigned) sizeof(sa)) != 0)
                res = Weave::System::MapErrorPOSIX(errno);
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            struct sockaddr_in sa;
            memset(&sa, 0, sizeof(sa));
            sa.sin_family = AF_INET;
            sa.sin_port = htons(port);
            sa.sin_addr = addr.ToIPv4();

            if (bind(mSocket, (const sockaddr *) &sa, (unsigned) sizeof(sa)) != 0)
                res = Weave::System::MapErrorPOSIX(errno);
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            res = INET_ERROR_WRONG_ADDRESS_TYPE;
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (res == INET_NO_ERROR)
        State = kState_Bound;

    return res;
}

INET_ERROR TCPEndPoint::Listen(uint16_t backlog)
{
    INET_ERROR res = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    Weave::System::Layer& lSystemLayer = SystemLayer();
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (State != kState_Bound)
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Start listening for incoming connections.
    mTCP = tcp_listen(mTCP);
    mLwIPEndPointType = kLwIPEndPointType_TCP;

    tcp_arg(mTCP, this);

    tcp_accept(mTCP, LwIPHandleIncomingConnection);

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (listen(mSocket, backlog) != 0)
        res = Weave::System::MapErrorPOSIX(errno);

    // Wake the thread calling select so that it recognizes the new socket.
    lSystemLayer.WakeSelect();

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (res == INET_NO_ERROR)
    {
        // Once Listening, bump the reference count.  The corresponding call to Release()
        // [or on LwIP, DeferredRelease()] will happen in DoClose().
        Retain();
        State = kState_Listening;
    }

    return res;
}

#if INET_CONFIG_TCP_CONN_REPAIR_SUPPORTED

bool TCPConnRepairInfo::IsValid (void) const
{
    if (!srcPort || !dstPort || !txSeq || !rxSeq || !sndWl1 || !sndWnd ||
        !maxWindow || !rcvWnd || !rcvWup)
    {
        return false;
    }

    return true;
}

void TCPConnRepairInfo::Dump (void) const
{
    char srcIPStr[64] = { 0 }, dstIPStr[64] = { 0 };

    srcIP.ToString(srcIPStr, sizeof(srcIPStr));
    dstIP.ToString(dstIPStr, sizeof(dstIPStr));

    WeaveLogDetail(Inet, "TCP repair src: %s:%d seq %u\n", srcIPStr, srcPort, txSeq);
    WeaveLogDetail(Inet, "TCP repair dst: %s:%d seq %u\n", dstIPStr, dstPort, rxSeq);

    WeaveLogDetail(Inet, "TCP repair opt: snd_wl1 %u snd_wnd %u max_window %u rcv_wnd %u rcv_wup %u\n",
                   sndWl1, sndWnd, maxWindow, rcvWnd, rcvWup);

    WeaveLogDetail(Inet, "TCP repair opt: mss %u snd_wscale %u rcv_wscale %u tcpi_opt %u\n",
                   mss, sndWscale, rcvWscale, tcpOptions);

    WeaveLogDetail(Inet, "local_port(%u), server_port(%u), tx_seq(%u), rx_seq(%u), snd_wl1(%u), snd_wnd(%u), max_window(%u), rcv_wnd(%u), rcv_wup(%u)\n",
                   srcPort, dstPort, txSeq, rxSeq, sndWl1, sndWnd,
                   maxWindow, rcvWnd, rcvWup);
}

INET_ERROR TCPEndPoint::RepairConnection(const TCPConnRepairInfo &connRepairInfo, InterfaceId intf)
{
    INET_ERROR res = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    res = INET_ERROR_NOT_SUPPORTED;
    ExitNow();
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    struct tcp_repair_opt opts[4];
    int opCtr = 0;
    uint32_t val;

    if (!connRepairInfo.IsValid())
    {
        WeaveLogError(Inet, "Not enough info to repair TCP connection\n");
        ExitNow(res = INET_ERROR_BAD_ARGS);
    }

    // Dump the contents of the TCP Connection Repair Info
    connRepairInfo.Dump();

    res = GetSocket(connRepairInfo.addrType);
    if (res != INET_NO_ERROR)
        ExitNow();

    val = 1;
    if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR, &val, sizeof(val)) != 0)
    {
        WeaveLogError(Inet, "TCP_REPAIR failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    val = 1;
    if (setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
    {
        WeaveLogError(Inet, "SO_REUSEADDR failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    /* ============= Restore TCP properties ==================*/

    val = TCP_SEND_QUEUE;
    if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val)) != 0)
    {
        WeaveLogError(Inet, "Repairing TCP_SEND_QUEUE failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    val = connRepairInfo.txSeq;
    WeaveLogDetail(Inet, "Restoring Tx seq: %u", val);
    if (setsockopt(mSocket, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val)) != 0)
    {
        WeaveLogError(Inet, "Tx Seq failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    val = TCP_RECV_QUEUE;
    if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val)) != 0) {
        WeaveLogError(Inet, "Repairing TCP_RECV_QUEUE failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    val = connRepairInfo.rxSeq;
    WeaveLogDetail(Inet, "Restoring Rx seq: %u", val);
    if (setsockopt(mSocket, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val)) != 0) {
        WeaveLogError(Inet, "Rx Seq failed: %d", errno);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    if (connRepairInfo.addrType == kIPAddressType_IPv6)
    {
        struct sockaddr_in6 serverAddress, localAddress;
        memset(&localAddress, 0, sizeof(localAddress));
        localAddress.sin6_family = AF_INET6;
        localAddress.sin6_addr = connRepairInfo.srcIP.ToIPv6();
        localAddress.sin6_port = htons(connRepairInfo.srcPort);

        memset(&serverAddress, 0, sizeof(serverAddress));
        serverAddress.sin6_family = AF_INET6;
        serverAddress.sin6_addr = connRepairInfo.dstIP.ToIPv6();
        serverAddress.sin6_port = htons(connRepairInfo.dstPort);

        if (bind(mSocket, (struct sockaddr *) &localAddress, sizeof(localAddress)) != 0)
        {
            WeaveLogError(Inet, "Bind src address failed: %d", errno);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }

        if (connect(mSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) != 0)
        {
            WeaveLogError(Inet, "Connect to dst address failed: %d", errno);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (connRepairInfo.addrType == kIPAddressType_IPv4)
    {
        struct sockaddr_in serverAddress, localAddress;
        memset(&localAddress, 0, sizeof(localAddress));
        localAddress.sin_family = AF_INET;
        localAddress.sin_addr = connRepairInfo.srcIP.ToIPv4();
        localAddress.sin_port = htons(connRepairInfo.srcPort);

        memset(&serverAddress, 0, sizeof(serverAddress));
        serverAddress.sin_family = AF_INET;
        serverAddress.sin_addr = connRepairInfo.dstIP.ToIPv4();
        serverAddress.sin_port = htons(connRepairInfo.dstPort);

        if (bind(mSocket, (struct sockaddr *) &localAddress, sizeof(localAddress)) != 0)
        {
            WeaveLogError(Inet, "Bind src address failed: %d", errno);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }

        if (connect(mSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) != 0)
        {
            WeaveLogError(Inet, "Connect to dst address failed: %d", errno);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }
    }
#endif // INET_CONFIG_ENABLE_IPV4
    else
    {
        ExitNow(res = INET_ERROR_WRONG_ADDRESS_TYPE);
    }

    /* Repair tcp options */

    if (connRepairInfo.tcpOptions & TCPI_OPT_SACK)
    {
        WeaveLogDetail(Inet, "Turning TCPI_OPT_SACK on\n");
        opts[opCtr].opt_code = TCPOPT_SACK_PERMITTED;
        opts[opCtr].opt_val = 0;
        opCtr++;
    }

    if (connRepairInfo.tcpOptions & TCPI_OPT_WSCALE)
    {
        WeaveLogDetail(Inet, "Set Send Window Scale to %u\n", connRepairInfo.sndWscale);
        WeaveLogDetail(Inet, "Set Receive Window Scale to %u\n", connRepairInfo.rcvWscale);
        opts[opCtr].opt_code = TCPOPT_WINDOW;
        opts[opCtr].opt_val = connRepairInfo.sndWscale + (connRepairInfo.rcvWscale << 16);
        opCtr++;
    }

    if (connRepairInfo.tcpOptions & TCPI_OPT_TIMESTAMPS)
    {
        WeaveLogDetail(Inet, "Turning TCPI_OPT_TIMESTAMPS on\n");
        opts[opCtr].opt_code = TCPOPT_TIMESTAMP;
        opts[opCtr].opt_val = 0;
        opCtr++;
    }

    WeaveLogDetail(Inet, "Set MSS clamp to %u\n", connRepairInfo.mss);
    opts[opCtr].opt_code = TCPOPT_MAXSEG;
    opts[opCtr].opt_val = connRepairInfo.mss;
    opCtr++;

    if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR_OPTIONS, opts, opCtr * sizeof(struct tcp_repair_opt)) < 0)
    {
        WeaveLogError(Inet, "%s: %d: Can't repair tcp options", __func__, __LINE__);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    if (connRepairInfo.tcpOptions & TCPI_OPT_TIMESTAMPS)
    {
        if (setsockopt(mSocket, SOL_TCP, TCP_TIMESTAMP, &connRepairInfo.tsVal, sizeof(connRepairInfo.tsVal)) < 0)
        {
            WeaveLogError(Inet, "%s: %d: Can't set timestamp", __func__, __LINE__);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }
    }

    if (connRepairInfo.maxWindow)
    {
        /* restore window */
        struct tcp_repair_window windowOpt = {
            .snd_wl1 = connRepairInfo.sndWl1,
            .snd_wnd = connRepairInfo.sndWnd,
            .max_window = connRepairInfo.maxWindow,
            .rcv_wnd = connRepairInfo.rcvWnd,
            .rcv_wup = connRepairInfo.rcvWup,
        };

        if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR_WINDOW, &windowOpt, sizeof(windowOpt)) != 0)
        {
            WeaveLogError(Inet, "%s: %d: Unable to set window parameters", __func__, __LINE__);
            ExitNow(res = Weave::System::MapErrorPOSIX(errno));
        }
    }

    val = 0;
    if (setsockopt(mSocket, SOL_TCP, TCP_REPAIR, &val, sizeof(val)) != 0)
    {
        WeaveLogError(Inet, "%s: %d: TCP_REPAIR failed", __func__, __LINE__);
        ExitNow(res = Weave::System::MapErrorPOSIX(errno));
    }

    mAddrType = connRepairInfo.addrType;

    // Mark state as Connected
    State = kState_Connected;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

exit:

    return res;
}
#endif // INET_CONFIG_TCP_CONN_REPAIR_SUPPORTED

INET_ERROR TCPEndPoint::Connect(IPAddress addr, uint16_t port, InterfaceId intf)
{
    INET_ERROR res = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    Weave::System::Layer& lSystemLayer = SystemLayer();
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (State != kState_Ready && State != kState_Bound)
        return INET_ERROR_INCORRECT_STATE;

    IPAddressType addrType = addr.Type();

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // LwIP does not provides an API for initiating a TCP connection via a specific interface.
    // As a work-around, if the destination is an IPv6 link-local address, we bind the PCB
    // to the link local address associated with the source interface; however this is only
    // viable if the endpoint hasn't already been bound.
    if (intf != INET_NULL_INTERFACEID)
    {
        IPAddress intfLLAddr;
        InetLayer& lInetLayer = Layer();

        if (!addr.IsIPv6LinkLocal() || State == kState_Bound)
            return INET_ERROR_NOT_IMPLEMENTED;

        res = lInetLayer.GetLinkLocalAddr(intf, &intfLLAddr);
        if (res != INET_NO_ERROR)
            return res;

        res = Bind(kIPAddressType_IPv6, intfLLAddr, 0, true);
        if (res != INET_NO_ERROR)
            return res;
    }

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    res = GetPCB(addrType);

    if (res == INET_NO_ERROR)
    {
        tcp_arg(mTCP, this);
        tcp_err(mTCP, LwIPHandleError);

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        ip_addr_t lwipAddr = addr.ToLwIPAddr();
        res = Weave::System::MapErrorLwIP(tcp_connect(mTCP, &lwipAddr, port, LwIPHandleConnectComplete));
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
        if (addrType == kIPAddressType_IPv6)
        {
            ip6_addr_t lwipAddr = addr.ToIPv6();
            res = Weave::System::MapErrorLwIP(tcp_connect_ip6(mTCP, &lwipAddr, port, LwIPHandleConnectComplete));
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            ip_addr_t lwipAddr = addr.ToIPv4();
            res = Weave::System::MapErrorLwIP(tcp_connect(mTCP, &lwipAddr, port, LwIPHandleConnectComplete));
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            res = INET_ERROR_WRONG_ADDRESS_TYPE;
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

        // Ensure that TCP timers are started
        if (res == INET_NO_ERROR)
        {
            res = start_tcp_timers();
        }

        if (res == INET_NO_ERROR)
        {
            State = kState_Connecting;
            Retain();
        }
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    res = GetSocket(addrType);
    if (res != INET_NO_ERROR)
        return res;

    if (intf == INET_NULL_INTERFACEID)
    {
        // The behavior when connecting to an IPv6 link-local address without specifying an outbound
        // interface is ambiguous. So prevent it in all cases.
        if (addr.IsIPv6LinkLocal())
            return INET_ERROR_WRONG_ADDRESS_TYPE;
    }
    else
    {
        // Try binding to the interface

        // If destination is link-local then there is no need to bind to
        // interface or address on the interface.

        if (!addr.IsIPv6LinkLocal())
        {
#ifdef SO_BINDTODEVICE
            struct ::ifreq ifr;
            memset(&ifr, 0, sizeof(ifr));

            res = GetInterfaceName(intf, ifr.ifr_name, sizeof(ifr.ifr_name));
            if (res != INET_NO_ERROR)
                return res;

            // Attempt to bind to the interface using SO_BINDTODEVICE which requires privileged access.
            // If the permission is denied(EACCES) because Weave is running in a context
            // that does not have privileged access, choose a source address on the
            // interface to bind the connetion to.
            int r = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
            if (r < 0 && errno != EACCES)
            {
                return res = Weave::System::MapErrorPOSIX(errno);
            }

            if (r < 0)
#endif // SO_BINDTODEVICE
            {
                // Attempting to initiate a connection via a specific interface is not allowed.
                // The only way to do this is to bind the local to an address on the desired
                // interface.
                res = BindSrcAddrFromIntf(addrType, intf);
                if (res != INET_NO_ERROR)
                    return res;
            }
        }
    }

    // Disable generation of SIGPIPE.
#ifdef SO_NOSIGPIPE
    int n = 1;
    setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));
#endif // defined(SO_NOSIGPIPE)

    // Enable non-blocking mode for the socket.
    int flags = fcntl(mSocket, F_GETFL, 0);
    fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);

    int sockaddrsize = 0;
    const sockaddr *sockaddrptr = NULL;

    union
    {
        sockaddr        any;
        sockaddr_in6    in6;
#if INET_CONFIG_ENABLE_IPV4
        sockaddr_in     in;
#endif // INET_CONFIG_ENABLE_IPV4
    } sa;
    memset(&sa, 0, sizeof(sa));

    if (addrType == kIPAddressType_IPv6)
    {
        sa.in6.sin6_family = AF_INET6;
        sa.in6.sin6_port = htons(port);
        sa.in6.sin6_flowinfo = 0;
        sa.in6.sin6_addr = addr.ToIPv6();
        sa.in6.sin6_scope_id = intf;
        sockaddrsize = sizeof(sockaddr_in6);
        sockaddrptr = (const sockaddr *) &sa.in6;
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (addrType == kIPAddressType_IPv4)
    {
        sa.in.sin_family = AF_INET;
        sa.in.sin_port = htons(port);
        sa.in.sin_addr = addr.ToIPv4();
        sockaddrsize = sizeof(sockaddr_in);
        sockaddrptr = (const sockaddr *) &sa.in;
    }
#endif // INET_CONFIG_ENABLE_IPV4
    else
        return INET_ERROR_WRONG_ADDRESS_TYPE;

    int conRes = connect(mSocket, sockaddrptr, sockaddrsize);

    if (conRes == -1 && errno != EINPROGRESS)
    {
        res = Weave::System::MapErrorPOSIX(errno);
        DoClose(res, true);
        return res;
    }

    // Once Connecting or Connected, bump the reference count.  The corresponding Release()
    // [or on LwIP, DeferredRelease()] will happen in DoClose().
    Retain();

    if (conRes == 0)
    {
        State = kState_Connected;
        if (OnConnectComplete != NULL)
            OnConnectComplete(this, INET_NO_ERROR);
    }
    else
        State = kState_Connecting;

    // Wake the thread calling select so that it recognizes the new socket.
    lSystemLayer.WakeSelect();

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    StartConnectTimerIfSet();

    return res;
}

/**
 * @brief   Set timeout for Connect to succeed or return an error.
 *
 * @param[in]   connTimeoutMsecs
 *
 * @note
 *  Setting a value of zero means use system defaults.
 */
void TCPEndPoint::SetConnectTimeout(const uint32_t connTimeoutMsecs)
{
    mConnectTimeoutMsecs = connTimeoutMsecs;
}

void TCPEndPoint::StartConnectTimerIfSet(void)
{
    if (mConnectTimeoutMsecs > 0)
    {
        Weave::System::Layer& lSystemLayer = SystemLayer();

        lSystemLayer.StartTimer(mConnectTimeoutMsecs, TCPConnectTimeoutHandler, this);
    }
}

void TCPEndPoint::StopConnectTimer(void)
{
    Weave::System::Layer& lSystemLayer = SystemLayer();

    lSystemLayer.CancelTimer(TCPConnectTimeoutHandler, this);
}

void TCPEndPoint::TCPConnectTimeoutHandler(Weave::System::Layer* aSystemLayer, void* aAppState, Weave::System::Error aError)
{
    TCPEndPoint * tcpEndPoint = reinterpret_cast<TCPEndPoint *>(aAppState);

    VerifyOrDie((aSystemLayer != NULL) && (tcpEndPoint != NULL));

    // Close Connection as we have timed out and Connect has not returned to
    // stop this timer.
    tcpEndPoint->DoClose(INET_ERROR_TCP_CONNECT_TIMEOUT, false);
}

INET_ERROR TCPEndPoint::GetPeerInfo(IPAddress *retAddr, uint16_t *retPort) const
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
    {
        *retPort = mTCP->remote_port;

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        *retAddr = IPAddress::FromLwIPAddr(mTCP->remote_ip);
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
#if INET_CONFIG_ENABLE_IPV4
        *retAddr = PCB_ISIPV6(mTCP) ? IPAddress::FromIPv6(mTCP->remote_ip.ip6) : IPAddress::FromIPv4(mTCP->remote_ip.ip4);
#else // !INET_CONFIG_ENABLE_IPV4
        *retAddr = IPAddress::FromIPv6(mTCP->remote_ip.ip6);
#endif // !INET_CONFIG_ENABLE_IPV4
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
    }
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    union
    {
        sockaddr any;
        sockaddr_in in;
        sockaddr_in6 in6;
    } sa;
    memset(&sa, 0, sizeof(sa));
    socklen_t saLen = sizeof(sa);

    if (getpeername(mSocket, &sa.any, &saLen) != 0)
        return Weave::System::MapErrorPOSIX(errno);

    if (sa.any.sa_family == AF_INET6)
    {
        *retAddr = IPAddress::FromIPv6(sa.in6.sin6_addr);
        *retPort = ntohs(sa.in6.sin6_port);
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (sa.any.sa_family == AF_INET)
    {
        *retAddr = IPAddress::FromIPv4(sa.in.sin_addr);
        *retPort = ntohs(sa.in.sin_port);
    }
#endif // INET_CONFIG_ENABLE_IPV4
    else
        return INET_ERROR_INCORRECT_STATE;

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

INET_ERROR TCPEndPoint::GetLocalInfo(IPAddress *retAddr, uint16_t *retPort)
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
    {
        *retPort = mTCP->local_port;

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        *retAddr = IPAddress::FromLwIPAddr(mTCP->local_ip);
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
#if INET_CONFIG_ENABLE_IPV4
        *retAddr = PCB_ISIPV6(mTCP) ? IPAddress::FromIPv6(mTCP->local_ip.ip6) : IPAddress::FromIPv4(mTCP->local_ip.ip4);
#else // !INET_CONFIG_ENABLE_IPV4
        *retAddr = IPAddress::FromIPv6(mTCP->local_ip.ip6);
#endif // !INET_CONFIG_ENABLE_IPV4
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
    }
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    union
    {
        sockaddr        any;
        sockaddr_in6    in6;
#if INET_CONFIG_ENABLE_IPV4
        sockaddr_in     in;
#endif // INET_CONFIG_ENABLE_IPV4
    } sa;

    memset(&sa, 0, sizeof(sa));
    socklen_t saLen = sizeof(sa);

    if (getsockname(mSocket, &sa.any, &saLen) != 0)
        return Weave::System::MapErrorPOSIX(errno);

    if (sa.any.sa_family == AF_INET6)
    {
        *retAddr = IPAddress::FromIPv6(sa.in6.sin6_addr);
        *retPort = ntohs(sa.in6.sin6_port);
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (sa.any.sa_family == AF_INET)
    {
        *retAddr = IPAddress::FromIPv4(sa.in.sin_addr);
        *retPort = ntohs(sa.in.sin_port);
    }
#endif // INET_CONFIG_ENABLE_IPV4
    else
        return INET_ERROR_INCORRECT_STATE;

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

INET_ERROR TCPEndPoint::Send(PacketBuffer *data, bool push)
{
    INET_ERROR res = INET_NO_ERROR;

    if (State != kState_Connected && State != kState_ReceiveShutdown)
    {
        PacketBuffer::Free(data);
        return INET_ERROR_INCORRECT_STATE;
    }

    if (mSendQueue == NULL)
        mSendQueue = data;
    else
        mSendQueue->AddToEnd(data);

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    if (!mUserTimeoutTimerRunning)
    {
        // Timer was not running before this send. So, start
        // the timer.

        StartTCPUserTimeoutTimer();
    }
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    if (push)
        res = DriveSending();

    return res;
}

void TCPEndPoint::DisableReceive()
{
    ReceiveEnabled = false;
}

void TCPEndPoint::EnableReceive()
{
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    Weave::System::Layer& lSystemLayer = SystemLayer();
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    ReceiveEnabled = true;

    DriveReceiving();

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    // Wake the thread calling select so that it can include the socket
    // in the select read fd_set.
    lSystemLayer.WakeSelect();

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
}

/**
 *  TCPEndPoint::EnableNoDelay
 *
 *  @brief
 *    Switch off nagle buffering algorithm in TCP by setting the
 *    TCP_NODELAY socket options.
 *
 */

INET_ERROR TCPEndPoint::EnableNoDelay(void)
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
        tcp_nagle_disable(mTCP);
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    {
        int val;

#ifdef TCP_NODELAY
        // Disable TCP Nagle buffering by setting TCP_NODELAY socket option to true
        val = 1;
        if (setsockopt(mSocket, TCP_SOCKOPT_LEVEL, TCP_NODELAY, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);
#endif // defined(TCP_NODELAY)
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

/**
 *  TCPEndPoint::EnableKeepAlive
 *
 *  @brief
 *    Enable TCP keepalive probes on the associated TCP connection.
 *
 *  @param interval
 *    The interval (in seconds) between keepalive probes.  This value also controls
 *    the time between last data packet sent and the transmission of the first keepalive
 *    probe.
 *
 *  @param timeoutCount
 *    The maximum number of unacknowledged probes before the connection will be deemed
 *    to have failed.
 *
 *  @note
 *    This method can only be called when the endpoint is in one of the connected states.
 *
 *    This method can be called multiple times to adjust the keepalive interval or timeout
 *    count.
 */

INET_ERROR TCPEndPoint::EnableKeepAlive(uint16_t interval, uint16_t timeoutCount)
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

#if LWIP_TCP_KEEPALIVE

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
    {
        // Set the idle interval
        mTCP->keep_idle = (uint32_t)interval * 1000;

        // Set the probe retransmission interval.
        mTCP->keep_intvl = (uint32_t)interval * 1000;

        // Set the probe timeout count
        mTCP->keep_cnt = timeoutCount;

        // Enable keepalives for the connection.
        ip_set_option(mTCP, SOF_KEEPALIVE);
    }
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#else // LWIP_TCP_KEEPALIVE

    res = INET_ERROR_NOT_IMPLEMENTED;

#endif // LWIP_TCP_KEEPALIVE

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    {
        int val;

        // Set the idle interval
        val = interval;
        if (setsockopt(mSocket, TCP_SOCKOPT_LEVEL, TCP_IDLE_INTERVAL_OPT_NAME, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);

        // Set the probe retransmission interval.
        val = interval;
        if (setsockopt(mSocket, TCP_SOCKOPT_LEVEL, TCP_KEEPINTVL, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);

        // Set the probe timeout count
        val = timeoutCount;
        if (setsockopt(mSocket, TCP_SOCKOPT_LEVEL, TCP_KEEPCNT, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);

        // Enable keepalives for the connection.
        val = 1; // enable
        if (setsockopt(mSocket, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

/**
 *  TCPEndPoint::DisableKeepAlive
 *
 *  @brief
 *    Disable TCP keepalive probes on the associated TCP connection.
 *
 *  @note
 *    This method can only be called when the endpoint is in one of the connected states.
 *
 *    This method does nothing if keepalives have not been enabled on the endpoint.
 */

INET_ERROR TCPEndPoint::DisableKeepAlive()
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

#if LWIP_TCP_KEEPALIVE

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
    {
        // Disable keepalives on the connection.
        ip_reset_option(mTCP, SOF_KEEPALIVE);
    }
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#else // LWIP_TCP_KEEPALIVE

    res = INET_ERROR_NOT_IMPLEMENTED;

#endif // LWIP_TCP_KEEPALIVE

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    {
        int val;

        // Disable keepalives on the connection.
        val = 0; // disable
        if (setsockopt(mSocket, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

/**
 *  TCPEndPoint::SetUserTimeout
 *
 *  @brief   Set the TCP user timeout socket option.
 *
 *  @details
 *    When the value is greater than 0, it specifies the maximum amount of
 *    time in milliseconds that transmitted data may remain
 *    unacknowledged before TCP will forcibly close the
 *    corresponding connection. If the option value is specified as 0,
 *    TCP will use the system default.
 *    See RFC 5482, for further details.
 *
 *  @note
 *    This method can only be called when the endpoint is in one of the connected states.
 *
 *    This method can be called multiple times to adjust the keepalive interval or timeout
 *    count.
 */
INET_ERROR TCPEndPoint::SetUserTimeout(uint32_t userTimeoutMillis)
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
    {
        return INET_ERROR_INCORRECT_STATE;
    }

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

    // Store the User timeout configuration if it is being overridden.

    mUserTimeoutMillis = userTimeoutMillis;

#else // !INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if defined(TCP_USER_TIMEOUT)
        // Set the user timeout
        uint32_t val = userTimeoutMillis;
        if (setsockopt(mSocket, TCP_SOCKOPT_LEVEL, TCP_USER_TIMEOUT, &val, sizeof(val)) != 0)
            return Weave::System::MapErrorPOSIX(errno);
#else // TCP_USER_TIMEOUT
    res = INET_ERROR_NOT_IMPLEMENTED;
#endif // defined(TCP_USER_TIMEOUT)

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    res = INET_ERROR_NOT_IMPLEMENTED;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#endif // !INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

    return res;
}

INET_ERROR TCPEndPoint::AckReceive(uint16_t len)
{
    INET_ERROR res = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    if (mTCP != NULL)
        tcp_recved(mTCP, len);
    else
        res = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    // nothing to do for sockets case

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return res;
}

INET_ERROR TCPEndPoint::PutBackReceivedData(PacketBuffer *data)
{
    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

    mRcvQueue = data;

    return INET_NO_ERROR;
}

uint32_t TCPEndPoint::PendingSendLength()
{
    if (mSendQueue != NULL)
        return mSendQueue->TotalLength();
    else
        return 0;
}

uint32_t TCPEndPoint::PendingReceiveLength()
{
    if (mRcvQueue != NULL)
        return mRcvQueue->TotalLength();
    else
        return 0;
}

INET_ERROR TCPEndPoint::Shutdown()
{
    INET_ERROR err = INET_NO_ERROR;

    if (!IsConnected())
        return INET_ERROR_INCORRECT_STATE;

    // If fully connected, enter the SendShutdown state.
    if (State == kState_Connected)
    {
        State = kState_SendShutdown;
        DriveSending();
    }

    // Otherwise, if the peer has already closed their end of the connection,
    else if (State == kState_ReceiveShutdown)
        err = DoClose(err, false);

    return err;
}

INET_ERROR TCPEndPoint::Close()
{
    // Clear the receive queue.
    PacketBuffer::Free(mRcvQueue);
    mRcvQueue = NULL;

    // Suppress closing callbacks, since the application explicitly called Close().
    OnConnectionClosed = NULL;
    OnPeerClose = NULL;
    OnConnectComplete = NULL;

    // Perform a graceful close.
    return DoClose(INET_NO_ERROR, true);
}

void TCPEndPoint::Abort()
{
    // Suppress closing callbacks, since the application explicitly called Abort().
    OnConnectionClosed = NULL;
    OnPeerClose = NULL;
    OnConnectComplete = NULL;

    DoClose(INET_ERROR_CONNECTION_ABORTED, true);
}

void TCPEndPoint::Free()
{
    INET_ERROR err;

    // Ensure no callbacks to the app after this point.
    OnAcceptError = NULL;
    OnConnectComplete = NULL;
    OnConnectionReceived = NULL;
    OnConnectionClosed = NULL;
    OnPeerClose = NULL;
    OnDataReceived = NULL;
    OnDataSent = NULL;

    // Ensure the end point is Closed or Closing.
    err = Close();
    if (err != INET_NO_ERROR)
        Abort();

    // Release the Retain() that happened when the end point was allocated
    // [on LwIP, the object may still be alive if DoClose() used the
    // EndPointBasis::DeferredFree() method.]
    Release();
}

#if INET_TCP_IDLE_CHECK_INTERVAL > 0
void TCPEndPoint::SetIdleTimeout(uint32_t timeoutMS)
{
    uint32_t newIdleTimeout = (timeoutMS + (INET_TCP_IDLE_CHECK_INTERVAL - 1)) / INET_TCP_IDLE_CHECK_INTERVAL;
    InetLayer& lInetLayer = Layer();
    bool isIdleTimerRunning = lInetLayer.IsIdleTimerRunning();

    if (newIdleTimeout > UINT16_MAX)
        newIdleTimeout = UINT16_MAX;
    mIdleTimeout = mRemainingIdleTime = newIdleTimeout;

    if (!isIdleTimerRunning && mIdleTimeout)
    {
        Weave::System::Layer& lSystemLayer = SystemLayer();

        lSystemLayer.StartTimer(INET_TCP_IDLE_CHECK_INTERVAL, InetLayer::HandleTCPInactivityTimer, &lInetLayer);
    }
}
#endif // INET_TCP_IDLE_CHECK_INTERVAL > 0

bool TCPEndPoint::IsConnected(int state)
{
    return state == kState_Connected || state == kState_SendShutdown || state == kState_ReceiveShutdown || state == kState_Closing;
}

void TCPEndPoint::Init(InetLayer *inetLayer)
{
    InitEndPointBasis(*inetLayer);
    ReceiveEnabled = true;

    // Initialize to zero for using system defaults.
    mConnectTimeoutMsecs = 0;

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    mUserTimeoutMillis = INET_CONFIG_DEFAULT_TCP_USER_TIMEOUT_MSEC;

    mUserTimeoutTimerRunning = false;

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
    mIsTCPSendIdle = true;

    mTCPSendQueuePollPeriodMillis = INET_CONFIG_TCP_SEND_QUEUE_POLL_INTERVAL_MSEC;

    mTCPSendQueueRemainingPollCount = MaxTCPSendQueuePolls();

    OnTCPSendIdleChanged = NULL;
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    mBytesWrittenSinceLastProbe = 0;

    mLastTCPKernelSendQueueLen = 0;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    mUnackedLength = 0;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
}

INET_ERROR TCPEndPoint::DriveSending()
{
    INET_ERROR err = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // If the connection hasn't been aborted ...
    if (mTCP != NULL)
    {
        err_t lwipErr;

        // Determine the current send window size. This is the maximum amount we can write to the connection.
        uint16_t sendWindowSize = tcp_sndbuf(mTCP);

        // If there's data to be sent and the send window is open...
        bool canSend = (RemainingToSend() > 0 && sendWindowSize > 0);
        if (canSend)
        {
            // Find first packet buffer with remaining data to send by skipping
            // all sent but un-acked data.
            TCPEndPoint::BufferOffset startOfUnsent = FindStartOfUnsent();
            const Weave::System::PacketBuffer* currentUnsentBuf = startOfUnsent.buffer;
            uint16_t unsentOffset = startOfUnsent.offset;

            // While there's data to be sent and a window to send it in...
            do
            {
                VerifyOrDie(currentUnsentBuf != NULL);

                uint16_t bufDataLen = currentUnsentBuf->DataLength();

                // Get a pointer to the start of unsent data within the first buffer on the unsent queue.
                const uint8_t *sendData = currentUnsentBuf->Start() + unsentOffset;

                // Determine the amount of data to send from the current buffer.
                uint16_t sendLen = bufDataLen - unsentOffset;
                if (sendLen > sendWindowSize)
                    sendLen = sendWindowSize;

                // Call LwIP to queue the data to be sent, telling it if there's more data to come.
                // Data is queued in-place as a reference within the source packet buffer. It is
                // critical that the underlying packet buffer not be freed until the data
                // is acknowledged, otherwise retransmissions could use an invalid
                // backing. Using TCP_WRITE_FLAG_COPY would eliminate this requirement, but overall
                // requires many more memory allocations which may be problematic when very
                // memory-constrained or when using pool-based allocations.
                lwipErr = tcp_write(mTCP, sendData, sendLen, (canSend) ? TCP_WRITE_FLAG_MORE : 0);
                if (lwipErr != ERR_OK)
                {
                    err = Weave::System::MapErrorLwIP(lwipErr);
                    break;
                }
                // Start accounting for the data sent as yet-to-be-acked.
                mUnackedLength += sendLen;

                // Adjust the unsent data offset by the length of data that was written.
                // If the entire buffer has been sent advance to the next one.
                unsentOffset += sendLen;
                if (unsentOffset == bufDataLen)
                {
                    currentUnsentBuf = currentUnsentBuf->Next();
                    unsentOffset = 0;
                }

                // Adjust the remaining window size.
                sendWindowSize -= sendLen;

                // Determine if there's more data to be sent after this buffer.
                canSend = (RemainingToSend() > 0 && sendWindowSize > 0);
            } while (canSend);

            // Call LwIP to send the queued data.
            INET_FAULT_INJECT(FaultInjection::kFault_Send, err = Weave::System::MapErrorLwIP(ERR_RTE));

            if (err == INET_NO_ERROR)
            {
                lwipErr = tcp_output(mTCP);

                if (lwipErr != ERR_OK)
                    err = Weave::System::MapErrorLwIP(lwipErr);
            }
        }

        if (err == INET_NO_ERROR)
        {
            // If in the SendShutdown state and the unsent queue is now empty, shutdown the PCB for sending.
            if (State == kState_SendShutdown && (RemainingToSend() == 0))
            {
                lwipErr = tcp_shutdown(mTCP, 0, 1);
                if (lwipErr != ERR_OK)
                    err = Weave::System::MapErrorLwIP(lwipErr);
            }
        }
    }

    else
        err = INET_ERROR_CONNECTION_ABORTED;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#ifdef MSG_NOSIGNAL
    const int sendFlags = MSG_NOSIGNAL;
#else
    const int sendFlags = 0;
#endif

    // Pretend send() fails in the while loop below
    INET_FAULT_INJECT(FaultInjection::kFault_Send,
                      {
                          err = Weave::System::MapErrorPOSIX(EIO);
                          DoClose(err, false);
                          return err;
                      });

    while (mSendQueue != NULL)
    {
        uint16_t bufLen = mSendQueue->DataLength();

        ssize_t lenSent = send(mSocket, mSendQueue->Start(), (size_t) bufLen, sendFlags);

        if (lenSent == -1)
        {
            if (errno != EAGAIN && errno != EWOULDBLOCK)
                err = (errno == EPIPE) ? INET_ERROR_PEER_DISCONNECTED : Weave::System::MapErrorPOSIX(errno);
            break;
        }

        // Mark the connection as being active.
        MarkActive();

        if (lenSent < bufLen)
            mSendQueue->ConsumeHead(lenSent);
        else
            mSendQueue = PacketBuffer::FreeHead(mSendQueue);

        if (OnDataSent != NULL)
            OnDataSent(this, (uint16_t) lenSent);

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
        // TCP Send is not Idle; Set state and notify if needed

        SetTCPSendIdleAndNotifyChange(false);
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
        mBytesWrittenSinceLastProbe += lenSent;

        bool isProgressing = false;

        err = CheckConnectionProgress(isProgressing);
        if (err != INET_NO_ERROR)
        {
            break;
        }

        if (!mUserTimeoutTimerRunning)
        {
            // Timer was not running before this write. So, start
            // the timer.

            StartTCPUserTimeoutTimer();
        }
        else if (isProgressing)
        {
            // Progress is being made. So, shift the timer
            // forward if it was started.

            RestartTCPUserTimeoutTimer();
        }
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

        if (lenSent < bufLen)
            break;
    }

    if (err == INET_NO_ERROR)
    {
        // If we're in the SendShutdown state and the send queue is now empty, shutdown writing on the socket.
        if (State == kState_SendShutdown && mSendQueue == NULL)
        {
            if (shutdown(mSocket, SHUT_WR) != 0)
                err = Weave::System::MapErrorPOSIX(errno);
        }
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (err != INET_NO_ERROR)
        DoClose(err, false);

    WEAVE_SYSTEM_FAULT_INJECT_ASYNC_EVENT();

    return err;
}

void TCPEndPoint::DriveReceiving()
{
    // If there's data in the receive queue and the app is ready to receive it then call the app's callback
    // with the entire receive queue.
    if (mRcvQueue != NULL && ReceiveEnabled && OnDataReceived != NULL)
    {
        PacketBuffer *rcvQueue = mRcvQueue;
        mRcvQueue = NULL;
        OnDataReceived(this, rcvQueue);
    }

    // If the connection is closing, and the receive queue is now empty, call DoClose() to complete
    // the process of closing the connection.
    if (State == kState_Closing && mRcvQueue == NULL)
        DoClose(INET_NO_ERROR, false);
}

void TCPEndPoint::HandleConnectComplete(INET_ERROR err)
{
    // If the connect succeeded enter the Connected state and call the app's callback.
    if (err == INET_NO_ERROR)
    {
        // Stop the TCP Connect timer in case it is still running.
        StopConnectTimer();

        // Mark the connection as being active.
        MarkActive();

        State = kState_Connected;
        if (OnConnectComplete != NULL)
            OnConnectComplete(this, INET_NO_ERROR);
    }

    // Otherwise, close the connection with an error.
    else
        DoClose(err, false);
}

INET_ERROR TCPEndPoint::DoClose(INET_ERROR err, bool suppressCallback)
{
    int             oldState        = State;

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    struct linger   lingerStruct;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    // If in one of the connected states (Connected, LocalShutdown, PeerShutdown or Closing)
    // AND this is a graceful close (i.e. not prompted by an error)
    // AND there is data waiting to be processed on either the send or receive queues
    // ... THEN enter the Closing state, allowing the queued data to drain,
    // ... OTHERWISE go straight to the Closed state.
    if (IsConnected() && err == INET_NO_ERROR && (mSendQueue != NULL || mRcvQueue != NULL))
        State = kState_Closing;
    else
        State = kState_Closed;

    // Stop the Connect timer in case it is still running.

    StopConnectTimer();

    // If not making a state transition, return immediately.
    if (State == oldState)
        return INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // If the LwIP PCB hasn't been closed yet...
    if (mTCP != NULL)
    {
        // If the endpoint was a connection endpoint (vs. a listening endpoint)...
        if (oldState != kState_Listening)
        {
            // Prevent further callbacks for incoming data.  This has the effect of instructing
            // LwIP to discard any further data received from the peer.
            tcp_recv(mTCP, NULL);

            // If entering the Closed state...
            if (State == kState_Closed)
            {
                // Prevent further callbacks to the error handler.
                //
                // Note: It is important to understand that LwIP can continue to make callbacks after
                // a PCB has been closed via the tcp_close() API. In particular, LwIP will continue
                // to call the 'data sent' callback to signal the acknowledgment of data that was
                // sent, but not acknowledged, prior to the close call. Additionally, LwIP will call
                // the error callback if the peer fails to respond in a timely manner to the either
                // sent data or the FIN. Unfortunately, there is no callback in the case where the
                // connection closes successfully. Because of this, it is impossible know definitively
                // when LwIP will no longer make callbacks to its user. Thus we must block further
                // callbacks to prevent them from happening after the endpoint has been freed.
                //
                tcp_err(mTCP, NULL);

                // If the endpoint is being closed without error, THEN call tcp_close() to close the underlying
                // TCP connection gracefully, preserving any in-transit send data.
                if (err == INET_NO_ERROR)
                {
                    tcp_close(mTCP);
                }

                // OTHERWISE, call tcp_abort() to abort the TCP connection, discarding any in-transit data.
                else
                {
                    tcp_abort(mTCP);
                }

                // Discard the reference to the PCB to ensure there is no further interaction with it
                // after this point.
                mTCP = NULL;
                mLwIPEndPointType = kLwIPEndPointType_Unknown;
            }
        }

        // OTHERWISE the endpoint was being used for listening, so simply close it.
        else
        {
            tcp_close(mTCP);

            // Discard the reference to the PCB to ensure there is no further interaction with it
            // after this point.
            mTCP = NULL;
            mLwIPEndPointType = kLwIPEndPointType_Unknown;
        }
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    // If the socket hasn't been closed already...
    if (mSocket != INET_INVALID_SOCKET_FD)
    {
        // If entering the Closed state
        // OR if entering the Closing state, and there's no unsent data in the send queue
        // THEN close the socket.
        if (State == kState_Closed ||
            (State == kState_Closing && mSendQueue == NULL))
        {
            Weave::System::Layer& lSystemLayer = SystemLayer();

            // If aborting the connection, ensure we send a TCP RST.
            if (IsConnected(oldState) && err != INET_NO_ERROR)
            {
                lingerStruct.l_onoff = 1;
                lingerStruct.l_linger = 0;

                if (setsockopt(mSocket, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct)) != 0)
                    WeaveLogError(Inet, "SO_LINGER: %d", errno);
            }

            if (close(mSocket) != 0 && err == INET_NO_ERROR)
                err = Weave::System::MapErrorPOSIX(errno);
            mSocket = INET_INVALID_SOCKET_FD;

            // Wake the thread calling select so that it recognizes the socket is closed.
            lSystemLayer.WakeSelect();
        }
    }

    // Clear any results from select() that indicate pending I/O for the socket.
    mPendingIO.Clear();

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    // Stop the TCP UserTimeout timer if it is running.
    StopTCPUserTimeoutTimer();
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

    // If entering the Closed state...
    if (State == kState_Closed)
    {
        // Clear clear the send and receive queues.
        PacketBuffer::Free(mSendQueue);
        mSendQueue = NULL;
        PacketBuffer::Free(mRcvQueue);
        mRcvQueue = NULL;
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
        mUnackedLength = 0;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

        // Call the appropriate app callback if allowed.
        if (!suppressCallback)
        {
            if (oldState == kState_Connecting)
            {
                if (OnConnectComplete != NULL)
                    OnConnectComplete(this, err);
            }
            else if ((oldState == kState_Connected || oldState == kState_SendShutdown ||
                      oldState == kState_ReceiveShutdown || oldState == kState_Closing) &&
                     OnConnectionClosed != NULL)
                OnConnectionClosed(this, err);
        }

        // Decrement the ref count that was added when the connection started (in Connect()) or listening started (in Listen()).
        //
        // When using LwIP, post a callback to Release() rather than calling it directly. Since up-calls
        // from LwIP are delivered as events (via the LwIP* methods), we must ensure that all events have been
        // cleared from the queue before the end point gets freed, otherwise we'll end up accessing freed memory.
        // We achieve this by first preventing further up-calls from LwIP (via the call to tcp_abort() above)
        // and then queuing the Release() call to happen after all existing events have been processed.
        //
        if (oldState != kState_Ready && oldState != kState_Bound)
        {
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
            DeferredFree(kReleaseDeferralErrorTactic_Ignore);
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
            Release();
#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP
        }
    }

    return err;
}

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
void TCPEndPoint::TCPUserTimeoutHandler(Weave::System::Layer* aSystemLayer, void* aAppState, Weave::System::Error aError)
{
    TCPEndPoint * tcpEndPoint = reinterpret_cast<TCPEndPoint *>(aAppState);

    VerifyOrDie((aSystemLayer != NULL) && (tcpEndPoint != NULL));

    // Set the timer running flag to false
    tcpEndPoint->mUserTimeoutTimerRunning = false;

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    INET_ERROR err = INET_NO_ERROR;
    bool isProgressing = false;
    err = tcpEndPoint->CheckConnectionProgress(isProgressing);
    SuccessOrExit(err);

    if (tcpEndPoint->mLastTCPKernelSendQueueLen == 0)
    {
#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
        // If the kernel TCP send queue as well as the TCPEndPoint
        // send queue have been flushed then notify application
        // that all data has been acknowledged.

        if (tcpEndPoint->mSendQueue == NULL)
        {
            tcpEndPoint->SetTCPSendIdleAndNotifyChange(true);
        }
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
    }
    else
    // There is data in the TCP Send Queue
    {
        if (isProgressing)
        {
            // Data is flowing, so restart the UserTimeout timer
            // to shift it forward while also resetting the max
            // poll count.

            tcpEndPoint->StartTCPUserTimeoutTimer();
        }
        else
        {
#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
            // Data flow is not progressing.
            // Decrement the remaining max TCP send queue polls.

            tcpEndPoint->mTCPSendQueueRemainingPollCount--;

            VerifyOrExit(tcpEndPoint->mTCPSendQueueRemainingPollCount != 0,
                         err = INET_ERROR_TCP_USER_TIMEOUT);

            // Restart timer to poll again

            tcpEndPoint->ScheduleNextTCPUserTimeoutPoll(tcpEndPoint->mTCPSendQueuePollPeriodMillis);
#else
            // Close the connection as the TCP UserTimeout has expired

            ExitNow(err = INET_ERROR_TCP_USER_TIMEOUT);
#endif // !INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
        }
    }

exit:

    if (err != INET_NO_ERROR)
    {
        // Close the connection as the TCP UserTimeout has expired

        tcpEndPoint->DoClose(err, false);
    }
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    // Close Connection as we have timed out and there is still
    // data not sent out successfully.

    tcpEndPoint->DoClose(INET_ERROR_TCP_USER_TIMEOUT, false);
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

}

void TCPEndPoint::ScheduleNextTCPUserTimeoutPoll(uint32_t aTimeOut)
{
    Weave::System::Layer& lSystemLayer = SystemLayer();

    lSystemLayer.StartTimer(aTimeOut, TCPUserTimeoutHandler, this);
}

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
void TCPEndPoint::SetTCPSendIdleAndNotifyChange(bool aIsTCPSendIdle)
{
    if (mIsTCPSendIdle != aIsTCPSendIdle)
    {
        WeaveLogDetail(Inet, "TCP con send channel idle state changed : %s", aIsTCPSendIdle ? "false->true" : "true->false");

        // Set the current Idle state
        mIsTCPSendIdle = aIsTCPSendIdle;

        if (OnTCPSendIdleChanged)
        {
            OnTCPSendIdleChanged(this, mIsTCPSendIdle);
        }
    }
}
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS

void TCPEndPoint::StartTCPUserTimeoutTimer()
{
    uint32_t timeOut = mUserTimeoutMillis;

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
    //Set timeout to the poll interval

    timeOut = mTCPSendQueuePollPeriodMillis;

    // Reset the poll count

    mTCPSendQueueRemainingPollCount = MaxTCPSendQueuePolls();
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS

    ScheduleNextTCPUserTimeoutPoll(timeOut);

    mUserTimeoutTimerRunning = true;
}

void TCPEndPoint::StopTCPUserTimeoutTimer()
{
    Weave::System::Layer& lSystemLayer = SystemLayer();

    lSystemLayer.CancelTimer(TCPUserTimeoutHandler, this);

    mUserTimeoutTimerRunning = false;
}

void TCPEndPoint::RestartTCPUserTimeoutTimer()
{
    StopTCPUserTimeoutTimer();

    StartTCPUserTimeoutTimer();
}

#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

uint32_t TCPEndPoint::RemainingToSend()
{
    if (mSendQueue == NULL)
    {
        return 0;
    }
    else
    {
        // We can never have reported more unacked data than there is pending
        // in the send queue! This would indicate a critical accounting bug.
        VerifyOrDie(mUnackedLength <= mSendQueue->TotalLength());

        return mSendQueue->TotalLength() - mUnackedLength;
    }
}

TCPEndPoint::BufferOffset TCPEndPoint::FindStartOfUnsent()
{
    // Find first packet buffer with remaining data to send by skipping
    // all sent but un-acked data. This is necessary because of the Consume()
    // call in HandleDataSent(), which potentially releases backing memory for
    // fully-sent packet buffers, causing an invalidation of all possible
    // offsets one might have cached. The TCP acnowledgements may come back
    // with a variety of sizes depending on prior activity, and size of the
    // send window. The only way to ensure we get the correct offsets into
    // unsent data while retaining the buffers that have un-acked data is to
    // traverse all sent-but-unacked data in the chain to reach the beginning
    // of ready-to-send data.
    Weave::System::PacketBuffer* currentUnsentBuf = mSendQueue;
    uint16_t unsentOffset = 0;
    uint32_t leftToSkip = mUnackedLength;

    VerifyOrDie(leftToSkip < mSendQueue->TotalLength());

    while (leftToSkip > 0)
    {
        VerifyOrDie(currentUnsentBuf != NULL);
        uint16_t bufDataLen = currentUnsentBuf->DataLength();
        if (leftToSkip >= bufDataLen)
        {
            // We have more to skip than current packet buffer size.
            // Follow the chain to continue.
            currentUnsentBuf = currentUnsentBuf->Next();
            leftToSkip -= bufDataLen;
        }
        else
        {
            // Done skipping all data, currentUnsentBuf is first packet buffer
            // containing unsent data.
            unsentOffset = leftToSkip;
            leftToSkip = 0;
        }
    }

    TCPEndPoint::BufferOffset startOfUnsent;
    startOfUnsent.buffer = currentUnsentBuf;
    startOfUnsent.offset = unsentOffset;

    return startOfUnsent;
}

INET_ERROR TCPEndPoint::GetPCB(IPAddressType addrType)
{
    // IMMPORTANT: This method MUST be called with the LwIP stack LOCKED!

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
    if (mTCP == NULL)
    {
        switch (addrType)
        {
        case kIPAddressType_IPv6:
            mTCP = tcp_new_ip_type(IPADDR_TYPE_V6);
            break;

#if INET_CONFIG_ENABLE_IPV4
        case kIPAddressType_IPv4:
            mTCP = tcp_new_ip_type(IPADDR_TYPE_V4);
            break;
#endif // INET_CONFIG_ENABLE_IPV4

        default:
            return INET_ERROR_WRONG_ADDRESS_TYPE;
        }

        if (mTCP == NULL)
        {
            return INET_ERROR_NO_MEMORY;
        }
        else
        {
            mLwIPEndPointType = kLwIPEndPointType_TCP;
        }
    }
    else
    {
        switch (IP_GET_TYPE(&mTCP->local_ip))
        {
        case IPADDR_TYPE_V6:
            if (addrType != kIPAddressType_IPv6)
                return INET_ERROR_WRONG_ADDRESS_TYPE;
            break;

#if INET_CONFIG_ENABLE_IPV4
        case IPADDR_TYPE_V4:
            if (addrType != kIPAddressType_IPv4)
                return INET_ERROR_WRONG_ADDRESS_TYPE;
            break;
#endif // INET_CONFIG_ENABLE_IPV4

        default:
            break;
        }
    }
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
    if (mTCP == NULL)
    {
        if (addrType == kIPAddressType_IPv6)
            mTCP = tcp_new_ip6();
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
            mTCP = tcp_new();
#endif // INET_CONFIG_ENABLE_IPV4
        else
            return INET_ERROR_WRONG_ADDRESS_TYPE;
        if (mTCP == NULL)
        {
            return INET_ERROR_NO_MEMORY;
        }
        else
        {
            mLwIPEndPointType = kLwIPEndPointType_TCP;
        }
    }
    else
    {
#if INET_CONFIG_ENABLE_IPV4
        const IPAddressType pcbType = PCB_ISIPV6(mTCP) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
#else // !INET_CONFIG_ENABLE_IPV4
        const IPAddressType pcbType = kIPAddressType_IPv6;
#endif // !INET_CONFIG_ENABLE_IPV4
        if (addrType != pcbType)
            return INET_ERROR_WRONG_ADDRESS_TYPE;
    }
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

    return INET_NO_ERROR;
}

void TCPEndPoint::HandleDataSent(uint16_t lenSent)
{
    if (IsConnected())
    {
        // Ensure we do not have internal inconsistency in the lwIP, which
        // could cause invalid pointer accesses.
        if (lenSent > mUnackedLength)
        {
            WeaveLogError(Inet, "Got more ACKed bytes (%d) than were pending (%d)", (int)lenSent, (int)mUnackedLength);
            DoClose(INET_ERROR_UNEXPECTED_EVENT, false);
            return;
        }
        else if (mSendQueue == NULL)
        {
            WeaveLogError(Inet, "Got ACK for %d bytes but data backing gone", (int)lenSent);
            DoClose(INET_ERROR_UNEXPECTED_EVENT, false);
            return;
        }

        // Consume data off the head of the send queue equal to the amount of data being acknowledged.
        mSendQueue = mSendQueue->Consume(lenSent);
        mUnackedLength -= lenSent;

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
        // Only change the UserTimeout timer if lenSent > 0,
        // indicating progress being made in sending data
        // across.
        if (lenSent > 0)
        {
            if (RemainingToSend() == 0)
            {
                // If the output queue has been flushed then stop the timer.

                StopTCPUserTimeoutTimer();

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
                // Notify up if all outstanding data has been acknowledged

                SetTCPSendIdleAndNotifyChange(true);
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
            }
            else
            {
                // Progress is being made. So, shift the timer
                // forward if it was started.
                RestartTCPUserTimeoutTimer();
            }
        }
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

        // Mark the connection as being active.
        MarkActive();

        // If requested, call the app's OnDataSent callback.
        if (OnDataSent != NULL)
            OnDataSent(this, lenSent);

        // If unsent data exists, attempt to send it now...
        if (RemainingToSend() > 0)
            DriveSending();

        // If in the closing state and the send queue is now empty, attempt to transition to closed.
        if ((State == kState_Closing) && (RemainingToSend() == 0))
            DoClose(INET_NO_ERROR, false);
    }
}

void TCPEndPoint::HandleDataReceived(PacketBuffer *buf)
{
    // Only receive new data while in the Connected or SendShutdown states.
    if (State == kState_Connected || State == kState_SendShutdown)
    {
        // Mark the connection as being active.
        MarkActive();

        // If we received a data buffer, queue it on the receive queue.  If there's already data in
        // the queue, compact the data into the head buffer.
        if (buf != NULL)
        {
            if (mRcvQueue == NULL)
                mRcvQueue = buf;
            else
            {
                mRcvQueue->AddToEnd(buf);
                mRcvQueue->CompactHead();
            }
        }

        // Otherwise buf == NULL means the other side closed the connection, so ...
        else {

            // If in the Connected state and the app has provided an OnPeerClose callback,
            // enter the ReceiveShutdown state.  Providing an OnPeerClose callback allows
            // the app to decide whether to keep the send side of the connection open after
            // the peer has closed. If no OnPeerClose is provided, we assume that the app
            // wants to close both directions and automatically enter the Closing state.
            if (State == kState_Connected && OnPeerClose != NULL)
                State = kState_ReceiveShutdown;
            else
                State = kState_Closing;

            // Call the app's OnPeerClose.
            if (OnPeerClose != NULL)
                OnPeerClose(this);
        }

        // Drive the received data into the app.
        DriveReceiving();
    }
    else
        PacketBuffer::Free(buf);
}

void TCPEndPoint::HandleIncomingConnection(TCPEndPoint *conEP)
{
    INET_ERROR err = INET_NO_ERROR;
    IPAddress peerAddr;
    uint16_t peerPort;

    if (State == kState_Listening)
    {
        // If there's no callback available, fail with an error.
        if (OnConnectionReceived == NULL)
            err = INET_ERROR_NO_CONNECTION_HANDLER;

        // Extract the peer's address information.
        if (err == INET_NO_ERROR)
            err = conEP->GetPeerInfo(&peerAddr, &peerPort);

        // If successful, call the app's callback function.
        if (err == INET_NO_ERROR)
            OnConnectionReceived(this, conEP, peerAddr, peerPort);

        // Otherwise clean up and call the app's error callback.
        else if (OnAcceptError != NULL)
            OnAcceptError(this, err);
    }
    else
        err = INET_ERROR_INCORRECT_STATE;

    // If something failed above, abort and free the connection end point.
    if (err != INET_NO_ERROR)
        conEP->Free();
}

void TCPEndPoint::HandleError(INET_ERROR err)
{
    if (State == kState_Listening)
    {
        if (OnAcceptError != NULL)
            OnAcceptError(this, err);
    }
    else
        DoClose(err, false);
}

err_t TCPEndPoint::LwIPHandleConnectComplete(void *arg, struct tcp_pcb *tpcb, err_t lwipErr)
{
    err_t res = ERR_OK;

    if (arg != NULL)
    {
        INET_ERROR              conErr;
        TCPEndPoint*            ep              = static_cast<TCPEndPoint*>(arg);
        Weave::System::Layer&   lSystemLayer    = ep->SystemLayer();

        if (lwipErr == ERR_OK)
        {
            // Setup LwIP callback functions for data transmission.
            tcp_recv(ep->mTCP, LwIPHandleDataReceived);
            tcp_sent(ep->mTCP, LwIPHandleDataSent);
        }

        // Post callback to HandleConnectComplete.
        conErr = Weave::System::MapErrorLwIP(lwipErr);
        if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPConnectComplete, (uintptr_t)conErr) != INET_NO_ERROR)
            res = ERR_ABRT;
    }
    else
        res = ERR_ABRT;

    if (res != ERR_OK)
        tcp_abort(tpcb);

    return res;
}

err_t TCPEndPoint::LwIPHandleIncomingConnection(void *arg, struct tcp_pcb *tpcb, err_t lwipErr)
{
    INET_ERROR err = Weave::System::MapErrorLwIP(lwipErr);

    if (arg != NULL)
    {
        TCPEndPoint*            listenEP        = static_cast<TCPEndPoint*>(arg);
        TCPEndPoint*            conEP           = NULL;
        Weave::System::Layer&   lSystemLayer    = listenEP->SystemLayer();

        // Tell LwIP we've accepted the connection so it can decrement the listen PCB's pending_accepts counter.
        tcp_accepted(listenEP->mTCP);

        // If we did in fact receive a connection, rather than an error, attempt to allocate an end point object.
        //
        // NOTE: Although most of the LwIP callbacks defer the real work to happen on the endpoint's thread
        // (by posting events to the thread's event queue) we can't do that here because as soon as this
        // function returns, LwIP is free to begin calling callbacks on the new PCB. For that to work we need
        // to have an end point associated with the PCB.
        //
        if (err == INET_NO_ERROR)
        {
            InetLayer& lInetLayer = listenEP->Layer();

            err = lInetLayer.NewTCPEndPoint(&conEP);
        }

        // Ensure that TCP timers have been started
        if (err == INET_NO_ERROR)
        {
            err = start_tcp_timers();
        }

        // If successful in allocating an end point...
        if (err == INET_NO_ERROR)
        {
            // Put the new end point into the Connected state.
            conEP->State = kState_Connected;
            conEP->mTCP = tpcb;
            conEP->mLwIPEndPointType = kLwIPEndPointType_TCP;
            conEP->Retain();

            // Setup LwIP callback functions for the new PCB.
            tcp_arg(tpcb, conEP);
            tcp_recv(tpcb, LwIPHandleDataReceived);
            tcp_sent(tpcb, LwIPHandleDataSent);
            tcp_err(tpcb, LwIPHandleError);

            // Post a callback to the HandleConnectionReceived() function, passing it the new end point.
            if (lSystemLayer.PostEvent(*listenEP, kInetEvent_TCPConnectionReceived, (uintptr_t)conEP) != INET_NO_ERROR)
            {
                err = INET_ERROR_CONNECTION_ABORTED;
                conEP->Release(); // for the Retain() above
                conEP->Release();// for the Retain() in NewTCPEndPoint()
            }
        }

        // Otherwise, there was an error accepting the connection, so post a callback to the HandleError function.
        else
            lSystemLayer.PostEvent(*listenEP, kInetEvent_TCPError, (uintptr_t)err);
    }
    else
        err = INET_ERROR_CONNECTION_ABORTED;

    if (err != INET_NO_ERROR && tpcb != NULL)
    {
        tcp_abort(tpcb);
        return ERR_ABRT;
    }
    else
    {
        return ERR_OK;
    }
}

err_t TCPEndPoint::LwIPHandleDataReceived(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    err_t res = ERR_OK;

    if (arg != NULL)
    {
        TCPEndPoint* ep = static_cast<TCPEndPoint*>(arg);
        Weave::System::Layer& lSystemLayer = ep->SystemLayer();

        // Post callback to HandleDataReceived.
        if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPDataReceived, (uintptr_t)p) != INET_NO_ERROR)
            res = ERR_ABRT;
    }
    else
        res = ERR_ABRT;

    if (res != ERR_OK)
        tcp_abort(tpcb);

    return res;
}

err_t TCPEndPoint::LwIPHandleDataSent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
    err_t res = ERR_OK;

    if (arg != NULL)
    {
        TCPEndPoint* ep = static_cast<TCPEndPoint*>(arg);
        Weave::System::Layer& lSystemLayer = ep->SystemLayer();

        // Post callback to HandleDataReceived.
        if (lSystemLayer.PostEvent(*ep, kInetEvent_TCPDataSent, (uintptr_t)len) != INET_NO_ERROR)
            res = ERR_ABRT;
    }
    else
        res = ERR_ABRT;

    if (res != ERR_OK)
        tcp_abort(tpcb);

    return res;
}

void TCPEndPoint::LwIPHandleError(void *arg, err_t lwipErr)
{
    if (arg != NULL)
    {
        TCPEndPoint* ep = static_cast<TCPEndPoint*>(arg);
        Weave::System::Layer& lSystemLayer = ep->SystemLayer();

        // At this point LwIP has already freed the PCB.  Since the thread that owns the TCPEndPoint may
        // try to use the PCB before it receives the TCPError event posted below, we set the PCB to NULL
        // as a means to signal the other thread that the connection has been aborted.  The implication
        // of this is that the mTCP field is shared state between the two threads and thus must only be
        // accessed with the LwIP lock held.
        ep->mTCP = NULL;
        ep->mLwIPEndPointType = kLwIPEndPointType_Unknown;

        // Post callback to HandleError.
        INET_ERROR err = Weave::System::MapErrorLwIP(lwipErr);
        lSystemLayer.PostEvent(*ep, kInetEvent_TCPError, (uintptr_t)err);
    }
}

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

INET_ERROR TCPEndPoint::BindSrcAddrFromIntf(IPAddressType addrType, InterfaceId intf)
{
    INET_ERROR err = INET_NO_ERROR;

    // If we are trying to make a TCP connection over a 'specified target interface',
    // then we bind the TCPEndPoint to an IP address on that target interface
    // and use that address as the source address for that connection. This is
    // done in the event that directly binding the connection to the target
    // interface is not allowed due to insufficient privileges.
    IPAddress curAddr = IPAddress::Any;
    InterfaceId curIntfId = INET_NULL_INTERFACEID;
    bool ipAddrFound = false;

    VerifyOrExit(State != kState_Bound, err = INET_ERROR_NOT_SUPPORTED);

    for (InterfaceAddressIterator addrIter; addrIter.HasCurrent(); addrIter.Next())
    {
        curAddr = addrIter.GetAddress();
        curIntfId = addrIter.GetInterface();

        if (curIntfId == intf)
        {
        // Search for an IPv4 address on the TargetInterface

#if INET_CONFIG_ENABLE_IPV4
            if (addrType == kIPAddressType_IPv4)
            {
                if (curAddr.IsIPv4())
                {
                    // Bind to the IPv4 address of the TargetInterface
                    ipAddrFound = true;
                    err = Bind(kIPAddressType_IPv4, curAddr, 0, true);
                    SuccessOrExit(err);

                    break;
                }
            }
#endif // INET_CONFIG_ENABLE_IPV4
            if (addrType == kIPAddressType_IPv6)
            {
                // Select an IPv6 address on the interface that is not
                // a link local or a multicast address.
                //TODO: Define a proper IPv6GlobalUnicast address checker.
                if (!curAddr.IsIPv4() && !curAddr.IsIPv6LinkLocal() &&
                    !curAddr.IsMulticast())
                {
                    // Bind to the IPv6 address of the TargetInterface
                    ipAddrFound = true;
                    err = Bind(kIPAddressType_IPv6, curAddr, 0, true);
                    SuccessOrExit(err);

                    break;
                }
            }
        }
    }

    VerifyOrExit(ipAddrFound, err = INET_ERROR_NOT_SUPPORTED);

exit:
    return err;
}

INET_ERROR TCPEndPoint::GetSocket(IPAddressType addrType)
{
    if (mSocket == INET_INVALID_SOCKET_FD)
    {
        int family;
        if (addrType == kIPAddressType_IPv6)
            family = PF_INET6;
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
            family = PF_INET;
#endif // INET_CONFIG_ENABLE_IPV4
        else
            return INET_ERROR_WRONG_ADDRESS_TYPE;
        mSocket = ::socket(family, SOCK_STREAM | SOCK_FLAGS, 0);
        if (mSocket == -1)
            return Weave::System::MapErrorPOSIX(errno);
        mAddrType = addrType;

        // If creating an IPv6 socket, tell the kernel that it will be IPv6 only.  This makes it
        // posible to bind two sockets to the same port, one for IPv4 and one for IPv6.
#ifdef IPV6_V6ONLY
        if (family == PF_INET6)
        {
            int one = 1;
            setsockopt(mSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &one, sizeof(one));
        }
#endif // defined(IPV6_V6ONLY)

        // On systems that support it, disable the delivery of SIGPIPE signals when writing to a closed
        // socket.
#ifdef SO_NOSIGPIPE
        {
            int one = 1;
            int res = setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one));
            if (res != 0)
            {
                WeaveLogError(Inet, "SO_NOSIGPIPE: %d", errno);
            }
        }
#endif // defined(SO_NOSIGPIPE)
    }
    else if (mAddrType != addrType)
        return INET_ERROR_INCORRECT_STATE;

    return INET_NO_ERROR;
}

SocketEvents TCPEndPoint::PrepareIO()
{
    SocketEvents ioType;

    // If initiating a new connection...
    // OR if connected and there is data to be sent...
    // THEN arrange for the kernel to alert us when the socket is ready to be written.
    if (State == kState_Connecting || (IsConnected() && mSendQueue != NULL))
        ioType.SetWrite();

    // If listening for incoming connections and the app is ready to receive a connection...
    // OR if in a state where receiving is allowed, and the app is ready to receive data...
    // THEN arrange for the kernel to alert us when the socket is ready to be read.
    if ((State == kState_Listening && OnConnectionReceived != NULL) ||
        ((State == kState_Connected || State == kState_SendShutdown) && ReceiveEnabled && OnDataReceived != NULL))
        ioType.SetRead();

    return ioType;
}

void TCPEndPoint::HandlePendingIO()
{
    // Prevent the end point from being freed while in the middle of a callback.
    Retain();

    // If in the Listening state, and the app is ready to receive a connection, and there is a connection
    // ready to be received on the socket, process the incoming connection.
    if (State == kState_Listening)
    {
        if (OnConnectionReceived != NULL && mPendingIO.IsReadable())
            HandleIncomingConnection();
    }

    // If in the processes of initiating a connection...
    else if (State == kState_Connecting)
    {
        // The socket being writable indicates the connection has completed (successfully or otherwise).
        if (mPendingIO.IsWriteable())
        {
            // Get the connection result from the socket.
            int osConRes;
            socklen_t optLen = sizeof(osConRes);
            if (getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &osConRes, &optLen) != 0)
                osConRes = errno;
            INET_ERROR conRes = Weave::System::MapErrorPOSIX(osConRes);

            // Process the connection result.
            HandleConnectComplete(conRes);
        }
    }

    else
    {
        // If in a state where sending is allowed, and there is data to be sent, and the socket is ready for
        // writing, drive outbound data into the connection.
        if (IsConnected() && mSendQueue != NULL && mPendingIO.IsWriteable())
            DriveSending();

        // If in a state were receiving is allowed, and the app is ready to receive data, and data is ready
        // on the socket, receive inbound data from the connection.
        if ((State == kState_Connected || State == kState_SendShutdown) && ReceiveEnabled && OnDataReceived != NULL && mPendingIO.IsReadable())
            ReceiveData();
    }

    mPendingIO.Clear();

    Release();
}

void TCPEndPoint::ReceiveData()
{
    PacketBuffer *rcvBuf;
    bool isNewBuf = true;

    if (mRcvQueue == NULL)
        rcvBuf = PacketBuffer::New(0);
    else
    {
        rcvBuf = mRcvQueue;
        for (PacketBuffer *nextBuf = rcvBuf->Next(); nextBuf != NULL; rcvBuf = nextBuf, nextBuf = nextBuf->Next())
            ;

        if (rcvBuf->AvailableDataLength() == 0)
            rcvBuf = PacketBuffer::New(0);
        else
        {
            isNewBuf = false;
            rcvBuf->CompactHead();
        }
    }

    if (rcvBuf == NULL)
    {
        DoClose(INET_ERROR_NO_MEMORY, false);
        return;
    }

    // Attempt to receive data from the socket.
    ssize_t rcvLen = recv(mSocket, rcvBuf->Start() + rcvBuf->DataLength(), rcvBuf->AvailableDataLength(), 0);

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    INET_ERROR err;
    bool isProgressing = false;

    err = CheckConnectionProgress(isProgressing);
    if (err != INET_NO_ERROR)
    {
        DoClose(err, false);

        return;
    }

    if (mLastTCPKernelSendQueueLen == 0)
    {
        // If the output queue has been flushed then stop the timer.

        StopTCPUserTimeoutTimer();

#if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
        // Notify up if all outstanding data has been acknowledged

        if (mSendQueue == NULL)
        {
            SetTCPSendIdleAndNotifyChange(true);
        }
#endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
    }
    else if (isProgressing && mUserTimeoutTimerRunning)
    {
        // Progress is being made. So, shift the timer
        // forward if it was started.
        RestartTCPUserTimeoutTimer();
    }
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    // If an error occurred, abort the connection.
    if (rcvLen < 0)
    {
        int systemErrno = errno;

        if (isNewBuf)
        {
            PacketBuffer::Free(rcvBuf);
        }

        if (systemErrno == EAGAIN)
        {
            // Note: in this case, we opt to not retry the recv call,
            // and instead we expect that the read flags will get
            // reset correctly upon a subsequent return from the
            // select call.
            WeaveLogError(Inet, "recv: EAGAIN, will retry");

            return;
        }

        DoClose(Weave::System::MapErrorPOSIX(systemErrno), false);
    }

    else
    {
        // Mark the connection as being active.
        MarkActive();

        // If the peer closed their end of the connection...
        if (rcvLen == 0)
        {
            if (isNewBuf)
                PacketBuffer::Free(rcvBuf);

            // If in the Connected state and the app has provided an OnPeerClose callback,
            // enter the ReceiveShutdown state.  Providing an OnPeerClose callback allows
            // the app to decide whether to keep the send side of the connection open after
            // the peer has closed. If no OnPeerClose is provided, we assume that the app
            // wants to close both directions and automatically enter the Closing state.
            if (State == kState_Connected && OnPeerClose != NULL)
                State = kState_ReceiveShutdown;
            else
                State = kState_Closing;

            // Call the app's OnPeerClose.
            if (OnPeerClose != NULL)
                OnPeerClose(this);
        }

        // Otherwise, add the new data onto the receive queue.
        else if (isNewBuf)
        {
            rcvBuf->SetDataLength(rcvBuf->DataLength() + (uint16_t) rcvLen);
            if (mRcvQueue == NULL)
                mRcvQueue = rcvBuf;
            else
                mRcvQueue->AddToEnd(rcvBuf);
        }

        else
            rcvBuf->SetDataLength(rcvBuf->DataLength() + (uint16_t) rcvLen, mRcvQueue);
    }

    // Drive any received data into the app.
    DriveReceiving();
}

void TCPEndPoint::HandleIncomingConnection()
{
    INET_ERROR err = INET_NO_ERROR;
    TCPEndPoint *conEP = NULL;
    IPAddress peerAddr;
    uint16_t peerPort;

    union
    {
        sockaddr any;
        sockaddr_in in;
        sockaddr_in6 in6;
    } sa;
    memset(&sa, 0, sizeof(sa));
    socklen_t saLen = sizeof(sa);

    // Accept the new connection.
    int conSocket = accept(mSocket, &sa.any, &saLen);
    if (conSocket == -1)
        err = Weave::System::MapErrorPOSIX(errno);

    // If there's no callback available, fail with an error.
    if (err == INET_NO_ERROR && OnConnectionReceived == NULL)
        err = INET_ERROR_NO_CONNECTION_HANDLER;

    // Extract the peer's address information.
    if (err == INET_NO_ERROR)
    {
        if (sa.any.sa_family == AF_INET6)
        {
            peerAddr = IPAddress::FromIPv6(sa.in6.sin6_addr);
            peerPort = ntohs(sa.in6.sin6_port);
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (sa.any.sa_family == AF_INET)
        {
            peerAddr = IPAddress::FromIPv4(sa.in.sin_addr);
            peerPort = ntohs(sa.in.sin_port);
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            err = INET_ERROR_INCORRECT_STATE;
    }

    // Attempt to allocate an end point object.
    if (err == INET_NO_ERROR)
    {
        InetLayer& lInetLayer = Layer();

        err = lInetLayer.NewTCPEndPoint(&conEP);
    }

    // If all went well...
    if (err == INET_NO_ERROR)
    {
        // Put the new end point into the Connected state.
        conEP->State = kState_Connected;
        conEP->mSocket = conSocket;
#if INET_CONFIG_ENABLE_IPV4
        conEP->mAddrType = (sa.any.sa_family == AF_INET6) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
#else // !INET_CONFIG_ENABLE_IPV4
        conEP->mAddrType = kIPAddressType_IPv6;
#endif // !INET_CONFIG_ENABLE_IPV4
        conEP->Retain();

        // Call the app's callback function.
        OnConnectionReceived(this, conEP, peerAddr, peerPort);
    }

    // Otherwise immediately close the connection, clean up and call the app's error callback.
    else
    {
        if (conSocket != -1)
            close(conSocket);
        if (conEP != NULL)
        {
            if (conEP->State == kState_Connected)
                conEP->Release();
            conEP->Release();
        }
        if (OnAcceptError != NULL)
            OnAcceptError(this, err);
    }
}

#if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
/**
 *  This function probes the TCP output queue and checks if data is successfully
 *  being transferred to the other end.
 */
INET_ERROR TCPEndPoint::CheckConnectionProgress(bool &isProgressing)
{
   INET_ERROR err = INET_NO_ERROR;
   int currPendingBytes = 0;

   // Fetch the bytes pending successful transmission in the TCP out queue.

   if (ioctl(mSocket, TIOCOUTQ, &currPendingBytes) < 0)
   {
       ExitNow(err = Weave::System::MapErrorPOSIX(errno));
   }

   if ((currPendingBytes != 0) &&
       (mBytesWrittenSinceLastProbe + mLastTCPKernelSendQueueLen == static_cast<uint32_t>(currPendingBytes)))
   {
       // No progress has been made

       isProgressing = false;
   }
   else
   {
       // Data is flowing successfully

       isProgressing = true;
   }

   // Reset the value of the bytes written since the last probe into the tcp
   // outqueue was made and update the last tcp outqueue sample.

   mBytesWrittenSinceLastProbe = 0;

   mLastTCPKernelSendQueueLen = currPendingBytes;

exit:
   return err;
}
#endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace nl
