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

/**
 *    @file
 *      This file contains definitions of the chip::System::Layer
 *      class methods and related data and functions.
 */

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

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

// Include local headers
#include <system/SystemClock.h>
#include <system/SystemTimer.h>

// Include additional CHIP headers
#include <support/CHIPMem.h>
#include <support/DLLUtil.h>
#include <support/DieMacros.h>
#include <support/ErrorMacros.h>
#include <support/ErrorStr.h>
#include <support/logging/CHIPLogging.h>

// Include system and language headers
#include <stddef.h>

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#include <lwip/err.h>
#include <lwip/sys.h>
#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#include <pthread.h>

// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one.
#ifndef PTHREAD_NULL
#define PTHREAD_NULL 0
#endif // PTHREAD_NULL
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

namespace chip {
namespace System {

using namespace ::chip::Callback;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
bool LwIPEventHandlerDelegate::IsInitialized() const
{
    return this->mFunction != NULL;
}

void LwIPEventHandlerDelegate::Init(LwIPEventHandlerFunction aFunction)
{
    this->mFunction     = aFunction;
    this->mNextDelegate = NULL;
}

void LwIPEventHandlerDelegate::Prepend(const LwIPEventHandlerDelegate *& aDelegateList)
{
    this->mNextDelegate = aDelegateList;
    aDelegateList       = this;
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

Layer::Layer() : mLayerState(kLayerState_NotInitialized), mContext(nullptr), mPlatformData(nullptr)
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (!sSystemEventHandlerDelegate.IsInitialized())
        sSystemEventHandlerDelegate.Init(HandleSystemLayerEvent);

    this->mEventDelegateList = NULL;
    this->mTimerList         = NULL;
    this->mTimerComplete     = false;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    this->mHandleSelectThread = PTHREAD_NULL;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
}

Error Layer::Init(void * aContext)
{
    Error lReturn;

    RegisterLayerErrorFormatter();
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    RegisterPOSIXErrorFormatter();
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    RegisterLwIPErrorFormatter();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    if (this->mLayerState != kLayerState_NotInitialized)
        return CHIP_SYSTEM_ERROR_UNEXPECTED_STATE;

    lReturn = Platform::Layer::WillInit(*this, aContext);
    SuccessOrExit(lReturn);

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    this->AddEventHandlerDelegate(sSystemEventHandlerDelegate);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
    // Create an event to allow an arbitrary thread to wake the thread in the select loop.
    lReturn = this->mWakeEvent.Open();
    SuccessOrExit(lReturn);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

    this->mLayerState = kLayerState_Initialized;
    this->mContext    = aContext;

exit:
    Platform::Layer::DidInit(*this, aContext, lReturn);
    return lReturn;
}

Error Layer::Shutdown()
{
    Error lReturn;
    void * lContext;

    if (this->mLayerState == kLayerState_NotInitialized)
        return CHIP_SYSTEM_ERROR_UNEXPECTED_STATE;

    lContext = this->mContext;
    lReturn  = Platform::Layer::WillShutdown(*this, lContext);
    SuccessOrExit(lReturn);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
    lReturn = mWakeEvent.Close();
    SuccessOrExit(lReturn);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

    for (size_t i = 0; i < Timer::sPool.Size(); ++i)
    {
        Timer * lTimer = Timer::sPool.Get(*this, i);

        if (lTimer != nullptr)
        {
            lTimer->Cancel();
        }
    }

    this->mContext    = nullptr;
    this->mLayerState = kLayerState_NotInitialized;

exit:
    Platform::Layer::DidShutdown(*this, lContext, lReturn);
    return lReturn;
}

/**
 * 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 * Layer::GetPlatformData() const
{
    return this->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 Layer::SetPlatformData(void * aPlatformData)
{
    this->mPlatformData = aPlatformData;
}

Error Layer::NewTimer(Timer *& aTimerPtr)
{
    Timer * lTimer = nullptr;

    if (this->State() != kLayerState_Initialized)
        return CHIP_SYSTEM_ERROR_UNEXPECTED_STATE;

    lTimer    = Timer::sPool.TryCreate(*this);
    aTimerPtr = lTimer;

    if (lTimer == nullptr)
    {
        ChipLogError(chipSystemLayer, "Timer pool EMPTY");
        return CHIP_SYSTEM_ERROR_NO_MEMORY;
    }

    return CHIP_SYSTEM_NO_ERROR;
}

static bool TimerReady(const Timer::Epoch epoch, const Cancelable * timer)
{
    return !Timer::IsEarlierEpoch(epoch, timer->mInfoScalar);
}

static int TimerCompare(void * p, const Cancelable * a, const Cancelable * b)
{
    (void) p;
    return (a->mInfoScalar > b->mInfoScalar) ? 1 : (a->mInfoScalar < b->mInfoScalar) ? -1 : 0;
}

/**
 * @brief
 *   This method starts a one-shot timer.
 *
 *   @note
 *       Only a single timer is allowed to be started with the same @a aComplete and @a aAppState
 *       arguments. If called with @a aComplete and @a aAppState identical to an existing timer,
 *       the currently-running timer will first be cancelled.
 *
 *   @param[in]  aMilliseconds Expiration time in milliseconds.
 *   @param[in]  aCallback     A pointer to the Callback that fires when the timer expires
 *
 *   @return CHIP_SYSTEM_NO_ERROR On success.
 *   @return Other Value indicating timer failed to start.
 *
 */
void Layer::StartTimer(uint32_t aMilliseconds, chip::Callback::Callback<> * aCallback)
{
    Cancelable * ca = aCallback->Cancel();

    ca->mInfoScalar = Timer::GetCurrentEpoch() + aMilliseconds;

    mTimerCallbacks.InsertBy(ca, TimerCompare, nullptr);

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (mTimerCallbacks.First() == ca)
    {
        // this is the new earliest timer and so the timer needs (re-)starting provided that
        // the system is not currently processing expired timers, in which case it is left to
        // HandleExpiredTimers() to re-start the timer.
        if (!mTimerComplete)
        {
            StartPlatformTimer(aMilliseconds);
        }
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @brief
 *   This method starts a one-shot timer.
 *
 *   @note
 *       Only a single timer is allowed to be started with the same @a aComplete and @a aAppState
 *       arguments. If called with @a aComplete and @a aAppState identical to an existing timer,
 *       the currently-running timer will first be cancelled.
 *
 *   @param[in]  aMilliseconds Expiration time in milliseconds.
 *   @param[in]  aComplete     A pointer to the function called when timer expires.
 *   @param[in]  aAppState     A pointer to the application state object used when timer expires.
 *
 *   @return CHIP_SYSTEM_NO_ERROR On success.
 *   @return CHIP_SYSTEM_ERROR_NO_MEMORY If a timer cannot be allocated.
 *   @return Other Value indicating timer failed to start.
 *
 */
Error Layer::StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplete, void * aAppState)
{
    Error lReturn;
    Timer * lTimer;

    this->CancelTimer(aComplete, aAppState);
    lReturn = this->NewTimer(lTimer);
    SuccessOrExit(lReturn);

    lReturn = lTimer->Start(aMilliseconds, aComplete, aAppState);
    if (lReturn != CHIP_SYSTEM_NO_ERROR)
    {
        lTimer->Release();
    }

exit:
    return lReturn;
}

/**
 * @brief
 *   This method cancels a one-shot timer, started earlier through @p StartTimer().
 *
 *   @note
 *       The cancellation could fail silently in two different ways. If the timer specified by the combination of the callback
 *       function and application state object couldn't be found, cancellation could fail. If the timer has fired, but not yet
 *       removed from memory, cancellation could also fail.
 *
 *   @param[in]  aOnComplete   A pointer to the callback function used in calling @p StartTimer().
 *   @param[in]  aAppState     A pointer to the application state object used in calling @p StartTimer().
 *
 */
void Layer::CancelTimer(Layer::TimerCompleteFunct aOnComplete, void * aAppState)
{
    if (this->State() != kLayerState_Initialized)
        return;

    for (size_t i = 0; i < Timer::sPool.Size(); ++i)
    {
        Timer * lTimer = Timer::sPool.Get(*this, i);

        if (lTimer != nullptr && lTimer->OnComplete == aOnComplete && lTimer->AppState == aAppState)
        {
            lTimer->Cancel();
            break;
        }
    }
}

/**
 * @brief
 *   Schedules a function with a signature identical to
 *   `TimerCompleteFunct` to be run as soon as possible on the CHIP
 *   thread.
 *
 * @note
 *   This function could, in principle, be implemented as
 *   `StartTimer(0, aComplete, aAppState)`.  The specification for
 *   `SystemTimer` however permits certain optimizations that might
 *   make that implementation impossible. Specifically, `SystemTimer`
 *   API may only be called from the thread owning the particular
 *   `SystemLayer`, whereas the `ScheduleWork` may be called from
 *   any thread.  Additionally, whereas the `SystemTimer` API permits
 *   the invocation of the already expired handler in line,
 *   `ScheduleWork` guarantees that the handler function will be
 *   called only after the current CHIP event completes.
 *
 * @param[in] aComplete A pointer to a callback function to be called
 *                      when this timer fires.
 *
 * @param[in] aAppState A pointer to an application state object to be
 *                      passed to the callback function as argument.
 *
 * @retval CHIP_SYSTEM_ERROR_UNEXPECTED_STATE If the SystemLayer has
 *                      not been initialized.
 *
 * @retval CHIP_SYSTEM_ERROR_NO_MEMORY If the SystemLayer cannot
 *                      allocate a new timer.
 *
 * @retval CHIP_SYSTEM_NO_ERROR On success.
 */
Error Layer::ScheduleWork(TimerCompleteFunct aComplete, void * aAppState)
{
    Error lReturn;
    Timer * lTimer;

    lReturn = this->NewTimer(lTimer);
    SuccessOrExit(lReturn);

    lReturn = lTimer->ScheduleWork(aComplete, aAppState);
    if (lReturn != CHIP_SYSTEM_NO_ERROR)
    {
        lTimer->Release();
    }

exit:
    return lReturn;
}

/**
 * @brief
 *   Returns a monotonic system time in units of microseconds.
 *
 * This function returns an elapsed time in microseconds since an arbitrary, platform-defined
 * epoch.  The value returned is guaranteed to be ever-increasing (i.e. never wrapping) between
 * reboots of the system.  Additionally, the underlying time source is guaranteed to tick
 * continuously during any system sleep modes that do not entail a restart upon wake.
 *
 * Although some platforms may choose to return a value that measures the time since boot for the
 * system, applications must *not* rely on this.  Additionally, the epoch for GetClock_Monotonic()
 * is *not* required to be the same as that for any of the other GetClock... functions.  Therefore
 * relative time calculations can only be performed on values returned by the same function.
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @returns             Elapsed time in microseconds since an arbitrary, platform-defined epoch.
 */
uint64_t Layer::GetClock_Monotonic()
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::GetClock_Monotonic();
}

/**
 * @brief
 *   Returns a monotonic system time in units of milliseconds.
 *
 * This function returns an elapsed time in milliseconds since an arbitrary, platform-defined
 * epoch.  The value returned is guaranteed to be ever-increasing (i.e. never wrapping) between
 * reboots of the system.  Additionally, the underlying time source is guaranteed to tick
 * continuously during any system sleep modes that do not entail a restart upon wake.
 *
 * Although some platforms may choose to return a value that measures the time since boot for the
 * system, applications must *not* rely on this.  Additionally, the epoch for GetClock_Monotonic()
 * is *not* required to be the same as that for any of the other GetClock... functions.  Therefore
 * relative time calculations can only be performed on values returned by the same function.
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @returns             Elapsed time in milliseconds since an arbitrary, platform-defined epoch.
 */
uint64_t Layer::GetClock_MonotonicMS()
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::GetClock_MonotonicMS();
}

/**
 * @brief
 *   Returns a (potentially) high-resolution monotonic system time in units of microseconds.
 *
 * This function returns an elapsed time in microseconds since an arbitrary, platform-defined
 * epoch.  The value returned is guaranteed to be ever-increasing (i.e. never wrapping) between
 * reboots of the system.  However, the underlying timer is *not* required to tick continuously
 * during system deep-sleep states.
 *
 * Some platforms may implement GetClock_MonotonicHiRes() using a high-resolution timer capable
 * of greater precision than GetClock_Monotonic(), and that is not subject to gradual clock
 * adjustments (slewing).  Systems without such a timer may simply return the same value as
 * GetClock_Monotonic().
 *
 * The epoch for time returned by GetClock_MonotonicHiRes() is not required to be the same that
 * for any of the other GetClock... functions, including GetClock_Monotonic().
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @returns             Elapsed time in microseconds since an arbitrary, platform-defined epoch.
 */
uint64_t Layer::GetClock_MonotonicHiRes()
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::GetClock_MonotonicHiRes();
}

/**
 * @brief
 *   Returns the current real (civil) time in microsecond Unix time format.
 *
 * This method returns the local platform's notion of current real time, expressed as a Unix time
 * value scaled to microseconds.  The underlying clock is guaranteed to tick at a rate of least at
 * whole seconds (values of 1,000,000), but on some platforms may tick faster.
 *
 * If the underlying platform is capable of tracking real time, but the system is currently
 * unsynchronized, GetClock_RealTime() will return the error CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED.
 *
 * On platforms that are incapable of tracking real time, the GetClock_RealTime() method may be absent,
 * resulting a link error for any application that references it.  Alternatively, such platforms may
 * supply an implementation of GetClock_RealTime() that always returns the error CHIP_SYSTEM_ERROR_NOT_SUPPORTED.
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @param[out] curTime                  The current time, expressed as Unix time scaled to microseconds.
 *
 * @retval #CHIP_SYSTEM_NO_ERROR       If the method succeeded.
 * @retval #CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED
 *                                      If the platform is capable of tracking real time, but is
 *                                      is currently unsynchronized.
 * @retval #CHIP_SYSTEM_ERROR_NOT_SUPPORTED
 *                                      If the platform is incapable of tracking real time.
 */
Error Layer::GetClock_RealTime(uint64_t & curTime)
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::GetClock_RealTime(curTime);
}

/**
 * @brief
 *   Returns the current real (civil) time in millisecond Unix time format.
 *
 * This method returns the local platform's notion of current real time, expressed as a Unix time
 * value scaled to milliseconds.  The underlying clock is guaranteed to tick at a rate of least at
 * whole seconds (values of 1,000,000), but on some platforms may tick faster.
 *
 * If the underlying platform is capable of tracking real time, but the system is currently
 * unsynchronized, GetClock_RealTimeMS() will return the error CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED.
 *
 * On platforms that are incapable of tracking real time, the GetClock_RealTimeMS() method may be absent,
 * resulting a link error for any application that references it.  Alternatively, such platforms may
 * supply an implementation of GetClock_RealTimeMS() that always returns the error CHIP_SYSTEM_ERROR_NOT_SUPPORTED.
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @param[out] curTimeMS               The current time, expressed as Unix time scaled to milliseconds.
 *
 * @retval #CHIP_SYSTEM_NO_ERROR       If the method succeeded.
 * @retval #CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED
 *                                      If the platform is capable of tracking real time, but is
 *                                      is currently unsynchronized.
 * @retval #CHIP_SYSTEM_ERROR_NOT_SUPPORTED
 *                                      If the platform is incapable of tracking real time.
 */
Error Layer::GetClock_RealTimeMS(uint64_t & curTimeMS)
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::GetClock_RealTimeMS(curTimeMS);
}

/**
 * @brief
 *   Sets the platform's notion of current real (civil) time.
 *
 * Applications can call this function to set the local platform's notion of current real time.  The
 * new current time is expressed as a Unix time value scaled to microseconds.
 *
 * Once set, underlying platform clock is guaranteed to track real time with a granularity of at least
 * whole seconds.
 *
 * Some platforms may restrict which applications or processes can set real time.  If the caller is
 * not permitted to change real time, the SetClock_RealTime() function will return the error
 * CHIP_SYSTEM_ERROR_ACCESS_DENIED.
 *
 * On platforms that are incapable of tracking real time, or do not offer the ability to set real time,
 * the SetClock_RealTime() function may be absent, resulting a link error for any application that
 * references it.  Alternatively, such platforms may supply an implementation of SetClock_RealTime()
 * that always returns the error CHIP_SYSTEM_ERROR_NOT_SUPPORTED.
 *
 * This function is guaranteed to be thread-safe on any platform that employs threading.
 *
 * @param[in] newCurTime                The new current time, expressed as Unix time scaled to microseconds.
 *
 * @retval #CHIP_SYSTEM_NO_ERROR       If the method succeeded.
 * @retval #CHIP_SYSTEM_ERROR_NOT_SUPPORTED
 *                                      If the platform is incapable of tracking real time.
 * @retval #CHIP_SYSTEM_ERROR_ACCESS_DENIED
 *                                      If the calling application does not have the privilege to set the
 *                                      current time.
 */
Error Layer::SetClock_RealTime(uint64_t newCurTime)
{
    // Current implementation is a simple pass-through to the platform.
    return Platform::Layer::SetClock_RealTime(newCurTime);
}

/**
 * @brief
 *   Run any timers that are due based on input current time
 */
void Layer::DispatchTimerCallbacks(const uint64_t kCurrentEpoch)
{
    // dispatch TimerCallbacks
    Cancelable ready;

    mTimerCallbacks.DequeueBy(TimerReady, kCurrentEpoch, ready);

    while (ready.mNext != &ready)
    {
        // one-shot
        chip::Callback::Callback<> * cb = chip::Callback::Callback<>::FromCancelable(ready.mNext);
        cb->Cancel();
        cb->mCall(cb->mContext);
    }
}

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

/**
 *  Prepare the sets of file descriptors for @p select() to work with.
 *
 *  @param[out] aSetSize        The range of file descriptors in the file descriptor set.
 *  @param[in]  aReadSet        A pointer to the set of readable file descriptors.
 *  @param[in]  aWriteSet       A pointer to the set of writable file descriptors.
 *  @param[in]  aExceptionSet   A pointer to the set of file descriptors with errors.
 *  @param[in]  aSleepTime      A reference to the maximum sleep time.
 */
void Layer::PrepareSelect(int & aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet,
                          struct timeval & aSleepTime)
{
    if (this->State() != kLayerState_Initialized)
        return;

    const int wakeEventFd = this->mWakeEvent.GetNotifFD();
    FD_SET(wakeEventFd, aReadSet);

    if (wakeEventFd + 1 > aSetSize)
        aSetSize = wakeEventFd + 1;

    const Timer::Epoch kCurrentEpoch = Timer::GetCurrentEpoch();
    Timer::Epoch lAwakenEpoch =
        kCurrentEpoch + static_cast<Timer::Epoch>(aSleepTime.tv_sec) * 1000 + static_cast<uint32_t>(aSleepTime.tv_usec) / 1000;

    for (size_t i = 0; i < Timer::sPool.Size(); i++)
    {
        Timer * lTimer = Timer::sPool.Get(*this, i);

        if (lTimer != nullptr)
        {
            if (!Timer::IsEarlierEpoch(kCurrentEpoch, lTimer->mAwakenEpoch))
            {
                lAwakenEpoch = kCurrentEpoch;
                break;
            }

            if (Timer::IsEarlierEpoch(lTimer->mAwakenEpoch, lAwakenEpoch))
                lAwakenEpoch = lTimer->mAwakenEpoch;
        }
    }

    // check for an earlier callback timer, too
    if (lAwakenEpoch != kCurrentEpoch)
    {
        Cancelable * ca = mTimerCallbacks.First();
        if (ca != nullptr && !Timer::IsEarlierEpoch(kCurrentEpoch, ca->mInfoScalar))
        {
            lAwakenEpoch = ca->mInfoScalar;
        }
    }

    const Timer::Epoch kSleepTime = lAwakenEpoch - kCurrentEpoch;
    aSleepTime.tv_sec             = static_cast<time_t>(kSleepTime / 1000);
    aSleepTime.tv_usec            = static_cast<suseconds_t>((kSleepTime % 1000) * 1000);
}

/**
 * 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]    aSetSize          The return value of the select call.
 *  @param[in]    aReadSet          A pointer to the set of read file descriptors.
 *  @param[in]    aWriteSet         A pointer to the set of write file descriptors.
 *  @param[in]    aExceptionSet     A pointer to the set of file descriptors with errors.
 *
 */
void Layer::HandleSelectResult(int aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet)
{
    pthread_t lThreadSelf;
    Error lReturn;

    if (this->State() != kLayerState_Initialized)
        return;

    if (aSetSize < 0)
        return;

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    lThreadSelf = pthread_self();
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

    if (aSetSize > 0)
    {
        // If we woke because of someone writing to the wake event, clear the event before returning.
        if (FD_ISSET(this->mWakeEvent.GetNotifFD(), aReadSet))
        {
            lReturn = this->mWakeEvent.Confirm();
            if (lReturn != CHIP_SYSTEM_NO_ERROR)
            {
                ChipLogError(chipSystemLayer, "System wake event confirm failed: %s", ErrorStr(lReturn));
            }
        }
    }

    const Timer::Epoch kCurrentEpoch = Timer::GetCurrentEpoch();

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    this->mHandleSelectThread = lThreadSelf;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

    for (size_t i = 0; i < Timer::sPool.Size(); i++)
    {
        Timer * lTimer = Timer::sPool.Get(*this, i);

        if (lTimer != nullptr && !Timer::IsEarlierEpoch(kCurrentEpoch, lTimer->mAwakenEpoch))
        {
            lTimer->HandleComplete();
        }
    }

    DispatchTimerCallbacks(kCurrentEpoch);

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    this->mHandleSelectThread = PTHREAD_NULL;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
}

/**
 * Wake up the I/O thread that monitors the file descriptors using select() by writing a single byte to the wake pipe.
 *
 *  @note
 *      If @p WakeSelect() is being called from within @p HandleSelectResult(), then writing to the wake pipe can be skipped,
 * since the I/O thread is already awake.
 *
 *      Furthermore, we don't care if this write fails as the only reasonably likely failure is that the pipe is full, in which
 *      case the select calling thread is going to wake up anyway.
 */
void Layer::WakeSelect()
{
    Error lReturn;

    if (this->State() != kLayerState_Initialized)
        return;

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    if (pthread_equal(this->mHandleSelectThread, pthread_self()))
    {
        return;
    }
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

    // Send notification to wake up the select call.
    lReturn = this->mWakeEvent.Notify();
    if (lReturn != CHIP_SYSTEM_NO_ERROR)
    {
        ChipLogError(chipSystemLayer, "System wake event notify failed: %s", ErrorStr(lReturn));
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_LWIP
LwIPEventHandlerDelegate Layer::sSystemEventHandlerDelegate;

/**
 * This is the dispatch handler for system layer events.
 *
 *  @param[in,out]  aTarget     A pointer to the CHIP System Layer object making the post request.
 *  @param[in]      aEventType  The type of event to post.
 *  @param[in,out]  aArgument   The argument associated with the event to post.
 */
Error Layer::HandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    ;

    // Dispatch logic specific to the event type
    switch (aEventType)
    {
    case kEvent_ReleaseObj:
        aTarget.Release();
        break;

    case kEvent_ScheduleWork:
        static_cast<Timer &>(aTarget).HandleComplete();
        break;

    default:
        lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT;
        break;
    }

    return lReturn;
}

/**
 * This adds an event handler delegate to the system layer to extend its ability to handle LwIP events.
 *
 *  @param[in]  aDelegate   An uninitialied LwIP event handler delegate structure
 *
 *  @retval     CHIP_SYSTEM_NO_ERROR          On success.
 *  @retval     CHIP_SYSTEM_ERROR_BAD_ARGS    If the function pointer contained in aDelegate is NULL
 */
Error Layer::AddEventHandlerDelegate(LwIPEventHandlerDelegate & aDelegate)
{
    Error lReturn;

    VerifyOrExit(aDelegate.mFunction != NULL, lReturn = CHIP_SYSTEM_ERROR_BAD_ARGS);
    aDelegate.Prepend(this->mEventDelegateList);
    lReturn = CHIP_SYSTEM_NO_ERROR;

exit:
    return lReturn;
}

/**
 * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event
 * queue.
 *
 *  @param[in,out]  aTarget     A pointer to the CHIP System Layer object making the post request.
 *  @param[in]      aEventType  The type of event to post.
 *  @param[in,out]  aArgument   The argument associated with the event to post.
 *
 *  @retval    CHIP_SYSTEM_NO_ERROR                   On success.
 *  @retval    CHIP_SYSTEM_ERROR_UNEXPECTED_STATE     If the state of the Layer object is incorrect.
 *  @retval    CHIP_SYSTEM_ERROR_NO_MEMORY            If the event queue is already full.
 *  @retval    other Platform-specific errors generated indicating the reason for failure.
 */
Error Layer::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    // Sanity check that this instance and the target layer haven't been "crossed".
    VerifyOrDieWithMsg(aTarget.IsRetained(*this), chipSystemLayer, "wrong poster! [target %p != this %p]", &(aTarget.SystemLayer()),
                       this);

    lReturn = Platform::Layer::PostEvent(*this, this->mContext, aTarget, aEventType, aArgument);
    if (lReturn != CHIP_SYSTEM_NO_ERROR)
    {
        ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer event (type %d): %s", aEventType, ErrorStr(lReturn));
    }
    SuccessOrExit(lReturn);

exit:
    return lReturn;
}

/**
 * This is a syntactic wrapper around a platform-specific hook that effects an event loop, waiting on a queue that services this
 * instance, pulling events off of that queue, and then dispatching them for handling.
 *
 *  @return #CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure.
 */
Error Layer::DispatchEvents()
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    lReturn = Platform::Layer::DispatchEvents(*this, this->mContext);
    SuccessOrExit(lReturn);

exit:
    return lReturn;
}

/**
 * This dispatches the specified event for handling by this instance.
 *
 *  The unmarshalling of the type and arguments from the event is handled by a platform-specific hook which should then call
 * back to Layer::HandleEvent for the actual dispatch.
 *
 *  @param[in]  aEvent  The platform-specific event object to dispatch for handling.
 *
 * @return CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure.
 */
Error Layer::DispatchEvent(Event aEvent)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    lReturn = Platform::Layer::DispatchEvent(*this, this->mContext, aEvent);
    SuccessOrExit(lReturn);

exit:
    return lReturn;
}

/**
 * This implements the actual dispatch and handling of a CHIP System Layer event.
 *
 *  @param[in,out]  aTarget     A reference to the layer object to which the event is targeted.
 *  @param[in]      aEventType  The event / message type to handle.
 *  @param[in]      aArgument   The argument associated with the event / message.
 *
 *  @retval   CHIP_SYSTEM_NO_ERROR                On success.
 *  @retval   CHIP_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the InetLayer object is incorrect.
 *  @retval   CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT  If the event type is unrecognized.
 */
Error Layer::HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
{
    const LwIPEventHandlerDelegate * lEventDelegate;
    Error lReturn;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    // Sanity check that this instance and the target layer haven't been "crossed".
    VerifyOrDieWithMsg(aTarget.IsRetained(*this), chipSystemLayer, "wrong handler! [target %p != this %p]",
                       &(aTarget.SystemLayer()), this);

    lReturn        = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT;
    lEventDelegate = this->mEventDelegateList;

    // Prevent the target object from being freed while dispatching the event.
    aTarget.Retain();

    while (lReturn == CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT && lEventDelegate != NULL)
    {
        lReturn        = lEventDelegate->mFunction(aTarget, aEventType, aArgument);
        lEventDelegate = lEventDelegate->mNextDelegate;
    }

    if (lReturn == CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT)
    {
        ChipLogError(chipSystemLayer, "Unexpected event type %d", aEventType);
    }

    /*
      Release the reference to the target object. When the object's lifetime finally comes to an end, in most cases this will be
      the release call that decrements the ref count to zero.
      */
    aTarget.Release();

exit:
    return lReturn;
}

/**
 * Start the platform timer with specified millsecond duration.
 *
 *  @brief
 *      Calls the Platform specific API to start a platform timer. This API is called by the chip::System::Timer class when
 *      one or more timers are active and require deferred execution.
 *
 *  @param[in]  aDelayMilliseconds  The timer duration in milliseconds.
 *
 *  @return CHIP_SYSTEM_NO_ERROR on success, error code otherwise.
 *
 */
Error Layer::StartPlatformTimer(uint32_t aDelayMilliseconds)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    lReturn = Platform::Layer::StartTimer(*this, this->mContext, aDelayMilliseconds);
    SuccessOrExit(lReturn);

exit:
    return lReturn;
}

/**
 * Handle the platform timer expiration event.
 *
 *  @brief
 *      Calls chip::System::Timer::HandleExpiredTimers to handle any expired timers.  It is assumed that this API is called
 *      only while on the thread which owns the CHIP System Layer object.
 *
 *  @return CHIP_SYSTEM_NO_ERROR on success, error code otherwise.
 *
 */
Error Layer::HandlePlatformTimer()
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_STATE);

    lReturn = Timer::HandleExpiredTimers(*this);

    DispatchTimerCallbacks(Timer::GetCurrentEpoch());

    SuccessOrExit(lReturn);

exit:
    return lReturn;
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS

// MARK: CHIP System Layer platform- and system-specific functions for LwIP-native eventing.
struct LwIPEvent
{
    EventType Type;
    Object * Target;
    uintptr_t Argument;
};

#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

namespace Platform {
namespace Layer {

#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS

/**
 * This is a platform-specific CHIP System Layer pre-initialization hook. This may be overridden by assserting the preprocessor
 * definition, #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[in,out] aLayer    A reference to the CHIP System Layer instance being initialized.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Init.
 *
 *  @return #CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure.
 *      Returning non-successful status will abort initialization.
 */
DLL_EXPORT Error WillInit(Layer & aLayer, void * aContext)
{
    static_cast<void>(aLayer);
    static_cast<void>(aContext);

    return CHIP_SYSTEM_NO_ERROR;
}

/**
 * This is a platform-specific CHIP System Layer pre-shutdown hook. This may be overridden by assserting the preprocessor
 * definition, #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[in,out] aLayer    A pointer to the CHIP System Layer instance being shutdown.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Shutdown.
 *
 *  @return #CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for shutdown failure. Returning
 *      non-successful status will abort shutdown.
 */
DLL_EXPORT Error WillShutdown(Layer & aLayer, void * aContext)
{
    static_cast<void>(aLayer);
    static_cast<void>(aContext);

    return CHIP_SYSTEM_NO_ERROR;
}

/**
 * This is a platform-specific CHIP System Layer post-initialization hook. This may be overridden by assserting the preprocessor
 * definition, #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[in,out] aLayer    A reference to the CHIP System Layer instance being initialized.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Init.
 *
 *  @param[in]     aStatus   The overall status being returned via the CHIP System Layer \::Init method.
 */
DLL_EXPORT void DidInit(Layer & aLayer, void * aContext, Error aStatus)
{
    static_cast<void>(aLayer);
    static_cast<void>(aContext);
    static_cast<void>(aStatus);
}

/**
 * This is a platform-specific CHIP System Layer pre-shutdown hook. This may be overridden by assserting the preprocessor
 * definition, #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[in,out] aLayer    A reference to the CHIP System Layer instance being shutdown.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Shutdown.
 *
 *  @param[in]     aStatus   The overall status being returned via the CHIP System Layer \::Shutdown method.
 *
 *  @return #CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for shutdown failure. Returning
 *      non-successful status will abort shutdown.
 */
DLL_EXPORT void DidShutdown(Layer & aLayer, void * aContext, Error aStatus)
{
    static_cast<void>(aLayer);
    static_cast<void>(aContext);
    static_cast<void>(aStatus);
}

#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS

using chip::System::LwIPEvent;

/**
 *  This is a platform-specific event / message post hook. This may be overridden by assserting the preprocessor definition,
 *  #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS.
 *
 *  This posts an event / message of the specified type with the provided argument to this instance's platform-specific event /
 *  message queue.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[in,out] aLayer    A pointer to the layer instance to which the event / message is being posted.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Init.
 *
 *  @param[in,out] aTarget   A pointer to the CHIP System Layer object making the post request.
 *
 *  @param[in]     aType     The type of event to post.
 *
 *  @param[in,out] aArgument The argument associated with the event to post.
 *
 *  @return #CHIP_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for initialization failure.
 */
DLL_EXPORT Error PostEvent(Layer & aLayer, void * aContext, Object & aTarget, EventType aType, uintptr_t aArgument)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    sys_mbox_t lSysMbox;
    LwIPEvent * ev;
    err_t lLwIPError;

    VerifyOrExit(aContext != NULL, lReturn = CHIP_SYSTEM_ERROR_BAD_ARGS);
    lSysMbox = reinterpret_cast<sys_mbox_t>(aContext);

    ev = chip::Platform::New<LwIPEvent>();
    VerifyOrExit(ev != nullptr, lReturn = CHIP_SYSTEM_ERROR_NO_MEMORY);

    ev->Type     = aType;
    ev->Target   = &aTarget;
    ev->Argument = aArgument;

    lLwIPError = sys_mbox_trypost(&lSysMbox, ev);
    VerifyOrExit(lLwIPError == ERR_OK, chip::Platform::Delete(ev); lReturn = chip::System::MapErrorLwIP(lLwIPError));

exit:
    return lReturn;
}

/**
 *  This is a platform-specific event / message dispatch hook. This may be overridden by assserting the preprocessor definition,
 *  #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS.
 *
 *  This effects an event loop, waiting on a queue that services this instance, pulling events off of that queue, and then
 *  dispatching them for handling.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[in,out] aLayer    A reference to the layer instance for which events / messages are being dispatched.
 *
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Init.
 *
 *  @retval   #CHIP_SYSTEM_ERROR_BAD_ARGS          If aLayer or aContext is NULL.
 *  @retval   #CHIP_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the CHIP System Layer object is unexpected.
 *  @retval   #CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT  If an event type is unrecognized.
 *  @retval   #CHIP_SYSTEM_NO_ERROR                On success.
 */
DLL_EXPORT Error DispatchEvents(Layer & aLayer, void * aContext)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;
    err_t lLwIPError;
    sys_mbox_t lSysMbox;
    void * lVoidPointer;
    const LwIPEvent * lEvent;

    // Sanity check the context / queue.
    VerifyOrExit(aContext != NULL, lReturn = CHIP_SYSTEM_ERROR_BAD_ARGS);
    lSysMbox = reinterpret_cast<sys_mbox_t>(aContext);

    while (true)
    {
        lLwIPError = sys_arch_mbox_tryfetch(&lSysMbox, &lVoidPointer);
        VerifyOrExit(lLwIPError == ERR_OK, lReturn = chip::System::MapErrorLwIP(lLwIPError));

        lEvent = static_cast<const LwIPEvent *>(lVoidPointer);
        VerifyOrExit(lEvent != NULL && lEvent->Target != NULL, lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT);

        lReturn = aLayer.HandleEvent(*lEvent->Target, lEvent->Type, lEvent->Argument);
        chip::Platform::Delete(lEvent);

        SuccessOrExit(lReturn);
    }

exit:
    return lReturn;
}

/**
 *  This is a platform-specific event / message dispatch hook. This may be overridden by assserting the preprocessor definition,
 *  #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS.
 *
 *  This dispatches the specified event for handling, unmarshalling the type and arguments from the event for hand off to CHIP
 *  System Layer::HandleEvent for the actual dispatch.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[in,out] aLayer    A reference to the layer instance for which events / messages are being dispatched.
 *  @param[in,out] aContext  Platform-specific context data passed to the layer initialization method, \::Init.
 *  @param[in]     aEvent    The platform-specific event object to dispatch for handling.
 *
 *  @retval   #CHIP_SYSTEM_ERROR_BAD_ARGS          If aLayer or the event target is NULL.
 *  @retval   #CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT  If the event type is unrecognized.
 *  @retval   #CHIP_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the CHIP System Layer object is unexpected.
 *  @retval   #CHIP_SYSTEM_NO_ERROR                On success.
 */
DLL_EXPORT Error DispatchEvent(Layer & aLayer, void * aContext, Event aEvent)
{
    const EventType type = aEvent->Type;
    Object * target      = aEvent->Target;
    const uint32_t data  = aEvent->Argument;
    Error lReturn        = CHIP_SYSTEM_NO_ERROR;

    // Sanity check the target object.
    VerifyOrExit(target != NULL, lReturn = CHIP_SYSTEM_ERROR_BAD_ARGS);

    // Handle the event.
    lReturn = aLayer.HandleEvent(*target, type, data);
    SuccessOrExit(lReturn);

exit:
    return lReturn;
}

/**
 *  This is a platform-specific event / message dispatch hook. This may be overridden by assserting the preprocessor definition,
 *  #CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[in,out] aLayer               A reference to the layer instance for which events / messages are being dispatched.
 *  @param[in,out] aContext             Platform-specific context data passed to the layer initialization method, \::Init.
 *  @param[in]     aMilliseconds        The number of milliseconds to set for the timer.
 *
 *  @retval   #CHIP_SYSTEM_NO_ERROR    Always succeeds unless overridden.
 */
DLL_EXPORT Error StartTimer(Layer & aLayer, void * aContext, uint32_t aMilliseconds)
{
    Error lReturn = CHIP_SYSTEM_NO_ERROR;

    // At the moment there is no need to do anything for standalone CHIP + LWIP.
    // the Task will periodically call HandleTimer which will process any expired
    // timers.
    static_cast<void>(aLayer);
    static_cast<void>(aContext);
    static_cast<void>(aMilliseconds);

    return lReturn;
}

#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

} // namespace Layer
} // namespace Platform
} // namespace System
} // namespace chip
