/*
 *
 *    Copyright (c) 2019 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
 *          Contains non-inline method definitions for the
 *          GenericThreadStackManagerImpl_OpenThread<> template.
 */

#ifndef GENERIC_THREAD_STACK_MANAGER_IMPL_OPENTHREAD_IPP
#define GENERIC_THREAD_STACK_MANAGER_IMPL_OPENTHREAD_IPP

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/ThreadStackManager.h>
#include <Weave/DeviceLayer/OpenThread/GenericThreadStackManagerImpl_OpenThread.h>
#include <Weave/DeviceLayer/OpenThread/OpenThreadUtils.h>
#include <Weave/Profiles/network-provisioning/NetworkProvisioning.h>
#include <Weave/DeviceLayer/internal/DeviceNetworkInfo.h>
#include <Weave/Support/crypto/WeaveRNG.h>
#include <Weave/Support/TraitEventUtils.h>
#include <nest/trait/network/TelemetryNetworkWpanTrait.h>

#include <openthread/thread.h>
#include <openthread/tasklet.h>
#include <openthread/link.h>
#include <openthread/dataset.h>
#include <openthread/dataset_ftd.h>
#include <openthread/thread_ftd.h>

using namespace ::nl::Weave::Profiles::NetworkProvisioning;
using namespace Schema::Nest::Trait::Network;

extern "C" void otSysProcessDrivers(otInstance *aInstance);

namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {

// Assert some presumptions in this code
static_assert(DeviceNetworkInfo::kMaxThreadNetworkNameLength == OT_NETWORK_NAME_MAX_SIZE);
static_assert(DeviceNetworkInfo::kThreadExtendedPANIdLength == OT_EXT_PAN_ID_SIZE);
static_assert(DeviceNetworkInfo::kThreadMeshPrefixLength == OT_MESH_LOCAL_PREFIX_SIZE);
static_assert(DeviceNetworkInfo::kThreadNetworkKeyLength == OT_MASTER_KEY_SIZE);
static_assert(DeviceNetworkInfo::kThreadPSKcLength == OT_PSKC_MAX_SIZE);

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>;

/**
 * Called by OpenThread to alert the ThreadStackManager of a change in the state of the Thread stack.
 *
 * By default, applications never need to call this method directly.  However, applications that
 * wish to receive OpenThread state change call-backs directly from OpenThread (e.g. by calling
 * otSetStateChangedCallback() with their own callback function) can call this method to pass
 * state change events to the ThreadStackManager.
 */
template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::OnOpenThreadStateChange(uint32_t flags, void * context)
{
    WeaveDeviceEvent event;
    event.Type = DeviceEventType::kThreadStateChange;
    event.ThreadStateChange.RoleChanged = (flags & OT_CHANGED_THREAD_ROLE) != 0;
    event.ThreadStateChange.AddressChanged = (flags & (OT_CHANGED_IP6_ADDRESS_ADDED|OT_CHANGED_IP6_ADDRESS_REMOVED)) != 0;
    event.ThreadStateChange.NetDataChanged = (flags & OT_CHANGED_THREAD_NETDATA) != 0;
    event.ThreadStateChange.ChildNodesChanged = (flags & (OT_CHANGED_THREAD_CHILD_ADDED|OT_CHANGED_THREAD_CHILD_REMOVED)) != 0;
    event.ThreadStateChange.OpenThread.Flags = flags;
    PlatformMgr().PostEvent(&event);
}

template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_ProcessThreadActivity(void)
{
    otTaskletsProcess(mOTInst);
    otSysProcessDrivers(mOTInst);
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::_HaveRouteToAddress(const IPAddress & destAddr)
{
    bool res = false;

    // Lock OpenThread
    Impl()->LockThreadStack();

    // No routing of IPv4 over Thread.
    VerifyOrExit(!destAddr.IsIPv4(), res = false);

    // If the device is attached to a Thread network...
    if (IsThreadAttachedNoLock())
    {
        // Link-local addresses are always presumed to be routable, provided the device is attached.
        if (destAddr.IsIPv6LinkLocal())
        {
            ExitNow(res = true);
        }

        // Iterate over the routes known to the OpenThread stack looking for a route that covers the
        // destination address.  If found, consider the address routable.
        // Ignore any routes advertised by this device.
        // If the destination address is a ULA, ignore default routes. Border routers advertising
        // default routes are not expected to be capable of routing Weave fabric ULAs unless they
        // advertise those routes specifically.
        {
            otError otErr;
            otNetworkDataIterator routeIter = OT_NETWORK_DATA_ITERATOR_INIT;
            otExternalRouteConfig routeConfig;
            const bool destIsULA = destAddr.IsIPv6ULA();

            while ((otErr = otNetDataGetNextRoute(Impl()->OTInstance(), &routeIter, &routeConfig)) == OT_ERROR_NONE)
            {
                const IPPrefix prefix = ToIPPrefix(routeConfig.mPrefix);
                char addrStr[64];
                prefix.IPAddr.ToString(addrStr, sizeof(addrStr));
                if (!routeConfig.mNextHopIsThisDevice &&
                    (!destIsULA || routeConfig.mPrefix.mLength > 0) &&
                    ToIPPrefix(routeConfig.mPrefix).MatchAddress(destAddr))
                {
                    ExitNow(res = true);
                }
            }
        }
    }

exit:

    // Unlock OpenThread
    Impl()->UnlockThreadStack();

    return res;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_OnPlatformEvent(const WeaveDeviceEvent * event)
{
    if (event->Type == DeviceEventType::kThreadStateChange)
    {
        Impl()->LockThreadStack();

#if WEAVE_DETAIL_LOGGING

        LogOpenThreadStateChange(mOTInst, event->ThreadStateChange.OpenThread.Flags);

#endif // WEAVE_DETAIL_LOGGING

        // The API we provide to enable/disable thread controls both the Thread
        // stack and the IP6 stack within OpenThread.  In order to properly
        // initialize OpenThread, we need to enable IP6 in OT, and we can
        // disable it once the OT stack is up and running and signaling events.
        if ((otThreadGetDeviceRole(mOTInst) == OT_DEVICE_ROLE_DISABLED) && otIp6IsEnabled(mOTInst))
        {
            otIp6SetEnabled(mOTInst, false);
        }

        Impl()->UnlockThreadStack();

    }
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::_IsThreadEnabled(void)
{
    otDeviceRole curRole;

    Impl()->LockThreadStack();
    curRole = otThreadGetDeviceRole(mOTInst);
    Impl()->UnlockThreadStack();

    return (curRole != OT_DEVICE_ROLE_DISABLED);
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetThreadEnabled(bool val)
{
    otError otErr = OT_ERROR_NONE;

    Impl()->LockThreadStack();

    bool isEnabled = (otThreadGetDeviceRole(mOTInst) != OT_DEVICE_ROLE_DISABLED);
    bool isIp6Enabled = otIp6IsEnabled(mOTInst);

    if (val && !isIp6Enabled)
    {
        otErr = otIp6SetEnabled(mOTInst, val);
        VerifyOrExit(otErr == OT_ERROR_NONE, );
    }

    if (val != isEnabled)
    {
        otErr = otThreadSetEnabled(mOTInst, val);
        VerifyOrExit(otErr == OT_ERROR_NONE, );
    }

    if (!val && isIp6Enabled)
    {
        otErr = otIp6SetEnabled(mOTInst, val);
        VerifyOrExit(otErr == OT_ERROR_NONE, );
    }

exit:
    Impl()->UnlockThreadStack();

    return MapOpenThreadError(otErr);
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::_IsThreadProvisioned(void)
{
    bool provisioned;

    Impl()->LockThreadStack();
    provisioned = otDatasetIsCommissioned(mOTInst);
    Impl()->UnlockThreadStack();

    return provisioned;
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::_IsThreadAttached(void)
{
    otDeviceRole curRole;

    Impl()->LockThreadStack();
    curRole = otThreadGetDeviceRole(mOTInst);
    Impl()->UnlockThreadStack();

    return (curRole != OT_DEVICE_ROLE_DISABLED && curRole != OT_DEVICE_ROLE_DETACHED);
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetThreadProvision(DeviceNetworkInfo & netInfo, bool includeCredentials)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otOperationalDataset activeDataset;

    netInfo.Reset();

    Impl()->LockThreadStack();

    if (otDatasetIsCommissioned(mOTInst))
    {
        otError otErr = otDatasetGetActive(mOTInst, &activeDataset);
        err = MapOpenThreadError(otErr);
    }
    else
    {
        err = WEAVE_ERROR_INCORRECT_STATE;
    }

    Impl()->UnlockThreadStack();

    SuccessOrExit(err);

    netInfo.NetworkType = kNetworkType_Thread;
    netInfo.NetworkId = kThreadNetworkId;
    netInfo.FieldPresent.NetworkId = true;
    if (activeDataset.mComponents.mIsNetworkNamePresent)
    {
        strncpy(netInfo.ThreadNetworkName, (const char *)activeDataset.mNetworkName.m8, sizeof(netInfo.ThreadNetworkName));
    }
    if (activeDataset.mComponents.mIsExtendedPanIdPresent)
    {
        memcpy(netInfo.ThreadExtendedPANId, activeDataset.mExtendedPanId.m8, sizeof(netInfo.ThreadExtendedPANId));
        netInfo.FieldPresent.ThreadExtendedPANId = true;
    }
    if (activeDataset.mComponents.mIsMeshLocalPrefixPresent)
    {
        memcpy(netInfo.ThreadMeshPrefix, activeDataset.mMeshLocalPrefix.m8, sizeof(netInfo.ThreadMeshPrefix));
        netInfo.FieldPresent.ThreadMeshPrefix = true;
    }
    if (includeCredentials)
    {
        if (activeDataset.mComponents.mIsMasterKeyPresent)
        {
            memcpy(netInfo.ThreadNetworkKey, activeDataset.mMasterKey.m8, sizeof(netInfo.ThreadNetworkKey));
            netInfo.FieldPresent.ThreadNetworkKey = true;
        }
#ifdef EFR32_OPENTHREAD_API
        if (activeDataset.mComponents.mIsPskcPresent)
        {
            memcpy(netInfo.ThreadPSKc, activeDataset.mPskc.m8, sizeof(netInfo.ThreadPSKc));
            netInfo.FieldPresent.ThreadPSKc = true;
        }
#else // !EFR32_OPENTHREAD_API
        if (activeDataset.mComponents.mIsPSKcPresent)
        {
            memcpy(netInfo.ThreadPSKc, activeDataset.mPSKc.m8, sizeof(netInfo.ThreadPSKc));
            netInfo.FieldPresent.ThreadPSKc = true;
        }
#endif // !EFR32_OPENTHREAD_API
    }
    if (activeDataset.mComponents.mIsPanIdPresent)
    {
        netInfo.ThreadPANId = activeDataset.mPanId;
    }
    if (activeDataset.mComponents.mIsChannelPresent)
    {
        netInfo.ThreadChannel = activeDataset.mChannel;
    }

exit:
    return err;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetThreadProvision(const DeviceNetworkInfo & netInfo)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otError otErr;
    otOperationalDataset newDataset;

    // Form a Thread operational dataset from the given network parameters.
    memset(&newDataset, 0, sizeof(newDataset));
    newDataset.mComponents.mIsActiveTimestampPresent = true;
    newDataset.mComponents.mIsPendingTimestampPresent = true;
    if (netInfo.ThreadNetworkName[0] != 0)
    {
        strncpy((char *)newDataset.mNetworkName.m8, netInfo.ThreadNetworkName, sizeof(newDataset.mNetworkName.m8));
        newDataset.mComponents.mIsNetworkNamePresent = true;
    }
    if (netInfo.FieldPresent.ThreadExtendedPANId)
    {
        memcpy(newDataset.mExtendedPanId.m8, netInfo.ThreadExtendedPANId, sizeof(newDataset.mExtendedPanId.m8));
        newDataset.mComponents.mIsExtendedPanIdPresent = true;
    }
    if (netInfo.FieldPresent.ThreadMeshPrefix)
    {
        memcpy(newDataset.mMeshLocalPrefix.m8, netInfo.ThreadMeshPrefix, sizeof(newDataset.mMeshLocalPrefix.m8));
        newDataset.mComponents.mIsMeshLocalPrefixPresent = true;
    }
    if (netInfo.FieldPresent.ThreadNetworkKey)
    {
        memcpy(newDataset.mMasterKey.m8, netInfo.ThreadNetworkKey, sizeof(newDataset.mMasterKey.m8));
        newDataset.mComponents.mIsMasterKeyPresent = true;
    }
    if (netInfo.FieldPresent.ThreadPSKc)
    {
#ifdef EFR32_OPENTHREAD_API
        memcpy(newDataset.mPskc.m8, netInfo.ThreadPSKc, sizeof(newDataset.mPskc.m8));
        newDataset.mComponents.mIsPskcPresent = true;
#else // !EFR32_OPENTHREAD_API
        memcpy(newDataset.mPSKc.m8, netInfo.ThreadPSKc, sizeof(newDataset.mPSKc.m8));
        newDataset.mComponents.mIsPSKcPresent = true;
#endif // !EFR32_OPENTHREAD_API
    }
    if (netInfo.ThreadPANId != kThreadPANId_NotSpecified)
    {
        newDataset.mPanId = netInfo.ThreadPANId;
        newDataset.mComponents.mIsPanIdPresent = true;
    }
    if (netInfo.ThreadChannel != kThreadChannel_NotSpecified)
    {
        newDataset.mChannel = netInfo.ThreadChannel;
        newDataset.mComponents.mIsChannelPresent = true;
    }

    // Set the dataset as the active dataset for the node.
    Impl()->LockThreadStack();
    otErr = otDatasetSetActive(mOTInst, &newDataset);
    Impl()->UnlockThreadStack();

    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

exit:
    return err;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_ClearThreadProvision(void)
{
    Impl()->LockThreadStack();
    otThreadSetEnabled(mOTInst, false);
    otInstanceErasePersistentInfo(mOTInst);
    Impl()->UnlockThreadStack();
}

template<class ImplClass>
ConnectivityManager::ThreadDeviceType GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetThreadDeviceType(void)
{
    otLinkModeConfig linkMode;
    ConnectivityManager::ThreadDeviceType deviceType;

    Impl()->LockThreadStack();

    linkMode = otThreadGetLinkMode(mOTInst);

    if (linkMode.mDeviceType)
    {
#ifdef EFR32_OPENTHREAD_API
        if (otThreadIsRouterEligible(mOTInst))
#else // !EFR32_OPENTHREAD_API
        if (otThreadIsRouterRoleEnabled(mOTInst))
#endif // !EFR32_OPENTHREAD_API
        {
            deviceType = ConnectivityManager::kThreadDeviceType_Router;
        }
        else
        {
            deviceType = ConnectivityManager::kThreadDeviceType_FullEndDevice;
        }
    }
    else
    {
        if (linkMode.mRxOnWhenIdle)
        {
            deviceType = ConnectivityManager::kThreadDeviceType_MinimalEndDevice;
        }
        else
        {
            deviceType = ConnectivityManager::kThreadDeviceType_SleepyEndDevice;
        }
    }

    Impl()->UnlockThreadStack();

    return deviceType;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otLinkModeConfig linkMode;

    VerifyOrExit(deviceType == ConnectivityManager::kThreadDeviceType_Router ||
                 deviceType == ConnectivityManager::kThreadDeviceType_FullEndDevice ||
                 deviceType == ConnectivityManager::kThreadDeviceType_MinimalEndDevice ||
                 deviceType == ConnectivityManager::kThreadDeviceType_SleepyEndDevice,
                 err = WEAVE_ERROR_INVALID_ARGUMENT);

#if WEAVE_PROGRESS_LOGGING

    {
        const char * deviceTypeStr;
        switch (deviceType)
        {
        case ConnectivityManager::kThreadDeviceType_Router:
            deviceTypeStr = "ROUTER";
            break;
        case ConnectivityManager::kThreadDeviceType_FullEndDevice:
            deviceTypeStr = "FULL END DEVICE";
            break;
        case ConnectivityManager::kThreadDeviceType_MinimalEndDevice:
            deviceTypeStr = "MINIMAL END DEVICE";
            break;
        case ConnectivityManager::kThreadDeviceType_SleepyEndDevice:
            deviceTypeStr = "SLEEPY END DEVICE";
            break;
        default:
            deviceTypeStr = "(unknown)";
            break;
        }
        WeaveLogProgress(DeviceLayer, "Setting OpenThread device type to %s", deviceTypeStr);
    }

#endif // WEAVE_PROGRESS_LOGGING

    Impl()->LockThreadStack();

    linkMode = otThreadGetLinkMode(mOTInst);

    switch (deviceType)
    {
    case ConnectivityManager::kThreadDeviceType_Router:
    case ConnectivityManager::kThreadDeviceType_FullEndDevice:
        linkMode.mDeviceType = true;
        linkMode.mRxOnWhenIdle = true;
#ifdef EFR32_OPENTHREAD_API
        otThreadSetRouterEligible(mOTInst, deviceType == ConnectivityManager::kThreadDeviceType_Router);
#else // !EFR32_OPENTHREAD_API
        otThreadSetRouterRoleEnabled(mOTInst, deviceType == ConnectivityManager::kThreadDeviceType_Router);
#endif // !EFR32_OPENTHREAD_API
        break;
    case ConnectivityManager::kThreadDeviceType_MinimalEndDevice:
        linkMode.mDeviceType = false;
        linkMode.mRxOnWhenIdle = true;
        break;
    case ConnectivityManager::kThreadDeviceType_SleepyEndDevice:
        linkMode.mDeviceType = false;
        linkMode.mRxOnWhenIdle = false;
        break;
    default:
        break;
    }

    otThreadSetLinkMode(mOTInst, linkMode);

    Impl()->UnlockThreadStack();

exit:
    return err;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig)
{
    pollingConfig = mPollingConfig;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig)
{
    mPollingConfig = pollingConfig;
    return Impl()->AdjustPollingInterval();
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::_HaveMeshConnectivity(void)
{
    bool res;
    otDeviceRole curRole;

    Impl()->LockThreadStack();

    // Get the current Thread role.
    curRole = otThreadGetDeviceRole(mOTInst);

    // If Thread is disabled, or the node is detached, then the node has no mesh connectivity.
    if (curRole == OT_DEVICE_ROLE_DISABLED || curRole == OT_DEVICE_ROLE_DETACHED)
    {
        res = false;
    }

    // If the node is a child, that implies the existence of a parent node which provides connectivity
    // to the mesh.
    else if (curRole == OT_DEVICE_ROLE_CHILD)
    {
        res = true;
    }

    // Otherwise, if the node is acting as a router, scan the Thread neighbor table looking for at least
    // one other node that is also acting as router.
    else
    {
        otNeighborInfoIterator neighborIter = OT_NEIGHBOR_INFO_ITERATOR_INIT;
        otNeighborInfo neighborInfo;

        res = false;

        while (otThreadGetNextNeighborInfo(mOTInst, &neighborIter, &neighborInfo) == OT_ERROR_NONE)
        {
            if (!neighborInfo.mIsChild)
            {
                res = true;
                break;
            }
        }
    }

    Impl()->UnlockThreadStack();

    return res;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_OnMessageLayerActivityChanged(bool messageLayerIsActive)
{
    Impl()->AdjustPollingInterval();
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetAndLogThreadStatsCounters(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otError otErr;
    nl::Weave::Profiles::DataManagement_Current::event_id_t eventId;
    Schema::Nest::Trait::Network::TelemetryNetworkWpanTrait::NetworkWpanStatsEvent counterEvent = { 0 };
    const otMacCounters *macCounters;
    const otIpCounters *ipCounters;
    otOperationalDataset activeDataset;
    otDeviceRole role;

    Impl()->LockThreadStack();

    // Get Mac Counters
    macCounters = otLinkGetCounters(mOTInst);

    // Rx Counters
    counterEvent.phyRx                = macCounters->mRxTotal;
    counterEvent.macUnicastRx         = macCounters->mRxUnicast;
    counterEvent.macBroadcastRx       = macCounters->mRxBroadcast;
    counterEvent.macRxData            = macCounters->mRxData;
    counterEvent.macRxDataPoll        = macCounters->mRxDataPoll;
    counterEvent.macRxBeacon          = macCounters->mRxBeacon;
    counterEvent.macRxBeaconReq       = macCounters->mRxBeaconRequest;
    counterEvent.macRxOtherPkt        = macCounters->mRxOther;
    counterEvent.macRxFilterWhitelist = macCounters->mRxAddressFiltered;
    counterEvent.macRxFilterDestAddr  = macCounters->mRxDestAddrFiltered;

    // Tx Counters
    counterEvent.phyTx          = macCounters->mTxTotal;
    counterEvent.macUnicastTx   = macCounters->mTxUnicast;
    counterEvent.macBroadcastTx = macCounters->mTxBroadcast;
    counterEvent.macTxAckReq    = macCounters->mTxAckRequested;
    counterEvent.macTxNoAckReq  = macCounters->mTxNoAckRequested;
    counterEvent.macTxAcked     = macCounters->mTxAcked;
    counterEvent.macTxData      = macCounters->mTxData;
    counterEvent.macTxDataPoll  = macCounters->mTxDataPoll;
    counterEvent.macTxBeacon    = macCounters->mTxBeacon;
    counterEvent.macTxBeaconReq = macCounters->mTxBeaconRequest;
    counterEvent.macTxOtherPkt  = macCounters->mTxOther;
    counterEvent.macTxRetry     = macCounters->mTxRetry;

    // Tx Error Counters
    counterEvent.macTxFailCca = macCounters->mTxErrCca;

    // Rx Error Counters
    counterEvent.macRxFailDecrypt         = macCounters->mRxErrSec;
    counterEvent.macRxFailNoFrame         = macCounters->mRxErrNoFrame;
    counterEvent.macRxFailUnknownNeighbor = macCounters->mRxErrUnknownNeighbor;
    counterEvent.macRxFailInvalidSrcAddr  = macCounters->mRxErrInvalidSrcAddr;
    counterEvent.macRxFailFcs             = macCounters->mRxErrFcs;
    counterEvent.macRxFailOther           = macCounters->mRxErrOther;

    // Get Ip Counters
    ipCounters = otThreadGetIp6Counters(mOTInst);

    // Ip Counters
    counterEvent.ipTxSuccess = ipCounters->mTxSuccess;
    counterEvent.ipRxSuccess = ipCounters->mRxSuccess;
    counterEvent.ipTxFailure = ipCounters->mTxFailure;
    counterEvent.ipRxFailure = ipCounters->mRxFailure;

    if (otDatasetIsCommissioned(mOTInst))
    {
        otErr = otDatasetGetActive(mOTInst, &activeDataset);
        VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

        if (activeDataset.mComponents.mIsChannelPresent)
        {
            counterEvent.channel = activeDataset.mChannel;
        }
    }

    role = otThreadGetDeviceRole(mOTInst);

    switch (role)
    {
    case OT_DEVICE_ROLE_LEADER:
        counterEvent.nodeType |= TelemetryNetworkWpanTrait::NODE_TYPE_LEADER;
        // Intentional fall-through: if it's a leader, then it's also a router
    case OT_DEVICE_ROLE_ROUTER:
        counterEvent.nodeType |= TelemetryNetworkWpanTrait::NODE_TYPE_ROUTER;
        break;
    case OT_DEVICE_ROLE_CHILD:
    case OT_DEVICE_ROLE_DISABLED:
    case OT_DEVICE_ROLE_DETACHED:
    default:
        counterEvent.nodeType = 0;
        break;
    }

    counterEvent.threadType = TelemetryNetworkWpanTrait::THREAD_TYPE_OPENTHREAD;

    WeaveLogProgress(DeviceLayer,
                     "Rx Counters:\n"
                     "PHY Rx Total:                 %d\n"
                     "MAC Rx Unicast:               %d\n"
                     "MAC Rx Broadcast:             %d\n"
                     "MAC Rx Data:                  %d\n"
                     "MAC Rx Data Polls:            %d",
                     counterEvent.phyRx, counterEvent.macUnicastRx, counterEvent.macBroadcastRx,
                     counterEvent.macRxData, counterEvent.macRxDataPoll);

    WeaveLogProgress(DeviceLayer,
                     "Rx Counters (Contd.):\n"
                     "MAC Rx Beacons:               %d\n"
                     "MAC Rx Beacon Reqs:           %d\n"
                     "MAC Rx Other:                 %d\n"
                     "MAC Rx Filtered Whitelist:    %d\n"
                     "MAC Rx Filtered DestAddr:     %d",
                     counterEvent.macRxBeacon, counterEvent.macRxBeaconReq, counterEvent.macRxOtherPkt,
                     counterEvent.macRxFilterWhitelist, counterEvent.macRxFilterDestAddr);

    WeaveLogProgress(DeviceLayer,
                     "Tx Counters:\n"
                     "PHY Tx Total:                 %d\n"
                     "MAC Tx Unicast:               %d\n"
                     "MAC Tx Broadcast:             %d\n"
                     "MAC Tx Data:                  %d\n"
                     "MAC Tx Data Polls:            %d",
                     counterEvent.phyTx, counterEvent.macUnicastTx, counterEvent.macBroadcastTx, counterEvent.macTxData,
                     counterEvent.macTxDataPoll);

    WeaveLogProgress(DeviceLayer,
                     "Tx Counters (Contd.):\n"
                     "MAC Tx Beacons:               %d\n"
                     "MAC Tx Beacon Reqs:           %d\n"
                     "MAC Tx Other:                 %d\n"
                     "MAC Tx Retry:                 %d\n"
                     "MAC Tx CCA Fail:              %d",
                     counterEvent.macTxBeacon, counterEvent.macTxBeaconReq, counterEvent.macTxOtherPkt,
                     counterEvent.macTxRetry, counterEvent.macTxFailCca);

    WeaveLogProgress(DeviceLayer,
                     "Failure Counters:\n"
                     "MAC Rx Decrypt Fail:          %d\n"
                     "MAC Rx No Frame Fail:         %d\n"
                     "MAC Rx Unknown Neighbor Fail: %d\n"
                     "MAC Rx Invalid Src Addr Fail: %d\n"
                     "MAC Rx FCS Fail:              %d\n"
                     "MAC Rx Other Fail:            %d",
                     counterEvent.macRxFailDecrypt, counterEvent.macRxFailNoFrame, counterEvent.macRxFailUnknownNeighbor,
                     counterEvent.macRxFailInvalidSrcAddr, counterEvent.macRxFailFcs, counterEvent.macRxFailOther);

    eventId = nl::LogEvent(&counterEvent);
    WeaveLogProgress(DeviceLayer, "OpenThread Telemetry Stats Event Id: %u", eventId);

exit:
    Impl()->UnlockThreadStack();

    return err;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetAndLogThreadTopologyMinimal(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otError otErr;
    nl::Weave::Profiles::DataManagement_Current::event_id_t eventId;
    Schema::Nest::Trait::Network::TelemetryNetworkWpanTrait::NetworkWpanTopoMinimalEvent topologyEvent = { 0 };
    const otExtAddress *extAddress;

    Impl()->LockThreadStack();

    topologyEvent.rloc16 = otThreadGetRloc16(mOTInst);

    // Router ID is the top 6 bits of the RLOC
    topologyEvent.routerId = (topologyEvent.rloc16 >> 10) & 0x3f;

    topologyEvent.leaderRouterId = otThreadGetLeaderRouterId(mOTInst);

    otErr = otThreadGetParentAverageRssi(mOTInst, &topologyEvent.parentAverageRssi);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    otErr = otThreadGetParentLastRssi(mOTInst, &topologyEvent.parentLastRssi);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    topologyEvent.partitionId = otThreadGetPartitionId(mOTInst);

    extAddress = otLinkGetExtendedAddress(mOTInst);

    topologyEvent.extAddress.mBuf = (uint8_t *)extAddress;
    topologyEvent.extAddress.mLen = sizeof(otExtAddress);

    topologyEvent.instantRssi = otPlatRadioGetRssi(mOTInst);

    WeaveLogProgress(DeviceLayer,
                     "Thread Topology:\n"
                     "RLOC16:           %04X\n"
                     "Router ID:        %u\n"
                     "Leader Router ID: %u\n"
                     "Parent Avg RSSI:  %d\n"
                     "Parent Last RSSI: %d\n"
                     "Partition ID:     %d\n"
                     "Extended Address: %02X%02X:%02X%02X:%02X%02X:%02X%02X\n"
                     "Instant RSSI:     %d",
                     topologyEvent.rloc16, topologyEvent.routerId, topologyEvent.leaderRouterId, topologyEvent.parentAverageRssi,
                     topologyEvent.parentLastRssi, topologyEvent.partitionId, topologyEvent.extAddress.mBuf[0], topologyEvent.extAddress.mBuf[1],
                     topologyEvent.extAddress.mBuf[2], topologyEvent.extAddress.mBuf[3], topologyEvent.extAddress.mBuf[4],
                     topologyEvent.extAddress.mBuf[5], topologyEvent.extAddress.mBuf[6], topologyEvent.extAddress.mBuf[7], topologyEvent.instantRssi);

    eventId = nl::LogEvent(&topologyEvent);
    WeaveLogProgress(DeviceLayer, "OpenThread Telemetry Stats Event Id: %u", eventId);

exit:
    Impl()->UnlockThreadStack();

    if (err != WEAVE_NO_ERROR)
    {
        WeaveLogError(DeviceLayer, "GetAndLogThreadTopologyMinimal failed: %s", nl::ErrorStr(err));
    }

    return err;
}

#define TELEM_NEIGHBOR_TABLE_SIZE (64)
#define TELEM_PRINT_BUFFER_SIZE (64)

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetAndLogThreadTopologyFull(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otError otErr;
    nl::Weave::Profiles::DataManagement_Current::EventOptions neighborTopoOpts(true);
    nl::Weave::Profiles::DataManagement_Current::event_id_t eventId;
    Schema::Nest::Trait::Network::TelemetryNetworkWpanTrait::NetworkWpanTopoFullEvent fullTopoEvent = { 0 };
    Schema::Nest::Trait::Network::TelemetryNetworkWpanTrait::TopoEntryEvent neighborTopoEvent = { 0 };
    otIp6Address * leaderAddr = NULL;
    uint8_t * networkData = NULL;
    uint8_t * stableNetworkData = NULL;
    uint8_t networkDataLen = 0;
    uint8_t stableNetworkDataLen = 0;
    const otExtAddress * extAddress;
    otNeighborInfo neighborInfo[TELEM_NEIGHBOR_TABLE_SIZE];
    otNeighborInfoIterator iter;
    otNeighborInfoIterator iterCopy;
    char printBuf[TELEM_PRINT_BUFFER_SIZE];

    Impl()->LockThreadStack();

    fullTopoEvent.rloc16 = otThreadGetRloc16(mOTInst);

    // Router ID is the top 6 bits of the RLOC
    fullTopoEvent.routerId = (fullTopoEvent.rloc16 >> 10) & 0x3f;

    fullTopoEvent.leaderRouterId = otThreadGetLeaderRouterId(mOTInst);

    otErr = otThreadGetLeaderRloc(mOTInst, leaderAddr);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    fullTopoEvent.leaderAddress.mBuf = leaderAddr->mFields.m8;
    fullTopoEvent.leaderAddress.mLen = OT_IP6_ADDRESS_SIZE;

    fullTopoEvent.leaderWeight = otThreadGetLeaderWeight(mOTInst);

    fullTopoEvent.leaderLocalWeight = otThreadGetLocalLeaderWeight(mOTInst);

    otErr = otNetDataGet(mOTInst, false, networkData, &networkDataLen);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    fullTopoEvent.networkData.mBuf = networkData;
    fullTopoEvent.networkData.mLen = networkDataLen;

    fullTopoEvent.networkDataVersion = otNetDataGetVersion(mOTInst);

    otErr = otNetDataGet(mOTInst, true, stableNetworkData, &stableNetworkDataLen);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    fullTopoEvent.stableNetworkData.mBuf = stableNetworkData;
    fullTopoEvent.stableNetworkData.mLen = stableNetworkDataLen;

    fullTopoEvent.stableNetworkDataVersion = otNetDataGetStableVersion(mOTInst);

    // Deprecated property
    fullTopoEvent.preferredRouterId = -1;

    extAddress = otLinkGetExtendedAddress(mOTInst);

    fullTopoEvent.extAddress.mBuf = (uint8_t *)extAddress;
    fullTopoEvent.extAddress.mLen = sizeof(otExtAddress);

    fullTopoEvent.partitionId = otThreadGetPartitionId(mOTInst);

    fullTopoEvent.instantRssi = otPlatRadioGetRssi(mOTInst);

    iter = OT_NEIGHBOR_INFO_ITERATOR_INIT;
    iterCopy = OT_NEIGHBOR_INFO_ITERATOR_INIT;
    fullTopoEvent.neighborTableSize = 0;
    fullTopoEvent.childTableSize = 0;

    while (otThreadGetNextNeighborInfo(mOTInst, &iter, &neighborInfo[iter]) == OT_ERROR_NONE)
    {
        fullTopoEvent.neighborTableSize++;
        if (neighborInfo[iterCopy].mIsChild)
        {
            fullTopoEvent.childTableSize++;
        }
        iterCopy = iter;
    }

    WeaveLogProgress(DeviceLayer,
                     "Thread Topology:\n"
                     "RLOC16:                %04X\n"
                     "Router ID:             %u\n"
                     "Leader Router ID:      %u\n"
                     "Leader Address:        %02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X\n"
                     "Leader Weight:         %d\n"
                     "Local Leader Weight:   %d",
                     fullTopoEvent.rloc16, fullTopoEvent.routerId, fullTopoEvent.leaderRouterId,
                     fullTopoEvent.leaderAddress.mBuf[0], fullTopoEvent.leaderAddress.mBuf[1], fullTopoEvent.leaderAddress.mBuf[2], fullTopoEvent.leaderAddress.mBuf[3],
                     fullTopoEvent.leaderAddress.mBuf[4], fullTopoEvent.leaderAddress.mBuf[5], fullTopoEvent.leaderAddress.mBuf[6], fullTopoEvent.leaderAddress.mBuf[7],
                     fullTopoEvent.leaderAddress.mBuf[8], fullTopoEvent.leaderAddress.mBuf[9], fullTopoEvent.leaderAddress.mBuf[10], fullTopoEvent.leaderAddress.mBuf[11],
                     fullTopoEvent.leaderAddress.mBuf[12], fullTopoEvent.leaderAddress.mBuf[13], fullTopoEvent.leaderAddress.mBuf[14], fullTopoEvent.leaderAddress.mBuf[15],
                     fullTopoEvent.leaderWeight, fullTopoEvent.leaderLocalWeight);

    WeaveLogProgress(DeviceLayer,
                     "Thread Topology (Contd.):\n"
                     "Network Data Len:      %d\n"
                     "Network Data Version:  %d\n"
                     "Extended Address:      %02X%02X:%02X%02X:%02X%02X:%02X%02X\n"
                     "Partition ID:          %X\n"
                     "Instant RSSI:          %d\n"
                     "Neighbor Table Length: %d\n"
                     "Child Table Length:    %d",
                     fullTopoEvent.networkData.mLen, fullTopoEvent.networkDataVersion,
                     fullTopoEvent.extAddress.mBuf[0], fullTopoEvent.extAddress.mBuf[1], fullTopoEvent.extAddress.mBuf[2], fullTopoEvent.extAddress.mBuf[3],
                     fullTopoEvent.extAddress.mBuf[4], fullTopoEvent.extAddress.mBuf[5], fullTopoEvent.extAddress.mBuf[6], fullTopoEvent.extAddress.mBuf[7],
                     fullTopoEvent.partitionId, fullTopoEvent.instantRssi, fullTopoEvent.neighborTableSize, fullTopoEvent.childTableSize);

    eventId = nl::LogEvent(&fullTopoEvent);
    WeaveLogProgress(DeviceLayer, "OpenThread Full Topology Event Id: %u", eventId);

    // Populate the neighbor event options.
    // This way the neighbor topology entries are linked to the actual topology full event.
    neighborTopoOpts.relatedEventID = eventId;
    neighborTopoOpts.relatedImportance = TelemetryNetworkWpanTrait::NetworkWpanTopoFullEvent::Schema.mImportance;

    // Handle each neighbor event seperatly.
    for (uint32_t i = 0; i < fullTopoEvent.neighborTableSize; i++)
    {
        otNeighborInfo * neighbor           = &neighborInfo[i];

        neighborTopoEvent.extAddress.mBuf   = neighbor->mExtAddress.m8;
        neighborTopoEvent.extAddress.mLen   = sizeof(uint64_t);

        neighborTopoEvent.rloc16            = neighbor->mRloc16;
        neighborTopoEvent.linkQualityIn     = neighbor->mLinkQualityIn;
        neighborTopoEvent.averageRssi       = neighbor->mAverageRssi;
        neighborTopoEvent.age               = neighbor->mAge;
        neighborTopoEvent.rxOnWhenIdle      = neighbor->mRxOnWhenIdle;
        // TODO: not supported in old version of OpenThread used by Nordic SDK.
        // neighborTopoEvent.fullFunction      = neighbor->mFullThreadDevice;
        neighborTopoEvent.fullFunction      = false;
        neighborTopoEvent.secureDataRequest = neighbor->mSecureDataRequest;
        neighborTopoEvent.fullNetworkData   = neighbor->mFullNetworkData;
        neighborTopoEvent.lastRssi          = neighbor->mLastRssi;
        neighborTopoEvent.linkFrameCounter  = neighbor->mLinkFrameCounter;
        neighborTopoEvent.mleFrameCounter   = neighbor->mMleFrameCounter;
        neighborTopoEvent.isChild           = neighbor->mIsChild;

        if (neighborTopoEvent.isChild)
        {
            otChildInfo * child =  NULL;
            otErr = otThreadGetChildInfoById(mOTInst, neighborTopoEvent.rloc16, child);
            VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

            neighborTopoEvent.timeout            = child->mTimeout;
            neighborTopoEvent.networkDataVersion = child->mNetworkDataVersion;

            neighborTopoEvent.SetTimeoutPresent();
            neighborTopoEvent.SetNetworkDataVersionPresent();

            snprintf(printBuf, TELEM_PRINT_BUFFER_SIZE, ", Timeout: %10lu NetworkDataVersion: %3d",
                               neighborTopoEvent.timeout, neighborTopoEvent.networkDataVersion);
        }
        else
        {
            neighborTopoEvent.SetTimeoutNull();
            neighborTopoEvent.SetNetworkDataVersionNull();

            printBuf[0] = 0;
        }

        WeaveLogProgress(DeviceLayer,
                         "TopoEntry[%u]:     %02X%02X:%02X%02X:%02X%02X:%02X%02X\n"
                         "RLOC:              %04X\n"
                         "Age:               %3d\n"
                         "LQI:               %1d\n"
                         "AvgRSSI:           %3d\n"
                         "LastRSSI:          %3d\n"
                         "LinkFrameCounter:  %10d\n"
                         "MleFrameCounter:   %10d",
                         i, neighborTopoEvent.extAddress.mBuf[0], neighborTopoEvent.extAddress.mBuf[1], neighborTopoEvent.extAddress.mBuf[2],
                         neighborTopoEvent.extAddress.mBuf[3], neighborTopoEvent.extAddress.mBuf[4], neighborTopoEvent.extAddress.mBuf[5],
                         neighborTopoEvent.extAddress.mBuf[6], neighborTopoEvent.extAddress.mBuf[7], neighborTopoEvent.rloc16, neighborTopoEvent.age,
                         neighborTopoEvent.linkQualityIn, neighborTopoEvent.averageRssi, neighborTopoEvent.lastRssi, neighborTopoEvent.linkFrameCounter,
                         neighborTopoEvent.mleFrameCounter);

        WeaveLogProgress(DeviceLayer,
                         "RxOnWhenIdle:      %c\n"
                         "SecureDataRequest: %c\n"
                         "FullFunction:      %c\n"
                         "FullNetworkData:   %c\n"
                         "IsChild:           %c%s",
                         neighborTopoEvent.rxOnWhenIdle ? 'Y' : 'n', neighborTopoEvent.secureDataRequest ? 'Y' : 'n',
                         neighborTopoEvent.fullFunction ? 'Y' : 'n', neighborTopoEvent.fullNetworkData ? 'Y' : 'n',
                         neighborTopoEvent.isChild ? 'Y' : 'n', printBuf);

        eventId = nl::LogEvent(&neighborTopoEvent, neighborTopoOpts);
        WeaveLogProgress(DeviceLayer, "OpenThread Neighbor TopoEntry[%u] Event Id: %ld", i, eventId);
    }

exit:
    Impl()->UnlockThreadStack();

    if (err != WEAVE_NO_ERROR)
    {
        WeaveLogError(DeviceLayer, "GetAndLogThreadTopologyFull failed: %s", nl::ErrorStr(err));
    }
    return err;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetPrimary802154MACAddress(uint8_t *buf)
{
    const otExtAddress *extendedAddr = otLinkGetExtendedAddress(mOTInst);
    memcpy(buf, extendedAddr, sizeof(otExtAddress));
    return WEAVE_NO_ERROR;
};

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstance * otInst)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    otError otErr;

    // Arrange for OpenThread errors to be translated to text.
    RegisterOpenThreadErrorFormatter();

    mOTInst = NULL;
    mPollingConfig.Clear();

    // If an OpenThread instance hasn't been supplied, call otInstanceInitSingle() to
    // create or acquire a singleton instance of OpenThread.
    if (otInst == NULL)
    {
        otInst = otInstanceInitSingle();
        VerifyOrExit(otInst != NULL, err = MapOpenThreadError(OT_ERROR_FAILED));
    }

    mOTInst = otInst;

    // Arrange for OpenThread to call the OnOpenThreadStateChange method whenever a
    // state change occurs.  Note that we reference the OnOpenThreadStateChange method
    // on the concrete implementation class so that that class can override the default
    // method implementation if it chooses to.
    otErr = otSetStateChangedCallback(otInst, ImplClass::OnOpenThreadStateChange, NULL);
    VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

    // Enable use of secure data requests.
    {
        otLinkModeConfig linkMode = otThreadGetLinkMode(otInst);
        linkMode.mSecureDataRequests = true;
        otErr = otThreadSetLinkMode(otInst, linkMode);
        VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));
    }

    // Disable automatic assignment of Thread advertised addresses.
#if OPENTHREAD_CONFIG_ENABLE_SLAAC
    otIp6SetSlaacEnabled(otInst, false);
#endif

    // If the Thread stack has been provisioned, but is not currently enabled, enable it now.
    if (otThreadGetDeviceRole(mOTInst) == OT_DEVICE_ROLE_DISABLED && otDatasetIsCommissioned(otInst))
    {
        // Enable the Thread IPv6 interface.
        otErr = otIp6SetEnabled(otInst, true);
        VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));

        otErr = otThreadSetEnabled(otInst, true);
        VerifyOrExit(otErr == OT_ERROR_NONE, err = MapOpenThreadError(otErr));
    }

exit:
    return err;
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::IsThreadAttachedNoLock(void)
{
    otDeviceRole curRole = otThreadGetDeviceRole(mOTInst);
    return (curRole != OT_DEVICE_ROLE_DISABLED && curRole != OT_DEVICE_ROLE_DETACHED);
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::AdjustPollingInterval(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    uint32_t newPollingIntervalMS = MessageLayer.IsMessageLayerActive()
            ? mPollingConfig.ActivePollingIntervalMS
            : mPollingConfig.InactivePollingIntervalMS;

    if (newPollingIntervalMS != 0)
    {
        Impl()->LockThreadStack();

        uint32_t curPollingIntervalMS = otLinkGetPollPeriod(mOTInst);

        if (newPollingIntervalMS != curPollingIntervalMS)
        {
            otError otErr = otLinkSetPollPeriod(mOTInst, newPollingIntervalMS);
            err = MapOpenThreadError(otErr);
        }

        Impl()->UnlockThreadStack();

        if (newPollingIntervalMS != curPollingIntervalMS)
        {
            WeaveLogProgress(DeviceLayer, "OpenThread polling interval set to %" PRId32 "ms", newPollingIntervalMS);
        }
    }

    return err;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace Weave
} // namespace nl


#endif // GENERIC_THREAD_STACK_MANAGER_IMPL_OPENTHREAD_IPP
