blob: aae63c75e764d40d040f3ee535ff3c6f5e96a442 [file] [log] [blame]
/*
* 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/as_core_type.hpp"
#include "common/code_utils.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "common/numeric_limits.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 the statistics of several ping requests.
*
*/
struct Statistics : public otPingSenderStatistics
{
Statistics(void) { Clear(); }
void Clear(void)
{
mSentCount = 0;
mReceivedCount = 0;
mTotalRoundTripTime = 0;
mMinRoundTripTime = NumericLimits<uint16_t>::kMax;
mMaxRoundTripTime = NumericLimits<uint16_t>::kMin;
mIsMulticast = false;
}
};
/**
* This class represents a ping request configuration.
*
*/
class Config : public otPingSenderConfig
{
friend class PingSender;
public:
/**
* This method gets the source IPv6 address of the ping.
*
* @returns The ping source IPv6 address.
*
*/
Ip6::Address &GetSource(void) { return AsCoreType(&mSource); }
/**
* This method gets the source IPv6 address of the ping.
*
* @returns The ping source IPv6 address.
*
*/
const Ip6::Address &GetSource(void) const { return AsCoreType(&mSource); }
/**
* This method gets the destination IPv6 address to ping.
*
* @returns The ping destination IPv6 address.
*
*/
Ip6::Address &GetDestination(void) { return AsCoreType(&mDestination); }
/**
* This method gets the destination IPv6 address to ping.
*
* @returns The ping destination IPv6 address.
*
*/
const Ip6::Address &GetDestination(void) const { return AsCoreType(&mDestination); }
private:
static constexpr uint16_t kDefaultSize = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE;
static constexpr uint16_t kDefaultCount = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT;
static constexpr uint32_t kDefaultInterval = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL;
static constexpr uint32_t kDefaultTimeout = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_TIMEOUT;
void SetUnspecifiedToDefault(void);
void InvokeReplyCallback(const Reply &aReply) const;
void InvokeStatisticsCallback(const Statistics &aStatistics) 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;
Statistics mStatistics;
uint16_t mIdentifier;
uint16_t mTargetEchoSequence;
TimerMilli mTimer;
Ip6::Icmp::Handler mIcmpHandler;
};
} // namespace Utils
DefineCoreType(otPingSenderReply, Utils::PingSender::Reply);
DefineCoreType(otPingSenderConfig, Utils::PingSender::Config);
DefineCoreType(otPingSenderStatistics, Utils::PingSender::Statistics);
} // namespace ot
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
#endif // PING_SENDER_HPP_