[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:
Abtin Keshavarzian
2021-03-19 16:04:55 -07:00
committed by GitHub
parent ae88a2c677
commit 06ca5d855c
31 changed files with 729 additions and 206 deletions
+2
View File
@@ -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 \
+5
View File
@@ -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")
+3
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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. |
+5
View File
@@ -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
+1
View File
@@ -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 \
+1
View File
@@ -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",
+1 -1
View File
@@ -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
+112
View File
@@ -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_
+2
View File
@@ -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"
+1
View File
@@ -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"
+2
View File
@@ -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"
+1
View File
@@ -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"
+1
View File
@@ -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"
+1
View File
@@ -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'
+1
View File
@@ -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
View File
@@ -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), &timestamp, 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, &timestamp, 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
View File
@@ -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
+8
View File
@@ -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",
+2
View File
@@ -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
)
+4
View File
@@ -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)
+59
View File
@@ -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
+3
View File
@@ -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
+14
View File
@@ -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)
{
+81
View File
@@ -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_
+1
View File
@@ -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"
+196
View File
@@ -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
+158
View File
@@ -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_
+1
View File
@@ -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
+1
View File
@@ -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 \