1 /* 2 * Copyright (c) 2016, 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 #ifndef IP6_MPL_HPP_ 30 #define IP6_MPL_HPP_ 31 32 /** 33 * @file 34 * This file includes definitions for MPL. 35 */ 36 37 #include "openthread-core-config.h" 38 39 #include "common/locator.hpp" 40 #include "common/message.hpp" 41 #include "common/non_copyable.hpp" 42 #include "common/time_ticker.hpp" 43 #include "common/timer.hpp" 44 #include "net/ip6_headers.hpp" 45 46 namespace ot { 47 namespace Ip6 { 48 49 /** 50 * @addtogroup core-ip6-mpl 51 * 52 * @brief 53 * This module includes definitions for MPL. 54 * 55 * @{ 56 */ 57 58 /** 59 * Implements MPL header generation and parsing. 60 */ 61 OT_TOOL_PACKED_BEGIN 62 class MplOption : public Option 63 { 64 public: 65 static constexpr uint8_t kType = 0x6d; ///< MPL option type - 01 1 01101 66 static constexpr uint8_t kMinSize = (2 + sizeof(Option)); ///< Minimum size (num of bytes) of `MplOption` 67 68 /** 69 * MPL Seed Id Lengths. 70 */ 71 enum SeedIdLength : uint8_t 72 { 73 kSeedIdLength0 = 0 << 6, ///< 0-byte MPL Seed Id Length. 74 kSeedIdLength2 = 1 << 6, ///< 2-byte MPL Seed Id Length. 75 kSeedIdLength8 = 2 << 6, ///< 8-byte MPL Seed Id Length. 76 kSeedIdLength16 = 3 << 6, ///< 16-byte MPL Seed Id Length. 77 }; 78 79 /** 80 * Initializes the MPL Option. 81 * 82 * The @p aSeedIdLength MUST be either `kSeedIdLength0` or `kSeedIdLength2`. Other values are not supported. 83 * 84 * @param[in] aSeedIdLength The MPL Seed Id Length. 85 */ 86 void Init(SeedIdLength aSeedIdLength); 87 88 /** 89 * Returns the MPL Seed Id Length value. 90 * 91 * @returns The MPL Seed Id Length value. 92 */ GetSeedIdLength(void) const93 SeedIdLength GetSeedIdLength(void) const { return static_cast<SeedIdLength>(mControl & kSeedIdLengthMask); } 94 95 /** 96 * Indicates whether or not the MPL M flag is set. 97 * 98 * @retval TRUE If the MPL M flag is set. 99 * @retval FALSE If the MPL M flag is not set. 100 */ IsMaxFlagSet(void) const101 bool IsMaxFlagSet(void) const { return (mControl & kMaxFlag) != 0; } 102 103 /** 104 * Clears the MPL M flag. 105 */ ClearMaxFlag(void)106 void ClearMaxFlag(void) { mControl &= ~kMaxFlag; } 107 108 /** 109 * Sets the MPL M flag. 110 */ SetMaxFlag(void)111 void SetMaxFlag(void) { mControl |= kMaxFlag; } 112 113 /** 114 * Returns the MPL Sequence value. 115 * 116 * @returns The MPL Sequence value. 117 */ GetSequence(void) const118 uint8_t GetSequence(void) const { return mSequence; } 119 120 /** 121 * Sets the MPL Sequence value. 122 * 123 * @param[in] aSequence The MPL Sequence value. 124 */ SetSequence(uint8_t aSequence)125 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 126 127 /** 128 * Returns the MPL Seed Id value. 129 * 130 * @returns The MPL Seed Id value. 131 */ GetSeedId(void) const132 uint16_t GetSeedId(void) const { return BigEndian::HostSwap16(mSeedId); } 133 134 /** 135 * Sets the MPL Seed Id value. 136 * 137 * @param[in] aSeedId The MPL Seed Id value. 138 */ SetSeedId(uint16_t aSeedId)139 void SetSeedId(uint16_t aSeedId) { mSeedId = BigEndian::HostSwap16(aSeedId); } 140 141 private: 142 static constexpr uint8_t kSeedIdLengthMask = 3 << 6; 143 static constexpr uint8_t kMaxFlag = 1 << 5; 144 145 uint8_t mControl; 146 uint8_t mSequence; 147 uint16_t mSeedId; 148 } OT_TOOL_PACKED_END; 149 150 /** 151 * Implements MPL message processing. 152 */ 153 class Mpl : public InstanceLocator, private NonCopyable 154 { 155 friend class ot::TimeTicker; 156 157 public: 158 /** 159 * Initializes the MPL object. 160 * 161 * @param[in] aInstance A reference to the OpenThread instance. 162 */ 163 explicit Mpl(Instance &aInstance); 164 165 /** 166 * Initializes the MPL option. 167 * 168 * @param[in] aOption A reference to the MPL header to initialize. 169 * @param[in] aAddress A reference to the IPv6 Source Address. 170 */ 171 void InitOption(MplOption &aOption, const Address &aAddress); 172 173 /** 174 * Processes an MPL option. When the MPL module acts as an MPL Forwarder 175 * it disseminates MPL Data Message using Trickle timer expirations. When acts as an 176 * MPL Seed it allows to send the first MPL Data Message directly, then sets up Trickle 177 * timer expirations for subsequent retransmissions. 178 * 179 * @param[in] aMessage A reference to the message. 180 * @param[in] aOffsetRange The offset range in @p aMessage to read the MPL option. 181 * @param[in] aAddress A reference to the IPv6 Source Address. 182 * @param[out] aReceive Set to FALSE if the MPL message is a duplicate and must not 183 * go through the receiving process again, untouched otherwise. 184 * 185 * @retval kErrorNone Successfully processed the MPL option. 186 * @retval kErrorDrop The MPL message is a duplicate and should be dropped. 187 */ 188 Error ProcessOption(Message &aMessage, const OffsetRange &aOffsetRange, const Address &aAddress, bool &aReceive); 189 190 #if OPENTHREAD_FTD 191 /** 192 * Returns a reference to the buffered message set. 193 * 194 * @returns A reference to the buffered message set. 195 */ GetBufferedMessageSet(void) const196 const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; } 197 #endif 198 199 private: 200 static constexpr uint16_t kNumSeedEntries = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRIES; 201 static constexpr uint32_t kSeedEntryLifetime = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRY_LIFETIME; 202 static constexpr uint32_t kSeedEntryLifetimeDt = 1000; 203 static constexpr uint8_t kDataMessageInterval = 64; 204 205 struct SeedEntry 206 { 207 uint16_t mSeedId; 208 uint8_t mSequence; 209 uint8_t mLifetime; 210 }; 211 212 void HandleTimeTick(void); 213 Error UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence); 214 215 SeedEntry mSeedSet[kNumSeedEntries]; 216 uint8_t mSequence; 217 218 #if OPENTHREAD_FTD 219 static constexpr uint8_t kChildRetransmissions = 0; // MPL retransmissions for Children. 220 static constexpr uint8_t kRouterRetransmissions = 2; // MPL retransmissions for Routers. 221 222 struct Metadata : public Message::FooterData<Metadata> 223 { 224 void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval); 225 226 TimeMilli mTransmissionTime; 227 uint16_t mSeedId; 228 uint8_t mSequence; 229 uint8_t mTransmissionCount; 230 uint8_t mIntervalOffset; 231 }; 232 233 uint8_t DetermineMaxRetransmissions(void) const; 234 void HandleRetransmissionTimer(void); 235 void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence); 236 237 using RetxTimer = TimerMilliIn<Mpl, &Mpl::HandleRetransmissionTimer>; 238 239 MessageQueue mBufferedMessageSet; 240 RetxTimer mRetransmissionTimer; 241 #endif // OPENTHREAD_FTD 242 }; 243 244 /** 245 * @} 246 */ 247 248 } // namespace Ip6 249 } // namespace ot 250 251 #endif // IP6_MPL_HPP_ 252