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 /** 60 * Implements MPL header generation and parsing. 61 * 62 */ 63 OT_TOOL_PACKED_BEGIN 64 class MplOption : public Option 65 { 66 public: 67 static constexpr uint8_t kType = 0x6d; ///< MPL option type - 01 1 01101 68 static constexpr uint8_t kMinSize = (2 + sizeof(Option)); ///< Minimum size (num of bytes) of `MplOption` 69 70 /** 71 * MPL Seed Id Lengths. 72 * 73 */ 74 enum SeedIdLength : uint8_t 75 { 76 kSeedIdLength0 = 0 << 6, ///< 0-byte MPL Seed Id Length. 77 kSeedIdLength2 = 1 << 6, ///< 2-byte MPL Seed Id Length. 78 kSeedIdLength8 = 2 << 6, ///< 8-byte MPL Seed Id Length. 79 kSeedIdLength16 = 3 << 6, ///< 16-byte MPL Seed Id Length. 80 }; 81 82 /** 83 * Initializes the MPL Option. 84 * 85 * The @p aSeedIdLength MUST be either `kSeedIdLength0` or `kSeedIdLength2`. Other values are not supported. 86 * 87 * @param[in] aSeedIdLength The MPL Seed Id Length. 88 * 89 */ 90 void Init(SeedIdLength aSeedIdLength); 91 92 /** 93 * Returns the MPL Seed Id Length value. 94 * 95 * @returns The MPL Seed Id Length value. 96 * 97 */ GetSeedIdLength(void) const98 SeedIdLength GetSeedIdLength(void) const { return static_cast<SeedIdLength>(mControl & kSeedIdLengthMask); } 99 100 /** 101 * Indicates whether or not the MPL M flag is set. 102 * 103 * @retval TRUE If the MPL M flag is set. 104 * @retval FALSE If the MPL M flag is not set. 105 * 106 */ IsMaxFlagSet(void) const107 bool IsMaxFlagSet(void) const { return (mControl & kMaxFlag) != 0; } 108 109 /** 110 * Clears the MPL M flag. 111 * 112 */ ClearMaxFlag(void)113 void ClearMaxFlag(void) { mControl &= ~kMaxFlag; } 114 115 /** 116 * Sets the MPL M flag. 117 * 118 */ SetMaxFlag(void)119 void SetMaxFlag(void) { mControl |= kMaxFlag; } 120 121 /** 122 * Returns the MPL Sequence value. 123 * 124 * @returns The MPL Sequence value. 125 * 126 */ GetSequence(void) const127 uint8_t GetSequence(void) const { return mSequence; } 128 129 /** 130 * Sets the MPL Sequence value. 131 * 132 * @param[in] aSequence The MPL Sequence value. 133 * 134 */ SetSequence(uint8_t aSequence)135 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 136 137 /** 138 * Returns the MPL Seed Id value. 139 * 140 * @returns The MPL Seed Id value. 141 * 142 */ GetSeedId(void) const143 uint16_t GetSeedId(void) const { return HostSwap16(mSeedId); } 144 145 /** 146 * Sets the MPL Seed Id value. 147 * 148 * @param[in] aSeedId The MPL Seed Id value. 149 * 150 */ SetSeedId(uint16_t aSeedId)151 void SetSeedId(uint16_t aSeedId) { mSeedId = HostSwap16(aSeedId); } 152 153 private: 154 static constexpr uint8_t kSeedIdLengthMask = 3 << 6; 155 static constexpr uint8_t kMaxFlag = 1 << 5; 156 157 uint8_t mControl; 158 uint8_t mSequence; 159 uint16_t mSeedId; 160 } OT_TOOL_PACKED_END; 161 162 /** 163 * Implements MPL message processing. 164 * 165 */ 166 class Mpl : public InstanceLocator, private NonCopyable 167 { 168 friend class ot::TimeTicker; 169 170 public: 171 /** 172 * Initializes the MPL object. 173 * 174 * @param[in] aInstance A reference to the OpenThread instance. 175 * 176 */ 177 explicit Mpl(Instance &aInstance); 178 179 /** 180 * Initializes the MPL option. 181 * 182 * @param[in] aOption A reference to the MPL header to initialize. 183 * @param[in] aAddress A reference to the IPv6 Source Address. 184 * 185 */ 186 void InitOption(MplOption &aOption, const Address &aAddress); 187 188 /** 189 * Processes an MPL option. When the MPL module acts as an MPL Forwarder 190 * it disseminates MPL Data Message using Trickle timer expirations. When acts as an 191 * MPL Seed it allows to send the first MPL Data Message directly, then sets up Trickle 192 * timer expirations for subsequent retransmissions. 193 * 194 * @param[in] aMessage A reference to the message. 195 * @param[in] aOffset The offset in @p aMessage to read the MPL option. 196 * @param[in] aAddress A reference to the IPv6 Source Address. 197 * @param[in] aIsOutbound TRUE if this message was locally generated, FALSE otherwise. 198 * @param[out] aReceive Set to FALSE if the MPL message is a duplicate and must not 199 * go through the receiving process again, untouched otherwise. 200 * 201 * @retval kErrorNone Successfully processed the MPL option. 202 * @retval kErrorDrop The MPL message is a duplicate and should be dropped. 203 * 204 */ 205 Error ProcessOption(Message &aMessage, uint16_t aOffset, const Address &aAddress, bool aIsOutbound, bool &aReceive); 206 207 #if OPENTHREAD_FTD 208 /** 209 * Returns a reference to the buffered message set. 210 * 211 * @returns A reference to the buffered message set. 212 * 213 */ GetBufferedMessageSet(void) const214 const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; } 215 #endif 216 217 private: 218 static constexpr uint16_t kNumSeedEntries = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRIES; 219 static constexpr uint32_t kSeedEntryLifetime = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRY_LIFETIME; 220 static constexpr uint32_t kSeedEntryLifetimeDt = 1000; 221 static constexpr uint8_t kDataMessageInterval = 64; 222 223 struct SeedEntry 224 { 225 uint16_t mSeedId; 226 uint8_t mSequence; 227 uint8_t mLifetime; 228 }; 229 230 void HandleTimeTick(void); 231 Error UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence); 232 233 SeedEntry mSeedSet[kNumSeedEntries]; 234 uint8_t mSequence; 235 236 #if OPENTHREAD_FTD 237 static constexpr uint8_t kChildTimerExpirations = 0; // MPL retransmissions for Children. 238 static constexpr uint8_t kRouterTimerExpirations = 2; // MPL retransmissions for Routers. 239 240 struct Metadata 241 { AppendToot::Ip6::Mpl::Metadata242 Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); } 243 void ReadFrom(const Message &aMessage); 244 void RemoveFrom(Message &aMessage) const; 245 void UpdateIn(Message &aMessage) const; 246 void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval); 247 248 TimeMilli mTransmissionTime; 249 uint16_t mSeedId; 250 uint8_t mSequence; 251 uint8_t mTransmissionCount; 252 uint8_t mIntervalOffset; 253 }; 254 255 uint8_t GetTimerExpirations(void) const; 256 void HandleRetransmissionTimer(void); 257 void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound); 258 259 using RetxTimer = TimerMilliIn<Mpl, &Mpl::HandleRetransmissionTimer>; 260 261 MessageQueue mBufferedMessageSet; 262 RetxTimer mRetransmissionTimer; 263 #endif // OPENTHREAD_FTD 264 }; 265 266 /** 267 * @} 268 * 269 */ 270 271 } // namespace Ip6 272 } // namespace ot 273 274 #endif // IP6_MPL_HPP_ 275