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 for generating and processing Network Diagnostics TLVs.
32  */
33 
34 #ifndef NETWORK_DIAGNOSTIC_TLVS_HPP_
35 #define NETWORK_DIAGNOSTIC_TLVS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/netdiag.h>
40 #include <openthread/thread.h>
41 
42 #include "common/clearable.hpp"
43 #include "common/encoding.hpp"
44 #include "common/message.hpp"
45 #include "common/tlvs.hpp"
46 #include "net/ip6_address.hpp"
47 #include "radio/radio.hpp"
48 #include "thread/child.hpp"
49 #include "thread/link_quality.hpp"
50 #include "thread/mle_tlvs.hpp"
51 #include "thread/mle_types.hpp"
52 #include "thread/router.hpp"
53 
54 namespace ot {
55 namespace NetworkDiagnostic {
56 
57 using ot::Encoding::BigEndian::HostSwap16;
58 using ot::Encoding::BigEndian::HostSwap32;
59 
60 /**
61  * Implements Network Diagnostic TLV generation and parsing.
62  *
63  */
64 OT_TOOL_PACKED_BEGIN
65 class Tlv : public ot::Tlv
66 {
67 public:
68     /**
69      * Network Diagnostic TLV Types.
70      *
71      */
72     enum Type : uint8_t
73     {
74         kExtMacAddress       = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS,
75         kAddress16           = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS,
76         kMode                = OT_NETWORK_DIAGNOSTIC_TLV_MODE,
77         kTimeout             = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT,
78         kConnectivity        = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY,
79         kRoute               = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE,
80         kLeaderData          = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA,
81         kNetworkData         = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA,
82         kIp6AddressList      = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST,
83         kMacCounters         = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS,
84         kBatteryLevel        = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL,
85         kSupplyVoltage       = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE,
86         kChildTable          = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE,
87         kChannelPages        = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES,
88         kTypeList            = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST,
89         kMaxChildTimeout     = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT,
90         kVersion             = OT_NETWORK_DIAGNOSTIC_TLV_VERSION,
91         kVendorName          = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME,
92         kVendorModel         = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL,
93         kVendorSwVersion     = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION,
94         kThreadStackVersion  = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION,
95         kChild               = OT_NETWORK_DIAGNOSTIC_TLV_CHILD,
96         kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST,
97         kRouterNeighbor      = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR,
98         kAnswer              = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER,
99         kQueryId             = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID,
100         kMleCounters         = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS,
101     };
102 
103     /**
104      * Maximum length of Vendor Name TLV.
105      *
106      */
107     static constexpr uint8_t kMaxVendorNameLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH;
108 
109     /**
110      * Maximum length of Vendor Model TLV.
111      *
112      */
113     static constexpr uint8_t kMaxVendorModelLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH;
114 
115     /**
116      * Maximum length of Vendor SW Version TLV.
117      *
118      */
119     static constexpr uint8_t kMaxVendorSwVersionLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH;
120 
121     /**
122      * Maximum length of Vendor SW Version TLV.
123      *
124      */
125     static constexpr uint8_t kMaxThreadStackVersionLength = OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH;
126 
127     /**
128      * Returns the Type value.
129      *
130      * @returns The Type value.
131      *
132      */
GetType(void) const133     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
134 
135     /**
136      * Sets the Type value.
137      *
138      * @param[in]  aType  The Type value.
139      *
140      */
SetType(Type aType)141     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
142 
143 } OT_TOOL_PACKED_END;
144 
145 /**
146  * Defines Extended MAC Address TLV constants and types.
147  *
148  */
149 typedef SimpleTlvInfo<Tlv::kExtMacAddress, Mac::ExtAddress> ExtMacAddressTlv;
150 
151 /**
152  * Defines Address16 TLV constants and types.
153  *
154  */
155 typedef UintTlvInfo<Tlv::kAddress16, uint16_t> Address16Tlv;
156 
157 /**
158  * Defines Mode TLV constants and types.
159  *
160  */
161 typedef UintTlvInfo<Tlv::kMode, uint8_t> ModeTlv;
162 
163 /**
164  * Defines Timeout TLV constants and types.
165  *
166  */
167 typedef UintTlvInfo<Tlv::kTimeout, uint32_t> TimeoutTlv;
168 
169 /**
170  * Defines Network Data TLV constants and types.
171  *
172  */
173 typedef TlvInfo<Tlv::kNetworkData> NetworkDataTlv;
174 
175 /**
176  * Defines IPv6 Address List TLV constants and types.
177  *
178  */
179 typedef TlvInfo<Tlv::kIp6AddressList> Ip6AddressListTlv;
180 
181 /**
182  * Defines Battery Level TLV constants and types.
183  *
184  */
185 typedef UintTlvInfo<Tlv::kBatteryLevel, uint8_t> BatteryLevelTlv;
186 
187 /**
188  * Defines Supply Voltage TLV constants and types.
189  *
190  */
191 typedef UintTlvInfo<Tlv::kSupplyVoltage, uint16_t> SupplyVoltageTlv;
192 
193 /**
194  * Defines Child Table TLV constants and types.
195  *
196  */
197 typedef TlvInfo<Tlv::kChildTable> ChildTableTlv;
198 
199 /**
200  * Defines Max Child Timeout TLV constants and types.
201  *
202  */
203 typedef UintTlvInfo<Tlv::kMaxChildTimeout, uint32_t> MaxChildTimeoutTlv;
204 
205 /**
206  * Defines Version TLV constants and types.
207  *
208  */
209 typedef UintTlvInfo<Tlv::kVersion, uint16_t> VersionTlv;
210 
211 /**
212  * Defines Vendor Name TLV constants and types.
213  *
214  */
215 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv;
216 
217 /**
218  * Defines Vendor Model TLV constants and types.
219  *
220  */
221 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv;
222 
223 /**
224  * Defines Vendor SW Version TLV constants and types.
225  *
226  */
227 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv;
228 
229 /**
230  * Defines Thread Stack Version TLV constants and types.
231  *
232  */
233 typedef StringTlvInfo<Tlv::kThreadStackVersion, Tlv::kMaxThreadStackVersionLength> ThreadStackVersionTlv;
234 
235 /**
236  * Defines Child IPv6 Address List TLV constants and types.
237  *
238  */
239 typedef TlvInfo<Tlv::kChildIp6AddressList> ChildIp6AddressListTlv;
240 
241 /**
242  * Defines Query ID TLV constants and types.
243  *
244  */
245 typedef UintTlvInfo<Tlv::kQueryId, uint16_t> QueryIdTlv;
246 
247 typedef otNetworkDiagConnectivity Connectivity; ///< Network Diagnostic Connectivity value.
248 
249 /**
250  * Implements Connectivity TLV generation and parsing.
251  *
252  */
253 OT_TOOL_PACKED_BEGIN
254 class ConnectivityTlv : public Mle::ConnectivityTlv
255 {
256 public:
257     static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kConnectivity; ///< The TLV Type value.
258 
259     /**
260      * Initializes the TLV.
261      *
262      */
Init(void)263     void Init(void)
264     {
265         Mle::ConnectivityTlv::Init();
266         ot::Tlv::SetType(kType);
267     }
268 
269     /**
270      * Retrieves the `Connectivity` value.
271      *
272      * @param[out] aConnectivity   A reference to `Connectivity` to populate.
273      *
274      */
GetConnectivity(Connectivity & aConnectivity) const275     void GetConnectivity(Connectivity &aConnectivity) const
276     {
277         aConnectivity.mParentPriority   = GetParentPriority();
278         aConnectivity.mLinkQuality3     = GetLinkQuality3();
279         aConnectivity.mLinkQuality2     = GetLinkQuality2();
280         aConnectivity.mLinkQuality1     = GetLinkQuality1();
281         aConnectivity.mLeaderCost       = GetLeaderCost();
282         aConnectivity.mIdSequence       = GetIdSequence();
283         aConnectivity.mActiveRouters    = GetActiveRouters();
284         aConnectivity.mSedBufferSize    = GetSedBufferSize();
285         aConnectivity.mSedDatagramCount = GetSedDatagramCount();
286     }
287 
288 } OT_TOOL_PACKED_END;
289 
290 /**
291  * Implements Route TLV generation and parsing.
292  *
293  */
294 OT_TOOL_PACKED_BEGIN
295 class RouteTlv : public Mle::RouteTlv
296 {
297 public:
298     static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kRoute; ///< The TLV Type value.
299 
300     /**
301      * Initializes the TLV.
302      *
303      */
Init(void)304     void Init(void)
305     {
306         Mle::RouteTlv::Init();
307         ot::Tlv::SetType(kType);
308     }
309 } OT_TOOL_PACKED_END;
310 
311 /**
312  * Implements Leader Data TLV generation and parsing.
313  *
314  */
315 OT_TOOL_PACKED_BEGIN
316 class LeaderDataTlv : public Mle::LeaderDataTlv
317 {
318 public:
319     static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kLeaderData; ///< The TLV Type value.
320 
321     /**
322      * Initializes the TLV.
323      *
324      */
Init(void)325     void Init(void)
326     {
327         Mle::LeaderDataTlv::Init();
328         ot::Tlv::SetType(kType);
329     }
330 } OT_TOOL_PACKED_END;
331 
332 /**
333  * Implements Mac Counters TLV generation and parsing.
334  *
335  */
336 OT_TOOL_PACKED_BEGIN
337 class MacCountersTlv : public Tlv, public TlvInfo<Tlv::kMacCounters>
338 {
339 public:
340     /**
341      * Initializes the TLV.
342      *
343      */
Init(void)344     void Init(void)
345     {
346         SetType(kMacCounters);
347         SetLength(sizeof(*this) - sizeof(Tlv));
348     }
349 
350     /**
351      * Indicates whether or not the TLV appears to be well-formed.
352      *
353      * @retval TRUE   If the TLV appears to be well-formed.
354      * @retval FALSE  If the TLV does not appear to be well-formed.
355      *
356      */
IsValid(void) const357     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
358 
359     /**
360      * Returns the IfInUnknownProtos counter.
361      *
362      * @returns The IfInUnknownProtos counter
363      *
364      */
GetIfInUnknownProtos(void) const365     uint32_t GetIfInUnknownProtos(void) const { return HostSwap32(mIfInUnknownProtos); }
366 
367     /**
368      * Sets the IfInUnknownProtos counter.
369      *
370      * @param[in]  aIfInUnknownProtos The IfInUnknownProtos counter
371      *
372      */
SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos)373     void SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos)
374     {
375         mIfInUnknownProtos = HostSwap32(aIfInUnknownProtos);
376     }
377 
378     /**
379      * Returns the IfInErrors counter.
380      *
381      * @returns The IfInErrors counter
382      *
383      */
GetIfInErrors(void) const384     uint32_t GetIfInErrors(void) const { return HostSwap32(mIfInErrors); }
385 
386     /**
387      * Sets the IfInErrors counter.
388      *
389      * @param[in]  aIfInErrors The IfInErrors counter
390      *
391      */
SetIfInErrors(const uint32_t aIfInErrors)392     void SetIfInErrors(const uint32_t aIfInErrors) { mIfInErrors = HostSwap32(aIfInErrors); }
393 
394     /**
395      * Returns the IfOutErrors counter.
396      *
397      * @returns The IfOutErrors counter
398      *
399      */
GetIfOutErrors(void) const400     uint32_t GetIfOutErrors(void) const { return HostSwap32(mIfOutErrors); }
401 
402     /**
403      * Sets the IfOutErrors counter.
404      *
405      * @param[in]  aIfOutErrors The IfOutErrors counter.
406      *
407      */
SetIfOutErrors(const uint32_t aIfOutErrors)408     void SetIfOutErrors(const uint32_t aIfOutErrors) { mIfOutErrors = HostSwap32(aIfOutErrors); }
409 
410     /**
411      * Returns the IfInUcastPkts counter.
412      *
413      * @returns The IfInUcastPkts counter
414      *
415      */
GetIfInUcastPkts(void) const416     uint32_t GetIfInUcastPkts(void) const { return HostSwap32(mIfInUcastPkts); }
417 
418     /**
419      * Sets the IfInUcastPkts counter.
420      *
421      * @param[in]  aIfInUcastPkts The IfInUcastPkts counter.
422      *
423      */
SetIfInUcastPkts(const uint32_t aIfInUcastPkts)424     void SetIfInUcastPkts(const uint32_t aIfInUcastPkts) { mIfInUcastPkts = HostSwap32(aIfInUcastPkts); }
425     /**
426      * Returns the IfInBroadcastPkts counter.
427      *
428      * @returns The IfInBroadcastPkts counter
429      *
430      */
GetIfInBroadcastPkts(void) const431     uint32_t GetIfInBroadcastPkts(void) const { return HostSwap32(mIfInBroadcastPkts); }
432 
433     /**
434      * Sets the IfInBroadcastPkts counter.
435      *
436      * @param[in]  aIfInBroadcastPkts The IfInBroadcastPkts counter.
437      *
438      */
SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts)439     void SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts)
440     {
441         mIfInBroadcastPkts = HostSwap32(aIfInBroadcastPkts);
442     }
443 
444     /**
445      * Returns the IfInDiscards counter.
446      *
447      * @returns The IfInDiscards counter
448      *
449      */
GetIfInDiscards(void) const450     uint32_t GetIfInDiscards(void) const { return HostSwap32(mIfInDiscards); }
451 
452     /**
453      * Sets the IfInDiscards counter.
454      *
455      * @param[in]  aIfInDiscards The IfInDiscards counter.
456      *
457      */
SetIfInDiscards(const uint32_t aIfInDiscards)458     void SetIfInDiscards(const uint32_t aIfInDiscards) { mIfInDiscards = HostSwap32(aIfInDiscards); }
459 
460     /**
461      * Returns the IfOutUcastPkts counter.
462      *
463      * @returns The IfOutUcastPkts counter
464      *
465      */
GetIfOutUcastPkts(void) const466     uint32_t GetIfOutUcastPkts(void) const { return HostSwap32(mIfOutUcastPkts); }
467 
468     /**
469      * Sets the IfOutUcastPkts counter.
470      *
471      * @param[in]  aIfOutUcastPkts The IfOutUcastPkts counter.
472      *
473      */
SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts)474     void SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts) { mIfOutUcastPkts = HostSwap32(aIfOutUcastPkts); }
475 
476     /**
477      * Returns the IfOutBroadcastPkts counter.
478      *
479      * @returns The IfOutBroadcastPkts counter
480      *
481      */
GetIfOutBroadcastPkts(void) const482     uint32_t GetIfOutBroadcastPkts(void) const { return HostSwap32(mIfOutBroadcastPkts); }
483 
484     /**
485      * Sets the IfOutBroadcastPkts counter.
486      *
487      * @param[in]  aIfOutBroadcastPkts The IfOutBroadcastPkts counter.
488      *
489      */
SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts)490     void SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts)
491     {
492         mIfOutBroadcastPkts = HostSwap32(aIfOutBroadcastPkts);
493     }
494 
495     /**
496      * Returns the IfOutDiscards counter.
497      *
498      * @returns The IfOutDiscards counter
499      *
500      */
GetIfOutDiscards(void) const501     uint32_t GetIfOutDiscards(void) const { return HostSwap32(mIfOutDiscards); }
502 
503     /**
504      * Sets the IfOutDiscards counter.
505      *
506      * @param[in]  aIfOutDiscards The IfOutDiscards counter.
507      *
508      */
SetIfOutDiscards(const uint32_t aIfOutDiscards)509     void SetIfOutDiscards(const uint32_t aIfOutDiscards) { mIfOutDiscards = HostSwap32(aIfOutDiscards); }
510 
511 private:
512     uint32_t mIfInUnknownProtos;
513     uint32_t mIfInErrors;
514     uint32_t mIfOutErrors;
515     uint32_t mIfInUcastPkts;
516     uint32_t mIfInBroadcastPkts;
517     uint32_t mIfInDiscards;
518     uint32_t mIfOutUcastPkts;
519     uint32_t mIfOutBroadcastPkts;
520     uint32_t mIfOutDiscards;
521 } OT_TOOL_PACKED_END;
522 
523 /**
524  * Implements Child Table Entry generation and parsing.
525  *
526  */
527 OT_TOOL_PACKED_BEGIN
528 class ChildTableEntry : public Clearable<ChildTableEntry>
529 {
530 public:
531     /**
532      * Returns the Timeout value.
533      *
534      * @returns The Timeout value.
535      *
536      */
GetTimeout(void) const537     uint8_t GetTimeout(void) const { return (GetTimeoutChildId() & kTimeoutMask) >> kTimeoutOffset; }
538 
539     /**
540      * Sets the Timeout value.
541      *
542      * @param[in]  aTimeout  The Timeout value.
543      *
544      */
SetTimeout(uint8_t aTimeout)545     void SetTimeout(uint8_t aTimeout)
546     {
547         SetTimeoutChildId((GetTimeoutChildId() & ~kTimeoutMask) | ((aTimeout << kTimeoutOffset) & kTimeoutMask));
548     }
549 
550     /**
551      * The Link Quality value.
552      *
553      * @returns The Link Quality value.
554      *
555      */
GetLinkQuality(void) const556     LinkQuality GetLinkQuality(void) const
557     {
558         return static_cast<LinkQuality>((GetTimeoutChildId() & kLqiMask) >> kLqiOffset);
559     }
560 
561     /**
562      * Set the Link Quality value.
563      *
564      * @param[in] aLinkQuality  The Link Quality value.
565      *
566      */
SetLinkQuality(LinkQuality aLinkQuality)567     void SetLinkQuality(LinkQuality aLinkQuality)
568     {
569         SetTimeoutChildId((GetTimeoutChildId() & ~kLqiMask) | ((aLinkQuality << kLqiOffset) & kLqiMask));
570     }
571 
572     /**
573      * Returns the Child ID value.
574      *
575      * @returns The Child ID value.
576      *
577      */
GetChildId(void) const578     uint16_t GetChildId(void) const { return (GetTimeoutChildId() & kChildIdMask) >> kChildIdOffset; }
579 
580     /**
581      * Sets the Child ID value.
582      *
583      * @param[in]  aChildId  The Child ID value.
584      *
585      */
SetChildId(uint16_t aChildId)586     void SetChildId(uint16_t aChildId)
587     {
588         SetTimeoutChildId((GetTimeoutChildId() & ~kChildIdMask) | ((aChildId << kChildIdOffset) & kChildIdMask));
589     }
590 
591     /**
592      * Returns the Device Mode
593      *
594      * @returns The Device Mode
595      *
596      */
GetMode(void) const597     Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); }
598 
599     /**
600      * Sets the Device Mode.
601      *
602      * @param[in]  aMode  The Device Mode.
603      *
604      */
SetMode(Mle::DeviceMode aMode)605     void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); }
606 
607 private:
608     //             1                   0
609     //   5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
610     //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
611     //  | Timeout |LQI|     Child ID    |
612     //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
613 
614     static constexpr uint8_t  kTimeoutOffset = 11;
615     static constexpr uint8_t  kLqiOffset     = 9;
616     static constexpr uint8_t  kChildIdOffset = 0;
617     static constexpr uint16_t kTimeoutMask   = 0x1f << kTimeoutOffset;
618     static constexpr uint16_t kLqiMask       = 0x3 << kLqiOffset;
619     static constexpr uint16_t kChildIdMask   = 0x1ff << kChildIdOffset;
620 
GetTimeoutChildId(void) const621     uint16_t GetTimeoutChildId(void) const { return HostSwap16(mTimeoutChildId); }
SetTimeoutChildId(uint16_t aTimeoutChildIf)622     void     SetTimeoutChildId(uint16_t aTimeoutChildIf) { mTimeoutChildId = HostSwap16(aTimeoutChildIf); }
623 
624     uint16_t mTimeoutChildId;
625     uint8_t  mMode;
626 } OT_TOOL_PACKED_END;
627 
628 /**
629  * Implements Channel Pages TLV generation and parsing.
630  *
631  */
632 OT_TOOL_PACKED_BEGIN
633 class ChannelPagesTlv : public Tlv, public TlvInfo<Tlv::kChannelPages>
634 {
635 public:
636     /**
637      * Initializes the TLV.
638      *
639      */
Init(void)640     void Init(void)
641     {
642         SetType(kChannelPages);
643         SetLength(sizeof(*this) - sizeof(Tlv));
644     }
645 
646     /**
647      * Indicates whether or not the TLV appears to be well-formed.
648      *
649      * @retval TRUE   If the TLV appears to be well-formed.
650      * @retval FALSE  If the TLV does not appear to be well-formed.
651      *
652      */
IsValid(void) const653     bool IsValid(void) const
654     {
655         // At least one channel page must be included.
656         return GetLength() >= 1;
657     }
658 
659     /**
660      * Returns a pointer to the list of Channel Pages.
661      *
662      * @returns A pointer to the list of Channel Pages.
663      *
664      */
GetChannelPages(void)665     uint8_t *GetChannelPages(void) { return mChannelPages; }
666 
667 private:
668     uint8_t mChannelPages[Radio::kNumChannelPages];
669 } OT_TOOL_PACKED_END;
670 
671 /**
672  * Implements IPv6 Address List TLV generation and parsing.
673  *
674  */
675 OT_TOOL_PACKED_BEGIN
676 class TypeListTlv : public Tlv, public TlvInfo<Tlv::kTypeList>
677 {
678 public:
679     /**
680      * Initializes the TLV.
681      *
682      */
Init(void)683     void Init(void)
684     {
685         SetType(kTypeList);
686         SetLength(sizeof(*this) - sizeof(Tlv));
687     }
688 } OT_TOOL_PACKED_END;
689 
690 #if OPENTHREAD_FTD
691 
692 /**
693  * Implements Child TLV generation and parsing.
694  *
695  */
696 OT_TOOL_PACKED_BEGIN
697 class ChildTlv : public Tlv, public TlvInfo<Tlv::kChild>, public Clearable<ChildTlv>
698 {
699 public:
700     static constexpr uint8_t kFlagsRxOnWhenIdle = 1 << 7; ///< Device mode - Rx-on when idle.
701     static constexpr uint8_t kFlagsFtd          = 1 << 6; ///< Device mode - Full Thread Device (FTD).
702     static constexpr uint8_t kFlagsFullNetdta   = 1 << 5; ///< Device mode - Full Network Data.
703     static constexpr uint8_t kFlagsCslSync      = 1 << 4; ///< Is CSL capable and CSL synchronized.
704     static constexpr uint8_t kFlagsTrackErrRate = 1 << 3; ///< Supports tracking error rates.
705 
706     /**
707      * Initializes the TLV using information from a given `Child`.
708      *
709      * @param[in] aChild   The child to initialize the TLV from.
710      *
711      */
712     void InitFrom(const Child &aChild);
713 
714     /**
715      * Initializes the TLV as empty (zero length).
716      *
717      */
InitAsEmpty(void)718     void InitAsEmpty(void)
719     {
720         SetType(kChild);
721         SetLength(0);
722     }
723 
724     /**
725      * Returns the Flags field (`kFlags*` constants define bits in flags).
726      *
727      * @returns The Flags field.
728      *
729      */
GetFlags(void) const730     uint8_t GetFlags(void) const { return mFlags; }
731 
732     /**
733      * Returns the RLOC16 field.
734      *
735      * @returns The RLOC16 of the child.
736      *
737      */
GetRloc16(void) const738     uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
739 
740     /**
741      * Returns the Extended Address.
742      *
743      * @returns The Extended Address of the child.
744      *
745      */
GetExtAddress(void) const746     const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
747 
748     /**
749      * Returns the Version field.
750      *
751      * @returns The Version of the child.
752      *
753      */
GetVersion(void) const754     uint16_t GetVersion(void) const { return HostSwap16(mVersion); }
755 
756     /**
757      * Returns the Timeout field
758      *
759      * @returns The Timeout value in seconds.
760      *
761      */
GetTimeout(void) const762     uint32_t GetTimeout(void) const { return HostSwap32(mTimeout); }
763 
764     /**
765      * Returns the Age field.
766      *
767      * @returns The Age field (seconds since last heard from the child).
768      *
769      */
GetAge(void) const770     uint32_t GetAge(void) const { return HostSwap32(mAge); }
771 
772     /**
773      * Returns the Connection Time field.
774      *
775      * @returns The Connection Time field (seconds since attach).
776      *
777      */
GetConnectionTime(void) const778     uint32_t GetConnectionTime(void) const { return HostSwap32(mConnectionTime); }
779 
780     /**
781      * Returns the Supervision Interval field
782      *
783      * @returns The Supervision Interval in seconds. Zero indicates not used.
784      *
785      */
GetSupervisionInterval(void) const786     uint16_t GetSupervisionInterval(void) const { return HostSwap16(mSupervisionInterval); }
787 
788     /**
789      * Returns the Link Margin field.
790      *
791      * @returns The Link Margin in dB.
792      *
793      */
GetLinkMargin(void) const794     uint8_t GetLinkMargin(void) const { return mLinkMargin; }
795 
796     /**
797      * Returns the Average RSSI field.
798      *
799      * @returns The Average RSSI in dBm. 127 if not available or unknown.
800      *
801      */
GetAverageRssi(void) const802     int8_t GetAverageRssi(void) const { return mAverageRssi; }
803 
804     /**
805      * Returns the Last RSSI field (RSSI of last received frame from child).
806      *
807      * @returns The Last RSSI field in dBm. 127 if not available or unknown.
808      *
809      */
GetLastRssi(void) const810     int8_t GetLastRssi(void) const { return mLastRssi; }
811 
812     /**
813      * Returns the Frame Error Rate field.
814      *
815      * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error
816      * rates and whether or not the value in this field is valid.
817      *
818      * @returns The Frame Error Rate (0x0000->0%, 0xffff->100%).
819      *
820      */
GetFrameErrorRate(void) const821     uint16_t GetFrameErrorRate(void) const { return HostSwap16(mFrameErrorRate); }
822 
823     /**
824      * Returns the Message Error Rate field.
825      *
826      * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error
827      * rates and whether or not the value in this field is valid.
828      *
829      * @returns The Message Error Rate (0x0000->0%, 0xffff->100%).
830      *
831      */
GetMessageErrorRate(void) const832     uint16_t GetMessageErrorRate(void) const { return HostSwap16(mMessageErrorRate); }
833 
834     /**
835      * Returns the Queued Message Count field.
836      *
837      * @returns The Queued Message Count (number of queued messages for indirect tx to child).
838      *
839      */
GetQueuedMessageCount(void) const840     uint16_t GetQueuedMessageCount(void) const { return HostSwap16(mQueuedMessageCount); }
841 
842     /**
843      * Returns the CSL Period in unit of 10 symbols.
844      *
845      * @returns The CSL Period in unit of 10-symbols-time. Zero if CSL is not supported.
846      *
847      */
GetCslPeriod(void) const848     uint16_t GetCslPeriod(void) const { return HostSwap16(mCslPeriod); }
849 
850     /**
851      * Returns the CSL Timeout in seconds.
852      *
853      * @returns The CSL Timeout in seconds. Zero if unknown on parent of if CSL Is not supported.
854      *
855      */
GetCslTimeout(void) const856     uint32_t GetCslTimeout(void) const { return HostSwap32(mCslTimeout); }
857 
858     /**
859      * Returns the CSL Channel.
860      *
861      * @returns The CSL channel.
862      *
863      */
GetCslChannel(void) const864     uint8_t GetCslChannel(void) const { return mCslChannel; }
865 
866 private:
867     uint8_t         mFlags;               // Flags (`kFlags*` constants).
868     uint16_t        mRloc16;              // RLOC16.
869     Mac::ExtAddress mExtAddress;          // Extended Address.
870     uint16_t        mVersion;             // Version.
871     uint32_t        mTimeout;             // Timeout in seconds.
872     uint32_t        mAge;                 // Seconds since last heard from the child.
873     uint32_t        mConnectionTime;      // Seconds since attach.
874     uint16_t        mSupervisionInterval; // Supervision interval in seconds. Zero to indicate not used.
875     uint8_t         mLinkMargin;          // Link margin in dB.
876     int8_t          mAverageRssi;         // Average RSSI. 127 if not available or unknown
877     int8_t          mLastRssi;            // RSSI of last received frame. 127 if not available or unknown.
878     uint16_t        mFrameErrorRate;      // Frame error rate (0x0000->0%, 0xffff->100%).
879     uint16_t        mMessageErrorRate;    // (IPv6) msg error rate (0x0000->0%, 0xffff->100%)
880     uint16_t        mQueuedMessageCount;  // Number of queued messages for indirect tx to child.
881     uint16_t        mCslPeriod;           // CSL Period in unit of 10 symbols.
882     uint32_t        mCslTimeout;          // CSL Timeout in seconds.
883     uint8_t         mCslChannel;          // CSL channel.
884 } OT_TOOL_PACKED_END;
885 
886 /**
887  * Implements Child IPv6 Address List Value generation and parsing.
888  *
889  * This TLV can use extended or normal format depending on the number of IPv6 addresses.
890  *
891  */
892 OT_TOOL_PACKED_BEGIN
893 class ChildIp6AddressListTlvValue
894 {
895 public:
896     /**
897      * Returns the RLOC16 of the child.
898      *
899      * @returns The RLOC16 of the child.
900      *
901      */
GetRloc16(void) const902     uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
903 
904     /**
905      * Sets the RLOC16.
906      *
907      * @param[in] aRloc16   The RLOC16 value.
908      *
909      */
SetRloc16(uint16_t aRloc16)910     void SetRloc16(uint16_t aRloc16) { mRloc16 = HostSwap16(aRloc16); }
911 
912 private:
913     uint16_t mRloc16;
914     // Followed by zero or more IPv6 address(es).
915 
916 } OT_TOOL_PACKED_END;
917 
918 /**
919  * Implements Router Neighbor TLV generation and parsing.
920  *
921  */
922 OT_TOOL_PACKED_BEGIN
923 class RouterNeighborTlv : public Tlv, public TlvInfo<Tlv::kRouterNeighbor>, public Clearable<RouterNeighborTlv>
924 {
925 public:
926     static constexpr uint8_t kFlagsTrackErrRate = 1 << 7; ///< Supports tracking error rates.
927 
928     /**
929      * Initializes the TLV using information from a given `Router`.
930      *
931      * @param[in] aRouter   The router to initialize the TLV from.
932      *
933      */
934     void InitFrom(const Router &aRouter);
935 
936     /**
937      * Initializes the TLV as empty (zero length).
938      *
939      */
InitAsEmpty(void)940     void InitAsEmpty(void)
941     {
942         SetType(kRouterNeighbor);
943         SetLength(0);
944     }
945 
946     /**
947      * Returns the Flags field (`kFlags*` constants define bits in flags).
948      *
949      * @returns The Flags field.
950      *
951      */
GetFlags(void) const952     uint8_t GetFlags(void) const { return mFlags; }
953 
954     /**
955      * Returns the RLOC16 field.
956      *
957      * @returns The RLOC16 of the router.
958      *
959      */
GetRloc16(void) const960     uint16_t GetRloc16(void) const { return HostSwap16(mRloc16); }
961 
962     /**
963      * Returns the Extended Address.
964      *
965      * @returns The Extended Address of the router.
966      *
967      */
GetExtAddress(void) const968     const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
969 
970     /**
971      * Returns the Version field.
972      *
973      * @returns The Version of the router.
974      *
975      */
GetVersion(void) const976     uint16_t GetVersion(void) const { return HostSwap16(mVersion); }
977 
978     /**
979      * Returns the Connection Time field.
980      *
981      * @returns The Connection Time field (seconds since link establishment).
982      *
983      */
GetConnectionTime(void) const984     uint32_t GetConnectionTime(void) const { return HostSwap32(mConnectionTime); }
985 
986     /**
987      * Returns the Link Margin field.
988      *
989      * @returns The Link Margin in dB.
990      *
991      */
GetLinkMargin(void) const992     uint8_t GetLinkMargin(void) const { return mLinkMargin; }
993 
994     /**
995      * Returns the Average RSSI field.
996      *
997      * @returns The Average RSSI in dBm. 127 if not available or unknown.
998      *
999      */
GetAverageRssi(void) const1000     int8_t GetAverageRssi(void) const { return mAverageRssi; }
1001 
1002     /**
1003      * Returns the Last RSSI field (RSSI of last received frame from router).
1004      *
1005      * @returns The Last RSSI field in dBm. 127 if not available or unknown.
1006      *
1007      */
GetLastRssi(void) const1008     int8_t GetLastRssi(void) const { return mLastRssi; }
1009 
1010     /**
1011      * Returns the Frame Error Rate field.
1012      *
1013      * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error
1014      * rates and whether or not the value in this field is valid.
1015      *
1016      * @returns The Frame Error Rate (0x0000->0%, 0xffff->100%).
1017      *
1018      */
GetFrameErrorRate(void) const1019     uint16_t GetFrameErrorRate(void) const { return HostSwap16(mFrameErrorRate); }
1020 
1021     /**
1022      * Returns the Message Error Rate field.
1023      *
1024      * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error
1025      * rates and whether or not the value in this field is valid.
1026      *
1027      * @returns The Message Error Rate (0x0000->0%, 0xffff->100%).
1028      *
1029      */
GetMessageErrorRate(void) const1030     uint16_t GetMessageErrorRate(void) const { return HostSwap16(mMessageErrorRate); }
1031 
1032 private:
1033     uint8_t         mFlags;            // Flags (`kFlags*` constants).
1034     uint16_t        mRloc16;           // RLOC16.
1035     Mac::ExtAddress mExtAddress;       // Extended Address.
1036     uint16_t        mVersion;          // Version.
1037     uint32_t        mConnectionTime;   // Seconds since link establishment.
1038     uint8_t         mLinkMargin;       // Link Margin.
1039     int8_t          mAverageRssi;      // Average RSSI. 127 if not available or unknown
1040     int8_t          mLastRssi;         // RSSI of last received frame. 127 if not available or unknown.
1041     uint16_t        mFrameErrorRate;   // Frame error rate (0x0000->0%, 0xffff->100%).
1042     uint16_t        mMessageErrorRate; // (IPv6) msg error rate (0x0000->0%, 0xffff->100%)
1043 } OT_TOOL_PACKED_END;
1044 
1045 #endif // OPENTHREAD_FTD
1046 
1047 /**
1048  * Implements Answer TLV generation and parsing.
1049  *
1050  */
1051 OT_TOOL_PACKED_BEGIN
1052 class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer>
1053 {
1054 public:
1055     /**
1056      * Initializes the TLV.
1057      *
1058      * @param[in] aIndex   The index value.
1059      * @param[in] aIsLast  The "IsLast" flag value.
1060      *
1061      */
1062     void Init(uint16_t aIndex, bool aIsLast);
1063 
1064     /**
1065      * Indicates whether or not the "IsLast" flag is set
1066      *
1067      * @retval TRUE   "IsLast" flag si set (this is the last answer for this query).
1068      * @retval FALSE  "IsLast" flag is not set (more answer messages are expected for this query).
1069      *
1070      */
IsLast(void) const1071     bool IsLast(void) const { return GetFlagsIndex() & kIsLastFlag; }
1072 
1073     /**
1074      * Gets the index.
1075      *
1076      * @returns The index.
1077      *
1078      */
GetIndex(void) const1079     uint16_t GetIndex(void) const { return GetFlagsIndex() & kIndexMask; }
1080 
1081 private:
1082     static constexpr uint16_t kIsLastFlag = 1 << 15;
1083     static constexpr uint16_t kIndexMask  = 0x7f;
1084 
GetFlagsIndex(void) const1085     uint16_t GetFlagsIndex(void) const { return HostSwap16(mFlagsIndex); }
SetFlagsIndex(uint16_t aFlagsIndex)1086     void     SetFlagsIndex(uint16_t aFlagsIndex) { mFlagsIndex = HostSwap16(aFlagsIndex); }
1087 
1088     uint16_t mFlagsIndex;
1089 } OT_TOOL_PACKED_END;
1090 
1091 /**
1092  * Represents the MLE Counters.
1093  *
1094  */
1095 typedef otNetworkDiagMleCounters MleCounters;
1096 
1097 /**
1098  * Implements MLE Counters TLV generation and parsing.
1099  *
1100  */
1101 OT_TOOL_PACKED_BEGIN
1102 class MleCountersTlv : public Tlv, public TlvInfo<Tlv::kMleCounters>
1103 {
1104 public:
1105     /**
1106      * Initializes the TLV.
1107      *
1108      * @param[in] aMleCounter    The MLE counters to initialize the TLV with.
1109      *
1110      */
1111     void Init(const Mle::Counters &aMleCounters);
1112 
1113     /**
1114      * Indicates whether or not the TLV appears to be well-formed.
1115      *
1116      * @retval TRUE   If the TLV appears to be well-formed.
1117      * @retval FALSE  If the TLV does not appear to be well-formed.
1118      *
1119      */
IsValid(void) const1120     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1121 
1122     /**
1123      *
1124      * Reads the counters from TLV.
1125      *
1126      * @param[out] aDiagMleCounters   A reference to `NetworkDiagnostic::MleCounters` to populate.
1127      *
1128      */
1129     void Read(MleCounters &aDiagMleCounters) const;
1130 
1131 private:
1132     uint16_t mDisabledRole;                  // Number of times device entered disabled role.
1133     uint16_t mDetachedRole;                  // Number of times device entered detached role.
1134     uint16_t mChildRole;                     // Number of times device entered child role.
1135     uint16_t mRouterRole;                    // Number of times device entered router role.
1136     uint16_t mLeaderRole;                    // Number of times device entered leader role.
1137     uint16_t mAttachAttempts;                // Number of attach attempts while device was detached.
1138     uint16_t mPartitionIdChanges;            // Number of changes to partition ID.
1139     uint16_t mBetterPartitionAttachAttempts; // Number of attempts to attach to a better partition.
1140     uint16_t mParentChanges;                 // Number of time device changed its parent.
1141     uint64_t mTrackedTime;                   // Milliseconds tracked by next counters.
1142     uint64_t mDisabledTime;                  // Milliseconds device has been in disabled role.
1143     uint64_t mDetachedTime;                  // Milliseconds device has been in detached role.
1144     uint64_t mChildTime;                     // Milliseconds device has been in child role.
1145     uint64_t mRouterTime;                    // Milliseconds device has been in router role.
1146     uint64_t mLeaderTime;                    // Milliseconds device has been in leader role.
1147 } OT_TOOL_PACKED_END;
1148 
1149 } // namespace NetworkDiagnostic
1150 } // namespace ot
1151 
1152 #endif // NETWORK_DIAGNOSTIC_TLVS_HPP_
1153