/*
 *
 *    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-key-export, for the
 *      Weave Key Export Protocol (Security Profile).
 *
 *      The weave-kye-export tool implements a facility for acting as either
 *      the originator or responder for the key export request, 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/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-key-export"

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 HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con);
static void StartClientConnection();
static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleKeyExportComplete(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint32_t exportedKeyId, const uint8_t *exportedKey, uint16_t exportedKeyLen);
static void HandleKeyExportError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, StatusReport *statusReport);
static void ParseDestAddress();
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
static WEAVE_ERROR GetRootDirectoryEntry(uint8_t *, uint16_t);
static void HandleServiceMgrStatus(void *appState, WEAVE_ERROR anError, StatusReport *aReport);
#endif

int32_t MaxKeyExportCount = -1;
int32_t KeyExportInterval = 1000000;
bool UseTCP = true;
bool Debug = false;
bool SignKeyExportMsgs = true;
uint32_t ExportKeyId = WeaveKeyId::kClientRootKey;
uint64_t DestNodeId;
const char *DestAddr = NULL;
IPAddress DestIPAddr; // only used for UDP
uint16_t DestPort = WEAVE_PORT; // only used for UDP
InterfaceId DestIntf = INET_NULL_INTERFACEID; // only used for UDP
uint64_t LastKeyExportTime = 0;
bool WaitingForKeyExportResponse = false;
uint64_t KeyExportRequestCount = 0;
uint64_t KeyExportResponseCount = 0;
WeaveConnection *Con = NULL;
bool ClientConInProgress = false;
bool ClientConEstablished = false;
WeaveAuthMode AuthMode = kWeaveAuthMode_Unauthenticated;
uint8_t InitiatorKeyExportConfig = kKeyExportConfig_Unspecified;

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

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

enum
{
    kToolOpt_UseServiceDir                          = 1000,
};

bool ParseKeyExportConfig(const char *str, uint8_t& output)
{
    uint32_t configNum;

    if (!ParseInt(str, configNum))
        return false;

    switch (configNum)
    {
    case 1:
        output = kKeyExportConfig_Config1;
        return true;
    case 2:
        output = kKeyExportConfig_Config2;
        return true;
    default:
        return false;
    }
}

static OptionDef gToolOptionDefs[] =
{
    { "dest-addr",         kArgumentRequired, 'D' },
    { "key-id",            kArgumentRequired, 'K' },
    { "key-export-config", kArgumentRequired, 'k' },
    { "dont-sign-msgs",    kNoArgument,       'd' },
    { "count",             kArgumentRequired, 'c' },
    { "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
    { NULL }
};

static const char *const gToolOptionHelp =
    "  -D, --dest-addr <host>[:<port>][%<interface>]\n"
    "       Send Key Export 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, Key Export\n"
    "       Requests will be sent to the specified port. If <interface> is\n"
    "       specified, Key Export 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"
    "  -K, --key-id <num>\n"
    "       Identifier of the key to be exported. If not specified the client\n"
    "       root key is exported by default.\n"
    "\n"
    "  -k, --key-export-config <num>\n"
    "       Proposed the specified key export configuration when initiating a key\n"
    "       export request. If not specified the dafult value provided by\n"
    "       WeaveSecurityManager is used.\n"
    "\n"
    "  -d, --dont-sign-msgs\n"
    "       Don't sign Key Export Request/Response messages. If not specified,\n"
    "       by default the messages are signed with ECDSA signature using device\n"
    "       private key.\n"
    "\n"
    "  -c, --count <num>\n"
    "       Send the specified number of Key Export Requests and exit.\n"
    "\n"
    "  -i, --interval <ms>\n"
    "       Send Key Export Requests at the specified interval in milliseconds.\n"
    "\n"
    "  -t, --tcp\n"
    "       Use TCP to send Key Export Requests. This is the default.\n"
    "\n"
    "  -u, --udp\n"
    "       Use UDP to send Key Export Requests.\n"
    "\n"
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    "  -w, --wrmp\n"
    "       Use UDP with Weave reliable messaging to send Key Export 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
    ;

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"
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT,
    "Send key export request and receive key export response messages.\n"
);

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

static void ResetTestContext(void)
{
    Done = false;
    WaitingForKeyExportResponse = false;
    KeyExportRequestCount = 0;
    KeyExportResponseCount = 0;
    SenderBusyRespCount = 0;
}

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

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

    {
        unsigned int seed;
        err = nl::Weave::Platform::Security::GetSecureRandomData((uint8_t *)&seed, sizeof(seed));
        FAIL_ERROR(err, "Random number generator seeding failed");
        srand(seed);
    }

    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);
    }

    // TODO (arg clean up): generalize code that infers node ids from local address
    if (gNetworkOptions.LocalIPv6Addr != IPAddress::Any)
    {
        if (!gNetworkOptions.LocalIPv6Addr.IsIPv6ULA())
        {
            printf("ERROR: 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(!UseTCP, true);

    if (InitiatorKeyExportConfig != kKeyExportConfig_Unspecified)
        SecurityMgr.InitiatorKeyExportConfig = InitiatorKeyExportConfig;

    if (gKeyExportOptions.AllowedKeyExportConfigs != 0)
        SecurityMgr.InitiatorAllowedKeyExportConfigs = gKeyExportOptions.AllowedKeyExportConfigs;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    err = ServiceMgr.init(&ExchangeMgr, ServiceDirCache, sizeof(ServiceDirCache),
            GetRootDirectoryEntry, kWeaveAuthMode_CASE_ServiceEndPoint);
    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;

    PrintNodeConfig();

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

    if (DestNodeId == 0)
        printf("Sending key export request to node at %s\n", DestAddr);
    else if (DestAddr == NULL)
        printf("Sending key export request to node %" PRIX64 "\n", DestNodeId);
    else
        printf("Sending key export request to node %" PRIX64 " at %s\n", DestNodeId, DestAddr);

#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 (!Done)
                DriveSending();

            fflush(stdout);
        }

        ResetTestContext();

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

#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 'K':
        if (!ParseInt(arg, ExportKeyId, 0) || !WeaveKeyId::IsValidKeyId(ExportKeyId))
        {
            PrintArgError("%s: Invalid value specified for key identifier: %s\n", progName, arg);
            return false;
        }
        break;
    case 'k':
        if (!ParseKeyExportConfig(arg, InitiatorKeyExportConfig))
        {
            PrintArgError("%s: Invalid value specified for KeyExport config: %s\n", progName, arg);
            return false;
        }
        break;
    case 'd':
        SignKeyExportMsgs = false;
        break;
    case 'c':
        if (!ParseInt(arg, MaxKeyExportCount) || MaxKeyExportCount < 0)
        {
            PrintArgError("%s: Invalid value specified for send count: %s\n", progName, arg);
            return false;
        }
        break;
    case 'i':
        if (!ParseInt(arg, KeyExportInterval) || KeyExportInterval < 0 || KeyExportInterval > (INT32_MAX / 1000))
        {
            PrintArgError("%s: Invalid value specified for send interval: %s\n", progName, arg);
            return false;
        }
        KeyExportInterval = KeyExportInterval * 1000;
        break;
    case 'D':
        DestAddr = arg;
        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;
        }

        // 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
    {
        PrintArgError("%s: Please specify destination node Id\n", progName);
        return false;
    }

    return true;
}

void DriveSending()
{
    WEAVE_ERROR err;

    if (Now() < LastKeyExportTime + KeyExportInterval)
        return;

    if (WaitingForKeyExportResponse)
    {
        printf("No key export response received\n");

        WaitingForKeyExportResponse = 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 (MaxKeyExportCount != -1 && KeyExportRequestCount >= (uint64_t) MaxKeyExportCount)
    {
        if (Con != NULL && Con->State != WeaveConnection::kState_Closed)
        {
            printf("Connection closed\n");
            Con->Close();
            Con = NULL;
            ClientConEstablished = false;
            ClientConInProgress = false;
        }

        Done = true;
        return;
    }

    if (UseTCP)
    {
        if (!ClientConEstablished)
        {
            StartClientConnection();
            return;
        }
        else
        {
            VerifyOrDie(Con != NULL && ClientConEstablished);
        }
    }

    err = SecurityMgr.StartKeyExport(Con, DestNodeId, DestIPAddr, DestPort, ExportKeyId, SignKeyExportMsgs,
                                     NULL, HandleKeyExportComplete, HandleKeyExportError);
    LastKeyExportTime = Now();
    if (err == WEAVE_NO_ERROR)
    {
        KeyExportRequestCount++;
        WaitingForKeyExportResponse = true;
    }
    else
    {
        printf("SecurityMgr.StartKeyExport() failed: %s\n", ErrorStr(err));
    }
}

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 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));
            LastKeyExportTime = Now();
            return;
        }
    }
    else
#endif
    {
        Con = MessageLayer.NewConnection();
        if (Con == NULL)
        {
            printf("WeaveConnection.Connect failed: %s\n", ErrorStr(WEAVE_ERROR_NO_MEMORY));
            LastKeyExportTime = 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;
            LastKeyExportTime = 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;
        LastKeyExportTime = Now();
        ClientConEstablished = false;
        ClientConInProgress = false;
        Done = true;
        return;
    }

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

    Con = con;

    con->OnConnectionClosed = HandleConnectionClosed;

    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 (con == Con)
    {
        con->Close();
        Con = NULL;
    }

    WaitingForKeyExportResponse = false;
    ClientConEstablished = false;
    ClientConInProgress = false;
}

void HandleKeyExportComplete(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint32_t exportedKeyId, const uint8_t *exportedKey, uint16_t exportedKeyLen)
{
    uint64_t peerNodeId;
    char ipAddrStr[64];

    WaitingForKeyExportResponse = false;
    KeyExportResponseCount++;
    LastKeyExportTime = Now();
    SenderBusyRespCount = 0;

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

    printf("Received Key Export Response from node %" PRIX64 " (%s) for requested keyId = 0x%08X.\n", peerNodeId, ipAddrStr, ExportKeyId);
    printf("Exported Key 0x%08X (%d bytes):\n", exportedKeyId, exportedKeyLen);
    DumpMemoryCStyle(exportedKey, exportedKeyLen, "  ", 16);
}

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

    WaitingForKeyExportResponse = false;

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

    if (localErr == WEAVE_ERROR_STATUS_REPORT_RECEIVED && statusReport != NULL)
        printf("FAILED to export key (keyId = 0x%08X) from node %" PRIX64 " (%s): %s\n", ExportKeyId, peerNodeId, ipAddrStr, StatusReportStr(statusReport->mProfileId, statusReport->mStatusCode));
    else
        printf("FAILED to export key (keyId = 0x%08X) from node %" PRIX64 " (%s): %s\n", ExportKeyId, 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.
        LastKeyExportTime = Now() + SenderBusyRespDelay;
        SenderBusyRespCount++;
    }

    if (!isSenderBusy || SenderBusyRespCount > MaxSenderBusyRespCount)
    {
        if (Con != NULL && Con->State != WeaveConnection::kState_Closed)
        {
            printf("Connection closed\n");
            Con->Close();
            Con = NULL;
            ClientConEstablished = false;
            ClientConInProgress = false;
        }
        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;
    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, 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
WEAVE_ERROR GetRootDirectoryEntry(uint8_t *buf, uint16_t bufSize)
{
    return gServiceDirClientOptions.GetRootDirectoryEntry(buf, bufSize);
}

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

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