/*
 *
 *    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 Tunnel Agent class APIs for coordinating
 *      and managing IPv6 packet routing between peripheral network devices
 *      and the Nest Service.
 *
 */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include <Weave/Profiles/weave-tunneling/WeaveTunnelAgent.h>

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Support/MathUtils.h>
#include <Weave/Support/FlagUtils.hpp>
#include <SystemLayer/SystemTimer.h>
#include <Weave/Profiles/time/WeaveTime.h>
#include <Weave/Support/logging/WeaveLogging.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelControl.h>

#if WEAVE_CONFIG_ENABLE_TUNNELING

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#endif

#include <inttypes.h>

using namespace nl::Weave::Profiles::WeaveTunnel;
using namespace nl::Inet;

using nl::Weave::System::PacketBuffer;

WeaveTunnelAgent::WeaveTunnelAgent()
{
    mInet                     = NULL;
    mExchangeMgr              = NULL;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    mServiceMgr               = NULL;
#endif

    mPeerNodeId               = 0;
    qFront                    = TUNNEL_PACKET_QUEUE_INVALID_INDEX;
    qRear                     = TUNNEL_PACKET_QUEUE_INVALID_INDEX;
    mTunAgentState            = kState_NotInitialized;
    mPeerNodeId               = kNodeIdNotSpecified;
    mServiceAddress           = IPAddress::Any;
    mServicePort              = WEAVE_PORT;
    mAuthMode                 = kWeaveAuthMode_Unauthenticated;
    mAppContext               = NULL;
}

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
/**
 * Initialize the Tunnel agent. This creates te Tunnel endpoint object, sets up the tunnel
 * interface, initializes member variables, callbacks and WeaveTunnelControl.
 *
 * @param[in] inet                         A pointer to the InetLayer object.
 *
 * @param[in] exchMgr                      A pointer to the WeaveExchangeManager object.
 *
 * @param[in] dstNodeId                    Node ID of the destination node.
 *
 * @param[in] authMode                     Weave authentication mode used with peer.
 *
 * @param[in] svcMgr                       Pointer to ServiceManager object for lookup and connection
 *                                         to Service.
 *
 * @param[in] intfName                     Interface name given by user; defaults to "weav-tun0".
 *
 * @param[in] role                         Role assumed by Tunnel Agent; Border Gateway, Standalone or Mobile Device.
 *
 * @param[in] appContext                   A pointer to an application level context object.
 *
 * @return WEAVE_NO_ERROR on success, else a corresponding WEAVE_ERROR type.
 */
WEAVE_ERROR WeaveTunnelAgent::Init (InetLayer *inet, WeaveExchangeManager *exchMgr,
                                    uint64_t dstNodeId, WeaveAuthMode authMode,
                                    WeaveServiceManager *svcMgr,
                                    const char *intfName, uint8_t role, void *appContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    VerifyOrExit(svcMgr != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);

    err = ConfigureAndInit(inet, exchMgr, dstNodeId, IPAddress::Any, authMode,
                           svcMgr,
                           intfName, role, appContext);

exit:
    return err;
}
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY

/**
 * Initialize the Tunnel agent. This creates te Tunnel endpoint object, sets up the tunnel
 * interface, initializes member variables, callbacks and WeaveTunnelControl.
 *
 * @param[in] inet                         A pointer to the InetLayer object.
 *
 * @param[in] exchMgr                      A pointer to the WeaveExchangeManager object.
 *
 * @param[in] dstNodeId                    Node ID of the destination node.
 *
 * @param[in] dstIPAddr                    IP address of the destination node.
 *
 * @param[in] authMode                     Weave authentication mode used with peer.
 *
 * @param[in] intfName                     Interface name given by user; defaults to "weav-tun0".
 *
 * @param[in] role                         Role assumed by Tunnel Agent; Border Gateway, Standalone or Mobile Device.
 *
 * @param[in] appContext                   A pointer to an application level context object.
 *
 * @return WEAVE_NO_ERROR on success, else a corresponding WEAVE_ERROR type.
 */
WEAVE_ERROR WeaveTunnelAgent::Init (InetLayer *inet, WeaveExchangeManager *exchMgr,
                                    uint64_t dstNodeId, IPAddress dstIPAddr, WeaveAuthMode authMode,
                                    const char *intfName, uint8_t role, void *appContext)
{
    return ConfigureAndInit(inet, exchMgr, dstNodeId, dstIPAddr, authMode,
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
                            NULL,
#endif
                            intfName, role, appContext);
}

WEAVE_ERROR WeaveTunnelAgent::ConfigureAndInit (InetLayer *inet, WeaveExchangeManager *exchMgr,
                                                uint64_t dstNodeId, IPAddress dstIPAddr, WeaveAuthMode authMode,
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
                                                WeaveServiceManager *svcMgr,
#endif
                                                const char *intfName, uint8_t role, void *appContext)
{
    WEAVE_ERROR err          = WEAVE_NO_ERROR;
    mInet                    = inet;
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    mServiceMgr              = svcMgr;
#endif
    mExchangeMgr             = exchMgr;
    mPeerNodeId              = dstNodeId;
    mServiceAddress          = dstIPAddr;
    mRole                    = role;
    mAuthMode                = authMode;
    mAppContext              = appContext;
    memset(queuedMsgs, 0, sizeof(queuedMsgs));
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    memset(&mWeaveTunnelStats, 0, sizeof(mWeaveTunnelStats));
#endif

    EnablePrimaryTunnel();
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    DisableBackupTunnel();
#endif

    // Set the TunnelAgent object pointer in WeaveMessageLayer for local UDP tunneling.

    mExchangeMgr->MessageLayer->AppState = this;
    mExchangeMgr->MessageLayer->OnUDPTunneledMessageReceived = RecvdFromShortcutUDPTunnel;

#if !WEAVE_SYSTEM_CONFIG_USE_LWIP
    if (sizeof(intfName) > TUN_INTF_NAME_MAX_LEN)
    {
        WeaveLogDetail(WeaveTunnel, "Interface name size too big; may be truncated\n");
    }
    strncpy(mIntfName, intfName, sizeof(mIntfName) - 1);
    mIntfName[sizeof(mIntfName) - 1] = '\0';
#endif

    // Create Tunnel EndPoint and populate into member mTunEP

    err = CreateTunEndPoint();
    SuccessOrExit(err);

    err = SetupTunEndPoint();
    SuccessOrExit(err);

#if WEAVE_CONFIG_TUNNEL_SHORTCUT_SUPPORTED
    // Initialize WeaveTunnelControl for the Tunnel Shortcut

    err = mTunShortcutControl.Init(this);
    SuccessOrExit(err);
#endif

    // Initialize the WeaveTunnelConnectionMgr

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    mPrimaryTunConnMgr.Init(this, kType_TunnelPrimary, kSrcInterface_WiFi, PRIMARY_TUNNEL_DEFAULT_INTF_NAME);

    mBackupTunConnMgr.Init(this, kType_TunnelBackup, kSrcInterface_Cellular, BACKUP_TUNNEL_DEFAULT_INTF_NAME);
#else // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    // Initialize the Primary Tunnel ConnectionManager. By default, set the source interface type to WiFi.

    mPrimaryTunConnMgr.Init(this, kType_TunnelPrimary, kSrcInterface_WiFi);

#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    // Register Recv function for TunEndPoint

    mTunEP->OnPacketReceived = RecvdFromTunnelEndPoint;

    // Set the TunEndPoint appState to the WeaveTunnelAgent.

    mTunEP->AppState = this;

#if WEAVE_CONFIG_TUNNEL_SHORTCUT_SUPPORTED
    // Enable Shortcut tunneling advertisments

    mTunShortcutControl.EnableShortcutTunneling();
#endif

    // Set the TunnelAgent state.

    mTunAgentState  = kState_Initialized_NoTunnel;

exit:
    return err;
}

/**
 * Set the WeaveAuthMode for the Tunnel.
 *
 * @note
 *   The application needs to stop and then start the tunnel for this configuration change
 *   to have effect.
 *
 * @param[in] authMode                 Weave authentication mode used with peer.
 *
 */
void WeaveTunnelAgent::SetAuthMode(const WeaveAuthMode authMode)
{
    mAuthMode         = authMode;
}

/**
 * Set the destination nodeId and IPAddress for the Tunnel.
 *
 * @note
 *   The application needs to stop and then start the tunnel for this configuration change
 *   to have effect.
 *
 * @param[in] nodeId                   Node ID of the destination node.
 *
 * @param[in] ipAddr                   IP address of the destination node.
 *
 * @param[in] servicePort              Port  of the destination node.
 */
void WeaveTunnelAgent::SetDestination(const uint64_t nodeId, const IPAddress ipAddr, const uint16_t servicePort)
{
    mPeerNodeId       = nodeId;
    mServiceAddress   = ipAddr;
    mServicePort      = servicePort;
}

/**
 * Set the Tunneling device role(BorderGateway vs Standalone) for the Tunnel.
 *
 * @note
 *   The application needs to stop and then start the tunnel for this configuration change
 *   to have effect.
 *
 * @param[in] role                     Role assumed by Tunnel Agent; Border Gateway, Standalone or Mobile Device.
 */
void WeaveTunnelAgent::SetTunnelingDeviceRole(const Role role)
{
    mRole             = role;
}

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
/**
 * Set the primary tunnel interface name.
 *
 * @param[in] primaryIntfName          Primary interface name for Service tunnel connection.
 *
 */
void WeaveTunnelAgent::SetPrimaryTunnelInterface(const char *primaryIntfName)
{
    mPrimaryTunConnMgr.SetInterfaceName(primaryIntfName);
}

/**
 * Set the primary tunnel interface type
 *
 * @param[in] primaryIntfType          The network technology type of the primary interface for Service tunnel connection.
 */
void WeaveTunnelAgent::SetPrimaryTunnelInterfaceType (const SrcInterfaceType primaryIntfType)
{
    mPrimaryTunConnMgr.SetInterfaceType(primaryIntfType);
}

/**
 * Set the backup tunnel interface name.
 *
 * @param[in] backupIntfName           Backup interface name for Service tunnel connection.
 *
 */
void WeaveTunnelAgent::SetBackupTunnelInterface(const char *backupIntfName)
{
    mBackupTunConnMgr.SetInterfaceName(backupIntfName);
}

/**
 * Set the backup tunnel interface type
 *
 * @param[in] backupIntfType           The network technology type of the backup interface for Service tunnel connection.
 */
void WeaveTunnelAgent::SetBackupTunnelInterfaceType (const SrcInterfaceType backupIntfType)
{
    mPrimaryTunConnMgr.SetInterfaceType(backupIntfType);
}

#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

/**
 * Get the TunnelAgent state.
 *
 * @return AgentState the current state of the WeaveTunnelAgent.
 *
 */
WeaveTunnelAgent::AgentState WeaveTunnelAgent::GetWeaveTunnelAgentState(void)
{
    return mTunAgentState;
}

/**
 * Shutdown the Tunnel Agent. This tears down connection to the Service and closes the TunEndPoint
 * interface after removing addresses and routes associated with the tunnel interface.
 *
 * @return WEAVE_NO_ERROR on success, else a corresponding WEAVE_ERROR type.
 */
WEAVE_ERROR WeaveTunnelAgent::Shutdown(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Verify that Tunnel Agent was at least initialized

    VerifyOrExit(mTunAgentState != kState_NotInitialized,
                 err = WEAVE_ERROR_INCORRECT_STATE);

    // Stop the tunnel to the Service

    StopServiceTunnel();

#if WEAVE_CONFIG_TUNNEL_SHORTCUT_SUPPORTED
    // Disable Shortcut tunneling advertisments

    mTunShortcutControl.DisableShortcutTunneling();
#endif

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    mPrimaryTunConnMgr.Shutdown();

    mBackupTunConnMgr.Shutdown();

#else // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    // Shutdown the Primary Tunnel ConnectionManager.

    mPrimaryTunConnMgr.Shutdown();

#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    SetState(kState_NotInitialized);

    // Tear down the tun endpoint setup

    err = TeardownTunEndPoint();

exit:
    return err;
}

#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
/**
 *  Configure the TCP user timeout option on the primary tunnel connection.
 *
 *  @param[in]  maxTimeoutSecs
 *    The maximum timeout for the TCP connection.
 *
 *  @retval  #WEAVE_NO_ERROR                     on successful configuration.
 *  @retval  #WEAVE_ERROR_INCORRECT_STATE        if the WeaveConnection object is not
 *                                               in the correct state for sending messages.
 *  @retval  other Inet layer errors related to the TCP endpoint.
 *
 */

WEAVE_ERROR WeaveTunnelAgent::ConfigurePrimaryTunnelTimeout(uint16_t maxTimeoutSecs)
{
    return mPrimaryTunConnMgr.ConfigureConnTimeout(maxTimeoutSecs);
}
#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
/**
 *  Configure and enable the TCP keepalive option on the primary
 *  tunnel connection.
 *
 *  @param[in]  keepAliveIntervalSecs
 *    The interval (in seconds) between keepalive probes.  This value also controls
 *    the time between last data packet sent and the transmission of the first keepalive
 *    probe.
 *
 *  @retval  #WEAVE_NO_ERROR                     on successful enabling of TCP keepalive probes
 *                                               on the connection.
 *  @retval  #WEAVE_ERROR_INCORRECT_STATE        if the WeaveConnection object is not
 *                                               in the correct state for sending messages.
 *  @retval  other Inet layer errors related to the TCP endpoint enable keepalive operation.
 *
 */
WEAVE_ERROR WeaveTunnelAgent::ConfigureAndEnablePrimaryTunnelTCPKeepAlive(uint16_t keepAliveIntervalSecs,
                                                                          uint16_t maxNumProbes)
{
    return mPrimaryTunConnMgr.ConfigureAndEnableTCPKeepAlive(keepAliveIntervalSecs,
                                                             maxNumProbes);
}
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
 * Configure the Primary Tunnel Liveness interval.
 */
void WeaveTunnelAgent::ConfigurePrimaryTunnelLivenessInterval(uint16_t livenessIntervalSecs)
{
    mPrimaryTunConnMgr.ConfigureTunnelLivenessInterval(livenessIntervalSecs);
}
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

/**
 *  Check if the primary tunnel is enabled.
 *
 *  @return true if it is enabled, else false.
 */
bool WeaveTunnelAgent::IsPrimaryTunnelEnabled(void) const
{
    return GetFlag(mTunnelFlags, kTunnelFlag_PrimaryEnabled);
}

/**
 *  Enable the Primary Tunnel.
 *
 *  @note
 *    This is a configuration change only and the tunnel needs to be
 *    explicitly started by calling StartServiceTunnel().
 */
void WeaveTunnelAgent::EnablePrimaryTunnel(void)
{
    SetFlag(mTunnelFlags, kTunnelFlag_PrimaryEnabled, true);
}

/**
 *  Disable the Primary Tunnel.
 *
 *  @note
 *    This is a configuration change only and the tunnel needs to be
 *    explicitly stopped by calling StopServiceTunnel().
 */
void WeaveTunnelAgent::DisablePrimaryTunnel(void)
{
    SetFlag(mTunnelFlags, kTunnelFlag_PrimaryEnabled, false);
}

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

/**
 *  Check if the backup tunnel is enabled.
 *
 *  @return true if it is enabled, else false.
 */
bool WeaveTunnelAgent::IsBackupTunnelEnabled(void) const
{
    return GetFlag(mTunnelFlags, kTunnelFlag_BackupEnabled);
}

/**
 *  Enable the Backup Tunnel.
 *
 *  @note
 *    This is a configuration change only and the tunnel needs to be
 *    explicitly started by calling StartServiceTunnel().
 */
void WeaveTunnelAgent::EnableBackupTunnel(void)
{
    SetFlag(mTunnelFlags, kTunnelFlag_BackupEnabled, true);
}

/**
 *  Disable the Backup Tunnel.
 *
 *  @note
 *    This is a configuration change only and the tunnel needs to be
 *    explicitly stopped by calling StopServiceTunnel().
 */
void WeaveTunnelAgent::DisableBackupTunnel(void)
{
    SetFlag(mTunnelFlags, kTunnelFlag_BackupEnabled, false);
}

/**
 *  Start the Primary Tunnel.
 *
 *
 */
void WeaveTunnelAgent::StartPrimaryTunnel(void)
{
    // Abort the primary tunnel if there is an outstanding connection.

    StopPrimaryTunnel();

    EnablePrimaryTunnel();

    // Try establishing the primary tunnel.

    mPrimaryTunConnMgr.ScheduleConnect(CONNECT_NO_DELAY);
}

/**
 *  Stop the Primary Tunnel.
 *
 */
void WeaveTunnelAgent::StopPrimaryTunnel(void)
{
    DisablePrimaryTunnel();

    // Abort the primary tunnel if there is an outstanding connection.

    mPrimaryTunConnMgr.ServiceTunnelClose(WEAVE_ERROR_TUNNEL_FORCE_ABORT);
}

/**
 *  Enable the Backup Tunnel.
 */
void WeaveTunnelAgent::StartBackupTunnel(void)
{
    // Abort the backup tunnel if there is an outstanding connection.

    StopBackupTunnel();

    EnableBackupTunnel();

    // Try establishing the backup tunnel.

    mBackupTunConnMgr.ScheduleConnect(CONNECT_NO_DELAY);
}

/**
 *  Disable the Backup Tunnel.
 */
void WeaveTunnelAgent::StopBackupTunnel(void)
{
    // Stop the Backup tunnel connection.

    DisableBackupTunnel();

    mBackupTunConnMgr.ServiceTunnelClose(WEAVE_ERROR_TUNNEL_FORCE_ABORT);
}

#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
/**
 *  Configure the TCP user timeout option on the backup tunnel connection.
 *
 *  @param[in]  maxTimeoutSecs
 *    The maximum timeout for the TCP connection.
 *
 *  @retval  #WEAVE_NO_ERROR                     on successful configuration.
 *  @retval  #WEAVE_ERROR_INCORRECT_STATE        if the WeaveConnection object is not
 *                                               in the correct state for sending messages.
 *  @retval  other Inet layer errors related to the TCP endpoint.
 *
 */

WEAVE_ERROR WeaveTunnelAgent::ConfigureBackupTunnelTimeout(uint16_t maxTimeoutSecs)
{
    return mBackupTunConnMgr.ConfigureConnTimeout(maxTimeoutSecs);
}
#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
/**
 *  Configure and enable the TCP keepalive option on the primary
 *  tunnel connection.
 *
 *  @param[in]  keepAliveIntervalSecs
 *    The interval (in seconds) between keepalive probes.  This value also controls
 *    the time between last data packet sent and the transmission of the first keepalive
 *    probe.
 *
 *  @retval  #WEAVE_NO_ERROR                     on successful enabling of TCP keepalive probes
 *                                               on the connection.
 *  @retval  #WEAVE_ERROR_INCORRECT_STATE        if the WeaveConnection object is not
 *                                               in the correct state for sending messages.
 *  @retval  other Inet layer errors related to the TCP endpoint enable keepalive operation.
 *
 */
WEAVE_ERROR WeaveTunnelAgent::ConfigureAndEnableBackupTunnelTCPKeepAlive(uint16_t keepAliveIntervalSecs,
                                                                         uint16_t maxNumProbes)
{
    return mBackupTunConnMgr.ConfigureAndEnableTCPKeepAlive(keepAliveIntervalSecs,
                                                            maxTimeoutSecs);
}
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
 * Configure the Backup Tunnel Liveness interval.
 */
void WeaveTunnelAgent::ConfigureBackupTunnelLivenessInterval(uint16_t livenessIntervalSecs)
{
    mBackupTunConnMgr.ConfigureTunnelLivenessInterval(livenessIntervalSecs);
}
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

/**
 * Start the Service Tunnel. This tries to establish a connection to the Service and also
 * sets the fabric route to the tunnel interface.
 *
 * @return WEAVE_NO_ERROR on success, else a corresponding WEAVE_ERROR type.
 */
WEAVE_ERROR WeaveTunnelAgent::StartServiceTunnel (void)
{
    return StartServiceTunnel(mPeerNodeId, mServiceAddress, mAuthMode);
}

/**
 * Start the Service Tunnel. This tries to establish a connection to the Service and also
 * sets the fabric route to the tunnel interface.
 *
 * @param[in] dstNodeId                    Node ID of the destination node.
 *
 * @param[in] dstIPAddr                    IP address of the destination node.
 *
 * @param[in] authMode                     Weave authentication mode used with peer.
 *
 *
 * @return WEAVE_NO_ERROR
 */
WEAVE_ERROR WeaveTunnelAgent::StartServiceTunnel(uint64_t dstNodeId,
                                                 IPAddress dstIPAddr,
                                                 WeaveAuthMode authMode)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Set the parameters

    mPeerNodeId              = dstNodeId;
    mServiceAddress          = dstIPAddr;
    mAuthMode                = authMode;

    // Make sure that the Weave Tunnel Agent has been initialized.
    VerifyOrExit(mTunAgentState != kState_NotInitialized,
                 err = WEAVE_ERROR_INCORRECT_STATE);

    // Abort any outstanding connections, if any, and reap resources.
    if (mTunAgentState > kState_Initialized_NoTunnel)
    {
        mPrimaryTunConnMgr.ReleaseResourcesAndStopTunnelConn(WEAVE_ERROR_TUNNEL_FORCE_ABORT);

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
        mBackupTunConnMgr.ReleaseResourcesAndStopTunnelConn(WEAVE_ERROR_TUNNEL_FORCE_ABORT);
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    }

    // Initiate TCP connection with Service and route exchange.

    if (IsPrimaryTunnelEnabled())
    {
        mPrimaryTunConnMgr.ScheduleConnect(CONNECT_NO_DELAY);
    }

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    if (IsBackupTunnelEnabled())
    {
        mBackupTunConnMgr.ScheduleConnect(CONNECT_NO_DELAY);
    }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

exit:
    return err;
}

/**
 * Close the Tunnel connection to the Service.
 *
 * @return void
 */
void WeaveTunnelAgent::StopServiceTunnel(void)
{
    StopServiceTunnel(WEAVE_NO_ERROR);
}

/**
 * Close the Tunnel connection to the Service.
 *
 * @param[in] err WEAVE_NO_ERROR if there is no specific reason for this
 *   StopServiceTunnel request, otherwise the cause of error would be passed down.
 *
 * @return void
 */
void WeaveTunnelAgent::StopServiceTunnel(WEAVE_ERROR err)
{
    // Set the WeaveTunnelAgent state to indicate that tunneling is disabled.

    // Send a Tunnel Close control message

    if (IsPrimaryTunnelEnabled())
    {
        mPrimaryTunConnMgr.ServiceTunnelClose(err);
    }

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    if (IsBackupTunnelEnabled())
    {
        mBackupTunConnMgr.ServiceTunnelClose(err);
    }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

}

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
/**
 * Get the WeaveTunnel statistics counters.
 *
 * @param[out] tunnelStats  A reference to the WeaveTunnelStatistics structure.
 *
 * @return WEAVE_ERROR  Weave error encountered when getting tunnel statistics.
 *
 */
WEAVE_ERROR WeaveTunnelAgent::GetWeaveTunnelStatistics(WeaveTunnelStatistics &tunnelStats)
{
    memcpy(&tunnelStats, &mWeaveTunnelStats, sizeof(WeaveTunnelStatistics));

    return WEAVE_NO_ERROR;
}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

void WeaveTunnelAgent::SetState(AgentState toState)
{

    WeaveLogDetail(WeaveTunnel, "FromState:%s ToState:%s\n", GetAgentStateName(mTunAgentState),
                                 GetAgentStateName(toState));
    mTunAgentState = toState;
}

/**
 * Parse the destination IP address of an IP packet within a PacketBuffer.
 *
 * @param[in]  inMsg        A constant reference to the PacketBuffer object containing the IPv6 packet.
 *
 * @param[out] outDest      A reference to the IPaddress object holding the destination address.
 *
 * @return void
 */
void WeaveTunnelAgent::ParseDestinationIPAddress(const PacketBuffer &inMsg, IPAddress &outDest)
{
    const uint8_t     *p   = NULL;
    struct ip6_hdr *ip6hdr = NULL;
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    ip6_addr_t ipv6Addr;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Extract the IPv6 header to look at the destination address

    p = inMsg.Start();
    ip6hdr = (struct ip6_hdr *)p;

    // Check destination address
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    ip6_addr_copy(ipv6Addr, ip6hdr->dest);
    outDest = IPAddress::FromIPv6(ipv6Addr);
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
    outDest = IPAddress::FromIPv6(ip6hdr->ip6_dst);
#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP
}

/**
 * Handler to receive IPv6 packets from the Tunnel EndPoint interface and forward, either to the Service
 * via the Service TCP connection after encapsulating IPv6 packet inside the tunnel header or to the Mobile
 * client over a local tunnel. If the Service connection is not yet up, the message is queued until the
 * connection is set up. For tunneling to the Mobile client device, the nexthop neighbor table is referenced.
 *
 * @param[in] tunEP                        A pointer to the TunEndPoint object.
 *
 * @param[in] message                      A pointer to the PacketBuffer object holding the raw IPv6 packet.
 *
 * @return void
 */
void WeaveTunnelAgent::RecvdFromTunnelEndPoint(TunEndPoint *tunEP, PacketBuffer *msg)
{
    WEAVE_ERROR err             = WEAVE_NO_ERROR;
    uint64_t nodeId;
    IPAddress destIP6Addr;
    WeaveTunnelAgent *tAgent    = static_cast<WeaveTunnelAgent *>(tunEP->AppState);

    tAgent->ParseDestinationIPAddress(*msg, destIP6Addr);

    err = tAgent->AddTunnelHdrToMsg(msg);
    SuccessOrExit(err);

    nodeId = destIP6Addr.InterfaceId();
    if (destIP6Addr.Subnet() == kWeaveSubnetId_Service)
    {
        // Destined for Service

        err = tAgent->HandleSendingToService(msg);
        msg = NULL;
        SuccessOrExit(err);
    }
    else if (destIP6Addr.Subnet() == kWeaveSubnetId_MobileDevice)
    {
        if (tAgent->mRole == kClientRole_BorderGateway)
        {
            // Decide based on lookup of nexthop table and send locally
            // via UDP tunnel or remotely via Service TCP connection.

            err = tAgent->DecideAndSendShortcutOrRemoteTunnel(nodeId, msg);
            msg = NULL;
            SuccessOrExit(err);
        }
    }
    else if ((destIP6Addr.Subnet() == kWeaveSubnetId_PrimaryWiFi) ||
             (destIP6Addr.Subnet() == kWeaveSubnetId_ThreadMesh))
    {
        // Generated locally on Mobile phone; Needs to go via local tunnel or Service

        if (tAgent->mRole == kClientRole_MobileDevice)
        {
            // Decide based on lookup of nexthop table and send locally
            // via UDP tunnel or remotely via Service TCP connection.

            err = tAgent->DecideAndSendShortcutOrRemoteTunnel(tAgent->mExchangeMgr->FabricState->FabricId, msg);
            msg = NULL;
            SuccessOrExit(err);
        }
    }

exit:
    if (msg != NULL)
    {
        PacketBuffer::Free(msg);

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        // Update tunnel statistics
        tAgent->mWeaveTunnelStats.mDroppedMessagesCount++;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    }

    return;
}

/**
 * Handler to receive tunneled IPv6 packets from the Service TCP connection and forward to the Tunnel
 * EndPoint interface after decapsulating the raw IPv6 packet from inside the tunnel header.
 *
 * @param[in] con                          A pointer to the WeaveConnection object.
 *
 * @param[in] msgInfo                      A pointer to the WeaveMessageInfo object.
 *
 * @param[in] message                      A pointer to the PacketBuffer object holding the tunneled IPv6 packet.
 *
 * @return void
 */
void WeaveTunnelAgent::RecvdFromShortcutUDPTunnel(WeaveMessageLayer *msgLayer, PacketBuffer *msg)
{
    WeaveTunnelAgent *tAgent = static_cast<WeaveTunnelAgent *>(msgLayer->AppState);

    tAgent->HandleTunneledReceive(msg, kType_TunnelShortcut);

    return;
}

/**
 * Get the WeaveTunnelAgentState name
 *
 */
const char *WeaveTunnelAgent::GetAgentStateName(const AgentState state)
{

    switch (state)
    {
      case kState_NotInitialized                       : return "NotInitialized";
      case kState_Initialized_NoTunnel                 : return "Initialized_NoTunnel";
      case kState_PrimaryTunModeEstablished            : return "PrimaryTunnelEstablished";
      case kState_BkupOnlyTunModeEstablished           : return "BackupTunnelEstablished";
      case kState_PrimaryAndBkupTunModeEstablished     : return "PrimaryAndBackupTunnelEstablished";
    }

    return NULL;
}

/* Create a new Tunnel endpoint */
WEAVE_ERROR WeaveTunnelAgent::CreateTunEndPoint(void)
{
    WEAVE_ERROR res = WEAVE_NO_ERROR;

    res = mInet->NewTunEndPoint(&mTunEP);
    SuccessOrExit(res);

    mTunEP->Init(mInet);

exit:

    return res;
}

/* Setup the TunEndPoint interface and configure the link-local address and fabric default route */
WEAVE_ERROR WeaveTunnelAgent::SetupTunEndPoint(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    err = mTunEP->Open();
#else
    err = mTunEP->Open(mIntfName);
#endif
    SuccessOrExit(err);

    if (!mTunEP->IsInterfaceUp())
    {
        // Bring interface up

        err = mTunEP->InterfaceUp();
        SuccessOrExit(err);
    }

    // Perform address and route additions when tunnel interface is
    // brought up.

    Platform::TunnelInterfaceUp(mTunEP->GetTunnelInterfaceId());

exit:
    if (err != WEAVE_NO_ERROR)
    {
        mTunEP->Free();
        mTunEP = NULL;
    }

    return err;
}

/* Tear down TunEndpoint interface and remove the link-local address and fabric default route */
WEAVE_ERROR WeaveTunnelAgent::TeardownTunEndPoint(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (mTunEP != NULL)
    {
        // Perform address and route deletions when tunnel interface is
        // brought down.

        Platform::TunnelInterfaceDown(mTunEP->GetTunnelInterfaceId());

        if (mTunEP->IsInterfaceUp())
        {
            // Bring interface down

            err = mTunEP->InterfaceDown();
        }
        // Free Tunnel Endpoint

        mTunEP->Free();
        mTunEP = NULL;
    }

    return err;
}

/* Utility function for populating a message header */
void WeaveTunnelAgent::PopulateTunnelMsgHeader(WeaveMessageInfo *msgInfo,
                                               const WeaveTunnelConnectionMgr *connMgr)
{
    msgInfo->Clear();

    // Set to no-encryption when not using a tunnel to the Service

    if (!connMgr)
    {
        msgInfo->KeyId            = WeaveKeyId::kNone;
        msgInfo->EncryptionType   = kWeaveEncryptionType_None;
    }
    else
    {
        msgInfo->KeyId = connMgr->mServiceCon->DefaultKeyId;
        msgInfo->EncryptionType = connMgr->mServiceCon->DefaultEncryptionType;
    }

    // Set the source node id

    msgInfo->SourceNodeId = mExchangeMgr->FabricState->LocalNodeId;
}

/* Prepare message for tunneling by encapsulating in the tunnel header */
WEAVE_ERROR WeaveTunnelAgent::AddTunnelHdrToMsg(PacketBuffer *msg)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    WeaveTunnelHeader tunHeader;

    // Ensure Reserved size for Tunnel header

    msg->EnsureReservedSize(TUN_HDR_SIZE_IN_BYTES);

    // Set version to V1

    tunHeader.Version = kWeaveTunnelVersion_V1;

    // Encapsulate with Tunnel Header and metadata

    err = WeaveTunnelHeader::EncodeTunnelHeader(&tunHeader, msg);

    return err;
}

WEAVE_ERROR WeaveTunnelAgent::SendMessageUponPktTransitAnalysis(const WeaveTunnelConnectionMgr *connMgr,
                                                                TunnelPktDirection pktDir,
                                                                TunnelType tunType,
                                                                WeaveMessageInfo *msgInfo,
                                                                PacketBuffer *msg,
                                                                bool &dropPacket)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t msgLen = 0;

#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    if (OnTunneledPacketTransit)
    {
        // Skip the Tunnel header and send the IP packet.
        OnTunneledPacketTransit(*msg, pktDir, tunType, dropPacket);
    }
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK

    if (!dropPacket)
    {
        msgLen = msg->DataLength();
        err = connMgr->mServiceCon->SendTunneledMessage(msgInfo, msg);
        SuccessOrExit(err);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        UpdateOutboundMessageStatistics(connMgr->mTunType, msgLen);
        mWeaveTunnelStats.mCurrentActiveTunnel = connMgr->mTunType;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
        // Received message over tunnel. Restart the liveness timer.

        RestartTunnelLivenessTimer(tunType);
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

    }

exit:
    return err;
}

/* Prepare message and send to Service via Remote tunnel */
WEAVE_ERROR WeaveTunnelAgent::HandleSendingToService(PacketBuffer *msg)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    bool dropPacket = false;

    if (mPrimaryTunConnMgr.mConnectionState != WeaveTunnelConnectionMgr::kState_TunnelOpen
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
        && mBackupTunConnMgr.mConnectionState != WeaveTunnelConnectionMgr::kState_TunnelOpen
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
       )
    {
        // Enqueue message until Service tunnel established

        WeaveLogDetail(WeaveTunnel, "Tunnel connection not up: Enqueuing message\n");
        err = EnQueuePacket(msg);

        if (err == WEAVE_NO_ERROR)
        {
            msg = NULL;
        }

        ExitNow();
    }

    // Send on primary tunnel if open; else send over backup tunnel

    if (mPrimaryTunConnMgr.mConnectionState == WeaveTunnelConnectionMgr::kState_TunnelOpen)
    {
        WeaveMessageInfo msgInfo;

        PopulateTunnelMsgHeader(&msgInfo, &mPrimaryTunConnMgr);

        err = SendMessageUponPktTransitAnalysis(&mPrimaryTunConnMgr, kDir_Outbound, kType_TunnelPrimary,
                                                &msgInfo, msg, dropPacket);
    }
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    else if (mBackupTunConnMgr.mConnectionState == WeaveTunnelConnectionMgr::kState_TunnelOpen)
    {
        WeaveMessageInfo msgInfo;

        PopulateTunnelMsgHeader(&msgInfo, &mBackupTunConnMgr);

        err = SendMessageUponPktTransitAnalysis(&mBackupTunConnMgr, kDir_Outbound, kType_TunnelBackup,
                                                &msgInfo, msg, dropPacket);
    }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

    if (!dropPacket)
    {
        msg = NULL;
    }

exit:
    if (msg != NULL || dropPacket)
    {
        PacketBuffer::Free(msg);

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        // Update tunnel statistics
        mWeaveTunnelStats.mDroppedMessagesCount++;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    }

    return err;
}

/* Prepare message and send to Service via Remote tunnel */
WEAVE_ERROR WeaveTunnelAgent::DecideAndSendShortcutOrRemoteTunnel(uint64_t peerId, PacketBuffer *msg)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    bool dropPacket = false;

#if WEAVE_CONFIG_TUNNEL_SHORTCUT_SUPPORTED

    // Lookup nexthop table

    if (mTunShortcutControl.IsPeerInShortcutTunnelCache(peerId))
    {
        WeaveMessageInfo msgInfo;

        PopulateTunnelMsgHeader(&msgInfo, NULL);

#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
        if (OnTunneledPacketTransit)
        {
            // Skip the Tunnel header and send the IP packet.
            OnTunneledPacketTransit(*msg, kDir_Outbound, kType_TunnelShortcut, dropPacket);
        }
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK

        // Send over UDP tunnel

        if (!dropPacket)
        {
            err = mTunShortcutControl.SendMessageOverTunnelShortcut(peerId, &msgInfo, msg);
            msg = NULL;
        }
    }
    else
#endif // WEAVE_CONFIG_TUNNEL_SHORTCUT_SUPPORTED
    {
        // Not found in nexthop table; default to sending to Service

        err = HandleSendingToService(msg);
        msg = NULL;
    }

    if (msg != NULL || dropPacket)
    {
        PacketBuffer::Free(msg);

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        // Update tunnel statistics
        mWeaveTunnelStats.mDroppedMessagesCount++;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    }

    return err;
}

/* handle a message received over tunnel and decode tunnel header and send
 * via appropriate interface */
WEAVE_ERROR WeaveTunnelAgent::HandleTunneledReceive(PacketBuffer *msg, TunnelType tunType)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    IPAddress destIP6Addr;
    WeaveTunnelHeader tunHeader;
    bool dropPacket = false;

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    WeaveTunnelCommonStatistics *tunStats = NULL;

    // Update tunnel statistics
    tunStats = GetCommonTunnelStatistics(tunType);

    if (tunStats != NULL)
    {
        tunStats->mRxBytesFromService += msg->DataLength();
        tunStats->mRxMessagesFromService++;
    }

    mWeaveTunnelStats.mCurrentActiveTunnel = tunType;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    if (OnTunneledPacketTransit)
    {
        OnTunneledPacketTransit(*msg, kDir_Inbound, tunType, dropPacket);
    }

    if (dropPacket)
    {
        ExitNow();
    }
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK

    // Decapsulate Tunnel header

    err = WeaveTunnelHeader::DecodeTunnelHeader(&tunHeader, msg);
    SuccessOrExit(err);

    ParseDestinationIPAddress(*msg, destIP6Addr);

    // Send down Tunnel Endpoint to be routed out to peripheral networks for
    // the Border gateway, or to percolate up the LwIP stack to the application
    // for the Mobile device.

    if (destIP6Addr.Subnet() == kWeaveSubnetId_MobileDevice ||
        destIP6Addr.Subnet() == kWeaveSubnetId_PrimaryWiFi ||
        destIP6Addr.Subnet() == kWeaveSubnetId_ThreadMesh)
    {
        mTunEP->Send(msg);
        msg = NULL;
    }

exit:

    if (msg != NULL || dropPacket)
    {
        WeaveLogProgress(WeaveTunnel, "Msg Rx Err %d", err);
        PacketBuffer::Free(msg);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        // Update tunnel statistics
        mWeaveTunnelStats.mDroppedMessagesCount++;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
    }

    return err;
}

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
WeaveTunnelCommonStatistics *WeaveTunnelAgent::GetCommonTunnelStatistics(const TunnelType tunType)
{
    WeaveTunnelCommonStatistics *tunStats = NULL;

    switch (tunType)
    {
      case kType_TunnelPrimary:
        tunStats = &mWeaveTunnelStats.mPrimaryStats;
        break;

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
      case kType_TunnelBackup:
        tunStats = &mWeaveTunnelStats.mBackupStats;
        break;
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
      default:
        break;
    }

    return tunStats;
}

void WeaveTunnelAgent::UpdateOutboundMessageStatistics(const TunnelType tunType, const uint64_t msgLen)
{
    WeaveTunnelCommonStatistics *tunStats = NULL;

    // Update tunnel statistics
    tunStats = GetCommonTunnelStatistics(tunType);

    if (tunStats != NULL)
    {
        tunStats->mTxBytesToService += msgLen;
        tunStats->mTxMessagesToService++;
    }
}

void WeaveTunnelAgent::UpdateTunnelDownStatistics(const TunnelType tunType, const WEAVE_ERROR conErr)
{
    WeaveTunnelCommonStatistics *tunStats = NULL;
    // Update tunnel statistics
    tunStats = GetCommonTunnelStatistics(tunType);

    if (tunStats != NULL)
    {
        tunStats->mTunnelDownCount++;
        tunStats->mLastTunnelDownError = conErr;
        tunStats->mLastTimeTunnelWentDown = GetTimeMsec();
    }
}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

/* Queue packet for Remote tunnel connection to get established */
WEAVE_ERROR WeaveTunnelAgent::EnQueuePacket(PacketBuffer *pkt)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if ((qFront == qRear + 1) || (qFront == 0 && qRear == WEAVE_CONFIG_TUNNELING_MAX_NUM_PACKETS_QUEUED - 1))
    {
        // Queue full;

        err = WEAVE_ERROR_TUNNEL_SERVICE_QUEUE_FULL;
        ExitNow();
    }
    else
    {
        if (qFront == TUNNEL_PACKET_QUEUE_INVALID_INDEX)
        {
            qFront = 0;
        }
        qRear = (qRear + 1) % WEAVE_CONFIG_TUNNELING_MAX_NUM_PACKETS_QUEUED;
        queuedMsgs[qRear] = pkt;
    }

exit:

    return err;
}

void WeaveTunnelAgent::DumpQueuedMessages(void)
{
    PacketBuffer *queuedPkt = NULL;

    while (qFront != TUNNEL_PACKET_QUEUE_INVALID_INDEX)
    {
        queuedPkt = DeQueuePacket();
        if (queuedPkt)
        {
            PacketBuffer::Free(queuedPkt);

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
            // Update tunnel statistics
            mWeaveTunnelStats.mDroppedMessagesCount++;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

            queuedPkt = NULL;
        }
    }
}

/* Dequeue a packet for sending via Service tunnel */
PacketBuffer *WeaveTunnelAgent::DeQueuePacket(void)
{
    PacketBuffer *retPkt = NULL;
    if (qFront != TUNNEL_PACKET_QUEUE_INVALID_INDEX)
    {
        retPkt = queuedMsgs[qFront];
        if (qFront == qRear) // Only one packet in queue
        {
            qFront = TUNNEL_PACKET_QUEUE_INVALID_INDEX;
            qRear  = TUNNEL_PACKET_QUEUE_INVALID_INDEX;
        }
        else
        {
            qFront = (qFront + 1) % WEAVE_CONFIG_TUNNELING_MAX_NUM_PACKETS_QUEUED;
        }
    }

    return retPkt;
}

/* Flush queued messages that were pending because Service tunnel
 * was not setup */
void WeaveTunnelAgent::SendQueuedMessages(const WeaveTunnelConnectionMgr *connMgr)
{
    WeaveMessageInfo  msgInfo;
    PacketBuffer*     queuedPkt   = NULL;

    while ((queuedPkt = DeQueuePacket()) != NULL)
    {
        PopulateTunnelMsgHeader(&msgInfo, connMgr);

        // Send over TCP Connection

        msgInfo.DestNodeId = connMgr->mServiceCon->PeerNodeId;
        connMgr->mServiceCon->SendTunneledMessage(&msgInfo, queuedPkt);

#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
        UpdateOutboundMessageStatistics(connMgr->mTunType, queuedPkt->DataLength());
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

        queuedPkt = NULL;
    }

    return;
}

/* Post processing function after Tunnel has been opened */
void WeaveTunnelAgent::WeaveTunnelConnectionUp(const WeaveMessageInfo *msgInfo,
                                               const WeaveTunnelConnectionMgr *connMgr,
                                               const bool isRoutingRestricted)
{
   // Update the Weave Tunnel Agent mode on tunnel establishment.

    switch (mTunAgentState)
    {
      case kState_Initialized_NoTunnel:
          // When Primary tunnel is established

          if (connMgr->mTunType == kType_TunnelPrimary)
          {
              WeaveTunnelUpNotifyAndSetState(kState_PrimaryTunModeEstablished,
                                             Platform::kMode_Primary,
                                             WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp,
                                             &mPrimaryTunConnMgr,
                                             isRoutingRestricted);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              // Update tunnel statistics
              mWeaveTunnelStats.mPrimaryStats.mLastTimeTunnelEstablished = GetTimeMsec();
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelPrimary;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          else if (connMgr->mTunType == kType_TunnelBackup)
          {
              WeaveTunnelUpNotifyAndSetState(kState_BkupOnlyTunModeEstablished,
                                             Platform::kMode_BackupOnly,
                                             WeaveTunnelConnectionMgr::kStatus_TunBackupUp,
                                             &mBackupTunConnMgr,
                                             isRoutingRestricted);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              // Update tunnel statistics
              mWeaveTunnelStats.mBackupStats.mLastTimeTunnelEstablished = GetTimeMsec();
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelBackup;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

          break;

      case kState_PrimaryTunModeEstablished:
          if (connMgr->mTunType == kType_TunnelPrimary)
          {
              WeaveTunnelUpNotifyAndSetState(kState_PrimaryTunModeEstablished,
                                             Platform::kMode_Primary,
                                             WeaveTunnelConnectionMgr::kStatus_TunPrimaryUp,
                                             &mPrimaryTunConnMgr,
                                             isRoutingRestricted);
          }
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          // When BackUp tunnel is established after Primary
          if (connMgr->mTunType == kType_TunnelBackup)
          {
              WeaveTunnelUpNotifyAndSetState(kState_PrimaryAndBkupTunModeEstablished,
                                             Platform::kMode_PrimaryAndBackup,
                                             WeaveTunnelConnectionMgr::kStatus_TunPrimaryAndBackupUp,
                                             &mBackupTunConnMgr,
                                             isRoutingRestricted);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              // Update tunnel statistics
              mWeaveTunnelStats.mBackupStats.mLastTimeTunnelEstablished = GetTimeMsec();
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

          break;

      case kState_BkupOnlyTunModeEstablished:
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          // When Primary tunnel is established after Backup

          if (connMgr->mTunType == kType_TunnelPrimary)
          {
              WeaveTunnelUpNotifyAndSetState(kState_PrimaryAndBkupTunModeEstablished,
                                             Platform::kMode_PrimaryAndBackup,
                                             WeaveTunnelConnectionMgr::kStatus_TunPrimaryAndBackupUp,
                                             &mPrimaryTunConnMgr,
                                             isRoutingRestricted);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              // Update tunnel statistics
              mWeaveTunnelStats.mBackupStats.mLastTimeTunnelEstablished = GetTimeMsec();
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelPrimary;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
          else if (connMgr->mTunType == kType_TunnelBackup)
          {
              WeaveTunnelUpNotifyAndSetState(kState_BkupOnlyTunModeEstablished,
                                             Platform::kMode_BackupOnly,
                                             WeaveTunnelConnectionMgr::kStatus_TunBackupUp,
                                             &mBackupTunConnMgr,
                                             isRoutingRestricted);
          }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          break;

      case kState_PrimaryAndBkupTunModeEstablished:

          break;

      default:
        break;
    }
}

/* Tunnel connection error notifier */
void WeaveTunnelAgent::WeaveTunnelConnectionErrorNotify(const WeaveTunnelConnectionMgr *connMgr, WEAVE_ERROR conErr)
{
    if (OnServiceTunStatusNotify)
    {
        if (connMgr->mTunType == kType_TunnelPrimary)
        {
            OnServiceTunStatusNotify(WeaveTunnelConnectionMgr::kStatus_TunPrimaryConnError, conErr, mAppContext);
        }
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
        else if (connMgr->mTunType == kType_TunnelBackup)
        {
            OnServiceTunStatusNotify(WeaveTunnelConnectionMgr::kStatus_TunBackupConnError, conErr, mAppContext);
        }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    }
}

void WeaveTunnelAgent::WeaveTunnelServiceReconnectRequested(const WeaveTunnelConnectionMgr *connMgr,
                                                            const char *reconnectHost,
                                                            const uint16_t reconnectPort)
{
    if (OnServiceTunReconnectNotify)
    {
        // Call application handler to report connection closing.

        OnServiceTunReconnectNotify(connMgr->mTunType, reconnectHost, reconnectPort, mAppContext);
    }
}

/* Post processing function after Tunnel has been closed */
void WeaveTunnelAgent::WeaveTunnelConnectionDown(const WeaveTunnelConnectionMgr *connMgr, WEAVE_ERROR conErr)
{
    // Update the Weave Tunnel mode and the Agent state upon tunnel closure.

    switch (mTunAgentState)
    {
      case kState_Initialized_NoTunnel:

          WeaveTunnelDownNotifyAndSetState(conErr);

          break;

      case kState_PrimaryTunModeEstablished:
          // When Primary tunnel fails

          if (connMgr->mTunType == kType_TunnelPrimary)
          {
              WeaveTunnelDownNotifyAndSetState(conErr);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              UpdateTunnelDownStatistics(kType_TunnelPrimary, conErr);
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelUnknown;
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
              mWeaveTunnelStats.mLastTimeWhenPrimaryAndBackupWentDown = GetTimeMsec();
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
          break;

      case kState_BkupOnlyTunModeEstablished:
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          // When Backup tunnel fails

          if (connMgr->mTunType == kType_TunnelBackup)
          {
              WeaveTunnelDownNotifyAndSetState(conErr);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              UpdateTunnelDownStatistics(kType_TunnelBackup, conErr);
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelUnknown;
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
              mWeaveTunnelStats.mLastTimeWhenPrimaryAndBackupWentDown = GetTimeMsec();
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          break;

      case kState_PrimaryAndBkupTunModeEstablished:
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          // When Primary tunnel fails

          if (connMgr->mTunType == kType_TunnelPrimary)
          {
              WeaveTunnelModeChangeNotifyAndSetState(kState_BkupOnlyTunModeEstablished,
                                                     Platform::kMode_BackupOnly,
                                                     WeaveTunnelConnectionMgr::kStatus_TunFailoverToBackup,
                                                     conErr);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              // Update tunnel statistics
              UpdateTunnelDownStatistics(kType_TunnelPrimary, conErr);
              mWeaveTunnelStats.mTunnelFailoverCount++;
              mWeaveTunnelStats.mLastTimeForTunnelFailover = GetTimeMsec();
              mWeaveTunnelStats.mLastTunnelFailoverError = conErr;
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelBackup;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS

          }
          else if (connMgr->mTunType == kType_TunnelBackup)
          {
              WeaveTunnelModeChangeNotifyAndSetState(kState_PrimaryTunModeEstablished,
                                                     Platform::kMode_Primary,
                                                     WeaveTunnelConnectionMgr::kStatus_TunBackupOnlyDown,
                                                     conErr);
#if WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
              UpdateTunnelDownStatistics(kType_TunnelBackup, conErr);
              mWeaveTunnelStats.mCurrentActiveTunnel = kType_TunnelPrimary;
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_STATISTICS
          }
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          break;

      default:
        break;
    }
}

void WeaveTunnelAgent::RemovePlatformTunnelRoute(void)
{
    // Notify platform about tunnel disconnection

    Platform::ServiceTunnelDisconnected(mTunEP->GetTunnelInterfaceId());
}

void WeaveTunnelAgent::WeaveTunnelDownNotifyAndSetState(WEAVE_ERROR conErr)
{
    // Change TunnelAgent state

    SetState(kState_Initialized_NoTunnel);

    // Remove Platform Tunnel Route

    RemovePlatformTunnelRoute();

    // When tunnel is down dump all queued messages

    DumpQueuedMessages();

    // Call application handler to report connection closing.

    if (OnServiceTunStatusNotify)
    {
       OnServiceTunStatusNotify(WeaveTunnelConnectionMgr::kStatus_TunDown, conErr, mAppContext);
    }
}

void WeaveTunnelAgent::WeaveTunnelUpNotifyAndSetState(AgentState state,
                                                      Platform::TunnelAvailabilityMode tunMode,
                                                      WeaveTunnelConnectionMgr::TunnelConnNotifyReasons notifyReason,
                                                      WeaveTunnelConnectionMgr *connMgr,
                                                      const bool isRoutingRestricted)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Change TunnelAgent state

    SetState(state);

    // Perform address and route additions when the Service tunnel connection
    // is established.

    if (isRoutingRestricted)
    {
        // Although tunnel is restricted, it is still open but can only be
        // usable by the border gateway for itself to access a limited set of
        // Service endpoints. The device is put in this mode, typically, when
        // it is unpaired from the account.

        err = WEAVE_ERROR_TUNNEL_ROUTING_RESTRICTED;

        WeaveLogDetail(WeaveTunnel, "Tunnel in restricted mode; Not operating as a Border Router\n");
    }
    else
    {
        // Add Platform Tunnel Route

        Platform::ServiceTunnelEstablished(mTunEP->GetTunnelInterfaceId(),
                                           tunMode);
    }

    // Check if queue is non-empty; then send queued packets through established tunnel;
    //
    // @note: Even if the tunnel is put in a restricted mode, we are sending
    // queued messages up the tunnel because it is not possible to ascertain
    // whether any of the queued packets are ones that this border router is forwarding
    // on behalf of a Thread device or its own packets. So, it is better to send these
    // across and have the Service decide to throw or accept.

    if (qFront != TUNNEL_PACKET_QUEUE_INVALID_INDEX)
    {
        SendQueuedMessages(connMgr);
    }

    // Notify application of successful tunnel establishment

    if (OnServiceTunStatusNotify)
    {
         OnServiceTunStatusNotify(notifyReason, err,
                                  mAppContext);
    }
}

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
void WeaveTunnelAgent::WeaveTunnelModeChangeNotifyAndSetState(AgentState state,
                                                              Platform::TunnelAvailabilityMode tunMode,
                                                              WeaveTunnelConnectionMgr::TunnelConnNotifyReasons notifyReason,
                                                              WEAVE_ERROR conErr)
{
    // Change TunnelAgent state

    SetState(state);

    // Notify platform about tunnel disconnection

    Platform::ServiceTunnelModeChange(mTunEP->GetTunnelInterfaceId(),
                                      tunMode);

    // Call application handler to report connection closing.

    if (OnServiceTunStatusNotify)
    {
       OnServiceTunStatusNotify(notifyReason, conErr, mAppContext);
    }
}
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
void WeaveTunnelAgent::RestartTunnelLivenessTimer(TunnelType tunType)
{
    switch (tunType)
    {
      case kType_TunnelPrimary:
        mPrimaryTunConnMgr.RestartLivenessTimer();
        break;

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
      case kType_TunnelBackup:
        mBackupTunConnMgr.RestartLivenessTimer();
        break;
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
      default:
        break;
    }
}

void WeaveTunnelAgent::NotifyTunnelLiveness(TunnelType tunType, WEAVE_ERROR err)
{
    if (OnServiceTunStatusNotify)
    {
        switch (tunType)
        {
          case kType_TunnelPrimary:
            OnServiceTunStatusNotify(WeaveTunnelConnectionMgr::kStatus_TunPrimaryLiveness, err, mAppContext);
            break;

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          case kType_TunnelBackup:
            OnServiceTunStatusNotify(WeaveTunnelConnectionMgr::kStatus_TunBackupLiveness, err, mAppContext);
            break;
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
          default:
            break;
        }
    }
}
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

/**
 * Get system time or monotonic time in milliseconds if system time is not available.
 *
 * @note
 *   If GetSystemTimeMs(..) fails we resort to use monotonic time. Fetching
 *   monotonic time in linux based systems uses an unspecified starting point
 *   that may not match with any expected epoch, e.g., system boottime.
 */
uint64_t WeaveTunnelAgent::GetTimeMsec(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint64_t time = 0;

    err = nl::Weave::Platform::Time::GetSystemTimeMs((Profiles::Time::timesync_t *)&time);

    if ((time == 0) || (err != WEAVE_NO_ERROR))
    {
        err = nl::Weave::Platform::Time::GetMonotonicRawTime((Profiles::Time::timesync_t *)&time);

        time = static_cast<uint64_t>(nl::Weave::Platform::DivideBy1000(time));
    }

    return time;
}

#endif // WEAVE_CONFIG_ENABLE_TUNNELING
