1 /* 2 * Copyright (c) 2021, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions to support ping functionality. 32 */ 33 34 #ifndef PING_SENDER_HPP_ 35 #define PING_SENDER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE 40 41 #include <openthread/ping_sender.h> 42 43 #include "common/code_utils.hpp" 44 #include "common/locator.hpp" 45 #include "common/message.hpp" 46 #include "common/non_copyable.hpp" 47 #include "common/numeric_limits.hpp" 48 #include "common/time.hpp" 49 #include "common/timer.hpp" 50 #include "net/icmp6.hpp" 51 #include "net/ip6_address.hpp" 52 53 namespace ot { 54 namespace Utils { 55 56 /** 57 * This class implements sending ICMPv6 Echo Request messages and processing ICMPv6 Echo Reply messages. 58 * 59 */ 60 class PingSender : public InstanceLocator, private NonCopyable 61 { 62 public: 63 /** 64 * This class represents a ping reply. 65 * 66 */ 67 typedef otPingSenderReply Reply; 68 69 /** 70 * This class represents the statistics of several ping requests. 71 * 72 */ 73 struct Statistics : public otPingSenderStatistics 74 { Statisticsot::Utils::PingSender::Statistics75 Statistics(void) { Clear(); } 76 Clearot::Utils::PingSender::Statistics77 void Clear(void) 78 { 79 mSentCount = 0; 80 mReceivedCount = 0; 81 mTotalRoundTripTime = 0; 82 mMinRoundTripTime = NumericLimits<uint16_t>::kMax; 83 mMaxRoundTripTime = NumericLimits<uint16_t>::kMin; 84 mIsMulticast = false; 85 } 86 }; 87 88 /** 89 * This class represents a ping request configuration. 90 * 91 */ 92 class Config : public otPingSenderConfig 93 { 94 friend class PingSender; 95 96 public: 97 /** 98 * This method gets the source IPv6 address of the ping. 99 * 100 * @returns The ping source IPv6 address. 101 * 102 */ GetSource(void)103 Ip6::Address &GetSource(void) { return static_cast<Ip6::Address &>(mSource); } 104 105 /** 106 * This method gets the source IPv6 address of the ping. 107 * 108 * @returns The ping source IPv6 address. 109 * 110 */ GetSource(void) const111 const Ip6::Address &GetSource(void) const { return static_cast<const Ip6::Address &>(mSource); } 112 113 /** 114 * This method gets the destination IPv6 address to ping. 115 * 116 * @returns The ping destination IPv6 address. 117 * 118 */ GetDestination(void)119 Ip6::Address &GetDestination(void) { return static_cast<Ip6::Address &>(mDestination); } 120 121 /** 122 * This method gets the destination IPv6 address to ping. 123 * 124 * @returns The ping destination IPv6 address. 125 * 126 */ GetDestination(void) const127 const Ip6::Address &GetDestination(void) const { return static_cast<const Ip6::Address &>(mDestination); } 128 129 private: 130 static constexpr uint16_t kDefaultSize = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_SIZE; 131 static constexpr uint16_t kDefaultCount = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_COUNT; 132 static constexpr uint32_t kDefaultInterval = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_INTEVRAL; 133 static constexpr uint32_t kDefaultTimeout = OPENTHREAD_CONFIG_PING_SENDER_DEFAULT_TIMEOUT; 134 135 void SetUnspecifiedToDefault(void); 136 void InvokeReplyCallback(const Reply &aReply) const; 137 void InvokeStatisticsCallback(const Statistics &aStatistics) const; 138 }; 139 140 /** 141 * This constructor initializes the `PingSender` object. 142 * 143 * @param[in] aInstance A reference to the OpenThread instance. 144 * 145 */ 146 explicit PingSender(Instance &aInstance); 147 148 /** 149 * This method starts a ping. 150 * 151 * @param[in] aConfig The ping config to use. 152 * 153 * @retval kErrorNone The ping started successfully. 154 * @retval kErrorBusy Could not start since busy with a previous ongoing ping request. 155 * @retval kErrorInvalidArgs The @p aConfig contains invalid parameters (e.g., ping interval is too long). 156 * 157 */ 158 Error Ping(const Config &aConfig); 159 160 /** 161 * This method stops an ongoing ping. 162 * 163 */ 164 void Stop(void); 165 166 private: 167 void SendPing(void); 168 static void HandleTimer(Timer &aTimer); 169 void HandleTimer(void); 170 static void HandleIcmpReceive(void * aContext, 171 otMessage * aMessage, 172 const otMessageInfo *aMessageInfo, 173 const otIcmp6Header *aIcmpHeader); 174 void HandleIcmpReceive(const Message & aMessage, 175 const Ip6::MessageInfo & aMessageInfo, 176 const Ip6::Icmp::Header &aIcmpHeader); 177 178 Config mConfig; 179 Statistics mStatistics; 180 uint16_t mIdentifier; 181 uint16_t mTargetEchoSequence; 182 TimerMilli mTimer; 183 Ip6::Icmp::Handler mIcmpHandler; 184 }; 185 186 } // namespace Utils 187 } // namespace ot 188 189 #endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE 190 191 #endif // PING_SENDER_HPP_ 192