• 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 /**
30  * @file
31  *   This file includes definitions and methods for generating and processing Thread Network Layer TLVs.
32  */
33 
34 #ifndef THREAD_TLVS_HPP_
35 #define THREAD_TLVS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/encoding.hpp"
40 #include "common/message.hpp"
41 #include "common/tlvs.hpp"
42 #include "meshcop/network_name.hpp"
43 #include "net/ip6_address.hpp"
44 #include "thread/mle.hpp"
45 #include "thread/mle_types.hpp"
46 
47 namespace ot {
48 
49 /**
50  * Implements Network Layer TLV generation and parsing.
51  */
52 OT_TOOL_PACKED_BEGIN
53 class ThreadTlv : public ot::Tlv
54 {
55 public:
56     /**
57      * Network Layer TLV Types.
58      */
59     enum Type : uint8_t
60     {
61         kTarget                = 0,  ///< Target EID TLV
62         kExtMacAddress         = 1,  ///< Extended MAC Address TLV
63         kRloc16                = 2,  ///< RLOC16 TLV
64         kMeshLocalEid          = 3,  ///< ML-EID TLV
65         kStatus                = 4,  ///< Status TLV
66         kLastTransactionTime   = 6,  ///< Time Since Last Transaction TLV
67         kRouterMask            = 7,  ///< Router Mask TLV
68         kNdOption              = 8,  ///< ND Option TLV
69         kNdData                = 9,  ///< ND Data TLV
70         kThreadNetworkData     = 10, ///< Thread Network Data TLV
71         kTimeout               = 11, ///< Timeout TLV
72         kNetworkName           = 12, ///< Network Name TLV
73         kIp6Addresses          = 14, ///< IPv6 Addresses TLV
74         kCommissionerSessionId = 15, ///< Commissioner Session ID TLV
75     };
76 
77     /**
78      * Returns the Type value.
79      *
80      * @returns The Type value.
81      */
GetType(void) const82     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
83 
84     /**
85      * Sets the Type value.
86      *
87      * @param[in]  aType  The Type value.
88      */
SetType(Type aType)89     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
90 
91 } OT_TOOL_PACKED_END;
92 
93 /**
94  * Defines Target TLV constants and types.
95  */
96 typedef SimpleTlvInfo<ThreadTlv::kTarget, Ip6::Address> ThreadTargetTlv;
97 
98 /**
99  * Defines Extended MAC Address TLV constants and types.
100  */
101 typedef SimpleTlvInfo<ThreadTlv::kExtMacAddress, Mac::ExtAddress> ThreadExtMacAddressTlv;
102 
103 /**
104  * Defines RLOC16 TLV constants and types.
105  */
106 typedef UintTlvInfo<ThreadTlv::kRloc16, uint16_t> ThreadRloc16Tlv;
107 
108 /**
109  * Defines ML-EID TLV constants and types.
110  */
111 typedef SimpleTlvInfo<ThreadTlv::kMeshLocalEid, Ip6::InterfaceIdentifier> ThreadMeshLocalEidTlv;
112 
113 /**
114  * Defines Time Since Last Transaction TLV constants and types.
115  */
116 typedef UintTlvInfo<ThreadTlv::kLastTransactionTime, uint32_t> ThreadLastTransactionTimeTlv;
117 
118 /**
119  * Defines Timeout TLV constants and types.
120  */
121 typedef UintTlvInfo<ThreadTlv::kTimeout, uint32_t> ThreadTimeoutTlv;
122 
123 /**
124  * Defines Network Name TLV constants and types.
125  */
126 typedef StringTlvInfo<ThreadTlv::kNetworkName, MeshCoP::NetworkName::kMaxSize> ThreadNetworkNameTlv;
127 
128 /**
129  * Defines Commissioner Session ID TLV constants and types.
130  */
131 typedef UintTlvInfo<ThreadTlv::kCommissionerSessionId, uint16_t> ThreadCommissionerSessionIdTlv;
132 
133 /**
134  * Defines Status TLV constants and types.
135  */
136 class ThreadStatusTlv : public UintTlvInfo<ThreadTlv::kStatus, uint8_t>
137 {
138 public:
139     /**
140      * Status values.
141      */
142     enum Status : uint8_t
143     {
144         kSuccess               = 0, ///< Success.
145         kNoAddressAvailable    = 1, ///< No address available.
146         kTooFewRouters         = 2, ///< Address Solicit due to too few routers.
147         kHaveChildIdRequest    = 3, ///< Address Solicit due to child ID request.
148         kParentPartitionChange = 4, ///< Address Solicit due to parent partition change
149         kBorderRouterRequest   = 5, ///< Address Solicit from Border Router request.
150         kUnrecognizedStatus    = 6, ///< The requested status is unrecognized or not meaningful in a request.
151     };
152 
153     /**
154      * Multicast Listener Registration (MLR) Status values
155      */
156     enum MlrStatus
157     {
158         kMlrSuccess        = 0, ///< Successful (de)registration of all IPv6 addresses.
159         kMlrInvalid        = 2, ///< Invalid IPv6 address(es) in request.
160         kMlrNoPersistent   = 3, ///< This device does not support persistent registrations.
161         kMlrNoResources    = 4, ///< BBR resource shortage.
162         kMlrBbrNotPrimary  = 5, ///< BBR is not Primary at this moment.
163         kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified.
164         kMlrStatusMax      = 6, ///< Max MLR status.
165     };
166 
167     /**
168      * Domain Unicast Address (DUA) Registration Status values
169      */
170     enum DuaStatus : uint8_t
171     {
172         kDuaSuccess        = 0, ///< Successful registration.
173         kDuaReRegister     = 1, ///< Registration was accepted but immediate reregistration is required to solve.
174         kDuaInvalid        = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA.
175         kDuaDuplicate      = 3, ///< Registration rejected (Fatal): DUA is already in use by another device.
176         kDuaNoResources    = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage.
177         kDuaNotPrimary     = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment.
178         kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified.
179     };
180 };
181 
182 /**
183  * Implements Router Mask TLV generation and parsing.
184  */
185 class ThreadRouterMaskTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kRouterMask>
186 {
187 public:
188     /**
189      * Initializes the TLV.
190      */
Init(void)191     void Init(void)
192     {
193         SetType(kRouterMask);
194         SetLength(sizeof(*this) - sizeof(ThreadTlv));
195         mAssignedRouterIdMask.Clear();
196     }
197 
198     /**
199      * Indicates whether or not the TLV appears to be well-formed.
200      *
201      * @retval TRUE   If the TLV appears to be well-formed.
202      * @retval FALSE  If the TLV does not appear to be well-formed.
203      */
IsValid(void) const204     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); }
205 
206     /**
207      * Returns the ID Sequence value.
208      *
209      * @returns The ID Sequence value.
210      */
GetIdSequence(void) const211     uint8_t GetIdSequence(void) const { return mIdSequence; }
212 
213     /**
214      * Sets the ID Sequence value.
215      *
216      * @param[in]  aSequence  The ID Sequence value.
217      */
SetIdSequence(uint8_t aSequence)218     void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; }
219 
220     /**
221      * Gets the Assigned Router ID Mask.
222      *
223      * @returns The Assigned Router ID Mask.
224      */
GetAssignedRouterIdMask(void) const225     const Mle::RouterIdSet &GetAssignedRouterIdMask(void) const { return mAssignedRouterIdMask; }
226 
227     /**
228      * Gets the Assigned Router ID Mask.
229      *
230      * @returns The Assigned Router ID Mask.
231      */
GetAssignedRouterIdMask(void)232     Mle::RouterIdSet &GetAssignedRouterIdMask(void) { return mAssignedRouterIdMask; }
233 
234     /**
235      * Sets the Assigned Router ID Mask.
236      *
237      * @param[in]  aRouterIdSet A reference to the Assigned Router ID Mask.
238      */
SetAssignedRouterIdMask(const Mle::RouterIdSet & aRouterIdSet)239     void SetAssignedRouterIdMask(const Mle::RouterIdSet &aRouterIdSet) { mAssignedRouterIdMask = aRouterIdSet; }
240 
241 private:
242     uint8_t          mIdSequence;
243     Mle::RouterIdSet mAssignedRouterIdMask;
244 };
245 
246 /**
247  * Implements Thread Network Data TLV generation and parsing.
248  */
249 OT_TOOL_PACKED_BEGIN
250 class ThreadNetworkDataTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kThreadNetworkData>
251 {
252 public:
253     /**
254      * Initializes the TLV.
255      */
Init(void)256     void Init(void)
257     {
258         SetType(kThreadNetworkData);
259         SetLength(0);
260     }
261 
262     /**
263      * Overrides same method of the base class
264      *
265      * @retval TRUE  the TLV appears to be well-formed.
266      */
IsValid(void) const267     bool IsValid(void) const { return true; }
268 
269     /**
270      * Returns a pointer to the Network Data TLVs.
271      *
272      * @returns A pointer to the Network Data TLVs.
273      */
GetTlvs(void)274     uint8_t *GetTlvs(void) { return mTlvs; }
275 
276 private:
277     static constexpr uint8_t kMaxSize = 255;
278 
279     uint8_t mTlvs[kMaxSize];
280 } OT_TOOL_PACKED_END;
281 
282 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
283 
284 /**
285  * Implements IPv6 Addresses TLV generation and parsing.
286  */
287 OT_TOOL_PACKED_BEGIN
288 class Ip6AddressesTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kIp6Addresses>
289 {
290 public:
291     // Thread 1.2.0 5.19.13 limits the number of IPv6 addresses to [1, 15].
292     static constexpr uint8_t kMinAddresses = 1;
293     static constexpr uint8_t kMaxAddresses = OT_IP6_MAX_MLR_ADDRESSES;
294 
295     /**
296      * Initializes the TLV.
297      */
Init(void)298     void Init(void) { SetType(kIp6Addresses); }
299 
300     /**
301      * Indicates whether or not the TLV appears to be well-formed.
302      *
303      * @retval TRUE   If the TLV appears to be well-formed.
304      * @retval FALSE  If the TLV does not appear to be well-formed.
305      */
IsValid(void) const306     bool IsValid(void) const
307     {
308         return GetLength() >= sizeof(Ip6::Address) * Ip6AddressesTlv::kMinAddresses &&
309                GetLength() <= sizeof(Ip6::Address) * Ip6AddressesTlv::kMaxAddresses &&
310                (GetLength() % sizeof(Ip6::Address)) == 0;
311     }
312 
313     /**
314      * Returns a pointer to the IPv6 address entry.
315      *
316      * @param[in]  aIndex  The index into the IPv6 address list.
317      *
318      * @returns A reference to the IPv6 address.
319      */
GetIp6Address(uint8_t aIndex) const320     const Ip6::Address &GetIp6Address(uint8_t aIndex) const
321     {
322         return *reinterpret_cast<const Ip6::Address *>(GetValue() + (aIndex * sizeof(Ip6::Address)));
323     }
324 } OT_TOOL_PACKED_END;
325 
326 #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
327 
328 } // namespace ot
329 
330 #endif // THREAD_TLVS_HPP_
331