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

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

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

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

// Include local headers
#include <SystemLayer/SystemTimer.h>

// Include additional Weave headers
#include <Weave/Support/logging/WeaveLogging.h>

#include <Weave/Support/NLDLLUtil.h>
#include <Weave/Support/CodeUtils.h>

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

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#if !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#include <lwip/err.h>
#include <lwip/sys.h>
#endif // !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_POSIX_LOCKING

namespace nl {
namespace Weave {
namespace System {

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

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

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

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    this->mWakePipeIn = 0;
    this->mWakePipeOut = 0;

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

Error Layer::Init(void* aContext)
{
    Error lReturn;
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    int lPipeFDs[2];
    int lOSReturn, lFlags;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

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

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

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

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    // Create a Unix pipe to allow an arbitrary thread to wake the thread in the select loop.
    lOSReturn = ::pipe(lPipeFDs);
    VerifyOrExit(lOSReturn == 0, lReturn = nl::Weave::System::MapErrorPOSIX(errno));

    this->mWakePipeIn = lPipeFDs[0];
    this->mWakePipeOut = lPipeFDs[1];

    // Enable non-blocking mode for both ends of the pipe.
    lFlags = ::fcntl(this->mWakePipeIn, F_GETFL, 0);
    lOSReturn = ::fcntl(this->mWakePipeIn, F_SETFL, lFlags | O_NONBLOCK);
    VerifyOrExit(lOSReturn == 0, lReturn = nl::Weave::System::MapErrorPOSIX(errno));

    lFlags = ::fcntl(this->mWakePipeOut, F_GETFL, 0);
    lOSReturn = ::fcntl(this->mWakePipeOut, F_SETFL, lFlags | O_NONBLOCK);
    VerifyOrExit(lOSReturn == 0, lReturn = nl::Weave::System::MapErrorPOSIX(errno));
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    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 WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE;

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

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    if (this->mWakePipeOut != -1)
    {
        ::close(this->mWakePipeOut);
        this->mWakePipeOut = -1;
        this->mWakePipeIn = -1;
    }
#endif

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

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

    this->mContext = NULL;
    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 = NULL;

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

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

    if (lTimer == NULL)
    {
        WeaveLogError(WeaveSystemLayer, "Timer pool EMPTY");
        return WEAVE_SYSTEM_ERROR_NO_MEMORY;
    }

    return WEAVE_SYSTEM_NO_ERROR;
}

/**
* @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 #WEAVE_SYSTEM_NO_ERROR On success.
*   @return #WEAVE_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 != WEAVE_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 != NULL && lTimer->OnComplete == aOnComplete && lTimer->AppState == aAppState)
        {
            lTimer->Cancel();
            break;
        }
    }
}

#if WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
void Layer::CancelAllMatchingInetTimers(nl::Inet::InetLayer& aInetLayer, void* aOnCompleteInetLayer, void* aAppState)
{
    for (size_t i = 0; i < Timer::sPool.Size(); ++i)
    {
        Timer* lTimer = Timer::sPool.Get(*this, i);

        if (lTimer != NULL && lTimer->mInetLayer == &aInetLayer && lTimer->mOnCompleteInetLayer == aOnCompleteInetLayer &&
            lTimer->mAppStateInetLayer == aAppState)
        {
            lTimer->Cancel();
            break;
        }
    }
}
#endif // WEAVE_SYSTEM_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

/**
 * @brief
 *   Schedules a function with a signature identical to
 *   `TimerCompleteFunct` to be run as soon as possible on the Weave
 *   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 Weave 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 #WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE If the SystemLayer has
 *                      not been initialized.
 *
 * @retval #WEAVE_SYSTEM_ERROR_NO_MEMORY If the SystemLayer cannot
 *                      allocate a new timer.
 *
 * @retval #WEAVE_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 != WEAVE_SYSTEM_NO_ERROR)
    {
        lTimer->Release();
    }

exit:
    return lReturn;
}

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

/**
 *  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;

    if (this->mWakePipeIn + 1 > aSetSize)
        aSetSize = this->mWakePipeIn + 1;

    FD_SET(this->mWakePipeIn, aReadSet);

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

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

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

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

    const uint64_t kSleepTime = (lAwakenEpoch - kCurrentEpoch) * kTimerFactor_micro_per_milli;
    aSleepTime.tv_sec = kSleepTime / 1000000;
    aSleepTime.tv_usec = kSleepTime % 1000000;
}

/**
 * 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;

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

    if (aSetSize < 0)
        return;

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

    if (aSetSize > 0)
    {
        // If we woke because of someone writing to the wake pipe, clear the contents of the pipe before returning.
        if (FD_ISSET(this->mWakePipeIn, aReadSet))
        {
            while (true)
            {
                uint8_t lBytes[128];
                int lTmp = ::read(this->mWakePipeIn, static_cast<void*>(lBytes), sizeof(lBytes));
                if (lTmp < static_cast<int>(sizeof(lBytes)))
                    break;
            }
        }
    }

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

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

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

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

#if WEAVE_SYSTEM_CONFIG_POSIX_LOCKING
    this->mHandleSelectThread = PTHREAD_NULL;
#endif // WEAVE_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()
{
    if (this->State() != kLayerState_Initialized)
        return;

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

    // Write a single byte to the wake pipe to wake up the select call.
    const uint8_t kByte = 0;
    const ssize_t kIOResult = ::write(this->mWakePipeOut, &kByte, 1);
    static_cast<void>(kIOResult);
}

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
LwIPEventHandlerDelegate Layer::sSystemEventHandlerDelegate;

/**
 * This is the dispatch handler for system layer events.
 *
 *  @param[inout]   aTarget     A pointer to the Weave System Layer object making the post request.
 *  @param[in]      aEventType  The type of event to post.
 *  @param[inout]   aArgument   The argument associated with the event to post.
 */
Error Layer::HandleSystemLayerEvent(Object& aTarget, EventType aEventType, uintptr_t aArgument)
{
    Error lReturn = WEAVE_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 = WEAVE_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     #WEAVE_SYSTEM_NO_ERROR          On success.
 *  @retval     #WEAVE_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 = WEAVE_SYSTEM_ERROR_BAD_ARGS);
    aDelegate.Prepend(this->mEventDelegateList);
    lReturn = WEAVE_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[inout]   aTarget     A pointer to the Weave System Layer object making the post request.
 *  @param[in]      aEventType  The type of event to post.
 *  @param[inout]   aArgument   The argument associated with the event to post.
 *
 *  @retval    #WEAVE_SYSTEM_NO_ERROR                   On success.
 *  @retval    #WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE     If the state of the Layer object is incorrect.
 *  @retval    #WEAVE_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 = WEAVE_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE);

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

    lReturn = Platform::Layer::PostEvent(*this, this->mContext, aTarget, aEventType, aArgument);
    if (lReturn != WEAVE_SYSTEM_NO_ERROR)
    {
        WeaveLogError(WeaveSystemLayer, "Failed to queue Weave 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 #WEAVE_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for intialization failure.
 */
Error Layer::DispatchEvents()
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = WEAVE_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 ::HandleEvent for the actual dispatch.
 *
 *  @param[in]  aEvent  The platform-specific event object to dispatch for handling.
 *
 * @return #WEAVE_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for intialization failure.
 */
Error Layer::DispatchEvent(Event aEvent)
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = WEAVE_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 Weave System Layer event.
 *
 *  @param[inout]   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   #WEAVE_SYSTEM_NO_ERROR                On success.
 *  @retval   #WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the InetLayer object is incorrect.
 *  @retval   #WEAVE_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 = WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE);

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

    lReturn = WEAVE_SYSTEM_ERROR_UNEXPECTED_EVENT;
    lEventDelegate = this->mEventDelegateList;

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

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

    if (lReturn == WEAVE_SYSTEM_ERROR_UNEXPECTED_EVENT)
    {
        WeaveLogError(WeaveSystemLayer, "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 nl::Weave::System::Timer class when
 *      one or more timers are active and require deferred execution.
 *
 *  @param[in]  aDelayMilliseconds  The timer duration in milliseconds.
 *
 *  @return WEAVE_SYSTEM_NO_ERROR on success, error code otherwise.
 *
 */
Error Layer::StartPlatformTimer(uint32_t aDelayMilliseconds)
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = WEAVE_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 nl::Weave::System::Timer::HandleExpiredTimers to handle any expired timers.  It is assumed that this API is called
 *      only while on the thread which owns the Weave System Layer object.
 *
 *  @return WEAVE_SYSTEM_NO_ERROR on success, error code otherwise.
 *
 */
Error Layer::HandlePlatformTimer()
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    VerifyOrExit(this->State() == kLayerState_Initialized, lReturn = WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE);

    lReturn = Timer::HandleExpiredTimers(*this);
    SuccessOrExit(lReturn);

 exit:
    return lReturn;
}
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#if !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS

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

#endif // !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

namespace Platform {
namespace Layer {

#if !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS

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

    return WEAVE_SYSTEM_NO_ERROR;
}

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

    return WEAVE_SYSTEM_NO_ERROR;
}

/**
 * This is a platform-specific Weave System Layer post-initialization hook. This may be overridden by assserting the preprocessor
 * definition, #WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[inout]  aLayer    A reference to the Weave System Layer instance being initialized.
 *
 *  @param[inout]  aContext  Platform-specific context data passed to the layer initialization method, ::Init.
 *
 *  @param[in]     anError   The overall status being returned via the Weave System Layer ::Init method.
 */
NL_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 Weave System Layer pre-shutdown hook. This may be overridden by assserting the preprocessor
 * definition, #WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS.
 *
 *  @param[inout]  aLayer    A reference to the Weave System Layer instance being shutdown.
 *
 *  @param[inout]  aContext  Platform-specific context data passed to the layer initialization method, ::Shutdown.
 *
 *  @param[in]     anError   The overall status being returned via the Weave System Layer ::Shutdown method.
 *
 *  @return #WEAVE_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for shutdown failure. Returning
 *      non-successful status will abort shutdown.
 */
NL_DLL_EXPORT void DidShutdown(Layer& aLayer, void* aContext, Error aStatus)
{
    static_cast<void>(aLayer);
    static_cast<void>(aContext);
    static_cast<void>(aStatus);
}

#endif // !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_XTOR_FUNCTIONS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#if !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS

using nl::Weave::System::LwIPEvent;

/**
 *  This is a platform-specific event / message post hook. This may be overridden by assserting the preprocessor definition,
 *  #WEAVE_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[inout]  aLayer    A pointer to the layer instance to which the event / message is being posted.
 *
 *  @param[inout]  aContext  Platform-specific context data passed to the layer initialization method, ::Init.
 *
 *  @param[inout]  aTarget   A pointer to the Weave System Layer object making the post request.
 *
 *  @param[in]     aType     The type of event to post.
 *
 *  @param[inout]  anArg     The argument associated with the event to post.
 *
 *  @return #WEAVE_SYSTEM_NO_ERROR on success; otherwise, a specific error indicating the reason for intialization failure.
 */
NL_DLL_EXPORT Error PostEvent(Layer& aLayer, void* aContext, Object& aTarget, EventType aType, uintptr_t aArgument)
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    sys_mbox_t lSysMbox;
    LwIPEvent* ev;
    err_t lLwIPError;

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

    ev = new LwIPEvent;
    VerifyOrExit(ev != NULL, lReturn = WEAVE_SYSTEM_ERROR_NO_MEMORY);

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

    lLwIPError = sys_mbox_trypost(&lSysMbox, ev);
    VerifyOrExit(lLwIPError == ERR_OK, delete ev; lReturn = nl::Weave::System::MapErrorLwIP(lLwIPError));

 exit:
    return lReturn;
}

/**
 *  This is a platform-specific event / message dispatch hook. This may be overridden by assserting the preprocessor definition,
 *  #WEAVE_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[inout]  aLayer    A reference to the layer instance for which events / messages are being dispatched.
 *
 *  @param[inout]  aContext  Platform-specific context data passed to the layer initialization method, ::Init.
 *
 *  @retval   #WEAVE_SYSTEM_ERROR_BAD_ARGS          If #aLayer or #aContext is NULL.
 *  @retval   #WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the Weave System Layer object is unexpected.
 *  @retval   #WEAVE_SYSTEM_ERROR_UNEXPECTED_EVENT  If an event type is unrecognized.
 *  @retval   #WEAVE_SYSTEM_NO_ERROR                On success.
 */
NL_DLL_EXPORT Error DispatchEvents(Layer& aLayer, void* aContext)
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;
    err_t lLwIPError;
    sys_mbox_t lSysMbox;
    void* lVoidPointer;
    const LwIPEvent* lEvent;

    // Sanity check the context / queue.
    VerifyOrExit(aContext != NULL, lReturn = WEAVE_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 = nl::Weave::System::MapErrorLwIP(lLwIPError));

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

        lReturn = aLayer.HandleEvent(*lEvent->Target, lEvent->Type, lEvent->Argument);
        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,
 *  #WEAVE_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 Weave
 *  System Layer::HandleEvent for the actual dispatch.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[inout]  aLayer    A reference to the layer instance for which events / messages are being dispatched.
 *  @param[inout]  aContext  Platform-specific context data passed to the layer initialization method, ::Init.
 *  @param[in]     anEvent   The platform-specific event object to dispatch for handling.
 *
 *  @retval   #WEAVE_SYSTEM_ERROR_BAD_ARGS          If #aLayer or the event target is NULL.
 *  @retval   #WEAVE_SYSTEM_ERROR_UNEXPECTED_EVENT  If the event type is unrecognized.
 *  @retval   #WEAVE_SYSTEM_ERROR_UNEXPECTED_STATE  If the state of the Weave System Layer object is unexpected.
 *  @retval   #WEAVE_SYSTEM_NO_ERROR                On success.
 */
NL_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 = WEAVE_SYSTEM_NO_ERROR;

    // Sanity check the target object.
    VerifyOrExit(target != NULL, lReturn = WEAVE_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,
 *  #WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS.
 *
 *  @note
 *    This is an implementation for LwIP.
 *
 *  @param[inout]  aLayer               A reference to the layer instance for which events / messages are being dispatched.
 *  @param[inout]  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   #WEAVE_SYSTEM_NO_ERROR    Always succeeds unless overriden.
 */
NL_DLL_EXPORT Error StartTimer(Layer& aLayer, void* aContext, uint32_t aMilliseconds)
{
    Error lReturn = WEAVE_SYSTEM_NO_ERROR;

    // At the moment there is no need to do anything for standalone weave + 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 // !WEAVE_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

} // namespace Layer
} // namespace Platform
} // namespace System
} // namespace Weave
} // namespace nl
