• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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