/*
 *
 *    Copyright (c) 2014-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 implements the Weave Mock Weave Border Gateway.
 *
 *      This is used to instantiate a Tunnel Agent which opens a
 *      tunnel endpoint and forwards IPv6 packets between the
 *      Service connection and the tunnel endpoint.
 *
 */

#define __STDC_FORMAT_MACROS

#include "TestWeaveTunnel.h"

#define DEFAULT_BG_NODE_ID 0xBADCAFE

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#include "ToolCommon.h"
#include <SystemLayer/SystemTimer.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/echo/WeaveEcho.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelAgent.h>
#include <SystemLayer/SystemTimer.h>

#if WEAVE_CONFIG_ENABLE_TUNNELING
using namespace ::nl::Weave::Profiles::WeaveTunnel;

#define TOOL_NAME "TestWeaveTunnelBR"

#define DEFAULT_TFE_NODE_ID 0x18b4300200000011

/* Proc file system to read IPv6 routing table. */
#ifndef NL_PATH_PROCNET_IPV6_ROUTE
#define NL_PATH_PROCNET_IPV6_ROUTE     "/proc/net/ipv6_route"
#endif /* NL_PATH_PROCNET_IPV6_ROUTE */

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);
static bool HandleNonOptionArgs(const char *progName, int argc, char *argv[]);
static void
WeaveTunnelOnStatusNotifyHandlerCB(WeaveTunnelConnectionMgr::TunnelConnNotifyReasons reason,
                                   WEAVE_ERROR aErr, void *appCtxt);
#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
static void
WeaveTunnelTCPIdleNotifyHandlerCB(TunnelType tunType,
                                  bool aIsIdle, void *appCtxt);
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
static WEAVE_ERROR SendWeavePingMessage(void);
static void WeaveTunnelOnReconnectNotifyCB(TunnelType tunType,
                                           const char *reconnectHost,
                                           const uint16_t reconnectPort,
                                           void *appCtxt);
static WEAVE_ERROR SendTunnelTestMessage(ExchangeContext *ec, uint32_t profileId, uint8_t msgType,
                                         uint16_t sendFlags);
static void HandleTunnelTestResponse(ExchangeContext *ec, const IPPacketInfo *pktInfo,
                                     const WeaveMessageInfo *msgInfo, uint32_t profileId,
                                     uint8_t msgType, PacketBuffer *payload);
static void ResetReconnectTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
static int AddDeleteIPv4Address(InterfaceId intf, const char *ipAddr, bool isAdd);
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
WeaveTunnelAgent gTunAgent;

bool gUseCASE = false;
bool gServiceConnDropSent = false;
const char *gConnectToAddr = NULL;
IPAddress gDestAddr = IPAddress::Any;
IPAddress gRemoteDataAddr = IPAddress::Any;
uint64_t gDestNodeId = DEFAULT_TFE_NODE_ID;
uint32_t gConnectIntervalMS = 2000;
WeaveAuthMode gAuthMode = kWeaveAuthMode_Unauthenticated;
uint64_t gTestStartTime = 0;
uint32_t gCurrTestNum = 0;
uint64_t gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
bool gTestSucceeded = false;
uint8_t  gEncryptionType = kWeaveEncryptionType_None;
uint16_t gKeyId = WeaveKeyId::kNone;
uint8_t gTunUpCount = 0;
uint8_t gConnAttemptsBeforeReset = 0;
bool gReconnectResetArmed = false;
uint64_t gReconnectResetArmTime = 0;
bool gtestDataSent = false;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
bool gUseServiceDir = false;
ServiceDirectory::WeaveServiceManager gServiceMgr;
uint8_t gServiceDirCache[100];
const char *gDirectoryServerURL = "frontdoor.integration.nestlabs.com";
#endif

#define TEST_MAX_TIMEOUT_SECS (30) // Set TCP_USER_TIMEOUT to 30 seconds
#define TEST_KEEPALIVE_INTERVAL_SECS (5) // Set TCP_KEEPALIVE INTERVAL to 5 seconds
#define TEST_GRACE_PERIOD_SECS  (4)

#define TEST_TUNNEL_LIVENESS_INTERVAL_SECS  (10)

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
// Used for storing the IP address upon removal to restore it at the end of the
// test case.
IPAddress gLocalIPAddr = IPAddress::Any;
InterfaceId gIntf = INET_NULL_INTERFACEID;
uint64_t gTCPUserTimeoutStartTime = 0;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
bool gLivenessTestTunnelUp = false;
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

uint8_t gTunnelingDeviceRole = kClientRole_BorderGateway; //Default Value

enum
{
    kToolOpt_ConnectTo                  = 1000,
    kToolOpt_ConnectToInterval,
    kToolOpt_UseServiceDir,
    kToolOpt_UseCASE,
};

static OptionDef gToolOptionDefs[] =
{
    { "dest-addr",           kArgumentRequired, 'D' },
    { "service-addr",        kArgumentRequired, 'S' },
    { "role",                kArgumentRequired, 'r' },
    { "connect-to",          kArgumentRequired, kToolOpt_ConnectTo },
    { "connect-to-interval", kArgumentRequired, kToolOpt_ConnectToInterval },
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    { "service-dir",         kNoArgument,       kToolOpt_UseServiceDir },
#endif
    { "case",                kNoArgument,       kToolOpt_UseCASE },
    { NULL }
};

static const char *const gToolOptionHelp =
    "  -r, --role <num>\n"
    "       Role for local client node, i.e., 1) Border Gateway or 2) Mobile Device.\n"
    "\n"
    "  -D, --dest-addr <host>[:<port>][%<interface>]\n"
    "       Send Echo Requests to a specific address rather than one\n"
    "       derived from the destination node id. <host> can be a hostname,\n"
    "       an IPv4 address or an IPv6 address. If <port> is specified, Echo\n"
    "       requests will be sent to the specified port. If <interface> is\n"
    "       specified, Echo Requests will be sent over the specified local\n"
    "       interface.\n"
    "\n"
    "       NOTE: When specifying a port with an IPv6 address, the IPv6 address\n"
    "       must be enclosed in brackets, e.g. [fd00:0:1:1::1]:11095.\n"
    "\n"
    "  --connect-to <addr>[:<port>][%<interface>]\n"
    "       Create a Weave connection to the specified address on start up. This\n"
    "       can be used to initiate a passive rendezvous with remote device manager.\n"
    "\n"
    "  --connect-to-interval <ms>\n"
    "       Interval at which to perform connect attempts to the connect-to address.\n"
    "       Defaults to 2 seconds.\n"
    "\n"
    "  -S, --service-addr <remote-ipv6-addr>\n"
    "       Remote destination IPv6 address for sending data traffic over tunnel.\n"
    "\n"
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    "  --service-dir\n"
    "       Use service directory to lookup destination node address.\n"
    "\n"
#endif
    "  --case\n"
    "       Use CASE to create an authenticated session and encrypt messages using\n"
    "       the negotiated session key.\n"
    "\n";

static OptionSet gToolOptions =
{
    HandleOption,
    gToolOptionDefs,
    "GENERAL OPTIONS",
    gToolOptionHelp
};

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] [<dest-node-id>]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

static OptionSet *gToolOptionSets[] =
{
    &gToolOptions,
    &gNetworkOptions,
    &gWeaveNodeOptions,
    &gCASEOptions,
    &gDeviceDescOptions,
    &gServiceDirClientOptions,
    &gFaultInjectionOptions,
    &gHelpOptions,
    NULL
};

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'r':
        if (!arg || !ParseInt(arg, gTunnelingDeviceRole) ||
            (gTunnelingDeviceRole != kClientRole_BorderGateway &&
             gTunnelingDeviceRole != kClientRole_MobileDevice))
        {
            PrintArgError("%s: Invalid value specified for device role: %s. Possible values: (1)BorderGateway and (2)MobileDevice\n", progName, arg);
            return false;
        }

        break;

    case kToolOpt_ConnectTo:
        gConnectToAddr = arg;

        break;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    case kToolOpt_UseServiceDir:
        gUseServiceDir = true;

        break;

#endif
    case kToolOpt_UseCASE:
        gUseCASE = true;

        break;

    case 'D':
        if (!ParseIPAddress(arg, gDestAddr))
        {
            PrintArgError("%s: Invalid value specified for destination IP address: %s\n", progName, arg);
            return false;
        }

        break;

    case 'S':
        if (!ParseIPAddress(arg, gRemoteDataAddr))
        {
            PrintArgError("%s: Invalid value specified for remote destination IPv6 address: %s\n", progName, arg);
            return false;
        }
        if (!gRemoteDataAddr.IsIPv6ULA())
        {
            PrintArgError("%s: Remote IP address %s should be IPv6 ULA. \n", progName, arg);
            return false;
        }

        break;

    case kToolOpt_ConnectToInterval:
        if (!ParseInt(arg, gConnectIntervalMS))
        {
            PrintArgError("%s: Invalid value specified for connect-to interval: %s\n", progName, arg);
            return false;
        }

        break;

    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

bool HandleNonOptionArgs(const char *progName, int argc, char *argv[])
{
    if (argc > 0)
    {
        if (argc > 1)
        {
            PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
            return false;
        }

        if (!ParseNodeId(argv[0], gDestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, argv[0]);
            return false;
        }
    }

    return true;
}

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
WEAVE_ERROR GetRootDirectoryEntry (uint8_t *buf, uint16_t bufSize)
{
    WEAVE_ERROR err;
    const char *host;
    uint16_t hostLen, port;

    using namespace nl::Weave::Encoding;

    err = ParseHostAndPort(gDirectoryServerURL, strlen(gDirectoryServerURL), host, hostLen, port);
    if (err != WEAVE_NO_ERROR)
    {
        return err;
    }
    if (port == 0)
    {
        port = WEAVE_PORT;
    }

    //TODO: Wrong values: Replace with correct ones when Service has Tunnel FrontEnd defined.
    Write8(buf, 0x41);
    LittleEndian::Write64(buf, 0x18B4300200000001ULL);  // Service Endpoint Id = Directory Service
    Write8(buf, 0x80);
    Write8(buf, hostLen);
    memcpy(buf, host, hostLen); buf += hostLen;
    LittleEndian::Write16(buf, port);

    return WEAVE_NO_ERROR;
}
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY

/**
 * Send an appropriate test message to synchronize with the Server.
 */
WEAVE_ERROR SendTunnelTestMessage(ExchangeContext *ec, uint32_t profileId,
                                  uint8_t msgType,
                                  uint16_t sendFlags)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    PacketBuffer *msg = NULL;

    msg = PacketBuffer::New();
    VerifyOrExit(msg, err = WEAVE_ERROR_NO_MEMORY);

    // Configure the encryption and signature types to be used to send the request.
    ec->EncryptionType = gEncryptionType;
    ec->KeyId = gKeyId;

    // Arrange for messages in this exchange to go to our response handler.
    ec->OnMessageReceived = HandleTunnelTestResponse;

    // Send a Test message. Discard the exchange context if the send fails.
    err = ec->SendMessage(profileId, msgType, msg, sendFlags);
    msg = NULL;

exit:
    return err;
}

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

int AddDeleteIPv4Address(InterfaceId intf, const char *ipAddr, bool isAdd)
{
    char intfStr[32];
    char command[64];
    char addOrDel[4];

    GetInterfaceName(intf, intfStr, sizeof(intfStr));

    strncpy(addOrDel, isAdd ? "add" : "del", sizeof(addOrDel));

    snprintf(command, sizeof(command), "ip addr %s %s/24 dev %s", addOrDel, ipAddr, intfStr);

    return system(command);
}

bool GetIPAddressOfWeaveTCPConnection(char **ip)
{
    FILE *fp = NULL;
    char buf [1024];
    bool found = false;

    // Command to get Weave TCP connections from netstat output
    const char *command = "netstat -an 2>/dev/null | grep 11095";
    fp = popen(command, "r");
    if (fp == NULL)
    {
        WeaveLogError(WeaveTunnel, "Can't open pipe %s : error %ld", command,
                      (long)errno);
        exit(-1);
    }

    while (fgets (buf, 1024, fp) != NULL)
    {
        char proto[4];
        int recvq, sendq;
        char localAddrPort[32];
        char foreignAddrPort[32];
        char *foreignPort;
        char state[16];
        char *str;
        sscanf(buf, "%s %04x %04x %s %s %s",
               proto, &recvq, &sendq, localAddrPort,
               foreignAddrPort, state);

        // Match entry for proto == tcp AND destPort == WEAVE_PORT
        foreignPort = strstr(foreignAddrPort, ":");
        if ((strcmp(foreignPort, ":11095") == 0) &&
            (strcmp(proto, "tcp") == 0))
        {
            str = strtok(localAddrPort, ":");
            strncpy(*ip, str, strlen(str));
            (*ip)[strlen(str)] = '\0';
            found = true;
            break;
        }
        else
        {
            continue;
        }

    }

    pclose(fp);

    return found;
}
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

bool Is48BitIPv6FabricRoutePresent(void)
{
    FILE *fp = NULL;
    char buf [256];
    bool found = false;

    /* Open /proc/net/ipv6_route */
    fp = fopen(NL_PATH_PROCNET_IPV6_ROUTE, "r");
    if (fp == NULL)
    {
        WeaveLogError(WeaveTunnel, "Can't open %s : error %ld", NL_PATH_PROCNET_IPV6_ROUTE,
                      (long)errno);
        exit(-1);
    }

    /* Skip the title line. */
    while (fgets (buf, 256, fp) != NULL)
    {
        int n;
        char dest[33], src[33], gw[33];
        char iface[17];
        int destPrefixLen, srcPrefixLen;
        int metric, use, refCnt, flags;

        n = sscanf (buf, "%32s %02x %32s %02x %32s %08x %08x %08x %08x %s",
                    dest, &destPrefixLen, src, &srcPrefixLen, gw,
                    &metric, &use, &refCnt, &flags, iface);

        if (n != 10)
        {
            continue;
        }

        if (destPrefixLen == 48 && strstr(iface, "weav"))
        {
            found = true;
            break;
        }
    }

    fclose(fp);

    return found;
}

/**
 * Test successful WeaveTunnelAgent Initialization.
 */
static void TestWeaveTunnelAgentInit(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    gCurrTestNum = kTestNum_TestWeaveTunnelAgentInit;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.Shutdown();

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
}

/**
 * Test successful WeaveTunnelAgent configuration.
 */
static void TestWeaveTunnelAgentConfigure(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    IPAddress bogusDestIPAddr = IPAddress::Any;
    uint64_t bogusDestNodeId = 0x1001;

    gCurrTestNum = kTestNum_TestWeaveTunnelAgentConfigure;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    // Set Auth Mode

    gTunAgent.SetAuthMode(kWeaveAuthMode_Unauthenticated);

    // Set bogus destination configuration

    gTunAgent.SetDestination(bogusDestNodeId, bogusDestIPAddr);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    // Start Service Tunnel should fail and return an error
    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.Shutdown();
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);
}

/**
 * Test successful WeaveTunnelAgent Initialization.
 */
static void TestWeaveTunnelAgentShutdown(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    gCurrTestNum = kTestNum_TestWeaveTunnelAgentShutdown;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }
    SuccessOrExit(err);

    err = gTunAgent.Shutdown();

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
}

/**
 * Test WeaveTunnelAgent StartServiceTunnel without Initialization.
 */
static void TestStartTunnelWithoutInit(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    gCurrTestNum = kTestNum_TestStartTunnelWithoutInit;
    gTestStartTime = Now();

    // Start Service Tunnel should fail with error WEAVE_ERROR_INCORRECT_STATE
    err = gTunAgent.StartServiceTunnel();

    NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_INCORRECT_STATE);
}

/**
 * Test back to back Start Stop and then Start Weave tunnel.
 */
static void TestBackToBackStartStopStart(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gCurrTestNum = kTestNum_TestBackToBackStartStopStart;
    gTestStartTime = Now();
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    gTunAgent.StopServiceTunnel();

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test Back to back Stop and Start after a Start completes
 * by receiving a StatusReport for a TunnelOpen message.
 */
static void TestTunnelOpenCompleteThenStopStart(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gTunUpCount = 0;
    gCurrTestNum = kTestNum_TestTunnelOpenCompleteThenStopStart;
    gTestStartTime = Now();
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    // Start the WeaveTunnel and when it completes do the Stop and Start
    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test sending a TunnelOpen and receiving a StatusReport in response successfully.
 */
static void TestReceiveStatusReportForTunnelOpen(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gCurrTestNum = kTestNum_TestReceiveStatusReportForTunnelOpen;
    gTestStartTime = Now();
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test a successful Tunnel Open followed by a successful Tunnel Close.
 */
static void TestTunnelOpenThenTunnelClose(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelOpenThenTunnelClose;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test setting up a Standalone Tunnel.
 */
static void TestStandaloneTunnelSetup(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gCurrTestNum = kTestNum_TestStandaloneTunnelSetup;
    gTestStartTime = Now();
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.SetTunnelingDeviceRole(kClientRole_StandaloneDevice);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test a successful Tunnel reconnect attempt on NOT receiving a StatusReport in
 * response to a TunnelOpen.
 */
static void TestTunnelNoStatusReportReconnect(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelNoStatusReportReconnect;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelNoStatusReportReconnect,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelNoStatusReportReconnect,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

void ResetReconnectTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError)
{
    WeaveLogDetail(WeaveTunnel, "Triggering a ResetReconnect Backoff after TunnelOpen sent\n");
    /* Try resetting the connection and issuing a reconnect */
    gTunAgent.ResetPrimaryReconnectBackoff(true);
}

/**
 * Test that a Tunnel reset reconnect backoff does not close an existing tunnel
 * open operation.
 * 1. Send Tunnel Open. The Mock Service is expected not to respond and the
 *    TunnelOpen should timeout.
 * 2. Schedule ResetReconnect before TunnelOpen response timeout happens.
 * 3. Verify that the TunnelOpen response timeout happens normally without
 *    the ResetReconnect re-establishing the connection.
 */
static void TestTunnelNoStatusReportResetReconnectBackoff(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;
    uint32_t delayForResetReconnect = 0;
    Done = false;
    gTestSucceeded = false;
    /* Set the test timeout to be a little longer than the Tunnel Control ExchangeContext
     * timeout */
    gMaxTestDurationMillisecs = (WEAVE_CONFIG_TUNNELING_CTRL_RESPONSE_TIMEOUT_SECS + 1 ) * System::kTimerFactor_milli_per_unit;
    gCurrTestNum = kTestNum_TestTunnelNoStatusReportResetReconnectBackoff;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelNoStatusReportResetReconnectBackoff,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    /* Wait for some time for tunnel connection to be established but before TunnelOpen
     * response timeout happens for triggering a reconnect */
    delayForResetReconnect = (WEAVE_CONFIG_TUNNELING_CTRL_RESPONSE_TIMEOUT_SECS - 1) * System::kTimerFactor_milli_per_unit;

    ExchangeMgr.MessageLayer->SystemLayer->StartTimer(delayForResetReconnect, ResetReconnectTimeout, NULL);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelNoStatusReportResetReconnectBackoff,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test a successful Tunnel reconnect attempt on receiving a StatusReport with
 * an Error status code in response to a TunnelOpen.
 */
static void TestTunnelErrorStatusReportReconnect(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelErrorStatusReportReconnect;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelErrorStatusReportReconnect,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelErrorStatusReportReconnect,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * When a StatusReport with an Error status code is received in response to a TunnelClose,
 * shutdown the tunnel and notify application.
 */
static void TestTunnelErrorStatusReportOnTunnelClose(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelErrorStatusReportOnTunnelClose;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelErrorStatusReportOnTunnelClose,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelErrorStatusReportOnTunnelClose,
                                        0);
            SuccessOrExit(err);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test to ensure the WeaveTunnelAgent tries to reconnect when a connection goes down.
 */
static void TestTunnelConnectionDownReconnect(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelConnectionDownReconnect;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelConnectionDownReconnect,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelConnectionDownReconnect,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test to ensure that the WeaveTunnelAgent notifies the application about the Tunnel
 * being down after the maximum number of reconnect attempts have been made.
 */
static void TestCallTunnelDownAfterMaxReconnects(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = 21000;
    IPAddress fakeAddr;
    gCurrTestNum = kTestNum_TestCallTunnelDownAfterMaxReconnects;
    gTestStartTime = Now();

    // Assign a fake address for the tunnel Service. Loopback should be good enough.

    IPAddress::FromString("127.0.0.1", fakeAddr);

    err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, fakeAddr,
                        gAuthMode);

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;


    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test receving of a Tunnel Reconnect control message and have the border gateway bring down
 * the connection and reconnect.
 */
static void TestReceiveReconnectFromService(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestReceiveReconnectFromService;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;
    gTunAgent.OnServiceTunReconnectNotify = WeaveTunnelOnReconnectNotifyCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestReceiveReconnectFromService,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestReceiveReconnectFromService,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test adding of the fabric default route when the Tunnel is established
 */
static void TestWARMRouteAddWhenTunnelEstablished(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    bool fabricRouteFound = false;

    Done = false;
    gTestSucceeded = false;
    gCurrTestNum = kTestNum_TestWARMRouteAddWhenTunnelEstablished;
    gTestStartTime = Now();
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;

    fabricRouteFound = Is48BitIPv6FabricRoutePresent();

    NL_TEST_ASSERT(inSuite, fabricRouteFound == false);

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test deleting of the fabric default route when the Tunnel is stopped
 */
static void TestWARMRouteDeleteWhenTunnelStopped(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestWARMRouteDeleteWhenTunnelStopped;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test to successfully send a Weave Ping data message over the Weave Tunnel.
 */
static void TestWeavePingOverTunnel(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestWeavePingOverTunnel;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test to ensure that the WeaveTunnelAgent queues data packets when it is tryng to
 * do fast reconnect attempts to the Service.
 */
static void TestQueueingOfTunneledPackets(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    // Set a longer duration for the queueing test. 3 times the default test
    // duration(~15 seconds) is sufficient for the completion of this test with
    // close to 100% confidence.
    gMaxTestDurationMillisecs = (DEFAULT_TEST_DURATION_MILLISECS * 3);
    gCurrTestNum = kTestNum_TestQueueingOfTunneledPackets;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestQueueingOfTunneledPackets,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {

            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestQueueingOfTunneledPackets,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
/**
 * Test gathering of tunnel statistics after performing a few tunnel operations.
 */
static void TestTunnelStatistics(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    WeaveTunnelStatistics tunnelStats;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelStatistics;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                             gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                             gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }
    }

    // Check statistics

    err = gTunAgent.GetWeaveTunnelStatistics(tunnelStats);
    SuccessOrExit(err);

    // Log statistics
    WeaveLogDetail(WeaveTunnel, "Current Timestamp = %" PRIu64 "\n", gTunAgent.GetTimeMsec());

    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelDownCount = %u\n", tunnelStats.mPrimaryStats.mTunnelDownCount);
    WeaveLogDetail(WeaveTunnel, "LastPrimaryTunnelDownWeaveError = %u\n", tunnelStats.mPrimaryStats.mLastTunnelDownError);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelConnAttemptCount = %u\n", tunnelStats.mPrimaryStats.mTunnelConnAttemptCount);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelTxBytes = %" PRIu64 "\n", tunnelStats.mPrimaryStats.mTxBytesToService);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelRxBytes = %" PRIu64 "\n", tunnelStats.mPrimaryStats.mRxBytesFromService);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelTxMessages = %u\n", tunnelStats.mPrimaryStats.mTxMessagesToService);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelRxMessages = %u\n", tunnelStats.mPrimaryStats.mRxMessagesFromService);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelUpTimeStamp = %" PRIu64 "\n", tunnelStats.mPrimaryStats.mLastTimeTunnelEstablished);
    WeaveLogDetail(WeaveTunnel, "PrimaryTunnelDownTimeStamp = %" PRIu64 "\n", tunnelStats.mPrimaryStats.mLastTimeTunnelWentDown);
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    WeaveLogDetail(WeaveTunnel, "BackupTunnelDownCount = %u\n", tunnelStats.mBackupStats.mTunnelDownCount);
    WeaveLogDetail(WeaveTunnel, "LastBackupTunnelDownWeaveError = %u\n", tunnelStats.mBackupStats.mLastTunnelDownError);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelConnAttemptCount = %u\n", tunnelStats.mBackupStats.mTunnelConnAttemptCount);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelTxBytes = %" PRIu64 "\n", tunnelStats.mBackupStats.mTxBytesToService);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelRxBytes = %" PRIu64 "\n", tunnelStats.mBackupStats.mRxBytesFromService);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelTxMessages = %u\n", tunnelStats.mBackupStats.mTxMessagesToService);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelUpTimeStamp = %" PRIu64 "\n", tunnelStats.mBackupStats.mLastTimeTunnelEstablished);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelDownTimeStamp = %" PRIu64 "\n", tunnelStats.mBackupStats.mLastTimeTunnelWentDown);
    WeaveLogDetail(WeaveTunnel, "BackupTunnelRxMessages = %u\n", tunnelStats.mBackupStats.mRxMessagesFromService);
    WeaveLogDetail(WeaveTunnel, "TunnelFailoverCount = %u\n", tunnelStats.mTunnelFailoverCount);
    WeaveLogDetail(WeaveTunnel, "TunnelFailoverTimestamp = %" PRIu64 "\n", tunnelStats.mLastTimeForTunnelFailover);
    WeaveLogDetail(WeaveTunnel, "PrimaryAndBackupTunnelDownTimeStamp = %" PRIu64 "\n", tunnelStats.mLastTimeWhenPrimaryAndBackupWentDown);
    WeaveLogDetail(WeaveTunnel, "LastTunnelFailoverWeaveError = %u\n", tunnelStats.mLastTunnelFailoverError);
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    WeaveLogDetail(WeaveTunnel, "DroppedMessageCount = %u\n", tunnelStats.mDroppedMessagesCount);

    NL_TEST_ASSERT(inSuite, tunnelStats.mPrimaryStats.mTunnelDownCount == 1);
    NL_TEST_ASSERT(inSuite, tunnelStats.mPrimaryStats.mTunnelConnAttemptCount == 1);
    NL_TEST_ASSERT(inSuite, tunnelStats.mPrimaryStats.mTxMessagesToService == 1);
    NL_TEST_ASSERT(inSuite, tunnelStats.mPrimaryStats.mRxMessagesFromService == 1);
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    NL_TEST_ASSERT(inSuite, tunnelStats.mTunnelFailoverCount == 0);
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
 * Test to successfully send a Tunnel Liveness Probe and receive a Status Report.
 */
static void TestTunnelLivenessSendAndRecvResponse(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gMaxTestDurationMillisecs = TEST_TUNNEL_LIVENESS_INTERVAL_SECS * nl::Weave::System::kTimerFactor_milli_per_unit + 2 * DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelLivenessSendAndRecvResponse;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    gTunAgent.ConfigurePrimaryTunnelLivenessInterval(TEST_TUNNEL_LIVENESS_INTERVAL_SECS);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

/**
 * Test Closing of Tunnel when a Liveness Probe receives no response.
 */
static void TestTunnelLivenessDisconnectOnNoResponse(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gLivenessTestTunnelUp = false;
    gMaxTestDurationMillisecs = TEST_TUNNEL_LIVENESS_INTERVAL_SECS * nl::Weave::System::kTimerFactor_milli_per_unit + 2 * DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelLivenessDisconnectOnNoResponse;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    SuccessOrExit(err);

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelLivenessDisconnectOnNoResponse,
                                0);
    SuccessOrExit(err);

    gTunAgent.ConfigurePrimaryTunnelLivenessInterval(TEST_TUNNEL_LIVENESS_INTERVAL_SECS);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelLivenessDisconnectOnNoResponse,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

static void TestTunnelRestrictedRoutingOnTunnelOpen(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gLivenessTestTunnelUp = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelRestrictedRoutingOnTunnelOpen;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelRestrictedRoutingOnTunnelOpen,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelRestrictedRoutingOnTunnelOpen,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

static void TestTunnelResetReconnectBackoffImmediately(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gConnAttemptsBeforeReset = 0;
    gReconnectResetArmed = false;
    gReconnectResetArmTime = 0;
    gMaxTestDurationMillisecs = RECONNECT_RESET_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelResetReconnectBackoffImmediately;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelResetReconnectBackoffImmediately,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelResetReconnectBackoffImmediately,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

static void TestTunnelResetReconnectBackoffRandomized(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    Done = false;
    gTestSucceeded = false;
    gConnAttemptsBeforeReset = 0;
    gReconnectResetArmed = false;
    gReconnectResetArmTime = 0;
    gMaxTestDurationMillisecs = RECONNECT_RESET_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelResetReconnectBackoffRandomized;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_Start,
                                kTestNum_TestTunnelResetReconnectBackoffRandomized,
                                0);
    SuccessOrExit(err);

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_End,
                                        kTestNum_TestTunnelResetReconnectBackoffRandomized,
                                        0);
            SuccessOrExit(err);

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_NOT_CONNECTED);
        }
    }

exit:
    if (exchangeCtxt)
    {
        exchangeCtxt->Close();
        exchangeCtxt = NULL;
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
/**
 * Test to verify that the TCP User Timeout is enforced when the IP address
 * on the border gateway interface is removed.
 */
static void TestTCPUserTimeoutOnAddrRemoval(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    char ip[32];
    char *strPtr = ip;
    gMaxTestDurationMillisecs = 4*RECONNECT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTCPUserTimeoutOnAddrRemoval;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
    gTunAgent.OnServiceTunTCPIdleNotify = WeaveTunnelTCPIdleNotifyHandlerCB;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK


    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gLocalIPAddr.ToString(strPtr, sizeof(ip));

            // Add the IP Address back on interface
            if (AddDeleteIPv4Address(gIntf, strPtr, true) < 0)
            {
               ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
            }

            gTunAgent.StopServiceTunnel(WEAVE_ERROR_TUNNEL_FORCE_ABORT);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
/**
 * Test to verify that sent TCP data is acknowledged.
 */
static void TestTunnelTCPIdle(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Done = false;
    gTestSucceeded = false;
    gtestDataSent = false;
    gMaxTestDurationMillisecs = DEFAULT_TEST_DURATION_MILLISECS;
    gCurrTestNum = kTestNum_TestTunnelTCPIdle;
    gTestStartTime = Now();

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDir)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            gAuthMode, &gServiceMgr);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            gAuthMode);
    }

    SuccessOrExit(err);

    gTunAgent.OnServiceTunStatusNotify = WeaveTunnelOnStatusNotifyHandlerCB;

    gTunAgent.OnServiceTunTCPIdleNotify = WeaveTunnelTCPIdleNotifyHandlerCB;

    err = gTunAgent.StartServiceTunnel();
    SuccessOrExit(err);

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = TEST_SLEEP_TIME_WITHIN_LOOP_SECS;
        sleepTime.tv_usec = TEST_SLEEP_TIME_WITHIN_LOOP_MICROSECS;

        ServiceNetwork(sleepTime);

        if (Now() < gTestStartTime + gMaxTestDurationMillisecs * System::kTimerFactor_micro_per_milli)
        {
            if (gTestSucceeded)
            {
                Done = true;
            }
            else
            {
                continue;
            }
        }
        else // Time's up
        {
            gTestSucceeded = false;
            Done = true;
        }

        if (Done)
        {
            gTunAgent.StopServiceTunnel(WEAVE_ERROR_TUNNEL_FORCE_ABORT);
        }
    }

exit:
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, gTestSucceeded == true);

    gTunAgent.Shutdown();
}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK

void HandleTunnelTestResponse(ExchangeContext *ec, const IPPacketInfo *pktInfo,
                              const WeaveMessageInfo *msgInfo, uint32_t profileId,
                              uint8_t msgType, PacketBuffer *payload)
{
    switch (gCurrTestNum)
    {
      case  kTestNum_TestWeavePingOverTunnel:
      case kTestNum_TestQueueingOfTunneledPackets:
        if (profileId == kWeaveProfile_Echo && msgType == kEchoMessageType_EchoResponse)
        {
            gTestSucceeded = true;
        }
        else
        {
            gTestSucceeded = false;
        }

        break;

      case  kTestNum_TestTunnelStatistics:
        if (profileId == kWeaveProfile_Echo && msgType == kEchoMessageType_EchoResponse)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
        else
        {
            gTestSucceeded = false;
        }

        break;

      default:

        break;

    }

    // Free the payload buffer.
    PacketBuffer::Free(payload);

    ec->Close();
}

void WeaveTunnelOnReconnectNotifyCB(TunnelType tunType,
                                    const char *reconnectHost,
                                    const uint16_t reconnectPort,
                                    void *appCtxt)
{
    if (gCurrTestNum == kTestNum_TestReceiveReconnectFromService)
    {
        if (0 == strncmp(reconnectHost, TEST_TUNNEL_RECONNECT_HOSTNAME, sizeof(TEST_TUNNEL_RECONNECT_HOSTNAME)))
        {
            WeaveLogDetail(WeaveTunnel, "Tunnel Reconnect received from Service for Tunnel type %d, to %s:%d\n", tunType,
                           reconnectHost, reconnectPort);
            gTestSucceeded = true;
        }
    }
}

WEAVE_ERROR SendWeavePingMessage(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gRemoteDataAddr, &gTunAgent);
    VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

    // Send Weave ping over tunnel.
    err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_Echo,
                                kEchoMessageType_EchoRequest,
                                0);
exit:
    return err;
}

#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
void
WeaveTunnelTCPIdleNotifyHandlerCB(TunnelType tunType,
                                  bool aIsIdle, void *appCtxt)
{
    switch (gCurrTestNum)
    {
      case kTestNum_TestTunnelTCPIdle:
        if (aIsIdle)
        {
            WeaveLogDetail(WeaveTunnel, "Tunnel sent data flushed for tunnel type %d\n", tunType);
            if (gtestDataSent)
            {
                gTestSucceeded = true;
            }
        }
        else
        {
            WeaveLogDetail(WeaveTunnel, "Tunnel data transmitted for tunnel type %d: TCP channel not Idle yet.\n",
                           tunType);
        }

        break;

      case kTestNum_TestTCPUserTimeoutOnAddrRemoval:
        if (aIsIdle)
        {
            WeaveLogDetail(WeaveTunnel, "Tunnel sent data flushed for tunnel type %d\n", tunType);
            gTestSucceeded = false;
        }
        else
        {
            WeaveLogDetail(WeaveTunnel, "Tunnel data transmitted for tunnel type %d: TCP channel not Idle yet.\n",
                           tunType);
        }
    }
}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK

void
WeaveTunnelOnStatusNotifyHandlerCB(WeaveTunnelConnectionMgr::TunnelConnNotifyReasons reason,
                                   WEAVE_ERROR aErr, void *appCtxt)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ExchangeContext *exchangeCtxt = NULL;

    WeaveLogDetail(WeaveTunnel, "WeaveTunnelAgent notification reason code is %d", reason);

    switch (gCurrTestNum)
    {
      case  kTestNum_TestReceiveStatusReportForTunnelOpen:
      case  kTestNum_TestStandaloneTunnelSetup:
      case  kTestNum_TestBackToBackStartStopStart:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            gTestSucceeded = true;
        }
        else
        {
            gTestSucceeded = false;
        }

        break;
      case  kTestNum_TestTunnelRestrictedRoutingOnTunnelOpen:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            // Check if we got the correct error code and the Fabric tunnel
            // route is installed.
            if (aErr == WEAVE_ERROR_TUNNEL_ROUTING_RESTRICTED && Is48BitIPv6FabricRoutePresent())
            {
                gTestSucceeded = true;
            }
            else
            {
                gTestSucceeded = false;
            }
        }

        break;
      case  kTestNum_TestTunnelOpenCompleteThenStopStart:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            if (gTunUpCount < 1)
            {
                gTunUpCount++;

                gTunAgent.StopServiceTunnel();

                gTunAgent.StartServiceTunnel();
            }
            else
            {
                gTestSucceeded = true;
            }
        }
        else
        {
            gTestSucceeded = false;
        }

        break;

      case  kTestNum_TestTunnelOpenThenTunnelClose:
      case  kTestNum_TestTunnelErrorStatusReportOnTunnelClose:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunDown)
        {
            gTestSucceeded = true;
        }

        break;

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
      case  kTestNum_TestTunnelStatistics:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            err = SendWeavePingMessage();
            SuccessOrExit(err);
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunDown)
        {
            gTestSucceeded = true;
        }

        break;

#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
      case kTestNum_TestTunnelNoStatusReportReconnect:
      case kTestNum_TestTunnelConnectionDownReconnect:
      case kTestNum_TestTunnelErrorStatusReportReconnect:
      case kTestNum_TestWeaveTunnelAgentConfigure:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError)
        {
            gTestSucceeded = true;
        }

        break;

      case kTestNum_TestTunnelNoStatusReportResetReconnectBackoff:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError)
        {
            if (aErr == WEAVE_ERROR_TIMEOUT)
            {
                WeaveLogDetail(WeaveTunnel, "Tun Open Timeout error");
                gTestSucceeded = true;
            }
            else
            {
                WeaveLogDetail(WeaveTunnel, "Connect error received with error %s", ErrorStr(aErr));
                gTestSucceeded = false;
            }
        }
        break;

      case kTestNum_TestCallTunnelDownAfterMaxReconnects:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunDown)
        {
            gTestSucceeded = true;
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError)
        {
            WeaveLogDetail(WeaveTunnel, "Tun Connection Error");
        }

        break;

      case kTestNum_TestWeavePingOverTunnel:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            err = SendWeavePingMessage();
            SuccessOrExit(err);
        }
        else
        {
            gTestSucceeded = false;
        }

        break;

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
      case kTestNum_TestTCPUserTimeoutOnAddrRemoval:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            char ip[32];
            char *strPtr = ip;
            bool found = GetIPAddressOfWeaveTCPConnection(&strPtr);
            if (!found)
            {
                gTestSucceeded = false;
                break;
            }

            IPAddress::FromString(strPtr, gLocalIPAddr);

            // Configure the TCP User Timeout
            err = gTunAgent.ConfigurePrimaryTunnelTimeout(TEST_MAX_TIMEOUT_SECS);
            SuccessOrExit(err);

            // Get the interface matching the IP
            err = Inet.GetInterfaceFromAddr(gLocalIPAddr, gIntf);
            SuccessOrExit(err);

            // Remove IP Address on interface
            if (AddDeleteIPv4Address(gIntf, strPtr, false) < 0)
            {
               ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
            }

            // Send some data
            err = SendWeavePingMessage();
            SuccessOrExit(err);

            // Mark the time for getting a connection reconnect up call when
            // TCP User timeout happens.
            gTCPUserTimeoutStartTime = Now();
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError &&
                 aErr == INET_ERROR_TCP_USER_TIMEOUT)
        {
            if ((Now() - gTCPUserTimeoutStartTime > TEST_MAX_TIMEOUT_SECS * nl::Weave::System::kTimerFactor_micro_per_unit) ||
                (Now() - gTCPUserTimeoutStartTime < (TEST_MAX_TIMEOUT_SECS + TEST_GRACE_PERIOD_SECS) * nl::Weave::System::kTimerFactor_micro_per_unit))
            {
                gTestSucceeded = true;
            }
        }

        break;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT

#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
      case kTestNum_TestTunnelTCPIdle:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            // Configure the TCP User Timeout
            err = gTunAgent.ConfigurePrimaryTunnelTimeout(TEST_MAX_TIMEOUT_SECS);
            SuccessOrExit(err);

            // Send some data
            err = SendWeavePingMessage();
            SuccessOrExit(err);

            gtestDataSent = true;
        }

        break;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
      case kTestNum_TestTunnelLivenessSendAndRecvResponse:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryLiveness &&
            aErr == WEAVE_NO_ERROR)
        {
            gTestSucceeded = true;
        }

        break;

      case kTestNum_TestTunnelLivenessDisconnectOnNoResponse:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            gLivenessTestTunnelUp = true;
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError &&
                 (aErr == WEAVE_ERROR_TIMEOUT || aErr == INET_ERROR_TCP_USER_TIMEOUT))
        {
            if (gLivenessTestTunnelUp)
            {
                gTestSucceeded = true;
            }
            else
            {
                gTestSucceeded = false;
            }
        }

        break;

#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
      case kTestNum_TestWARMRouteAddWhenTunnelEstablished:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            if (Is48BitIPv6FabricRoutePresent())
            {
                gTestSucceeded = true;
            }
            else
            {
                gTestSucceeded = false;
            }
        }

        break;

      case kTestNum_TestWARMRouteDeleteWhenTunnelStopped:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            gTunAgent.StopServiceTunnel(WEAVE_NO_ERROR);
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunDown)
        {
            if (Is48BitIPv6FabricRoutePresent())
            {
                gTestSucceeded = false;
            }
            else
            {
                gTestSucceeded = true;
            }
        }

        break;

      case kTestNum_TestReceiveReconnectFromService:
        WeaveLogDetail(WeaveTunnel, "Tunnel established; Expecting a Reconnect\n");

        break;

      case kTestNum_TestQueueingOfTunneledPackets:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp)
        {
            if (!gServiceConnDropSent)
            {
                IPAddress fakeAddr;

                // Configure wrong IP address to generate connection error

                IPAddress::FromString("127.0.0.1", fakeAddr);

                gTunAgent.SetDestination(gDestNodeId, fakeAddr);

                // Now, instruct Service to drop connection to trigger reconnect attempt

                exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gDestAddr, &gTunAgent);
                VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

                err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_TunnelTest_RequestTunnelConnDrop,
                                            kTestNum_TestQueueingOfTunneledPackets,
                                            0);
                SuccessOrExit(err);

                gServiceConnDropSent = true;
            }
        }
        else if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError)
        {
            if (gServiceConnDropSent)
            {

                // Send Weave ping over tunnel which should get queued.
                exchangeCtxt = ExchangeMgr.NewContext(gDestNodeId, gRemoteDataAddr, &gTunAgent);
                VerifyOrExit(exchangeCtxt, err = WEAVE_ERROR_NO_MEMORY);

                err = SendTunnelTestMessage(exchangeCtxt, kWeaveProfile_Echo,
                                            kEchoMessageType_EchoRequest,
                                            0);
                SuccessOrExit(err);

                // Set correct Destination address configuration for subsequent successful reconnection
                // and delivery of queued ping request.

                gTunAgent.SetDestination(gDestNodeId, gDestAddr);
            }
            else
            {
                gTestSucceeded = false;
            }
        }

        break;

      case kTestNum_TestTunnelResetReconnectBackoffImmediately:
      case kTestNum_TestTunnelResetReconnectBackoffRandomized:
        if (reason == WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError)
        {
            if (gReconnectResetArmed)
            {
                WeaveLogDetail(WeaveTunnel, "Tunnel Connect error after reset armed\n");

                if (gCurrTestNum == kTestNum_TestTunnelResetReconnectBackoffImmediately)
                {
                    if (Now() - gReconnectResetArmTime < (BACKOFF_RESET_IMMEDIATE_THRESHOLD_SECS *
                                                          nl::Weave::System::kTimerFactor_micro_per_unit))
                    {
                        gTestSucceeded = true;
                    }
                    else
                    {
                        gTestSucceeded = false;
                    }
                }
                else
                {
                    if (Now() - gReconnectResetArmTime < (BACKOFF_RESET_RANDOMIZED_THRESHOLD_SECS *
                                                          nl::Weave::System::kTimerFactor_micro_per_unit))
                    {
                        gTestSucceeded = true;
                    }
                    else
                    {
                        gTestSucceeded = false;
                    }

                }
            }
            else
            {
                gConnAttemptsBeforeReset++;

                if (gConnAttemptsBeforeReset == TEST_CONN_ATTEMPTS_BEFORE_RESET)
                {
                    if (gCurrTestNum == kTestNum_TestTunnelResetReconnectBackoffImmediately)
                    {
                        gTunAgent.ResetPrimaryReconnectBackoff(true);
                    }
                    else
                    {
                        gTunAgent.ResetPrimaryReconnectBackoff(false);
                    }

                    gReconnectResetArmTime = Now();

                    gReconnectResetArmed = true;
                    WeaveLogDetail(WeaveTunnel, "Tunnel Reconnect Reset armed\n");
                }
            }
        }

        break;

      default:

        break;

    }

exit:
    if (err != WEAVE_NO_ERROR)
    {
        if (exchangeCtxt)
        {
            exchangeCtxt->Close();
            exchangeCtxt = NULL;
        }

        gTestSucceeded = false;
    }
}

static const nlTest tunnelTests[] = {
    NL_TEST_DEF("TestWeaveTunnelAgentInit", TestWeaveTunnelAgentInit),
    NL_TEST_DEF("TestWeaveTunnelAgentConfigure", TestWeaveTunnelAgentConfigure),
    NL_TEST_DEF("TestWeaveTunnelAgentShutdown", TestWeaveTunnelAgentShutdown),
    NL_TEST_DEF("TestStartTunnelWithoutInit", TestStartTunnelWithoutInit),
    NL_TEST_DEF("TestBackToBackStartStopStart", TestBackToBackStartStopStart),
    NL_TEST_DEF("TestTunnelOpenCompleteThenStopStart", TestTunnelOpenCompleteThenStopStart),
    NL_TEST_DEF("TestReceiveStatusReportForTunnelOpen", TestReceiveStatusReportForTunnelOpen),
    NL_TEST_DEF("TestTunnelOpenThenTunnelClose", TestTunnelOpenThenTunnelClose),
    NL_TEST_DEF("TestStandaloneTunnelSetup", TestStandaloneTunnelSetup),
    NL_TEST_DEF("TestTunnelNoStatusReportReconnect", TestTunnelNoStatusReportReconnect),
    NL_TEST_DEF("TestTunnelErrorStatusReportReconnect", TestTunnelErrorStatusReportReconnect),
    NL_TEST_DEF("TestTunnelErrorStatusReportOnTunnelClose", TestTunnelErrorStatusReportOnTunnelClose),
    NL_TEST_DEF("TestTunnelConnectionDownReconnect", TestTunnelConnectionDownReconnect),
    NL_TEST_DEF("TestCallTunnelDownAfterMaxReconnects", TestCallTunnelDownAfterMaxReconnects),
    NL_TEST_DEF("TestReceiveReconnectFromService", TestReceiveReconnectFromService),
    NL_TEST_DEF("TestWARMRouteAddWhenTunnelEstablished", TestWARMRouteAddWhenTunnelEstablished),
    NL_TEST_DEF("TestWARMRouteDeleteWhenTunnelStopped", TestWARMRouteDeleteWhenTunnelStopped),
    NL_TEST_DEF("TestWeavePingOverTunnel", TestWeavePingOverTunnel),
    NL_TEST_DEF("TestQueueingOfTunneledPackets", TestQueueingOfTunneledPackets),
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    NL_TEST_DEF("TestTunnelStatistics", TestTunnelStatistics),
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
    NL_TEST_DEF("TestTunnelLivenessSendAndRecvResponse", TestTunnelLivenessSendAndRecvResponse),
    NL_TEST_DEF("TestTunnelLivenessDisconnectOnNoResponse", TestTunnelLivenessDisconnectOnNoResponse),
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
    NL_TEST_DEF("TestTunnelRestrictedRoutingOnTunnelOpen", TestTunnelRestrictedRoutingOnTunnelOpen),
    NL_TEST_DEF("TestTunnelResetReconnectBackoffImmediately", TestTunnelResetReconnectBackoffImmediately),
    NL_TEST_DEF("TestTunnelResetReconnectBackoffRandomized", TestTunnelResetReconnectBackoffRandomized),
    NL_TEST_DEF("TestTunnelNoStatusReportResetReconnectBackoff", TestTunnelNoStatusReportResetReconnectBackoff),
#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
    NL_TEST_DEF("TestTunnelTCPIdle", TestTunnelTCPIdle),
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    NL_TEST_DEF("TestTCPUserTimeoutOnAddrRemoval", TestTCPUserTimeoutOnAddrRemoval),
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS && WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
    NL_TEST_SENTINEL()
};
#endif // WEAVE_CONFIG_ENABLE_TUNNELING

int main(int argc, char *argv[])
{
#if WEAVE_CONFIG_ENABLE_TUNNELING
    WEAVE_ERROR err;
    gWeaveNodeOptions.LocalNodeId = DEFAULT_BG_NODE_ID;

    nlTestSuite tunnelTestSuite = {
        "WeaveTunnel",
        &tunnelTests[0]
    };

    nl_test_set_output_style(OUTPUT_CSV);

    UseStdoutLineBuffering();
    SetSIGUSR1Handler();

    // Set default Remote data IP address to be of the Service Tunnel Endpoint;

    IPAddress::FromString("fd00:0:1:5:1ab4:3002:0000:0011", gRemoteDataAddr);

    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (!ParseArgsFromEnvVar(TOOL_NAME, TOOL_OPTIONS_ENV_VAR_NAME, gToolOptionSets, NULL, true) ||
        !ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets, HandleNonOptionArgs))
    {
        exit(EXIT_FAILURE);
    }

    if (gNetworkOptions.LocalIPv6Addr != IPAddress::Any)
    {
        if (!gNetworkOptions.LocalIPv6Addr.IsIPv6ULA())
        {
            WeaveLogError(WeaveTunnel, "Local address must be an IPv6 ULA\n");
            exit(EXIT_FAILURE);
        }
        gWeaveNodeOptions.FabricId = gNetworkOptions.LocalIPv6Addr.GlobalId();
        gWeaveNodeOptions.LocalNodeId = IPv6InterfaceIdToWeaveNodeId(gNetworkOptions.LocalIPv6Addr.InterfaceId());
        gWeaveNodeOptions.SubnetId = gNetworkOptions.LocalIPv6Addr.Subnet();

    }

    InitSystemLayer();
    InitNetwork();
    InitWeaveStack(false, true);

    if (gDestAddr == IPAddress::Any)
    {
        gDestAddr = FabricState.SelectNodeAddress(gDestNodeId);
    }

    WeaveLogDetail(WeaveTunnel, "Weave Node Configuration:\n");
    WeaveLogDetail(WeaveTunnel, "Fabric Id: %" PRIX64 "\n", FabricState.FabricId);
    WeaveLogDetail(WeaveTunnel, "Subnet Number: %X\n", FabricState.DefaultSubnet);
    WeaveLogDetail(WeaveTunnel, "Node Id: %" PRIX64 "\n", FabricState.LocalNodeId);

    if (gConnectToAddr != NULL)
    {
        IPAddress::FromString(gConnectToAddr, gDestAddr);
    }

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    err = gServiceMgr.init(&ExchangeMgr, gServiceDirCache, sizeof(gServiceDirCache),
            GetRootDirectoryEntry, kWeaveAuthMode_CASE_ServiceEndPoint);
    FAIL_ERROR(err, "gServiceMgr.Init failed");
#endif

    if (gUseCASE)
        gAuthMode = kWeaveAuthMode_CASE_AnyCert;

    // Run all tests in Suite

    nlTestRunner(&tunnelTestSuite, NULL);

    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return nlTestRunnerStats(&tunnelTestSuite);
#endif // WEAVE_CONFIG_ENABLE_TUNNELING
}
