/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file defines classes for abstracting access to and
 *      interactions with a platform- and system-specific Internet
 *      Protocol stack which, as of this implementation, may be either
 *      BSD/POSIX Sockets or LwIP.
 *
 *      Major abstractions provided are:
 *
 *        * Timers
 *        * Domain Name System (DNS) resolution
 *        * TCP network transport
 *        * UDP network transport
 *        * Raw network transport
 *
 *      For BSD/POSIX Sockets, event readiness notification is handled
 *      via file descriptors and a traditional poll / select
 *      implementation on the platform adaptation.
 *
 *      For LwIP, event readiness notification is handle via events /
 *      messages and platform- and system-specific hooks for the event
 *      / message system.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include "InetLayer.h"

#include "InetFaultInjection.h"

#include <system/SystemTimer.h>

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

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/netif.h>
#include <lwip/sys.h>
#else // !CHIP_SYSTEM_CONFIG_USE_LWIP
#include <fcntl.h>
#include <net/if.h>
#include <unistd.h>
#ifdef __ANDROID__
#include <ifaddrs-android.h>
#elif CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
#include <ifaddrs.h>
#endif
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#include <net/net_if.h>
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

namespace chip {
namespace Inet {

void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot)
{
#if INET_CONFIG_ENABLE_DNS_RESOLVER
    DNSResolver::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumDNSResolvers],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumDNSResolvers]);
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    TCPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumTCPEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumTCPEps]);
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    UDPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumUDPEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumUDPEps]);
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    RawEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumRawEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumRawEps]);
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
}

/**
 *  This is the InetLayer default constructor.
 *
 *  It performs some basic data member initialization; however, since
 *  InetLayer follows an explicit initializer design pattern, the InetLayer::Init
 *  method must be called successfully prior to using the object.
 *
 */
InetLayer::InetLayer(void)
{
    State = kState_NotInitialized;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (!sInetEventHandlerDelegate.IsInitialized())
        sInetEventHandlerDelegate.Init(HandleInetLayerEvent);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
chip::System::LwIPEventHandlerDelegate InetLayer::sInetEventHandlerDelegate;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_NO_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    mDroppableEvents = 0;
    return INET_NO_ERROR;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    if (__sync_add_and_fetch(&mDroppableEvents, 1) <= INET_CONFIG_MAX_DROPPABLE_EVENTS)
    {
        return true;
    }
    else
    {
        __sync_add_and_fetch(&mDroppableEvents, -1);
        return false;
    }
}

void InetLayer::DroppableEventDequeued(void)
{
    __sync_add_and_fetch(&mDroppableEvents, -1);
}

#elif CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    const unsigned portBASE_TYPE maximum = INET_CONFIG_MAX_DROPPABLE_EVENTS;
    const unsigned portBASE_TYPE initial = INET_CONFIG_MAX_DROPPABLE_EVENTS;

#if (configSUPPORT_STATIC_ALLOCATION == 1)
    mDroppableEvents                     = xSemaphoreCreateCountingStatic(maximum, initial, &mDroppableEventsObj);
#else
    mDroppableEvents = xSemaphoreCreateCounting(maximum, initial);
#endif

    if (mDroppableEvents != NULL)
        return INET_NO_ERROR;
    else
        return INET_ERROR_NO_MEMORY;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    if (xSemaphoreTake(mDroppableEvents, 0) != pdTRUE)
    {
        return false;
    }
    return true;
}

void InetLayer::DroppableEventDequeued(void)
{
    xSemaphoreGive(mDroppableEvents);
}

#else // !CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    if (sem_init(&mDroppableEvents, 0, INET_CONFIG_MAX_DROPPABLE_EVENTS) != 0)
    {
        return chip::System::MapErrorPOSIX(errno);
    }
    return INET_NO_ERROR;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    // Striclty speaking, we should check for EAGAIN.  But, other
    // errno values probably should signal that that we should drop
    // the packet: EINVAL means that the semaphore is not valid (we
    // failed initialization), and EINTR should probably also lead to
    // dropping a packet.

    if (sem_trywait(&mDroppableEvents) != 0)
    {
        return false;
    }
    return true;
}

void InetLayer::DroppableEventDequeued(void)
{
    sem_post(&mDroppableEvents);
}

#endif // !CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#endif // INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP

/**
 *  This is the InetLayer explicit initializer. This must be called
 *  and complete successfully before the InetLayer may be used.
 *
 *  The caller may provide an optional context argument which will be
 *  passed back via any platform-specific hook functions. For
 *  LwIP-based adaptations, this will typically be a pointer to the
 *  event queue associated with the InetLayer instance.
 *
 *  Platforms may choose to assert
 *  #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS in their
 *  platform-specific configuration header and enable the
 *  Platform::InetLayer::WillInit and Platform::InetLayer::DidInit
 *  hooks to effect platform-specific customizations or data extensions
 *  to InetLayer.
 *
 *  @param[in]  aSystemLayer  A required instance of the chip System Layer
 *                            already successfully initialized.
 *
 *  @param[in]  aContext  An optional context argument which will be passed
 *                        back to the caller via any platform-specific hook
 *                        functions.
 *
 *  @retval   #INET_ERROR_INCORRECT_STATE        If the InetLayer is in an
 *                                               incorrect state.
 *  @retval   #INET_ERROR_NO_MEMORY              If the InetLayer runs out
 *                                               of resource for this
 *                                               request for a new timer.
 *  @retval   other Platform-specific errors indicating the reason for
 *            initialization failure.
 *  @retval   #INET_NO_ERROR                     On success.
 *
 */
INET_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext)
{
    INET_ERROR err = INET_NO_ERROR;

    Inet::RegisterLayerErrorFormatter();

    if (State != kState_NotInitialized)
        return INET_ERROR_INCORRECT_STATE;

    // Platform-specific initialization may elect to set this data
    // member. Ensure it is set to a sane default value before
    // invoking platform-specific initialization.

    mPlatformData = NULL;

    err = Platform::InetLayer::WillInit(this, aContext);
    SuccessOrExit(err);

    mSystemLayer = &aSystemLayer;
    mContext     = aContext;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    err = InitQueueLimiter();
    SuccessOrExit(err);

    mSystemLayer->AddEventHandlerDelegate(sInetEventHandlerDelegate);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    State = kState_Initialized;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

    err = mAsyncDNSResolver.Init(this);
    SuccessOrExit(err);

#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

exit:
    Platform::InetLayer::DidInit(this, mContext, err);
    return err;
}

/**
 *  This is the InetLayer explicit deinitializer and should be called
 *  prior to disposing of an instantiated InetLayer instance.
 *
 *  Platforms may choose to assert
 *  #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS in their
 *  platform-specific configuration header and enable the
 *  Platform::InetLayer::WillShutdown and
 *  Platform::InetLayer::DidShutdown hooks to effect clean-up of
 *  platform-specific customizations or data extensions to InetLayer.
 *
 *  @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *          the reason for shutdown failure.
 *
 */
INET_ERROR InetLayer::Shutdown(void)
{
    INET_ERROR err;

    err = Platform::InetLayer::WillShutdown(this, mContext);
    SuccessOrExit(err);

    if (State == kState_Initialized)
    {
#if INET_CONFIG_ENABLE_DNS_RESOLVER
        // Cancel all DNS resolution requests owned by this instance.
        for (size_t i = 0; i < DNSResolver::sPool.Size(); i++)
        {
            DNSResolver * lResolver = DNSResolver::sPool.Get(*mSystemLayer, i);
            if ((lResolver != NULL) && lResolver->IsCreatedByInetLayer(*this))
            {
                lResolver->Cancel();
            }
        }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

        err = mAsyncDNSResolver.Shutdown();

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        // Close all raw endpoints owned by this Inet layer instance.
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Close();
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        // Abort all TCP endpoints owned by this instance.
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Abort();
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        // Close all UDP endpoints owned by this instance.
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Close();
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
    }

    State = kState_NotInitialized;

exit:
    Platform::InetLayer::DidShutdown(this, mContext, err);

    return err;
}

/**
 * This returns any client-specific platform data assigned to the
 * instance, if it has been previously set.
 *
 * @return Client-specific platform data, if is has been previously set;
 *         otherwise, NULL.
 *
 */
void * InetLayer::GetPlatformData(void)
{
    return mPlatformData;
}

/**
 * This sets the specified client-specific platform data to the
 * instance for later retrieval by the client platform.
 *
 * @param[in]  aPlatformData  The client-specific platform data to set.
 *
 */
void InetLayer::SetPlatformData(void * aPlatformData)
{
    mPlatformData = aPlatformData;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
bool InetLayer::IsIdleTimerRunning(void)
{
    bool timerRunning = false;

    // see if there are any TCP connections with the idle timer check in use.
    for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);

        if ((lEndPoint != NULL) && (lEndPoint->mIdleTimeout != 0))
        {
            timerRunning = true;
            break;
        }
    }

    return timerRunning;
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0

/**
 *  Get the link local IPv6 address for a specified link or interface.
 *
 *  @param[in]    link    The interface for which the link local IPv6
 *                        address is being sought.
 *
 *  @param[out]   llAddr  The link local IPv6 address for the link.
 *
 *  @retval    #INET_ERROR_NOT_IMPLEMENTED      If IPv6 is not supported.
 *  @retval    #INET_ERROR_BAD_ARGS             If the link local address
 *                                              is NULL.
 *  @retval    #INET_ERROR_ADDRESS_NOT_FOUND    If the link does not have
 *                                              any address configured.
 *  @retval    #INET_NO_ERROR                   On success.
 *
 */
INET_ERROR InetLayer::GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr)
{
    INET_ERROR err = INET_NO_ERROR;
#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !LWIP_IPV6
    err = INET_ERROR_NOT_IMPLEMENTED;
    goto exit;
#endif //! LWIP_IPV6
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    if (llAddr == NULL)
    {
        err = INET_ERROR_BAD_ARGS;
        goto exit;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    for (struct netif * intf = netif_list; intf != NULL; intf = intf->next)
    {
        if ((link != NULL) && (link != intf))
            continue;
        int j;
        for (j = 0; j < LWIP_IPV6_NUM_ADDRESSES; ++j)
        {
            if (ip6_addr_isvalid(netif_ip6_addr_state(intf, j)) && ip6_addr_islinklocal(netif_ip6_addr(intf, j)))
            {
                (*llAddr) = IPAddress::FromIPv6(*netif_ip6_addr(intf, j));
                goto exit;
            }
        }
        if (link != NULL)
        {
            err = INET_ERROR_ADDRESS_NOT_FOUND;
            break;
        }
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    struct ifaddrs * ifaddr;
    int rv;
    rv = getifaddrs(&ifaddr);
    if (rv != -1)
    {
        struct ifaddrs * ifaddr_iter = ifaddr;
        while (ifaddr_iter != NULL)
        {

            if (ifaddr_iter->ifa_addr != NULL)
            {
                if ((ifaddr_iter->ifa_addr->sa_family == AF_INET6) &&
                    ((link == INET_NULL_INTERFACEID) || (if_nametoindex(ifaddr_iter->ifa_name) == link)))
                {
                    struct in6_addr * sin6_addr = &((struct sockaddr_in6 *) ifaddr_iter->ifa_addr)->sin6_addr;
                    if (sin6_addr->s6_addr[0] == 0xfe && (sin6_addr->s6_addr[1] & 0xc0) == 0x80) // Link Local Address
                    {
                        (*llAddr) = IPAddress::FromIPv6(((struct sockaddr_in6 *) ifaddr_iter->ifa_addr)->sin6_addr);
                        break;
                    }
                }
            }
            ifaddr_iter = ifaddr_iter->ifa_next;
        }
        freeifaddrs(ifaddr);
    }
    else
    {
        err = INET_ERROR_ADDRESS_NOT_FOUND;
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    net_if * iface;
    in6_addr * ip6_addr;

    iface = (link == INET_NULL_INTERFACEID) ? net_if_get_default() : net_if_get_by_index(link);
    VerifyOrExit(iface != nullptr, err = INET_ERROR_ADDRESS_NOT_FOUND);

    ip6_addr = net_if_ipv6_get_ll(iface, NET_ADDR_PREFERRED);
    VerifyOrExit(ip6_addr != nullptr, err = INET_ERROR_ADDRESS_NOT_FOUND);

    *llAddr = IPAddress::FromIPv6(*ip6_addr);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

exit:
    return err;
}

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
/**
 *  Creates a new RawEndPoint object for a specific IP version and protocol.
 *
 *  @note
 *    This function gets a free RawEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in]      ipVer          IPv4 or IPv6.
 *
 *  @param[in]      ipProto        A protocol within the IP family (e.g., ICMPv4 or ICMPv6).
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the RawEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer RawEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = NULL;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = RawEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != NULL)
    {
        (*retEndPoint)->Inet::RawEndPoint::Init(this, ipVer, ipProto);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumRawEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "Raw");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
/**
 *  Creates a new TCPEndPoint object.
 *
 *  @note
 *    This function gets a free TCPEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the TCPEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer TCPEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewTCPEndPoint(TCPEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = NULL;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = TCPEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != NULL)
    {
        (*retEndPoint)->Init(this);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumTCPEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "TCP");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
/**
 *  Creates a new UDPEndPoint object.
 *
 *  @note
 *    This function gets a free UDPEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the UDPEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer UDPEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewUDPEndPoint(UDPEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = NULL;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = UDPEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != NULL)
    {
        (*retEndPoint)->Init(this);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumUDPEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "UDP");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

#if INET_CONFIG_ENABLE_DNS_RESOLVER
/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @note
 *    This is an asynchronous operation and the result will be communicated back
 *    via the OnComplete() callback.
 *
 *  @param[in]  hostName    A pointer to a NULL-terminated C string representing
 *                          the host name to be queried.
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint8_t maxAddrs, IPAddress * addrArray,
                                         DNSResolveCompleteFunct onComplete, void * appState)
{
    size_t hostNameLength = strlen(hostName);
    if (hostNameLength > UINT16_MAX)
    {
        return INET_ERROR_HOST_NAME_TOO_LONG;
    }
    return ResolveHostAddress(hostName, static_cast<uint16_t>(hostNameLength), maxAddrs, addrArray, onComplete, appState);
}

/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @param[in]  hostName    A pointer to a non NULL-terminated C string representing the host name
 *                          to be queried.
 *
 *  @param[in]  hostNameLen The string length of host name.
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t maxAddrs, IPAddress * addrArray,
                                         DNSResolveCompleteFunct onComplete, void * appState)
{
    return ResolveHostAddress(hostName, hostNameLen, kDNSOption_Default, maxAddrs, addrArray, onComplete, appState);
}

/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @param[in]  hostName    A pointer to a non NULL-terminated C string representing the host name
 *                          to be queried.
 *
 *  @param[in]  hostNameLen The string length of host name.
 *
 *  @param[in]  options     An integer value controlling how host name resolution is performed.
 *
 *                          Value should be one of the address family values from the
 *                          #DNSOptions enumeration:
 *
 *                          #kDNSOption_AddrFamily_Any
 *                          #kDNSOption_AddrFamily_IPv4Only
 *                          #kDNSOption_AddrFamily_IPv6Only
 *                          #kDNSOption_AddrFamily_IPv4Preferred
 *                          #kDNSOption_AddrFamily_IPv6Preferred
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t options, uint8_t maxAddrs,
                                         IPAddress * addrArray, DNSResolveCompleteFunct onComplete, void * appState)
{
    INET_ERROR err         = INET_NO_ERROR;
    DNSResolver * resolver = NULL;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    INET_FAULT_INJECT(FaultInjection::kFault_DNSResolverNew, return INET_ERROR_NO_MEMORY);

    // Store context information and set the resolver state.
    VerifyOrExit(hostNameLen <= NL_DNS_HOSTNAME_MAX_LEN, err = INET_ERROR_HOST_NAME_TOO_LONG);
    VerifyOrExit(maxAddrs > 0, err = INET_ERROR_NO_MEMORY);

    resolver = DNSResolver::sPool.TryCreate(*mSystemLayer);
    if (resolver != NULL)
    {
        resolver->InitInetLayerBasis(*this);
    }
    else
    {
        ChipLogError(Inet, "%s resolver pool FULL", "DNS");
        ExitNow(err = INET_ERROR_NO_MEMORY);
    }

    // Short-circuit full address resolution if the supplied host name is a text-form
    // IP address...
    if (IPAddress::FromString(hostName, hostNameLen, *addrArray))
    {
        uint8_t addrTypeOption = (options & kDNSOption_AddrFamily_Mask);
        IPAddressType addrType = addrArray->Type();

        if ((addrTypeOption == kDNSOption_AddrFamily_IPv6Only && addrType != kIPAddressType_IPv6)
#if INET_CONFIG_ENABLE_IPV4
            || (addrTypeOption == kDNSOption_AddrFamily_IPv4Only && addrType != kIPAddressType_IPv4)
#endif
        )
        {
            err = INET_ERROR_INCOMPATIBLE_IP_ADDRESS_TYPE;
        }

        if (onComplete)
        {
            onComplete(appState, err, (err == INET_NO_ERROR) ? 1 : 0, addrArray);
        }

        resolver->Release();
        resolver = NULL;

        ExitNow(err = INET_NO_ERROR);
    }

    // After this point, the resolver will be released by:
    // - mAsyncDNSResolver (in case of ASYNC_DNS_SOCKETS)
    // - resolver->Resolve() (in case of synchronous resolving)
    // - the event handlers (in case of LwIP)

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

    err =
        mAsyncDNSResolver.PrepareDNSResolver(*resolver, hostName, hostNameLen, options, maxAddrs, addrArray, onComplete, appState);
    SuccessOrExit(err);

    mAsyncDNSResolver.EnqueueRequest(*resolver);

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

#if !INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
    err = resolver->Resolve(hostName, hostNameLen, options, maxAddrs, addrArray, onComplete, appState);
#endif // !INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
exit:

    return err;
}

/**
 *  Cancel any outstanding DNS query (for a matching completion callback and
 *  application state) that may still be active.
 *
 *  @note
 *    This situation can arise if the application initiates a connection
 *    to a peer using a hostname and then aborts/closes the connection
 *    before the hostname resolution completes.
 *
 *  @param[in]    onComplete   A pointer to the callback function when a DNS
 *                             request is complete.
 *
 *  @param[in]    appState     A pointer to an application state object to be passed
 *                             to the callback function as argument.
 *
 */
void InetLayer::CancelResolveHostAddress(DNSResolveCompleteFunct onComplete, void * appState)
{
    if (State != kState_Initialized)
        return;

    for (size_t i = 0; i < DNSResolver::sPool.Size(); i++)
    {
        DNSResolver * lResolver = DNSResolver::sPool.Get(*mSystemLayer, i);

        if (lResolver == NULL)
        {
            continue;
        }

        if (!lResolver->IsCreatedByInetLayer(*this))
        {
            continue;
        }

        if (lResolver->OnComplete != onComplete)
        {
            continue;
        }

        if (lResolver->AppState != appState)
        {
            continue;
        }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
        if (lResolver->mState == DNSResolver::kState_Canceled)
        {
            continue;
        }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

        lResolver->Cancel();
        break;
    }
}

#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

/**
 *  Get the interface identifier for the specified IP address. If the
 *  interface identifier cannot be derived it is set to the
 *  #INET_NULL_INTERFACEID.
 *
 *  @note
 *    This function fetches the first interface (from the configured list
 *    of interfaces) that matches the specified IP address.
 *
 *  @param[in]    addr      A reference to the IPAddress object.
 *
 *  @param[out]   intfId    A reference to the InterfaceId object.
 *
 *  @return  #INET_NO_ERROR unconditionally.
 *
 */
INET_ERROR InetLayer::GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId)
{
    InterfaceAddressIterator addrIter;

    for (; addrIter.HasCurrent(); addrIter.Next())
    {
        IPAddress curAddr = addrIter.GetAddress();
        if (addr == curAddr)
        {
            intfId = addrIter.GetInterface();
            return INET_NO_ERROR;
        }
    }

    intfId = INET_NULL_INTERFACEID;

    return INET_NO_ERROR;
}

/**
 *  Check if there is a prefix match between the specified IPv6 address and any of
 *  the locally configured IPv6 addresses.
 *
 *  @param[in]    addr    The IPv6 address to check for the prefix-match.
 *
 *  @return true if a successful match is found, otherwise false.
 *
 */
bool InetLayer::MatchLocalIPv6Subnet(const IPAddress & addr)
{
    if (addr.IsIPv6LinkLocal())
        return true;

    InterfaceAddressIterator ifAddrIter;
    for (; ifAddrIter.HasCurrent(); ifAddrIter.Next())
    {
        IPPrefix addrPrefix;
        addrPrefix.IPAddr = ifAddrIter.GetAddress();
#if INET_CONFIG_ENABLE_IPV4
        if (addrPrefix.IPAddr.IsIPv4())
            continue;
#endif // INET_CONFIG_ENABLE_IPV4
        if (addrPrefix.IPAddr.IsIPv6LinkLocal())
            continue;
        addrPrefix.Length = ifAddrIter.GetIPv6PrefixLength();
        if (addrPrefix.MatchAddress(addr))
            return true;
    }

    return false;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
void InetLayer::HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, void * aAppState, chip::System::Error aError)
{
    InetLayer & lInetLayer = *reinterpret_cast<InetLayer *>(aAppState);
    bool lTimerRequired    = lInetLayer.IsIdleTimerRunning();

    for (size_t i = 0; i < INET_CONFIG_NUM_TCP_ENDPOINTS; i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*aSystemLayer, i);

        if (lEndPoint == NULL)
            continue;
        if (!lEndPoint->IsCreatedByInetLayer(lInetLayer))
            continue;
        if (!lEndPoint->IsConnected())
            continue;
        if (lEndPoint->mIdleTimeout == 0)
            continue;

        if (lEndPoint->mRemainingIdleTime == 0)
        {
            lEndPoint->DoClose(INET_ERROR_IDLE_TIMEOUT, false);
        }
        else
        {
            --lEndPoint->mRemainingIdleTime;
        }
    }

    if (lTimerRequired)
    {
        aSystemLayer->StartTimer(INET_TCP_IDLE_CHECK_INTERVAL, HandleTCPInactivityTimer, &lInetLayer);
    }
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0

#if CHIP_SYSTEM_CONFIG_USE_LWIP
chip::System::Error InetLayer::HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType,
                                                    uintptr_t aArgument)
{
    chip::System::Error lReturn = CHIP_SYSTEM_NO_ERROR;
    InetLayerBasis & lBasis     = static_cast<InetLayerBasis &>(aTarget);

    VerifyOrExit(INET_IsInetEvent(aEventType), lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT);

    // Dispatch the event according to its type.
    switch (aEventType)
    {
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    case kInetEvent_TCPConnectComplete:
        static_cast<TCPEndPoint &>(aTarget).HandleConnectComplete(static_cast<INET_ERROR>(aArgument));
        break;

    case kInetEvent_TCPConnectionReceived:
        static_cast<TCPEndPoint &>(aTarget).HandleIncomingConnection(reinterpret_cast<TCPEndPoint *>(aArgument));
        break;

    case kInetEvent_TCPDataReceived:
        static_cast<TCPEndPoint &>(aTarget).HandleDataReceived(reinterpret_cast<chip::System::PacketBuffer *>(aArgument));
        break;

    case kInetEvent_TCPDataSent:
        static_cast<TCPEndPoint &>(aTarget).HandleDataSent(static_cast<uint16_t>(aArgument));
        break;

    case kInetEvent_TCPError:
        static_cast<TCPEndPoint &>(aTarget).HandleError(static_cast<INET_ERROR>(aArgument));
        break;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    case kInetEvent_RawDataReceived:
        static_cast<RawEndPoint &>(aTarget).HandleDataReceived(reinterpret_cast<chip::System::PacketBuffer *>(aArgument));
        break;
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    case kInetEvent_UDPDataReceived:
        static_cast<UDPEndPoint &>(aTarget).HandleDataReceived(reinterpret_cast<chip::System::PacketBuffer *>(aArgument));
        break;
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

#if INET_CONFIG_ENABLE_DNS_RESOLVER
    case kInetEvent_DNSResolveComplete:
        static_cast<DNSResolver &>(aTarget).HandleResolveComplete();
        break;
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

    default:
        lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT;
        ExitNow();
    }

    // If the event was droppable, record the fact that it has been dequeued.
    if (IsDroppableEvent(aEventType))
    {
        InetLayer & lInetLayer = lBasis.Layer();

        lInetLayer.DroppableEventDequeued();
    }

exit:
    return lReturn;
}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
/**
 *  Prepare the sets of file descriptors for @p select() to work with.
 *
 *  @param[out]    nfds       The range of file descriptors in the file
 *                            descriptor set.
 *
 *  @param[in]     readfds    A pointer to the set of readable file descriptors.
 *
 *  @param[in]     writefds   A pointer to the set of writable file descriptors.
 *
 *  @param[in]     exceptfds  A pointer to the set of file descriptors with errors.
 *
 * @param[in]      sleepTimeTV A pointer to a structure specifying how long the select should sleep
 *
 */
void InetLayer::PrepareSelect(int & nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval & sleepTimeTV)
{
    if (State != kState_Initialized)
        return;

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
    {
        RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
    {
        UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
}

/**
 *  Handle I/O from a select call. This method registers the pending I/O
 *  event in each active endpoint and then invokes the respective I/O
 *  handling functions for those endpoints.
 *
 *  @note
 *    It is important to set the pending I/O fields for all endpoints
 *    *before* making any callbacks. This avoids the case where an
 *    endpoint is closed and then re-opened within the callback for
 *    another endpoint. When this happens the new endpoint is likely
 *    to be assigned the same file descriptor as the old endpoint.
 *    However, any pending I/O for that file descriptor number represents
 *    I/O related to the old incarnation of the endpoint, not the current
 *    one. Saving the pending I/O state in each endpoint before acting
 *    on it allows the endpoint code to clear the I/O flags in the event
 *    of a close, thus avoiding any confusion.
 *
 *  @param[in]    selectRes    The return value of the select call.
 *
 *  @param[in]    readfds      A pointer to the set of read file descriptors.
 *
 *  @param[in]    writefds     A pointer to the set of write file descriptors.
 *
 *  @param[in]    exceptfds    A pointer to the set of file descriptors with
 *                             errors.
 *
 */
void InetLayer::HandleSelectResult(int selectRes, fd_set * readfds, fd_set * writefds, fd_set * exceptfds)
{
    if (State != kState_Initialized)
        return;

    if (selectRes < 0)
        return;

    if (selectRes > 0)
    {
        // Set the pending I/O field for each active endpoint based on the value returned by select.
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

        // Now call each active endpoint to handle its pending I/O.
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != NULL) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

/**
 *  Reset the members of the IPPacketInfo object.
 *
 */
void IPPacketInfo::Clear()
{
    SrcAddress  = IPAddress::Any;
    DestAddress = IPAddress::Any;
    Interface   = INET_NULL_INTERFACEID;
    SrcPort     = 0;
    DestPort    = 0;
}

#if !INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS

// MARK: InetLayer platform- and system-specific functions for InetLayer
//       construction and destruction.

namespace Platform {
namespace InetLayer {

/**
 * This is a platform-specific InetLayer pre-initialization hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          initialized.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *         the reason for initialization failure. Returning non-successful
 *         status will abort initialization.
 *
 */
DLL_EXPORT INET_ERROR WillInit(Inet::InetLayer * aLayer, void * aContext)
{
    (void) aLayer;
    (void) aContext;

    return INET_NO_ERROR;
}

/**
 * This is a platform-specific InetLayer post-initialization hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          initialized.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @param[in]     anError   The overall status being returned via the
 *                          InetLayer \::Init method.
 *
 */
DLL_EXPORT void DidInit(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError)
{
    (void) aLayer;
    (void) aContext;
    (void) anError;

    return;
}

/**
 * This is a platform-specific InetLayer pre-shutdown hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          shutdown.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *         the reason for shutdown failure. Returning non-successful
 *         status will abort shutdown.
 *
 */
DLL_EXPORT INET_ERROR WillShutdown(Inet::InetLayer * aLayer, void * aContext)
{
    (void) aLayer;
    (void) aContext;

    return INET_NO_ERROR;
}

/**
 * This is a platform-specific InetLayer post-shutdown hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          shutdown.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @param[in]     anError   The overall status being returned via the
 *                          InetLayer \::Shutdown method.
 *
 */
DLL_EXPORT void DidShutdown(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError)
{
    (void) aLayer;
    (void) aContext;
    (void) anError;

    return;
}

} // namespace InetLayer
} // namespace Platform

#endif // !INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS

} // namespace Inet
} // namespace chip
