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

/**
 *    @file
 *     This file implements a unit test suite for Inet EndPoint related features
 *
 */

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

#include <pw_unit_test/framework.h>

#include <CHIPVersion.h>
#include <inet/IPPrefix.h>
#include <inet/InetConfig.h>
#include <inet/InetError.h>
#include <inet/UDPEndPoint.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <system/SystemError.h>

#include "TestInetCommon.h"
#include "TestSetupSignalling.h"

using namespace chip;
using namespace chip::Inet;
using namespace chip::System;
using namespace chip::System::Clock::Literals;

#define TOOL_NAME "TestInetEndPoint"

bool callbackHandlerCalled = false;

void HandleDNSResolveComplete(void * appState, CHIP_ERROR err, uint8_t addrCount, IPAddress * addrArray)
{
    callbackHandlerCalled = true;

    if (addrCount > 0)
    {
        char destAddrStr[64];
        addrArray->ToString(destAddrStr);
        printf("    DNS name resolution complete: %s\n", destAddrStr);
    }
    else
        printf("    DNS name resolution return no addresses\n");
}

void HandleTimer(Layer * aLayer, void * aAppState)
{
    printf("    timer handler\n");
}

class TestInetEndPoint : public ::testing::Test
{
public:
    static void SetUpTestSuite()
    {
        SetSIGUSR1Handler();
        ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);
    }
    static void TearDownTestSuite()
    {
        ShutdownNetwork();
        ShutdownSystemLayer();
        chip::Platform::MemoryShutdown();
    }
};

// Test before init network, Inet is not initialized
TEST_F(TestInetEndPoint, TestInetPre)
{
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    UDPEndPoint * testUDPEP = nullptr;
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    TCPEndPoint * testTCPEP = nullptr;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
    CHIP_ERROR err = CHIP_NO_ERROR;

    // Deinit system layer and network
    ShutdownNetwork();
    if (gSystemLayer.IsInitialized())
    {
        ShutdownSystemLayer();
    }

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    err = gUDP.NewEndPoint(&testUDPEP);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    err = gTCP.NewEndPoint(&testTCPEP);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

    err = gSystemLayer.StartTimer(10_ms32, HandleTimer, nullptr);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);

    // then init network
    InitSystemLayer();
    InitNetwork();
}

TEST_F(TestInetEndPoint, TestInetError)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    err = CHIP_ERROR_POSIX(EPERM);
    EXPECT_TRUE(DescribeErrorPOSIX(err));
    EXPECT_TRUE(err.IsRange(ChipError::Range::kPOSIX));
}

TEST_F(TestInetEndPoint, TestInetInterface)
{
    InterfaceIterator intIterator;
    InterfaceAddressIterator addrIterator;
    char intName[InterfaceId::kMaxIfNameLength];
    InterfaceId intId;
    IPAddress addr;
    InterfaceType intType;
    // 64 bit IEEE MAC address
    const uint8_t kMaxHardwareAddressSize = 8;
    uint8_t intHwAddress[kMaxHardwareAddressSize];
    uint8_t intHwAddressSize;

    CHIP_ERROR err;

#ifndef __MBED__
    // Mbed interface name has different format
    err = InterfaceId::InterfaceNameToId("0", intId);
    EXPECT_NE(err, CHIP_NO_ERROR);
#endif

    err = InterfaceId::Null().GetInterfaceName(intName, 0);
    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);

    err = InterfaceId::Null().GetInterfaceName(intName, sizeof(intName));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(intName[0], '\0');

    intId = InterfaceId::FromIPAddress(addr);
    EXPECT_FALSE(intId.IsPresent());

    err = intId.GetLinkLocalAddr(nullptr);
    EXPECT_EQ(err, CHIP_ERROR_INVALID_ARGUMENT);

    printf("    Interfaces:\n");
    for (; intIterator.HasCurrent(); intIterator.Next())
    {
        intId = intIterator.GetInterfaceId();
        EXPECT_TRUE(intId.IsPresent());
        memset(intName, 42, sizeof(intName));
        err = intIterator.GetInterfaceName(intName, sizeof(intName));
        EXPECT_EQ(err, CHIP_NO_ERROR);
        printf("     interface id: 0x%" PRIxPTR ", interface name: %s, interface state: %s, %s multicast, %s broadcast addr\n",
#if CHIP_SYSTEM_CONFIG_USE_LWIP
               reinterpret_cast<uintptr_t>(intId.GetPlatformInterface()),
#else
               static_cast<uintptr_t>(intId.GetPlatformInterface()),
#endif
               intName, intIterator.IsUp() ? "UP" : "DOWN", intIterator.SupportsMulticast() ? "supports" : "no",
               intIterator.HasBroadcastAddress() ? "has" : "no");

        intId.GetLinkLocalAddr(&addr);
        InterfaceId::MatchLocalIPv6Subnet(addr);

        // Not all platforms support getting interface type and hardware address
        err = intIterator.GetInterfaceType(intType);
        EXPECT_TRUE(err == CHIP_NO_ERROR || err == CHIP_ERROR_NOT_IMPLEMENTED);

        err = intIterator.GetHardwareAddress(intHwAddress, intHwAddressSize, sizeof(intHwAddress));
        EXPECT_TRUE(err == CHIP_NO_ERROR || err == CHIP_ERROR_NOT_IMPLEMENTED);
        if (err == CHIP_NO_ERROR)
        {
            EXPECT_TRUE(intHwAddressSize == 6 || intHwAddressSize == 8);
            EXPECT_EQ(intIterator.GetHardwareAddress(nullptr, intHwAddressSize, sizeof(intHwAddress)), CHIP_ERROR_INVALID_ARGUMENT);
            EXPECT_EQ(intIterator.GetHardwareAddress(intHwAddress, intHwAddressSize, 4), CHIP_ERROR_BUFFER_TOO_SMALL);
        }
    }

    EXPECT_FALSE(intIterator.Next());
    EXPECT_EQ(intIterator.GetInterfaceId(), InterfaceId::Null());
    EXPECT_EQ(intIterator.GetInterfaceName(intName, sizeof(intName)), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(intIterator.SupportsMulticast());
    EXPECT_FALSE(intIterator.HasBroadcastAddress());

    // Not all platforms support getting interface type and hardware address
    err = intIterator.GetInterfaceType(intType);
    EXPECT_TRUE(err == CHIP_ERROR_INCORRECT_STATE || err == CHIP_ERROR_NOT_IMPLEMENTED);
    err = intIterator.GetHardwareAddress(intHwAddress, intHwAddressSize, sizeof(intHwAddress));
    EXPECT_TRUE(err == CHIP_ERROR_INCORRECT_STATE || err == CHIP_ERROR_NOT_IMPLEMENTED);

    printf("    Addresses:\n");
    for (; addrIterator.HasCurrent(); addrIterator.Next())
    {
        err = addrIterator.GetAddress(addr);
        EXPECT_EQ(err, CHIP_NO_ERROR);
        IPPrefix addrWithPrefix(addr, addrIterator.GetPrefixLength());
        char addrStr[80];
        addrWithPrefix.IPAddr.ToString(addrStr);
        intId = addrIterator.GetInterfaceId();
        EXPECT_TRUE(intId.IsPresent());
        memset(intName, 42, sizeof(intName));
        err = addrIterator.GetInterfaceName(intName, sizeof(intName));
        EXPECT_EQ(err, CHIP_NO_ERROR);
        EXPECT_TRUE(intName[0] != '\0' && memchr(intName, '\0', sizeof(intName)) != nullptr);
        printf("     %s/%d, interface id: 0x%" PRIxPTR
               ", interface name: %s, interface state: %s, %s multicast, %s broadcast addr\n",
               addrStr, addrWithPrefix.Length,
#if CHIP_SYSTEM_CONFIG_USE_LWIP
               reinterpret_cast<uintptr_t>(intId.GetPlatformInterface()),
#else
               static_cast<uintptr_t>(intId.GetPlatformInterface()),
#endif
               intName, addrIterator.IsUp() ? "UP" : "DOWN", addrIterator.SupportsMulticast() ? "supports" : "no",
               addrIterator.HasBroadcastAddress() ? "has" : "no");
    }
    EXPECT_FALSE(addrIterator.Next());
    EXPECT_EQ(addrIterator.GetAddress(addr), CHIP_ERROR_SENTINEL);
    EXPECT_EQ(addrIterator.GetInterfaceId(), InterfaceId::Null());
    EXPECT_EQ(addrIterator.GetInterfaceName(intName, sizeof(intName)), CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(addrIterator.SupportsMulticast());
    EXPECT_FALSE(addrIterator.HasBroadcastAddress());
}

TEST_F(TestInetEndPoint, TestInetEndPointInternal)
{
    CHIP_ERROR err;
    IPAddress addr_any = IPAddress::Any;
    IPAddress addr;
#if INET_CONFIG_ENABLE_IPV4
    IPAddress addr_v4;
#endif // INET_CONFIG_ENABLE_IPV4
    InterfaceId intId;

    // EndPoint
    UDPEndPoint * testUDPEP = nullptr;
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    TCPEndPoint * testTCPEP1 = nullptr;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
    PacketBufferHandle buf = PacketBufferHandle::New(PacketBuffer::kMaxSize);

    // init all the EndPoints
    SYSTEM_STATS_RESET(System::Stats::kInetLayer_NumUDPEps);
    err = gUDP.NewEndPoint(&testUDPEP);
    ASSERT_EQ(err, CHIP_NO_ERROR);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, 1));

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    SYSTEM_STATS_RESET(System::Stats::kInetLayer_NumTCPEps);
    err = gTCP.NewEndPoint(&testTCPEP1);
    ASSERT_EQ(err, CHIP_NO_ERROR);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumTCPEps, 1));
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

    err = InterfaceId::Null().GetLinkLocalAddr(&addr);

    // We should skip the following checks if the interface does not have the Link local address.
    // This can happen if you don't have network interfaces connected to any link (like happened
    // to the author of this comment at YYZ before CSA 2025 Chicago Member Meeting).
    if (err == INET_ERROR_ADDRESS_NOT_FOUND)
    {
        return;
    }

    EXPECT_EQ(err, CHIP_NO_ERROR);
    intId = InterfaceId::FromIPAddress(addr);
    EXPECT_TRUE(intId.IsPresent());

#if INET_CONFIG_ENABLE_IPV4
    EXPECT_TRUE(IPAddress::FromString("10.0.0.1", addr_v4));
#endif // INET_CONFIG_ENABLE_IPV4

    // UdpEndPoint special cases to cover the error branch
    err = testUDPEP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testUDPEP->Bind(IPAddressType::kUnknown, addr_any, 3000);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);
    err = testUDPEP->Bind(IPAddressType::kUnknown, addr, 3000);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);
#if INET_CONFIG_ENABLE_IPV4
    err = testUDPEP->Bind(IPAddressType::kIPv4, addr, 3000);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);
#endif // INET_CONFIG_ENABLE_IPV4

    err            = testUDPEP->Bind(IPAddressType::kIPv6, addr, 3000, intId);
    err            = testUDPEP->BindInterface(IPAddressType::kIPv6, intId);
    InterfaceId id = testUDPEP->GetBoundInterface();
    EXPECT_EQ(id, intId);

    err = testUDPEP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/);
    err = testUDPEP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/);
    err = testUDPEP->Bind(IPAddressType::kIPv6, addr, 3000, intId);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testUDPEP->BindInterface(IPAddressType::kIPv6, intId);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    testUDPEP->Free();
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, 0));
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumUDPEps, 1));

    err = gUDP.NewEndPoint(&testUDPEP);
    ASSERT_EQ(err, CHIP_NO_ERROR);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, 1));
#if INET_CONFIG_ENABLE_IPV4
    err = testUDPEP->Bind(IPAddressType::kIPv4, addr_v4, 3000, intId);
    EXPECT_NE(err, CHIP_NO_ERROR);
    buf = PacketBufferHandle::New(PacketBuffer::kMaxSize);
    err = testUDPEP->SendTo(addr_v4, 3000, std::move(buf));
#endif // INET_CONFIG_ENABLE_IPV4
    testUDPEP->Free();
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, 0));

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    // TcpEndPoint special cases to cover the error branch
    err = testTCPEP1->GetPeerInfo(nullptr, nullptr);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    buf = PacketBufferHandle::New(PacketBuffer::kMaxSize);
    err = testTCPEP1->Send(std::move(buf), false);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testTCPEP1->EnableKeepAlive(10, 100);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testTCPEP1->DisableKeepAlive();
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testTCPEP1->AckReceive(10);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    EXPECT_FALSE(testTCPEP1->PendingReceiveLength());
    err = testTCPEP1->Listen(4);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testTCPEP1->GetLocalInfo(nullptr, nullptr);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);

    err = testTCPEP1->Bind(IPAddressType::kUnknown, addr_any, 3000, true);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);
#if INET_CONFIG_ENABLE_IPV4
    err = testTCPEP1->Bind(IPAddressType::kIPv4, addr, 3000, true);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);
#endif // INET_CONFIG_ENABLE_IPV4
    err = testTCPEP1->Bind(IPAddressType::kUnknown, addr, 3000, true);
    EXPECT_EQ(err, INET_ERROR_WRONG_ADDRESS_TYPE);

    err = testTCPEP1->Bind(IPAddressType::kIPv6, addr_any, 3000, true);
    err = testTCPEP1->Bind(IPAddressType::kIPv6, addr_any, 3000, true);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    err = testTCPEP1->Listen(4);
#if INET_CONFIG_ENABLE_IPV4
    err = testTCPEP1->Connect(addr_v4, 4000, intId);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
#endif // INET_CONFIG_ENABLE_IPV4

    testTCPEP1->Free();
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumTCPEps, 0));
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumTCPEps, 1));
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
}

#if !CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
// Test the Inet resource limitations.
TEST_F(TestInetEndPoint, TestInetEndPointLimit)
{
    UDPEndPoint * testUDPEP[INET_CONFIG_NUM_UDP_ENDPOINTS + 1] = { nullptr };
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    TCPEndPoint * testTCPEP[INET_CONFIG_NUM_TCP_ENDPOINTS + 1] = { nullptr };
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

    CHIP_ERROR err = CHIP_NO_ERROR;

    // we assume NO open endpoints
    gUDP.ForEachEndPoint([](UDPEndPoint * ep) {
        ChipLogError(Test, "NOTE: Unexpected UDP endpoint in use. Will free it");
        ep->Free();
        return Loop::Continue;
    });

    int udpCount = 0;
    SYSTEM_STATS_RESET(System::Stats::kInetLayer_NumUDPEps);
    for (int i = INET_CONFIG_NUM_UDP_ENDPOINTS; i >= 0; --i)
    {
        err = gUDP.NewEndPoint(&testUDPEP[i]);

        CHIP_ERROR expected_error = (i ? CHIP_NO_ERROR : CHIP_ERROR_ENDPOINT_POOL_FULL);
        if (err != expected_error)
        {
            // have a log to debug things
            ChipLogError(Test, "UDP: Failure on index %d: (out of %d)", i, INET_CONFIG_NUM_UDP_ENDPOINTS);

            // this will fail after the above log
            EXPECT_EQ(err, expected_error);
        }

        if (err == CHIP_NO_ERROR)
        {
            ++udpCount;
            EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, udpCount));
        }
    }
    const int udpHighWaterMark = udpCount;
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumUDPEps, udpHighWaterMark));

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    // we assume NO open endpoints
    gTCP.ForEachEndPoint([](TCPEndPoint * ep) {
        ChipLogError(Test, "NOTE: Unexpected TCP endpoint in use. Will free it");
        ep->Free();
        return Loop::Continue;
    });

    int tcpCount = 0;
    SYSTEM_STATS_RESET(System::Stats::kInetLayer_NumTCPEps);
    for (int i = INET_CONFIG_NUM_TCP_ENDPOINTS; i >= 0; --i)
    {
        err                       = gTCP.NewEndPoint(&testTCPEP[i]);
        CHIP_ERROR expected_error = (i ? CHIP_NO_ERROR : CHIP_ERROR_ENDPOINT_POOL_FULL);
        if (err != expected_error)
        {
            // have a log to debug things
            ChipLogError(Test, "TCP: Failure on index %d: (out of %d)", i, INET_CONFIG_NUM_TCP_ENDPOINTS);

            // this will fail after the above log
            EXPECT_EQ(err, expected_error);
        }
        if (err == CHIP_NO_ERROR)
        {
            ++tcpCount;
            EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumTCPEps, tcpCount));
        }
    }
    const int tcpHighWaterMark = tcpCount;
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumTCPEps, tcpHighWaterMark));
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if CHIP_SYSTEM_CONFIG_NUM_TIMERS
    // Verify same aComplete and aAppState args do not exhaust timer pool
    for (int i = 0; i < CHIP_SYSTEM_CONFIG_NUM_TIMERS + 1; i++)
    {
        err = gSystemLayer.StartTimer(10_ms32, HandleTimer, nullptr);
        EXPECT_EQ(err, CHIP_NO_ERROR);
    }

    char numTimersTest[CHIP_SYSTEM_CONFIG_NUM_TIMERS + 1];
    for (int i = 0; i < CHIP_SYSTEM_CONFIG_NUM_TIMERS + 1; i++)
        err = gSystemLayer.StartTimer(10_ms32, HandleTimer, &numTimersTest[i]);
    EXPECT_EQ(err, CHIP_ERROR_NO_MEMORY);
#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS

    // Release UDP endpoints
    for (int i = 0; i <= INET_CONFIG_NUM_UDP_ENDPOINTS; i++)
    {
        if (testUDPEP[i] != nullptr)
        {
            testUDPEP[i]->Free();
            --udpCount;
            EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumUDPEps, udpCount));
        }
    }
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumUDPEps, udpHighWaterMark));

    // Release TCP endpoints
    for (int i = 0; i <= INET_CONFIG_NUM_TCP_ENDPOINTS; i++)
    {
        if (testTCPEP[i] != nullptr)
        {
            testTCPEP[i]->Free();
            --tcpCount;
            EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(System::Stats::kInetLayer_NumTCPEps, tcpCount));
        }
    }
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(System::Stats::kInetLayer_NumTCPEps, tcpHighWaterMark));

    ShutdownNetwork();
    ShutdownSystemLayer();
}
#endif // !CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
