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