/*
 *
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2013-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 a command line tool, weave-ping, for the
 *      Weave Echo Profile.
 *
 *      The Weave Echo Profile implements two simple methods, in the
 *      style of ICMP ECHO REQUEST and ECHO REPLY, in which a sent
 *      payload is turned around by the responder and echoed back to
 *      the originator.
 *
 *      The weave-ping tool implements a facility for acting as either
 *      the originator or responder for the Echo Profile, with a
 *      variety of options.
 *
 */

#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS

#include <inttypes.h>
#include <limits.h>
#include <signal.h>

#include "ToolCommon.h"
#include <Weave/WeaveVersion.h>
#include <Weave/Core/WeaveSecurityMgr.h>
#include <Weave/Profiles/echo/WeaveEcho.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include <Weave/Profiles/service-directory/ServiceDirectory.h>
#include <Weave/Support/crypto/WeaveCrypto.h>
#include <Weave/Support/TimeUtils.h>
#include <Weave/Support/WeaveFaultInjection.h>

using nl::StatusReportStr;
using namespace nl::Weave::Profiles::Security;

#define TOOL_NAME "weave-ping"

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 DriveSending();
static void HandleEchoRequestReceived(uint64_t nodeId, IPAddress nodeAddr, PacketBuffer *payload);
static void HandleEchoResponseReceived(uint64_t nodeId, IPAddress nodeAddr, PacketBuffer *payload);
static void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con);
static void StartClientConnection();
static void StartSecureSession();
static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType);
static void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport);
static void ParseDestAddress();
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
static void HandleServiceMgrStatus(void *appState, WEAVE_ERROR anError, StatusReport *aReport);
#endif

bool Listening = false;
int32_t MaxEchoCount = -1;
int32_t EchoInterval = 1000000;
int32_t EchoLength = -1;
bool UseTCP = true;
bool Debug = false;
uint64_t DestNodeId;
const char *DestAddr = NULL;
IPAddress DestIPAddr; // only used for UDP
uint16_t DestPort; // only used for UDP
InterfaceId DestIntf = INET_NULL_INTERFACEID; // only used for UDP
uint64_t LastEchoTime = 0;
bool WaitingForEchoResp = false;
int64_t EchoCount = 0;
int64_t EchoRespCount = 0;
WeaveEchoClient EchoClient;
WeaveEchoServer EchoServer;
WeaveConnection *Con = NULL;
bool ClientConInProgress = false;
bool ClientConEstablished = false;
bool ClientSecureSessionInProgress = false;
bool ClientSecureSessionEstablished = false;
WeaveAuthMode AuthMode = kWeaveAuthMode_Unauthenticated;

// The server should not reply a StatusReport with kStatus_Busy for more than 30 seconds.
// See WeaveSecurityManager::StartSessionTimer()
uint32_t SenderBusyRespCount = 0;
const uint32_t MaxSenderBusyRespCount = 10;
// In case of SenderBusy, wait 10 seconds before trying again to establish a secure session
const uint64_t SenderBusyRespDelay = 10*nl::kMicrosecondsPerSecond;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
bool UseServiceDir = false;
ServiceDirectory::WeaveServiceManager ServiceMgr;
uint8_t ServiceDirCache[300];
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY

#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
bool UseWRMP = false;
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING

bool TestSessionSuspend = false;

enum NameResolutionStateEnum
{
    kNameResolutionState_NotStarted,
    kNameResolutionState_InProgress,
    kNameResolutionState_Complete
} NameResolutionState = kNameResolutionState_NotStarted;

enum
{
    kToolOpt_UseServiceDir                          = 1000,
    kToolOpt_TestSessionSuspend                     = 1001,
};

static OptionDef gToolOptionDefs[] =
{
    { "listen",       kNoArgument,       'L' },
    { "dest-addr",    kArgumentRequired, 'D' },
    { "count",        kArgumentRequired, 'c' },
    { "length",       kArgumentRequired, 'l' },
    { "interval",     kArgumentRequired, 'i' },
    { "tcp",          kNoArgument,       't' },
    { "udp",          kNoArgument,       'u' },
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    { "wrmp",         kNoArgument,       'w' },
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    { "service-dir",  kNoArgument,       kToolOpt_UseServiceDir },
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    { "test-session-suspend", kNoArgument, kToolOpt_TestSessionSuspend },
    { }
};

static const char *const gToolOptionHelp =
    "  -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"
    "  -L, --listen\n"
    "       Listen and respond to Echo Requests sent from another node.\n"
    "\n"
    "  -c, --count <num>\n"
    "       Send the specified number of Echo Requests and exit.\n"
    "\n"
    "  -l, --length <num>\n"
    "       Send Echo Requests with the specified number of bytes in the payload.\n"
    "\n"
    "  -i, --interval <ms>\n"
    "       Send Echo Requests at the specified interval in milliseconds.\n"
    "\n"
    "  -t, --tcp\n"
    "       Use TCP to send Echo Requests. This is the default.\n"
    "\n"
    "  -u, --udp\n"
    "       Use UDP to send Echo Requests.\n"
    "\n"
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    "  -w, --wrmp\n"
    "       Use UDP with Weave reliable messaging to send Echo requests.\n"
    "\n"
#endif
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    "  --service-dir\n"
    "       Use service directory to lookup the destination node address.\n"
    "\n"
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    "  --test-session-suspend\n"
    "       Test the ability to suspend and restore a CASE session.\n"
    "\n"
    ;

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

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] <dest-node-id>[@<dest-host>[:<dest-port>][%<interface>]]\n"
    "       " TOOL_NAME " [<options...>] --listen\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT,
    "Send and receive Weave Echo profile messages.\n"
);

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


#if WEAVE_CONFIG_TEST
static void ResetTestContext(void)
{
    Done = false;
    WaitingForEchoResp = false;
    EchoCount = 0;
    EchoRespCount = 0;
    SenderBusyRespCount = 0;
}
#endif // WEAVE_CONFIG_TEST

int main(int argc, char *argv[])
{
    WEAVE_ERROR err;
#if WEAVE_CONFIG_TEST
    nl::Weave::System::Stats::Snapshot before;
    nl::Weave::System::Stats::Snapshot after;
    const bool printStats = true;
    uint64_t lastListeningPrintTimeMs = 0;
    uint32_t iter;
#endif

    InitToolCommon();

#if WEAVE_CONFIG_TEST
    SetupFaultInjectionContext(argc, argv);
    SetSignalHandler(DoneOnHandleSIGUSR1);
#endif

    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) ||
        !ResolveWeaveNetworkOptions(TOOL_NAME, gWeaveNodeOptions, gNetworkOptions))
    {
        exit(EXIT_FAILURE);
    }

    if (WeaveSecurityMode::kGroupEnc == gWeaveSecurityMode.SecurityMode && gGroupKeyEncOptions.GetEncKeyId() == WeaveKeyId::kNone)
    {
        PrintArgError("%s: Please specify a group encryption key id using the --group-enc-... options.\n", TOOL_NAME);
        exit(EXIT_FAILURE);
    }

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(Listening || !UseTCP, true);

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    err = ServiceMgr.init(&ExchangeMgr, ServiceDirCache, sizeof(ServiceDirCache),
                          GetRootServiceDirectoryEntry, kWeaveAuthMode_CASE_ServiceEndPoint,
                          NULL, NULL, OverrideServiceConnectArguments);
    if (err != WEAVE_NO_ERROR)
    {
        printf("ServiceMgr.init() failed with error: %s\n", ErrorStr(err));
        exit(EXIT_FAILURE);
    }
#endif

#if WEAVE_CONFIG_TEST
    nl::Weave::Stats::UpdateSnapshot(before);
#endif

    // Arrange to get called for various activities in the message layer.
    MessageLayer.OnConnectionReceived = HandleConnectionReceived;
    MessageLayer.OnReceiveError = HandleMessageReceiveError;
    MessageLayer.OnAcceptError = HandleAcceptConnectionError;

    if (!Listening)
    {
        // Initialize the EchoClient application.
        err = EchoClient.Init(&ExchangeMgr);
        if (err != WEAVE_NO_ERROR)
        {
            printf("WeaveEchoClient.Init failed: %s\n", ErrorStr(err));
            exit(EXIT_FAILURE);
        }

        // Arrange to get a callback whenever an Echo Response is received.
        EchoClient.OnEchoResponseReceived = HandleEchoResponseReceived;

        if (!UseTCP && (WeaveSecurityMode::kPASE == gWeaveSecurityMode.SecurityMode || WeaveSecurityMode::kTAKE == gWeaveSecurityMode.SecurityMode))
        {
            printf("PASE/TAKE not supported for UDP.\n");
            exit(EXIT_FAILURE);
        }

#if !WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        if (!UseTCP && (WeaveSecurityMode::kCASE == gWeaveSecurityMode.SecurityMode ||
                        WeaveSecurityMode::kCASEShared == gWeaveSecurityMode.SecurityMode))
        {
            printf("CASE not supported for UDP without WRMP support.\n");
            exit(EXIT_FAILURE);
        }
#endif

        if (WeaveSecurityMode::kPASE == gWeaveSecurityMode.SecurityMode)
            AuthMode = kWeaveAuthMode_PASE_PairingCode;
        else if (WeaveSecurityMode::kCASE == gWeaveSecurityMode.SecurityMode ||
                 WeaveSecurityMode::kCASEShared == gWeaveSecurityMode.SecurityMode)
            AuthMode = kWeaveAuthMode_CASE_AnyCert;
        else if (WeaveSecurityMode::kTAKE == gWeaveSecurityMode.SecurityMode)
            AuthMode = kWeaveAuthMode_TAKE_IdentificationKey;
        else
            AuthMode = kWeaveAuthMode_Unauthenticated;
    }
    else
    {
        // Initialize the EchoServer application.
        err = EchoServer.Init(&ExchangeMgr);
        if (err)
        {
            printf("WeaveEchoServer.Init failed: %s\n", ErrorStr(err));
            exit(EXIT_FAILURE);
        }

        // Arrange to get a callback whenever an Echo Request is received.
        EchoServer.OnEchoRequestReceived = HandleEchoRequestReceived;

        SecurityMgr.OnSessionEstablished = HandleSecureSessionEstablished;
        SecurityMgr.OnSessionError = HandleSecureSessionError;
    }

    PrintNodeConfig();

    if (!Listening)
    {
        if (!UseTCP && DestAddr != NULL)
            ParseDestAddress();

        if (DestNodeId == 0)
            printf("Sending Echo requests to node at %s\n", DestAddr);
        else if (DestAddr == NULL)
            printf("Sending Echo requests to node %" PRIX64 "\n", DestNodeId);
        else
            printf("Sending Echo requests to node %" PRIX64 " at %s\n", DestNodeId, DestAddr);
    }
    else
    {
        printf("Listening for Echo requests...\n");
    }

#if WEAVE_CONFIG_TEST
    for (iter = 0; iter < gFaultInjectionOptions.TestIterations; iter++)
    {
        printf("Iteration %u\n", iter);
#endif // WEAVE_CONFIG_TEST

        while (!Done)
        {
            struct timeval sleepTime;
            sleepTime.tv_sec = 0;
            sleepTime.tv_usec = 100000;

            ServiceNetwork(sleepTime);

            if (!Listening && !Done)
                DriveSending();

#if WEAVE_CONFIG_TEST
            if (Listening)
            {
                uint64_t nowMs = NowMs();

                if (nowMs - lastListeningPrintTimeMs > gGeneralSecurityOptions.GetIdleSessionTimeout())
                {
                    // Print something to show progress to the harness.
                    // The harness gives enough time to the listening node for the
                    // idle session timer to expire twice and remove idle keys; the harness
                    // needs the node to log something regularly to measure the
                    // time elapsed by parsing the timestamps, since the tests can
                    // be run at faster than real time.
                    // TODO (WEAV-2199) mark this log line as special
                    WeaveLogProgress(Echo, "Listening...");
                    lastListeningPrintTimeMs = nowMs;
                }
            }
#endif

            fflush(stdout);
        }

#if WEAVE_CONFIG_TEST
        if (!Listening && EchoCount == MaxEchoCount && EchoCount == EchoRespCount)
        {
            printf("The ping test was successful, no more iterations needed\n");
            break;
        }

        ResetTestContext();

        if (gSigusr1Received)
        {
            printf("Sigusr1Received\n");
            break;
        }
    }
#endif // WEAVE_CONFIG_TEST

    EchoClient.Shutdown();
    EchoServer.Shutdown();

#if WEAVE_CONFIG_TEST
    ProcessStats(before, after, printStats, NULL);
    PrintFaultInjectionCounters();
#endif // WEAVE_CONFIG_TEST

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

    return EXIT_SUCCESS;
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 't':
        UseTCP = true;
        break;
    case 'u':
        UseTCP = false;
        break;
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    case 'w':
        UseTCP = false;
        UseWRMP = true;
        break;
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    case kToolOpt_UseServiceDir:
        UseServiceDir = true;
        break;
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    case 'L':
        Listening = true;
        break;
    case 'c':
        if (!ParseInt(arg, MaxEchoCount) || MaxEchoCount < 0)
        {
            PrintArgError("%s: Invalid value specified for send count: %s\n", progName, arg);
            return false;
        }
        break;
    case 'l':
        if (!ParseInt(arg, EchoLength) || EchoLength < 0 || EchoLength > UINT16_MAX)
        {
            PrintArgError("%s: Invalid value specified for data length: %s\n", progName, arg);
            return false;
        }
        break;
    case 'i':
        if (!ParseInt(arg, EchoInterval) || EchoInterval < 0 || EchoInterval > (INT32_MAX / 1000))
        {
            PrintArgError("%s: Invalid value specified for send interval: %s\n", progName, arg);
            return false;
        }
        EchoInterval = EchoInterval * 1000;
        break;
    case 'D':
        DestAddr = arg;
        break;
    case kToolOpt_TestSessionSuspend:
        TestSessionSuspend = true;
        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 (Listening)
        {
            PrintArgError("%s: Please specify either a node id or --listen\n", progName);
            return false;
        }

        // TODO (arg clean up): generalize parsing of destination node ids and addresses.

        const char *nodeId = argv[0];
        char *p = (char *)strchr(nodeId, '@');
        if (p != NULL)
        {
            *p = 0;
            DestAddr = p+1;
        }

        if (!ParseNodeId(nodeId, DestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, nodeId);
            return false;
        }
    }

    else
    {
        if (!Listening)
        {
            PrintArgError("%s: Please specify either a node id or --listen\n", progName);
            return false;
        }
    }

    return true;
}

void DriveSending()
{
    WEAVE_ERROR err;

    if (Now() < LastEchoTime + EchoInterval)
        return;

    if (WaitingForEchoResp)
    {
        printf("No response received\n");

        WaitingForEchoResp = false;

        // Rescan interfaces to see if we got any new IP addresses
        if (!UseTCP)
        {
            printf("Refreshing endpoints\n");
            err = MessageLayer.RefreshEndpoints();
            if (err != WEAVE_NO_ERROR)
                printf("WeaveMessageLayer.RefreshEndpoints() failed: %s\n", ErrorStr(err));
        }
    }

    if (MaxEchoCount != -1 && EchoCount >= MaxEchoCount)
    {
        if (Con != NULL)
        {
            printf("Connection closed\n");
            Con->Close();
            Con = NULL;
            ClientConEstablished = false;
            ClientConInProgress = false;
        }

        Done = true;
        return;
    }

    if (UseTCP)
    {
        if (!ClientConEstablished)
        {
            StartClientConnection();
            return;
        }
    }
    else if (WeaveSecurityMode::kPASE == gWeaveSecurityMode.SecurityMode ||
             WeaveSecurityMode::kCASE == gWeaveSecurityMode.SecurityMode ||
             WeaveSecurityMode::kCASEShared == gWeaveSecurityMode.SecurityMode)
    {
        if (!ClientSecureSessionEstablished)
        {
            StartSecureSession();
            return;
        }
    }

    PacketBuffer *payloadBuf = PacketBuffer::New();
    if (payloadBuf == NULL)
    {
        printf("Unable to allocate PacketBuffer\n");
        LastEchoTime = Now();
        return;
    }

    char *p = (char *) payloadBuf->Start();
    int32_t len = sprintf(p, "Echo Message %" PRIi64 "\n", EchoCount);

    if (EchoLength > payloadBuf->MaxDataLength())
        EchoLength = payloadBuf->MaxDataLength();

    if (EchoLength != -1)
    {
        if (len > EchoLength)
            len = EchoLength;
        else
            while (len < EchoLength)
            {
                int32_t copyLen = EchoLength - len;
                if (copyLen > len)
                    copyLen = len;
                memcpy(p + len, p, copyLen);
                len += copyLen;
            }
    }
    payloadBuf->SetDataLength((uint16_t) len);

    LastEchoTime = Now();

    if (UseTCP)
    {
        VerifyOrDie(Con != NULL && ClientConEstablished);
    }
    else if (WeaveSecurityMode::kCASE == gWeaveSecurityMode.SecurityMode || WeaveSecurityMode::kPASE == gWeaveSecurityMode.SecurityMode)
    {
        VerifyOrDie(ClientSecureSessionEstablished);
    }

    if (Con != NULL)
    {
        err = EchoClient.SendEchoRequest(Con, payloadBuf);
        payloadBuf = NULL;
    }
    else
    {
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        EchoClient.SetRequestAck(UseWRMP);
        EchoClient.SetWRMPACKDelay(gWRMPOptions.ACKDelay);
        EchoClient.SetWRMPRetransInterval(gWRMPOptions.RetransInterval);
        EchoClient.SetWRMPRetransCount(gWRMPOptions.RetransCount);
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING

        if (WeaveSecurityMode::kGroupEnc == gWeaveSecurityMode.SecurityMode)
        {
            EchoClient.EncryptionType = kWeaveEncryptionType_AES128CTRSHA1;
            EchoClient.KeyId = gGroupKeyEncOptions.GetEncKeyId();
        }

        // If the --test-session-suspend option has been enabled, suspend and restore
        // the CASE session every 4 echo requests.  Every 8th echo request, remove the
        // suspended session before attempting to restore it.
        if (TestSessionSuspend && gWeaveSecurityMode.SecurityMode == WeaveSecurityMode::kCASE)
        {
            if (EchoCount > 0 && (EchoCount % 4) == 0)
            {
                uint8_t buf[256];
                uint16_t serializedKeyLen;

                printf("Suspending CASE session\n");
                err = FabricState.SuspendSession(EchoClient.KeyId, DestNodeId, buf, sizeof(buf), serializedKeyLen);
                if (err != WEAVE_NO_ERROR)
                {
                    printf("FabricState.SuspendSession() failed: %s\n", ErrorStr(err));
                }

                if (err == WEAVE_NO_ERROR && (EchoCount % 8) == 0)
                {
                    printf("Removing suspended CASE session\n");
                    err = FabricState.RemoveSessionKey(EchoClient.KeyId, DestNodeId);
                    if (err != WEAVE_NO_ERROR)
                    {
                        printf("FabricState.RemoveSessionKey() failed: %s\n", ErrorStr(err));
                    }
                }

                if (err == WEAVE_NO_ERROR)
                {
                    printf("Restoring suspended CASE session\n");
                    err = FabricState.RestoreSession(buf, serializedKeyLen);
                    if (err != WEAVE_NO_ERROR)
                    {
                        printf("FabricState.RestoreSession() failed: %s\n", ErrorStr(err));
                    }
                }
            }
        }

        err = EchoClient.SendEchoRequest(DestNodeId, DestIPAddr, DestPort, DestIntf, payloadBuf);
        payloadBuf = NULL;
    }

    if (err == WEAVE_NO_ERROR)
    {
        WaitingForEchoResp = true;
        EchoCount++;
    }
    else
    {
        printf("WeaveEchoClient.SendEchoRequest() failed: %s\n", ErrorStr(err));
        if (err == WEAVE_ERROR_KEY_NOT_FOUND)
        {
            ClientSecureSessionEstablished = false;
        }
    }
}

void HandleEchoRequestReceived(uint64_t nodeId, IPAddress nodeAddr, PacketBuffer *payload)
{
    if (Listening)
    {
        char ipAddrStr[64];
        nodeAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

        printf("Echo Request from node %" PRIX64 " (%s): len=%u ... sending response.\n", nodeId, ipAddrStr,
                payload->DataLength());

        if (Debug)
            DumpMemory(payload->Start(), payload->DataLength(), "    ", 16);
    }
}

void HandleEchoResponseReceived(uint64_t nodeId, IPAddress nodeAddr, PacketBuffer *payload)
{
    uint32_t respTime = Now();
    uint32_t transitTime = respTime - LastEchoTime;

    WaitingForEchoResp = false;
    EchoRespCount++;

    char ipAddrStr[64];
    nodeAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Echo Response from node %" PRIX64 " (%s): %" PRIi64 "/%" PRIi64 "(%.2f%%) len=%u time=%.3fms\n", nodeId, ipAddrStr,
            EchoRespCount, EchoCount, ((double) EchoRespCount) * 100 / EchoCount, payload->DataLength(),
            ((double) transitTime) / 1000);

    if (Debug)
        DumpMemory(payload->Start(), payload->DataLength(), "    ", 16);
}

void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Connection received from node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    con->OnConnectionClosed = HandleConnectionClosed;
}

void StartSecureSession()
{
    WEAVE_ERROR err;
    IPAddress coreRouterAddress;

    // Do nothing if a secure session attempt is already in progress.
    if (ClientSecureSessionInProgress)
    {
        return;
    }

    ClientSecureSessionEstablished = false;

    // Set the InProgress flag to true now, because
    // StartSecureSession can invoke HandleSecureSessionError, which clears
    // the InProgress flag.
    ClientSecureSessionInProgress = true;

    switch (gWeaveSecurityMode.SecurityMode)
    {
        case WeaveSecurityMode::kPASE:
            err = SecurityMgr.StartPASESession(Con, AuthMode, NULL,
                                               HandleSecureSessionEstablished, HandleSecureSessionError);
            break;
        case WeaveSecurityMode::kCASE:
            err = SecurityMgr.StartCASESession(Con, DestNodeId, DestIPAddr, WEAVE_PORT, AuthMode,
                                               NULL, HandleSecureSessionEstablished, HandleSecureSessionError);
            break;
        case WeaveSecurityMode::kCASEShared:
            coreRouterAddress = IPAddress::MakeULA(WeaveFabricIdToIPv6GlobalId(FabricState.FabricId),
                                                   nl::Weave::kWeaveSubnetId_Service,
                                                   nl::Weave::WeaveNodeIdToIPv6InterfaceId(kServiceEndpoint_CoreRouter));

            err = SecurityMgr.StartCASESession(Con, DestNodeId, coreRouterAddress, WEAVE_PORT, AuthMode,
                                               NULL, HandleSecureSessionEstablished, HandleSecureSessionError,
                                               NULL, kServiceEndpoint_CoreRouter);
            break;
        default:
            err = WEAVE_ERROR_UNSUPPORTED_AUTH_MODE;
    }

    if (err != WEAVE_NO_ERROR)
    {
        printf("SecurityMgr.StartSecureSession() failed: %s\n", ErrorStr(err));
        LastEchoTime = Now();
        ClientSecureSessionInProgress = false;
        return;
    }
}

void StartClientConnection()
{
    WEAVE_ERROR err;

    if (Con != NULL && Con->State == WeaveConnection::kState_Closed)
    {
        Con->Close();
        Con = NULL;
    }

    // Do nothing if a connect attempt is already in progress.
    if (ClientConInProgress)
        return;

    ClientConEstablished = false;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (UseServiceDir)
    {
        err = ServiceMgr.connect(DestNodeId,
                                 AuthMode,
                                 NULL,
                                 HandleServiceMgrStatus,
                                 HandleConnectionComplete);
        if (err != WEAVE_NO_ERROR)
        {
            printf("WeaveServiceManager.Connect(): failed: %s\n", ErrorStr(err));
            LastEchoTime = Now();
            return;
        }
    }
    else
#endif
    {
        Con = MessageLayer.NewConnection();
        if (Con == NULL)
        {
            printf("WeaveConnection.Connect failed: %s\n", ErrorStr(WEAVE_ERROR_NO_MEMORY));
            LastEchoTime = Now();
            Done = true;
            return;
        }
        Con->OnConnectionComplete = HandleConnectionComplete;
        Con->OnConnectionClosed = HandleConnectionClosed;

        err = Con->Connect(DestNodeId, AuthMode, DestAddr);
        if (err != WEAVE_NO_ERROR)
        {
            printf("WeaveConnection.Connect failed: %s\n", ErrorStr(err));
            Con->Close();
            Con = NULL;
            LastEchoTime = Now();
            Done = true;
            return;
        }
    }

    ClientConInProgress = true;
}

void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr != WEAVE_NO_ERROR)
    {
        printf("Connection FAILED to node %" PRIX64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));
        con->Close();
        Con = NULL;
        LastEchoTime = Now();
        ClientConEstablished = false;
        ClientConInProgress = false;
        Done = true;
        return;
    }

    printf("Connection established to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    Con = con;

    con->OnConnectionClosed = HandleConnectionClosed;

    EchoClient.EncryptionType = con->DefaultEncryptionType;
    EchoClient.KeyId = con->DefaultKeyId;

    ClientConEstablished = true;
    ClientConInProgress = false;
}

void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr == WEAVE_NO_ERROR)
        printf("Connection closed to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);
    else
        printf("Connection ABORTED to node %" PRIX64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));

    if (Listening)
        con->Close();
    else if (con == Con)
    {
        con->Close();
        Con = NULL;
    }

    WaitingForEchoResp = false;
    ClientConEstablished = false;
    ClientConInProgress = false;
}

void HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType)
{
    char ipAddrStr[64];

    if (con != NULL)
    {
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
    }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    else
    {
        DestIPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

        EchoClient.EncryptionType = encType;
        EchoClient.KeyId = sessionKeyId;

        ClientSecureSessionEstablished = true;
        ClientSecureSessionInProgress = false;
    }
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING

    printf("Secure session established with node %" PRIX64 " (%s)\n", peerNodeId, ipAddrStr);
}

void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport)
{
    char ipAddrStr[64];
    bool isSenderBusy = false;

    if (con != NULL)
    {
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
    }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    else
    {
        DestIPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

        ClientSecureSessionInProgress = false;
        ClientSecureSessionEstablished = false;
    }
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING

    if (localErr == WEAVE_ERROR_STATUS_REPORT_RECEIVED && statusReport != NULL)
        printf("FAILED to establish secure session to node %" PRIX64 " (%s): %s\n", peerNodeId, ipAddrStr, StatusReportStr(statusReport->mProfileId, statusReport->mStatusCode));
    else
        printf("FAILED to establish secure session to node %" PRIX64 " (%s): %s\n", peerNodeId, ipAddrStr, ErrorStr(localErr));

    isSenderBusy = (localErr == WEAVE_ERROR_STATUS_REPORT_RECEIVED &&
                    statusReport != NULL &&
                    statusReport->mProfileId == nl::Weave::Profiles::kWeaveProfile_Common &&
                    statusReport->mStatusCode == nl::Weave::Profiles::Common::kStatus_Busy);

    if (isSenderBusy)
    {
        // Force the main loop not to retry too soon
        LastEchoTime = Now() + SenderBusyRespDelay;
        SenderBusyRespCount++;
    }

    if (!Listening && (!isSenderBusy || SenderBusyRespCount > MaxSenderBusyRespCount))
    {
        Done = true;
    }
}

void ParseDestAddress()
{
    // NOTE: This function is only used when communicating over UDP.  Code in the WeaveConnection object handles
    // parsing the destination node address for TCP connections.

    WEAVE_ERROR err;
    const char *addr;
    uint16_t addrLen = 0;
    const char *intfName;
    uint16_t intfNameLen;

    err = ParseHostPortAndInterface(DestAddr, strlen(DestAddr), addr, addrLen, DestPort, intfName, intfNameLen);
    if (err != INET_NO_ERROR)
    {
        printf("Invalid destination address: %s\n", DestAddr);
        exit(EXIT_FAILURE);
    }

    if (!IPAddress::FromString(addr, addrLen, DestIPAddr))
    {
        printf("Invalid destination address: %s\n", DestAddr);
        exit(EXIT_FAILURE);
    }

    if (intfName != NULL)
    {
        err = InterfaceNameToId(intfName, DestIntf);
        if (err != INET_NO_ERROR)
        {
            printf("Invalid interface name: %s\n", intfName);
            exit(EXIT_FAILURE);
        }
    }
}

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
void HandleServiceMgrStatus(void* anAppState, WEAVE_ERROR anError, StatusReport *aReport)
{
    if (aReport)
        printf("service directory status report [%" PRIx32 ", %" PRIx32 "]", aReport->mProfileId, aReport->mStatusCode);

    else
        printf("service directory error %" PRIx32 "", static_cast<uint32_t>(anError));

    LastEchoTime = Now();
    ClientConEstablished = false;
    ClientConInProgress = false;
}
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
