mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[utils] add 'Utils::PingSender' (#6284)
This commit adds a new module `Utils::PingSender`. This module is then used by CLI to support ping command.
This commit is contained in:
committed by
GitHub
parent
ae88a2c677
commit
06ca5d855c
@@ -188,6 +188,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/api/netdata_api.cpp \
|
||||
src/core/api/netdiag_api.cpp \
|
||||
src/core/api/network_time_api.cpp \
|
||||
src/core/api/ping_sender_api.cpp \
|
||||
src/core/api/random_crypto_api.cpp \
|
||||
src/core/api/random_noncrypto_api.cpp \
|
||||
src/core/api/server_api.cpp \
|
||||
@@ -331,6 +332,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/utils/lookup_table.cpp \
|
||||
src/core/utils/otns.cpp \
|
||||
src/core/utils/parse_cmdline.cpp \
|
||||
src/core/utils/ping_sender.cpp \
|
||||
src/core/utils/slaac_address.cpp \
|
||||
src/lib/hdlc/hdlc.cpp \
|
||||
src/lib/platform/exit_code.c \
|
||||
|
||||
@@ -257,6 +257,11 @@ if(OT_MULTIPLE_INSTANCE)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_PING_SENDER "enable ping sender support" ${OT_APP_CLI})
|
||||
if(OT_PING_SENDER)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_PLATFORM_NETIF "enable platform netif support")
|
||||
if(OT_PLATFORM_NETIF)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1")
|
||||
|
||||
@@ -204,6 +204,9 @@ if (openthread_enable_core_config_args) {
|
||||
# Enable SRP Server support
|
||||
openthread_config_srp_server_enable = false
|
||||
|
||||
# Enable ping sender support
|
||||
openthread_config_ping_sender = false
|
||||
|
||||
# Enable the time synchronization service feature
|
||||
openthread_config_time_sync_enable = false
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ LEGACY ?= 1
|
||||
LINK_RAW ?= 1
|
||||
MAC_FILTER ?= 1
|
||||
MTD_NETDIAG ?= 1
|
||||
PING_SENDER ?= 1
|
||||
REFERENCE_DEVICE ?= 1
|
||||
SERVICE ?= 1
|
||||
SNTP_CLIENT ?= 1
|
||||
|
||||
@@ -48,6 +48,7 @@ This page lists the available common switches with description. Unless stated ot
|
||||
| MLR | OT_MLR | Enables Multicast Listener Registration feature for Thread 1.2. |
|
||||
| MTD_NETDIAG | OT_MTD_NETDIAG | Enables the TMF network diagnostics on MTDs. |
|
||||
| MULTIPLE_INSTANCE | OT_MULTIPLE_INSTANCE | Enables multiple OpenThread instances. |
|
||||
| PING_SENDER | OT_PING_SENDER | Enables support for ping sender. |
|
||||
| OTNS | OT_OTNS | Enables support for [OpenThread Network Simulator](https://github.com/openthread/ot-ns). Enable this switch if you are building OpenThread for OpenThread Network Simulator. |
|
||||
| PLATFORM_UDP | OT_PLATFORM_UDP | Enables platform UDP support. |
|
||||
| REFERENCE_DEVICE | OT_REFERENCE_DEVICE | Enables support for Thread Test Harness reference device. Enable this switch on the reference device during certification. |
|
||||
|
||||
@@ -70,6 +70,7 @@ MLR ?= 0
|
||||
MTD_NETDIAG ?= 0
|
||||
MULTIPLE_INSTANCE ?= 0
|
||||
OTNS ?= 0
|
||||
PING_SENDER ?= 1
|
||||
PLATFORM_UDP ?= 0
|
||||
REFERENCE_DEVICE ?= 0
|
||||
SERVICE ?= 0
|
||||
@@ -255,6 +256,10 @@ ifeq ($(MULTIPLE_INSTANCE),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(PING_SENDER),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_PING_SENDER_ENABLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM_UDP),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1
|
||||
endif
|
||||
|
||||
@@ -72,6 +72,7 @@ openthread_headers = \
|
||||
openthread/netdata.h \
|
||||
openthread/netdiag.h \
|
||||
openthread/network_time.h \
|
||||
openthread/ping_sender.h \
|
||||
openthread/random_crypto.h \
|
||||
openthread/random_noncrypto.h \
|
||||
openthread/server.h \
|
||||
|
||||
@@ -93,6 +93,7 @@ source_set("openthread") {
|
||||
"netdata.h",
|
||||
"netdiag.h",
|
||||
"network_time.h",
|
||||
"ping_sender.h",
|
||||
"platform/alarm-micro.h",
|
||||
"platform/alarm-milli.h",
|
||||
"platform/debug_uart.h",
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (85)
|
||||
#define OPENTHREAD_API_VERSION (86)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the OpenThread API for ping sender module.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_PING_SENDER_H_
|
||||
#define OPENTHREAD_PING_SENDER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/error.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure represents a ping reply.
|
||||
*
|
||||
*/
|
||||
typedef struct otPingSenderReply
|
||||
{
|
||||
otIp6Address mSenderAddress; ///< Sender IPv6 address (address from which ping reply was received).
|
||||
uint32_t mRoundTripTime; ///< Round trip time in msec.
|
||||
uint16_t mSize; ///< Data size (number of bytes) in reply (excluding IPv6 and ICMP6 headers).
|
||||
uint16_t mSequenceNumber; ///< Sequence number.
|
||||
uint8_t mHopLimit; ///< Hop limit.
|
||||
} otPingSenderReply;
|
||||
|
||||
/**
|
||||
* This function pointer type specifies the callback to notify receipt of a ping reply.
|
||||
*
|
||||
* @param[in] aReply A pointer to a `otPingSenderReply` containing info about the received ping reply.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*otPingSenderCallback)(const otPingSenderReply *aReply, void *aContext);
|
||||
|
||||
/**
|
||||
* This structure represents a ping request configuration.
|
||||
*
|
||||
*/
|
||||
typedef struct otPingSenderConfig
|
||||
{
|
||||
otIp6Address mDestination; ///< Destination address to ping.
|
||||
otPingSenderCallback mCallback; ///< Callback function to report replies (can be NULL if not needed).
|
||||
void * mCallbackContext; ///< A pointer to the callback application-specific context.
|
||||
uint16_t mSize; ///< Data size (# of bytes) excludes IPv6/ICMPv6 header. Zero for default.
|
||||
uint16_t mCount; ///< Number of ping messages to send. Zero to use default.
|
||||
uint32_t mInterval; ///< Ping tx interval in milliseconds. Zero to use default.
|
||||
uint8_t mHopLimit; ///< Hop limit (used if `mAllowZeroHopLimit` is false). Zero for default.
|
||||
bool mAllowZeroHopLimit; ///< Indicates whether hop limit is zero.
|
||||
} otPingSenderConfig;
|
||||
|
||||
/**
|
||||
* This function starts a ping.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aConfig The ping config to use.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The ping started successfully.
|
||||
* @retval OT_ERROR_BUSY Could not start since busy with a previous ongoing ping request.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig contains invalid parameters (e.g., ping interval is too long).
|
||||
|
||||
*
|
||||
*/
|
||||
otError otPingSenderPing(otInstance *aInstance, const otPingSenderConfig *aConfig);
|
||||
|
||||
/**
|
||||
* This function stops an ongoing ping.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otPingSenderStop(otInstance *aInstance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_PING_SENDER_H_
|
||||
@@ -173,6 +173,7 @@ build_nrf52833()
|
||||
"LINK_RAW=1"
|
||||
"MAC_FILTER=1"
|
||||
"MTD_NETDIAG=1"
|
||||
"PING_SENDER=1"
|
||||
"SERVICE=1"
|
||||
"SLAAC=1"
|
||||
"SNTP_CLIENT=1"
|
||||
@@ -216,6 +217,7 @@ build_nrf52840()
|
||||
"LINK_RAW=1"
|
||||
"MAC_FILTER=1"
|
||||
"MTD_NETDIAG=1"
|
||||
"PING_SENDER=1"
|
||||
"SERVICE=1"
|
||||
"SLAAC=1"
|
||||
"SNTP_CLIENT=1"
|
||||
|
||||
@@ -68,6 +68,7 @@ do_scan_build()
|
||||
"-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE"
|
||||
"-DOPENTHREAD_CONFIG_PING_SENDER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
|
||||
|
||||
@@ -75,6 +75,7 @@ build_all_features()
|
||||
"-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE"
|
||||
"-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PING_SENDER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1"
|
||||
@@ -133,6 +134,7 @@ build_nest_common()
|
||||
"-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PING_SENDER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
||||
|
||||
@@ -136,6 +136,7 @@ size_nrf52840_version()
|
||||
"-DOT_MAC_FILTER=ON"
|
||||
"-DOT_MESSAGE_USE_HEAP=ON"
|
||||
"-DOT_MTD_NETDIAG=ON"
|
||||
"-DOT_PING_SENDER=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
"-DOT_SLAAC=ON"
|
||||
"-DOT_SNTP_CLIENT=ON"
|
||||
|
||||
@@ -93,6 +93,7 @@ readonly OT_POSIX_SIM_COMMON_OPTIONS=(
|
||||
"-DOT_LEGACY=ON"
|
||||
"-DOT_MAC_FILTER=ON"
|
||||
"-DOT_MTD_NETDIAG=ON"
|
||||
"-DOT_PING_SENDER=ON"
|
||||
"-DOT_REFERENCE_DEVICE=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
"-DOT_SNTP_CLIENT=ON"
|
||||
|
||||
@@ -106,6 +106,7 @@ readonly OT_CLANG_TIDY_BUILD_OPTS=(
|
||||
'-DOT_LINK_METRICS=ON'
|
||||
'-DOT_MAC_FILTER=ON'
|
||||
'-DOT_MTD_NETDIAG=ON'
|
||||
'-DOT_PING_SENDER=ON'
|
||||
'-DOT_REFERENCE_DEVICE=ON'
|
||||
'-DOT_SERVICE=ON'
|
||||
'-DOT_SLAAC=ON'
|
||||
|
||||
@@ -63,6 +63,7 @@ build_simulation()
|
||||
"-DOT_SRP_CLIENT=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
"-DOT_ECDSA=ON"
|
||||
"-DOT_PING_SENDER=ON"
|
||||
"-DOT_DNSSD_SERVER=ON"
|
||||
"-DOT_DNS_CLIENT=ON"
|
||||
)
|
||||
|
||||
+39
-168
@@ -86,12 +86,9 @@
|
||||
#include "common/new.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "mac/channel_mask.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "utils/otns.hpp"
|
||||
#include "utils/parse_cmdline.hpp"
|
||||
|
||||
using ot::Encoding::BigEndian::HostSwap16;
|
||||
using ot::Encoding::BigEndian::HostSwap32;
|
||||
|
||||
using ot::Utils::CmdLineParser::ParseAsBool;
|
||||
using ot::Utils::CmdLineParser::ParseAsHexString;
|
||||
@@ -117,13 +114,6 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
|
||||
, mOutputContext(aContext)
|
||||
, mUserCommands(nullptr)
|
||||
, mUserCommandsLength(0)
|
||||
, mPingLength(kDefaultPingLength)
|
||||
, mPingCount(kDefaultPingCount)
|
||||
, mPingInterval(kDefaultPingInterval)
|
||||
, mPingHopLimit(0)
|
||||
, mPingAllowZeroHopLimit(false)
|
||||
, mPingIdentifier(0)
|
||||
, mPingTimer(*aInstance, Interpreter::HandlePingTimer)
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
, mSntpQueryingInProgress(false)
|
||||
#endif
|
||||
@@ -152,10 +142,6 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
|
||||
#if OPENTHREAD_FTD
|
||||
otThreadSetDiscoveryRequestCallback(mInstance, &Interpreter::HandleDiscoveryRequest, this);
|
||||
#endif
|
||||
|
||||
mIcmpHandler.mReceiveCallback = Interpreter::HandleIcmpReceive;
|
||||
mIcmpHandler.mContext = this;
|
||||
IgnoreError(otIcmp6RegisterHandler(mInstance, &mIcmpHandler));
|
||||
}
|
||||
|
||||
void Interpreter::OutputResult(otError aError)
|
||||
@@ -211,6 +197,8 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
otError Interpreter::ParsePingInterval(const char *aString, uint32_t &aInterval)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -257,6 +245,8 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
otError Interpreter::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
@@ -3151,153 +3141,70 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
void Interpreter::HandleIcmpReceive(void * aContext,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
void Interpreter::HandlePingReply(const otPingSenderReply *aReply, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleIcmpReceive(aMessage, aMessageInfo, aIcmpHeader);
|
||||
static_cast<Interpreter *>(aContext)->HandlePingReply(aReply);
|
||||
}
|
||||
|
||||
void Interpreter::HandleIcmpReceive(otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
void Interpreter::HandlePingReply(const otPingSenderReply *aReply)
|
||||
{
|
||||
uint32_t timestamp = 0;
|
||||
uint16_t dataSize;
|
||||
|
||||
VerifyOrExit(aIcmpHeader->mType == OT_ICMP6_TYPE_ECHO_REPLY);
|
||||
VerifyOrExit((mPingIdentifier != 0) && (mPingIdentifier == HostSwap16(aIcmpHeader->mData.m16[0])));
|
||||
|
||||
dataSize = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
|
||||
OutputFormat("%u bytes from ", dataSize + static_cast<uint16_t>(sizeof(otIcmp6Header)));
|
||||
|
||||
OutputIp6Address(aMessageInfo->mPeerAddr);
|
||||
|
||||
OutputFormat(": icmp_seq=%d hlim=%d", HostSwap16(aIcmpHeader->mData.m16[1]), aMessageInfo->mHopLimit);
|
||||
|
||||
if (otMessageRead(aMessage, otMessageGetOffset(aMessage), ×tamp, sizeof(uint32_t)) == sizeof(uint32_t))
|
||||
{
|
||||
OutputFormat(" time=%dms", TimerMilli::GetNow().GetValue() - HostSwap32(timestamp));
|
||||
}
|
||||
|
||||
OutputLine("");
|
||||
|
||||
SignalPingReply(static_cast<const Ip6::MessageInfo *>(aMessageInfo)->GetPeerAddr(), dataSize, HostSwap32(timestamp),
|
||||
aMessageInfo->mHopLimit);
|
||||
|
||||
exit:
|
||||
return;
|
||||
OutputFormat("%u bytes from ", static_cast<uint16_t>(aReply->mSize + sizeof(otIcmp6Header)));
|
||||
OutputIp6Address(aReply->mSenderAddress);
|
||||
OutputLine(": icmp_seq=%d hlim=%d time=%dms", aReply->mSequenceNumber, aReply->mHopLimit, aReply->mRoundTripTime);
|
||||
}
|
||||
|
||||
otError Interpreter::ProcessPing(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t index = 1;
|
||||
uint32_t interval;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPingSenderConfig config;
|
||||
|
||||
VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(aArgs[0], "stop") == 0)
|
||||
{
|
||||
mPingIdentifier = 0;
|
||||
VerifyOrExit(mPingTimer.IsRunning(), error = OT_ERROR_INVALID_STATE);
|
||||
mPingTimer.Stop();
|
||||
otPingSenderStop(mInstance);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
VerifyOrExit(!mPingTimer.IsRunning(), error = OT_ERROR_BUSY);
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
SuccessOrExit(error = ParseAsIp6Address(aArgs[0], mPingDestAddress));
|
||||
SuccessOrExit(error = ParseAsIp6Address(aArgs[0], config.mDestination));
|
||||
|
||||
mPingLength = kDefaultPingLength;
|
||||
mPingCount = kDefaultPingCount;
|
||||
mPingInterval = kDefaultPingInterval;
|
||||
mPingHopLimit = 0;
|
||||
mPingAllowZeroHopLimit = false;
|
||||
|
||||
while (index < aArgsLength)
|
||||
if (aArgsLength > 1)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[index], mPingLength));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[index], mPingCount));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
SuccessOrExit(error = ParsePingInterval(aArgs[index], interval));
|
||||
VerifyOrExit(0 < interval && interval <= Timer::kMaxDelay, error = OT_ERROR_INVALID_ARGS);
|
||||
mPingInterval = interval;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
SuccessOrExit(error = ParseAsUint8(aArgs[index], mPingHopLimit));
|
||||
mPingAllowZeroHopLimit = (mPingHopLimit == 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
index++;
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[1], config.mSize));
|
||||
}
|
||||
|
||||
mPingIdentifier++;
|
||||
|
||||
if (mPingIdentifier == 0)
|
||||
if (aArgsLength > 2)
|
||||
{
|
||||
mPingIdentifier++;
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[2], config.mCount));
|
||||
}
|
||||
|
||||
SendPing();
|
||||
if (aArgsLength > 3)
|
||||
{
|
||||
SuccessOrExit(error = ParsePingInterval(aArgs[3], config.mInterval));
|
||||
}
|
||||
|
||||
if (aArgsLength > 4)
|
||||
{
|
||||
SuccessOrExit(error = ParseAsUint8(aArgs[4], config.mHopLimit));
|
||||
config.mAllowZeroHopLimit = (config.mHopLimit == 0);
|
||||
}
|
||||
|
||||
VerifyOrExit(aArgsLength <= 5, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
config.mCallback = Interpreter::HandlePingReply;
|
||||
config.mCallbackContext = this;
|
||||
|
||||
error = otPingSenderPing(mInstance, &config);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Interpreter::HandlePingTimer(Timer &aTimer)
|
||||
{
|
||||
GetOwner(aTimer).SendPing();
|
||||
}
|
||||
|
||||
void Interpreter::SendPing(void)
|
||||
{
|
||||
uint32_t timestamp = HostSwap32(TimerMilli::GetNow().GetValue());
|
||||
otMessage * message = nullptr;
|
||||
otMessageInfo messageInfo;
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.mPeerAddr = mPingDestAddress;
|
||||
messageInfo.mHopLimit = mPingHopLimit;
|
||||
messageInfo.mAllowZeroHopLimit = mPingAllowZeroHopLimit;
|
||||
|
||||
message = otIp6NewMessage(mInstance, nullptr);
|
||||
VerifyOrExit(message != nullptr);
|
||||
|
||||
SuccessOrExit(otMessageAppend(message, ×tamp, sizeof(timestamp)));
|
||||
SuccessOrExit(otMessageSetLength(message, mPingLength));
|
||||
SuccessOrExit(otIcmp6SendEchoRequest(mInstance, message, &messageInfo, mPingIdentifier));
|
||||
|
||||
SignalPingRequest(static_cast<Ip6::MessageInfo *>(&messageInfo)->GetPeerAddr(), mPingLength, HostSwap32(timestamp),
|
||||
messageInfo.mHopLimit);
|
||||
|
||||
message = nullptr;
|
||||
|
||||
exit:
|
||||
if (message != nullptr)
|
||||
{
|
||||
otMessageFree(message);
|
||||
}
|
||||
|
||||
if (--mPingCount)
|
||||
{
|
||||
mPingTimer.Start(mPingInterval);
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
otError Interpreter::ProcessPollPeriod(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
@@ -5071,42 +4978,6 @@ void Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLength
|
||||
mUserCommandsContext = aContext;
|
||||
}
|
||||
|
||||
Interpreter &Interpreter::GetOwner(InstanceLocator &aInstanceLocator)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstanceLocator);
|
||||
return Interpreter::GetInterpreter();
|
||||
}
|
||||
|
||||
void Interpreter::SignalPingRequest(const Ip6::Address &aPeerAddress,
|
||||
uint16_t aPingLength,
|
||||
uint32_t aTimestamp,
|
||||
uint8_t aHopLimit)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aPeerAddress);
|
||||
OT_UNUSED_VARIABLE(aPingLength);
|
||||
OT_UNUSED_VARIABLE(aTimestamp);
|
||||
OT_UNUSED_VARIABLE(aHopLimit);
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
mInstance->Get<Utils::Otns>().EmitPingRequest(aPeerAddress, aPingLength, aTimestamp, aHopLimit);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Interpreter::SignalPingReply(const Ip6::Address &aPeerAddress,
|
||||
uint16_t aPingLength,
|
||||
uint32_t aTimestamp,
|
||||
uint8_t aHopLimit)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aPeerAddress);
|
||||
OT_UNUSED_VARIABLE(aPingLength);
|
||||
OT_UNUSED_VARIABLE(aTimestamp);
|
||||
OT_UNUSED_VARIABLE(aHopLimit);
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
mInstance->Get<Utils::Otns>().EmitPingReply(aPeerAddress, aPingLength, aTimestamp, aHopLimit);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
|
||||
{
|
||||
OutputFormat("~ Discovery Request from ");
|
||||
|
||||
+21
-37
@@ -41,9 +41,14 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <openthread/cli.h>
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/dns_client.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/ip6.h>
|
||||
#include <openthread/link.h>
|
||||
#include <openthread/sntp.h>
|
||||
#include <openthread/thread.h>
|
||||
#include <openthread/thread_ftd.h>
|
||||
#include <openthread/udp.h>
|
||||
|
||||
#include "cli/cli_commissioner.hpp"
|
||||
@@ -59,10 +64,10 @@
|
||||
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
|
||||
#include "cli/cli_coap_secure.hpp"
|
||||
#endif
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
#include "utils/lookup_table.hpp"
|
||||
|
||||
namespace ot {
|
||||
@@ -296,12 +301,7 @@ private:
|
||||
kIndentSize = 4,
|
||||
kMaxArgs = 32,
|
||||
kMaxAutoAddresses = 8,
|
||||
|
||||
kDefaultPingInterval = 1000, // (in mses)
|
||||
kDefaultPingLength = 8, // (in bytes)
|
||||
kDefaultPingCount = 1,
|
||||
|
||||
kMaxLineLength = OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH,
|
||||
kMaxLineLength = OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH,
|
||||
};
|
||||
|
||||
struct Command
|
||||
@@ -310,7 +310,9 @@ private:
|
||||
otError (Interpreter::*mHandler)(uint8_t aArgsLength, char *aArgs[]);
|
||||
};
|
||||
|
||||
otError ParsePingInterval(const char *aString, uint32_t &aInterval);
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
otError ParsePingInterval(const char *aString, uint32_t &aInterval);
|
||||
#endif
|
||||
static otError ParseJoinerDiscerner(char *aString, otJoinerDiscerner &aDiscerner);
|
||||
|
||||
otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
|
||||
@@ -474,17 +476,10 @@ private:
|
||||
#if OPENTHREAD_FTD
|
||||
otError ProcessParentPriority(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
otError ProcessPing(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
otError ProcessPollPeriod(uint8_t aArgsLength, char *aArgs[]);
|
||||
void SignalPingRequest(const Ip6::Address &aPeerAddress,
|
||||
uint16_t aPingLength,
|
||||
uint32_t aTimestamp,
|
||||
uint8_t aHopLimit);
|
||||
void SignalPingReply(const Ip6::Address &aPeerAddress,
|
||||
uint16_t aPingLength,
|
||||
uint32_t aTimestamp,
|
||||
uint8_t aHopLimit);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
otError ProcessPrefix(uint8_t aArgsLength, char *aArgs[]);
|
||||
otError ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[]);
|
||||
@@ -543,11 +538,9 @@ private:
|
||||
otError ProcessMacSend(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
|
||||
static void HandleIcmpReceive(void * aContext,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
static void HandlePingTimer(Timer &aTimer);
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
static void HandlePingReply(const otPingSenderReply *aReply, void *aContext);
|
||||
#endif
|
||||
static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
|
||||
static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
|
||||
static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
|
||||
@@ -587,8 +580,9 @@ private:
|
||||
static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult);
|
||||
#endif
|
||||
|
||||
void HandleIcmpReceive(otMessage *aMessage, const otMessageInfo *aMessageInfo, const otIcmp6Header *aIcmpHeader);
|
||||
void SendPing(void);
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
void HandlePingReply(const otPingSenderReply *aReply);
|
||||
#endif
|
||||
void HandleActiveScanResult(otActiveScanResult *aResult);
|
||||
void HandleEnergyScanResult(otEnergyScanResult *aResult);
|
||||
void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
|
||||
@@ -623,8 +617,6 @@ private:
|
||||
const char *LinkMetricsStatusToStr(uint8_t aStatus);
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_ENABLE
|
||||
|
||||
static Interpreter &GetOwner(InstanceLocator &aInstanceLocator);
|
||||
|
||||
static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleDiscoveryRequest(*aInfo);
|
||||
@@ -753,7 +745,9 @@ private:
|
||||
{"parentpriority", &Interpreter::ProcessParentPriority},
|
||||
{"partitionid", &Interpreter::ProcessPartitionId},
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
{"ping", &Interpreter::ProcessPing},
|
||||
#endif
|
||||
{"pollperiod", &Interpreter::ProcessPollPeriod},
|
||||
#if OPENTHREAD_FTD
|
||||
{"preferrouterid", &Interpreter::ProcessPreferRouterId},
|
||||
@@ -806,19 +800,9 @@ private:
|
||||
Instance * mInstance;
|
||||
otCliOutputCallback mOutputCallback;
|
||||
void * mOutputContext;
|
||||
|
||||
const otCliCommand *mUserCommands;
|
||||
uint8_t mUserCommandsLength;
|
||||
void * mUserCommandsContext;
|
||||
uint16_t mPingLength;
|
||||
uint16_t mPingCount;
|
||||
uint32_t mPingInterval;
|
||||
uint8_t mPingHopLimit;
|
||||
bool mPingAllowZeroHopLimit;
|
||||
uint16_t mPingIdentifier;
|
||||
otIp6Address mPingDestAddress;
|
||||
TimerMilli mPingTimer;
|
||||
otIcmp6Handler mIcmpHandler;
|
||||
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
|
||||
bool mSntpQueryingInProgress;
|
||||
#endif
|
||||
|
||||
@@ -236,6 +236,10 @@ if (openthread_enable_core_config_args) {
|
||||
defines += [ "OPENTHREAD_CONFIG_SRP_SERVER_ENABLE=1" ]
|
||||
}
|
||||
|
||||
if (openthread_config_ping_sender) {
|
||||
defines += [ "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1" ]
|
||||
}
|
||||
|
||||
if (openthread_config_time_sync_enable) {
|
||||
defines += [ "OPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1" ]
|
||||
}
|
||||
@@ -320,6 +324,7 @@ openthread_core_files = [
|
||||
"api/netdata_api.cpp",
|
||||
"api/netdiag_api.cpp",
|
||||
"api/network_time_api.cpp",
|
||||
"api/ping_sender_api.cpp",
|
||||
"api/random_crypto_api.cpp",
|
||||
"api/random_noncrypto_api.cpp",
|
||||
"api/server_api.cpp",
|
||||
@@ -619,6 +624,8 @@ openthread_core_files = [
|
||||
"utils/otns.hpp",
|
||||
"utils/parse_cmdline.cpp",
|
||||
"utils/parse_cmdline.hpp",
|
||||
"utils/ping_sender.cpp",
|
||||
"utils/ping_sender.hpp",
|
||||
"utils/slaac_address.cpp",
|
||||
"utils/slaac_address.hpp",
|
||||
]
|
||||
@@ -689,6 +696,7 @@ source_set("libopenthread_core_config") {
|
||||
"config/openthread-core-config-check.h",
|
||||
"config/openthread-core-default-config.h",
|
||||
"config/parent_search.h",
|
||||
"config/ping_sender.h",
|
||||
"config/platform.h",
|
||||
"config/radio_link.h",
|
||||
"config/sntp_client.h",
|
||||
|
||||
@@ -64,6 +64,7 @@ set(COMMON_SOURCES
|
||||
api/netdata_api.cpp
|
||||
api/netdiag_api.cpp
|
||||
api/network_time_api.cpp
|
||||
api/ping_sender_api.cpp
|
||||
api/random_crypto_api.cpp
|
||||
api/random_noncrypto_api.cpp
|
||||
api/server_api.cpp
|
||||
@@ -207,6 +208,7 @@ set(COMMON_SOURCES
|
||||
utils/lookup_table.cpp
|
||||
utils/otns.cpp
|
||||
utils/parse_cmdline.cpp
|
||||
utils/ping_sender.cpp
|
||||
utils/slaac_address.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ SOURCES_COMMON = \
|
||||
api/netdata_api.cpp \
|
||||
api/netdiag_api.cpp \
|
||||
api/network_time_api.cpp \
|
||||
api/ping_sender_api.cpp \
|
||||
api/random_crypto_api.cpp \
|
||||
api/random_noncrypto_api.cpp \
|
||||
api/server_api.cpp \
|
||||
@@ -284,6 +285,7 @@ SOURCES_COMMON = \
|
||||
utils/lookup_table.cpp \
|
||||
utils/otns.cpp \
|
||||
utils/parse_cmdline.cpp \
|
||||
utils/ping_sender.cpp \
|
||||
utils/slaac_address.cpp \
|
||||
$(NULL)
|
||||
|
||||
@@ -423,6 +425,7 @@ HEADERS_COMMON = \
|
||||
config/openthread-core-config-check.h \
|
||||
config/openthread-core-default-config.h \
|
||||
config/parent_search.h \
|
||||
config/ping_sender.h \
|
||||
config/platform.h \
|
||||
config/radio_link.h \
|
||||
config/sntp_client.h \
|
||||
@@ -543,6 +546,7 @@ HEADERS_COMMON = \
|
||||
utils/lookup_table.hpp \
|
||||
utils/otns.hpp \
|
||||
utils/parse_cmdline.hpp \
|
||||
utils/ping_sender.hpp \
|
||||
utils/slaac_address.hpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the OpenThread ping sender APIs.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/ping_sender.h>
|
||||
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
otError otPingSenderPing(otInstance *aInstance, const otPingSenderConfig *aConfig)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Utils::PingSender>().Ping(*static_cast<const Utils::PingSender::Config *>(aConfig));
|
||||
}
|
||||
|
||||
void otPingSenderStop(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.Get<Utils::PingSender>().Stop();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
@@ -74,6 +74,9 @@ Instance::Instance(void)
|
||||
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
|
||||
, mApplicationCoapSecure(*this, /* aLayerTwoSecurity */ true)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
, mPingSender(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
|
||||
, mChannelMonitor(*this)
|
||||
#endif
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
#include "thread/thread_netif.hpp"
|
||||
#include "thread/tmf.hpp"
|
||||
#include "utils/heap.hpp"
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
#include "utils/ping_sender.hpp"
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
|
||||
#include "utils/channel_manager.hpp"
|
||||
#endif
|
||||
@@ -350,6 +353,10 @@ private:
|
||||
Coap::CoapSecure mApplicationCoapSecure;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
Utils::PingSender mPingSender;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
|
||||
Utils::ChannelMonitor mChannelMonitor;
|
||||
#endif
|
||||
@@ -742,6 +749,13 @@ template <> inline Utils::SupervisionListener &Instance::Get(void)
|
||||
return mThreadNetif.mSupervisionListener;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
template <> inline Utils::PingSender &Instance::Get(void)
|
||||
{
|
||||
return mPingSender;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
|
||||
template <> inline Utils::ChannelMonitor &Instance::Get(void)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes compile-time configurations for ping sender module.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_PING_SENDER_H_
|
||||
#define CONFIG_PING_SENDER_H_
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
*
|
||||
* Define to 1 to enable ping sender module.
|
||||
*
|
||||
* Ping sender module implements sending ICMPv6 Echo Request messages and processing ICMPv6 Echo Reply messages.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
#define OPENTHREAD_CONFIG_PING_SENDER_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL
|
||||
*
|
||||
* Specifies the default ping interval (time between sending echo requests) in milliseconds.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL
|
||||
#define OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL 1000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE
|
||||
*
|
||||
* Specifies the default ping data size in bytes. The data size specifies the Echo Request data payload which excludes
|
||||
* the IPv6 and ICMPv6 headers.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE
|
||||
#define OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT
|
||||
*
|
||||
* Specifies the default ping count (number of ping messages to send).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT
|
||||
#define OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT 1
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_PING_SENDER_H_
|
||||
@@ -75,6 +75,7 @@
|
||||
#include "config/mac.h"
|
||||
#include "config/mle.h"
|
||||
#include "config/parent_search.h"
|
||||
#include "config/ping_sender.h"
|
||||
#include "config/platform.h"
|
||||
#include "config/radio_link.h"
|
||||
#include "config/sntp_client.h"
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the ping sender module.
|
||||
*/
|
||||
|
||||
#include "ping_sender.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/random.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Utils {
|
||||
|
||||
using Encoding::BigEndian::HostSwap32;
|
||||
|
||||
void PingSender::Config::SetUnspecifiedToDefault(void)
|
||||
{
|
||||
if (mSize == 0)
|
||||
{
|
||||
mSize = kDefaultSize;
|
||||
}
|
||||
|
||||
if (mCount == 0)
|
||||
{
|
||||
mCount = kDefaultCount;
|
||||
}
|
||||
|
||||
if (mInterval == 0)
|
||||
{
|
||||
mInterval = kDefaultInterval;
|
||||
}
|
||||
}
|
||||
|
||||
void PingSender::Config::InvokeCallback(const Reply &aReply) const
|
||||
{
|
||||
VerifyOrExit(mCallback != nullptr);
|
||||
mCallback(&aReply, mCallbackContext);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
PingSender::PingSender(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mIdentifier(0)
|
||||
, mTimer(aInstance, PingSender::HandleTimer)
|
||||
, mIcmpHandler(PingSender::HandleIcmpReceive, this)
|
||||
{
|
||||
IgnoreError(Get<Ip6::Icmp>().RegisterHandler(mIcmpHandler));
|
||||
}
|
||||
|
||||
Error PingSender::Ping(const Config &aConfig)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(!mTimer.IsRunning(), error = kErrorBusy);
|
||||
|
||||
mConfig = aConfig;
|
||||
mConfig.SetUnspecifiedToDefault();
|
||||
VerifyOrExit(mConfig.mInterval <= Timer::kMaxDelay, error = kErrorInvalidArgs);
|
||||
|
||||
mIdentifier++;
|
||||
SendPing();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void PingSender::Stop(void)
|
||||
{
|
||||
mTimer.Stop();
|
||||
mIdentifier++;
|
||||
}
|
||||
|
||||
void PingSender::SendPing(void)
|
||||
{
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
Message * message = nullptr;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
messageInfo.SetPeerAddr(mConfig.GetDestination());
|
||||
messageInfo.mHopLimit = mConfig.mHopLimit;
|
||||
messageInfo.mAllowZeroHopLimit = mConfig.mAllowZeroHopLimit;
|
||||
|
||||
message = Get<Ip6::Icmp>().NewMessage(0);
|
||||
VerifyOrExit(message != nullptr);
|
||||
|
||||
SuccessOrExit(message->Append(HostSwap32(now.GetValue())));
|
||||
|
||||
if (mConfig.mSize > message->GetLength())
|
||||
{
|
||||
SuccessOrExit(message->SetLength(mConfig.mSize));
|
||||
}
|
||||
|
||||
SuccessOrExit(Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, mIdentifier));
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
Get<Utils::Otns>().EmitPingRequest(mConfig.GetDestination(), mConfig.mSize, now.GetValue(), mConfig.mHopLimit);
|
||||
#endif
|
||||
|
||||
message = nullptr;
|
||||
|
||||
exit:
|
||||
FreeMessage(message);
|
||||
mConfig.mCount--;
|
||||
|
||||
if (mConfig.mCount != 0)
|
||||
{
|
||||
mTimer.Start(mConfig.mInterval);
|
||||
}
|
||||
}
|
||||
|
||||
void PingSender::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.Get<PingSender>().HandleTimer();
|
||||
}
|
||||
|
||||
void PingSender::HandleTimer(void)
|
||||
{
|
||||
SendPing();
|
||||
}
|
||||
|
||||
void PingSender::HandleIcmpReceive(void * aContext,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
reinterpret_cast<PingSender *>(aContext)->HandleIcmpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
|
||||
*static_cast<const Ip6::Icmp::Header *>(aIcmpHeader));
|
||||
}
|
||||
|
||||
void PingSender::HandleIcmpReceive(const Message & aMessage,
|
||||
const Ip6::MessageInfo & aMessageInfo,
|
||||
const Ip6::Icmp::Header &aIcmpHeader)
|
||||
{
|
||||
Reply reply;
|
||||
uint32_t timestamp;
|
||||
|
||||
VerifyOrExit(aIcmpHeader.GetType() == Ip6::Icmp::Header::kTypeEchoReply);
|
||||
VerifyOrExit(aIcmpHeader.GetId() == mIdentifier);
|
||||
|
||||
SuccessOrExit(aMessage.Read(aMessage.GetOffset(), timestamp));
|
||||
timestamp = HostSwap32(timestamp);
|
||||
|
||||
reply.mSenderAddress = aMessageInfo.GetPeerAddr();
|
||||
reply.mRoundTripTime = TimerMilli::GetNow() - TimeMilli(timestamp);
|
||||
reply.mSize = aMessage.GetLength() - aMessage.GetOffset();
|
||||
reply.mSequenceNumber = aIcmpHeader.GetSequence();
|
||||
reply.mHopLimit = aMessageInfo.GetHopLimit();
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
Get<Utils::Otns>().EmitPingReply(aMessageInfo.GetPeerAddr(), reply.mSize, timestamp, reply.mHopLimit);
|
||||
#endif
|
||||
|
||||
mConfig.InvokeCallback(reply);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace ot
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions to support ping functionality.
|
||||
*/
|
||||
|
||||
#ifndef PING_SENDER_HPP_
|
||||
#define PING_SENDER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
#include <openthread/ping_sender.h>
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/time.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Utils {
|
||||
|
||||
/**
|
||||
* This class implements sending ICMPv6 Echo Request messages and processing ICMPv6 Echo Reply messages.
|
||||
*
|
||||
*/
|
||||
class PingSender : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This class represents a ping reply.
|
||||
*
|
||||
*/
|
||||
typedef otPingSenderReply Reply;
|
||||
|
||||
/**
|
||||
* This class represents a ping request configuration.
|
||||
*
|
||||
*/
|
||||
class Config : public otPingSenderConfig
|
||||
{
|
||||
friend class PingSender;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This method gets the destination IPv6 address to ping.
|
||||
*
|
||||
* @returns The ping destination IPv6 address.
|
||||
*
|
||||
*/
|
||||
Ip6::Address &GetDestination(void) { return static_cast<Ip6::Address &>(mDestination); }
|
||||
|
||||
/**
|
||||
* This method gets the destination IPv6 address to ping.
|
||||
*
|
||||
* @returns The ping destination IPv6 address.
|
||||
*
|
||||
*/
|
||||
const Ip6::Address &GetDestination(void) const { return static_cast<const Ip6::Address &>(mDestination); }
|
||||
|
||||
private:
|
||||
enum : uint16_t
|
||||
{
|
||||
kDefaultSize = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE,
|
||||
kDefaultCount = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT,
|
||||
};
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
kDefaultInterval = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL,
|
||||
};
|
||||
|
||||
void SetUnspecifiedToDefault(void);
|
||||
void InvokeCallback(const Reply &aReply) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the `PingSender` object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit PingSender(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method starts a ping.
|
||||
*
|
||||
* @param[in] aConfig The ping config to use.
|
||||
*
|
||||
* @retval kErrorNone The ping started successfully.
|
||||
* @retval kErrorBusy Could not start since busy with a previous ongoing ping request.
|
||||
* @retval kErrorInvalidArgs The @p aConfig contains invalid parameters (e.g., ping interval is too long).
|
||||
*
|
||||
*/
|
||||
Error Ping(const Config &aConfig);
|
||||
|
||||
/**
|
||||
* This method stops an ongoing ping.
|
||||
*
|
||||
*/
|
||||
void Stop(void);
|
||||
|
||||
private:
|
||||
void SendPing(void);
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
static void HandleIcmpReceive(void * aContext,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
void HandleIcmpReceive(const Message & aMessage,
|
||||
const Ip6::MessageInfo & aMessageInfo,
|
||||
const Ip6::Icmp::Header &aIcmpHeader);
|
||||
|
||||
Config mConfig;
|
||||
uint16_t mIdentifier;
|
||||
TimerMilli mTimer;
|
||||
Ip6::Icmp::Handler mIcmpHandler;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
|
||||
#endif // PING_SENDER_HPP_
|
||||
@@ -62,6 +62,7 @@ LOG_OUTPUT ?= PLATFORM_DEFINED
|
||||
MAC_FILTER ?= 1
|
||||
MAX_POWER_TABLE ?= 1
|
||||
MTD_NETDIAG ?= 1
|
||||
PING_SENDER ?= 1
|
||||
READLINE ?= readline
|
||||
REFERENCE_DEVICE ?= 1
|
||||
SERVICE ?= 1
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
-DOT_LOG_OUTPUT=APP \
|
||||
-DOT_MAC_FILTER=ON \
|
||||
-DOT_MTD_NETDIAG=ON \
|
||||
-DOT_PING_SENDER=ON \
|
||||
-DOT_SERVICE=ON \
|
||||
-DOT_SLAAC=ON \
|
||||
-DOT_SNTP_CLIENT=ON \
|
||||
|
||||
Reference in New Issue
Block a user