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/timer.hpp" 43 #include "net/ip6_headers.hpp" 44 45 namespace ot { 46 namespace Ip6 { 47 48 /** 49 * @addtogroup core-ip6-mpl 50 * 51 * @brief 52 * This module includes definitions for MPL. 53 * 54 * @{ 55 * 56 */ 57 58 /** 59 * This class implements MPL header generation and parsing. 60 * 61 */ 62 OT_TOOL_PACKED_BEGIN 63 class OptionMpl : public OptionHeader 64 { 65 public: 66 static constexpr uint8_t kType = 0x6d; // 01 1 01101 67 static constexpr uint8_t kMinLength = 2; 68 69 /** 70 * This method initializes the MPL header. 71 * 72 */ Init(void)73 void Init(void) 74 { 75 OptionHeader::SetType(kType); 76 OptionHeader::SetLength(sizeof(*this) - sizeof(OptionHeader)); 77 mControl = 0; 78 } 79 80 /** 81 * This method returns the total MPL Option length value including option 82 * header. 83 * 84 * @returns The total IPv6 Option Length. 85 * 86 */ GetTotalLength(void) const87 uint8_t GetTotalLength(void) const { return OptionHeader::GetLength() + sizeof(OptionHeader); } 88 89 /** 90 * MPL Seed Id lengths. 91 * 92 */ 93 enum SeedIdLength : uint8_t 94 { 95 kSeedIdLength0 = 0 << 6, ///< 0-byte MPL Seed Id Length. 96 kSeedIdLength2 = 1 << 6, ///< 2-byte MPL Seed Id Length. 97 kSeedIdLength8 = 2 << 6, ///< 8-byte MPL Seed Id Length. 98 kSeedIdLength16 = 3 << 6, ///< 16-byte MPL Seed Id Length. 99 }; 100 101 /** 102 * This method returns the MPL Seed Id Length value. 103 * 104 * @returns The MPL Seed Id Length value. 105 * 106 */ GetSeedIdLength(void) const107 SeedIdLength GetSeedIdLength(void) const { return static_cast<SeedIdLength>(mControl & kSeedIdLengthMask); } 108 109 /** 110 * This method sets the MPL Seed Id Length value. 111 * 112 * @param[in] aSeedIdLength The MPL Seed Length. 113 * 114 */ SetSeedIdLength(SeedIdLength aSeedIdLength)115 void SetSeedIdLength(SeedIdLength aSeedIdLength) 116 { 117 mControl = static_cast<uint8_t>((mControl & ~kSeedIdLengthMask) | aSeedIdLength); 118 } 119 120 /** 121 * This method indicates whether or not the MPL M flag is set. 122 * 123 * @retval TRUE If the MPL M flag is set. 124 * @retval FALSE If the MPL M flag is not set. 125 * 126 */ IsMaxFlagSet(void) const127 bool IsMaxFlagSet(void) const { return (mControl & kMaxFlag) != 0; } 128 129 /** 130 * This method clears the MPL M flag. 131 * 132 */ ClearMaxFlag(void)133 void ClearMaxFlag(void) { mControl &= ~kMaxFlag; } 134 135 /** 136 * This method sets the MPL M flag. 137 * 138 */ SetMaxFlag(void)139 void SetMaxFlag(void) { mControl |= kMaxFlag; } 140 141 /** 142 * This method returns the MPL Sequence value. 143 * 144 * @returns The MPL Sequence value. 145 * 146 */ GetSequence(void) const147 uint8_t GetSequence(void) const { return mSequence; } 148 149 /** 150 * This method sets the MPL Sequence value. 151 * 152 * @param[in] aSequence The MPL Sequence value. 153 * 154 */ SetSequence(uint8_t aSequence)155 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 156 157 /** 158 * This method returns the MPL Seed Id value. 159 * 160 * @returns The MPL Seed Id value. 161 * 162 */ GetSeedId(void) const163 uint16_t GetSeedId(void) const { return HostSwap16(mSeedId); } 164 165 /** 166 * This method sets the MPL Seed Id value. 167 * 168 * @param[in] aSeedId The MPL Seed Id value. 169 * 170 */ SetSeedId(uint16_t aSeedId)171 void SetSeedId(uint16_t aSeedId) { mSeedId = HostSwap16(aSeedId); } 172 173 private: 174 static constexpr uint8_t kSeedIdLengthMask = 3 << 6; 175 static constexpr uint8_t kMaxFlag = 1 << 5; 176 177 uint8_t mControl; 178 uint8_t mSequence; 179 uint16_t mSeedId; 180 } OT_TOOL_PACKED_END; 181 182 /** 183 * This class implements MPL message processing. 184 * 185 */ 186 class Mpl : public InstanceLocator, private NonCopyable 187 { 188 public: 189 /** 190 * This constructor initializes the MPL object. 191 * 192 * @param[in] aInstance A reference to the OpenThread instance. 193 * 194 */ 195 explicit Mpl(Instance &aInstance); 196 197 /** 198 * This method initializes the MPL option. 199 * 200 * @param[in] aOption A reference to the MPL header to initialize. 201 * @param[in] aAddress A reference to the IPv6 Source Address. 202 * 203 */ 204 void InitOption(OptionMpl &aOption, const Address &aAddress); 205 206 /** 207 * This method processes an MPL option. When the MPL module acts as an MPL Forwarder 208 * it disseminates MPL Data Message using Trickle timer expirations. When acts as an 209 * MPL Seed it allows to send the first MPL Data Message directly, then sets up Trickle 210 * timer expirations for subsequent retransmissions. 211 * 212 * @param[in] aMessage A reference to the message. 213 * @param[in] aAddress A reference to the IPv6 Source Address. 214 * @param[in] aIsOutbound TRUE if this message was locally generated, FALSE otherwise. 215 * @param[out] aReceive Set to FALSE if the MPL message is a duplicate and must not 216 * go through the receiving process again, untouched otherwise. 217 * 218 * @retval kErrorNone Successfully processed the MPL option. 219 * @retval kErrorDrop The MPL message is a duplicate and should be dropped. 220 * 221 */ 222 Error ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound, bool &aReceive); 223 224 /** 225 * This method returns the MPL Seed Id value. 226 * 227 * @returns The MPL Seed Id value. 228 * 229 */ GetSeedId(void) const230 uint16_t GetSeedId(void) const { return mSeedId; } 231 232 /** 233 * This method sets the MPL Seed Id value. 234 * 235 * @param[in] aSeedId The MPL Seed Id value. 236 * 237 */ SetSeedId(uint16_t aSeedId)238 void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; } 239 240 /** 241 * This method sets the IPv6 matching address, that allows to elide MPL Seed Id. 242 * 243 * @param[in] aAddress The reference to the IPv6 matching address. 244 * 245 */ SetMatchingAddress(const Address & aAddress)246 void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; } 247 248 #if OPENTHREAD_FTD 249 /** 250 * This method gets the MPL number of Trickle timer expirations that occur before 251 * terminating the Trickle algorithm's retransmission of a given MPL Data Message. 252 * 253 * @returns The MPL number of Trickle timer expirations. 254 * 255 */ GetTimerExpirations(void) const256 uint8_t GetTimerExpirations(void) const { return mTimerExpirations; } 257 258 /** 259 * This method sets the MPL number of Trickle timer expirations that occur before 260 * terminating the Trickle algorithm's retransmission of a given MPL Data Message. 261 * 262 * @param[in] aTimerExpirations The number of Trickle timer expirations. 263 * 264 */ SetTimerExpirations(uint8_t aTimerExpirations)265 void SetTimerExpirations(uint8_t aTimerExpirations) { mTimerExpirations = aTimerExpirations; } 266 267 /** 268 * This method returns a reference to the buffered message set. 269 * 270 * @returns A reference to the buffered message set. 271 * 272 */ GetBufferedMessageSet(void) const273 const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; } 274 #endif // OPENTHREAD_FTD 275 276 private: 277 static constexpr uint16_t kNumSeedEntries = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRIES; 278 static constexpr uint32_t kSeedEntryLifetime = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRY_LIFETIME; 279 static constexpr uint32_t kSeedEntryLifetimeDt = 1000; 280 static constexpr uint8_t kDataMessageInterval = 64; 281 282 struct SeedEntry 283 { 284 uint16_t mSeedId; 285 uint8_t mSequence; 286 uint8_t mLifetime; 287 }; 288 289 static void HandleSeedSetTimer(Timer &aTimer); 290 void HandleSeedSetTimer(void); 291 292 Error UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence); 293 294 SeedEntry mSeedSet[kNumSeedEntries]; 295 const Address *mMatchingAddress; 296 TimerMilli mSeedSetTimer; 297 uint16_t mSeedId; 298 uint8_t mSequence; 299 300 #if OPENTHREAD_FTD 301 struct Metadata 302 { AppendToot::Ip6::Mpl::Metadata303 Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); } 304 void ReadFrom(const Message &aMessage); 305 void RemoveFrom(Message &aMessage) const; 306 void UpdateIn(Message &aMessage) const; 307 void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval); 308 309 TimeMilli mTransmissionTime; 310 uint16_t mSeedId; 311 uint8_t mSequence; 312 uint8_t mTransmissionCount; 313 uint8_t mIntervalOffset; 314 }; 315 316 static void HandleRetransmissionTimer(Timer &aTimer); 317 void HandleRetransmissionTimer(void); 318 319 void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound); 320 321 MessageQueue mBufferedMessageSet; 322 TimerMilli mRetransmissionTimer; 323 uint8_t mTimerExpirations; 324 #endif // OPENTHREAD_FTD 325 }; 326 327 /** 328 * @} 329 * 330 */ 331 332 } // namespace Ip6 333 } // namespace ot 334 335 #endif // IP6_MPL_HPP_ 336