1 /*
2 * Copyright (c) 2023, 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 implements methods for generating and processing Network Diagnostics TLVs.
32 */
33
34 #include "network_diagnostic_tlvs.hpp"
35
36 #include "common/time.hpp"
37
38 namespace ot {
39 namespace NetworkDiagnostic {
40
41 #if OPENTHREAD_FTD
42
InitFrom(const Child & aChild)43 void ChildTlv::InitFrom(const Child &aChild)
44 {
45 Clear();
46
47 SetType(kChild);
48 SetLength(sizeof(*this) - sizeof(Tlv));
49
50 mFlags |= aChild.IsRxOnWhenIdle() ? kFlagsRxOnWhenIdle : 0;
51 mFlags |= aChild.IsFullThreadDevice() ? kFlagsFtd : 0;
52 mFlags |= (aChild.GetNetworkDataType() == NetworkData::kFullSet) ? kFlagsFullNetdta : 0;
53 mFlags |= kFlagsTrackErrRate;
54
55 mRloc16 = BigEndian::HostSwap16(aChild.GetRloc16());
56 mExtAddress = aChild.GetExtAddress();
57 mVersion = BigEndian::HostSwap16(aChild.GetVersion());
58 mTimeout = BigEndian::HostSwap32(aChild.GetTimeout());
59 mAge = BigEndian::HostSwap32(Time::MsecToSec(TimerMilli::GetNow() - aChild.GetLastHeard()));
60 mConnectionTime = BigEndian::HostSwap32(aChild.GetConnectionTime());
61 mSupervisionInterval = aChild.IsRxOnWhenIdle() ? 0 : BigEndian::HostSwap16(aChild.GetSupervisionInterval());
62 mLinkMargin = aChild.GetLinkInfo().GetLinkMargin();
63 mAverageRssi = aChild.GetLinkInfo().GetAverageRss();
64 mLastRssi = aChild.GetLinkInfo().GetLastRss();
65 mFrameErrorRate = BigEndian::HostSwap16(aChild.GetLinkInfo().GetFrameErrorRate());
66 mMessageErrorRate = BigEndian::HostSwap16(aChild.GetLinkInfo().GetMessageErrorRate());
67 mQueuedMessageCount = BigEndian::HostSwap16(aChild.GetIndirectMessageCount());
68
69 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
70 mFlags |= aChild.IsCslSynchronized() ? kFlagsCslSync : 0;
71 mCslPeriod = BigEndian::HostSwap16(aChild.GetCslPeriod());
72 mCslTimeout = BigEndian::HostSwap32(aChild.GetCslTimeout());
73 mCslChannel = aChild.GetCslChannel();
74 #endif
75 }
76
InitFrom(const Router & aRouter)77 void RouterNeighborTlv::InitFrom(const Router &aRouter)
78 {
79 Clear();
80
81 SetType(kRouterNeighbor);
82 SetLength(sizeof(*this) - sizeof(Tlv));
83
84 mFlags |= kFlagsTrackErrRate;
85 mRloc16 = BigEndian::HostSwap16(aRouter.GetRloc16());
86 mExtAddress = aRouter.GetExtAddress();
87 mVersion = BigEndian::HostSwap16(aRouter.GetVersion());
88 mConnectionTime = BigEndian::HostSwap32(aRouter.GetConnectionTime());
89 mLinkMargin = aRouter.GetLinkInfo().GetLinkMargin();
90 mAverageRssi = aRouter.GetLinkInfo().GetAverageRss();
91 mLastRssi = aRouter.GetLinkInfo().GetLastRss();
92 mFrameErrorRate = BigEndian::HostSwap16(aRouter.GetLinkInfo().GetFrameErrorRate());
93 mMessageErrorRate = BigEndian::HostSwap16(aRouter.GetLinkInfo().GetMessageErrorRate());
94 }
95
96 #endif // OPENTHREAD_FTD
97
Init(uint16_t aIndex,bool aIsLast)98 void AnswerTlv::Init(uint16_t aIndex, bool aIsLast)
99 {
100 SetType(kAnswer);
101 SetLength(sizeof(*this) - sizeof(Tlv));
102
103 SetFlagsIndex((aIndex & kIndexMask) | (aIsLast ? kIsLastFlag : 0));
104 }
105
Init(const Mle::Counters & aMleCounters)106 void MleCountersTlv::Init(const Mle::Counters &aMleCounters)
107 {
108 SetType(kMleCounters);
109 SetLength(sizeof(*this) - sizeof(Tlv));
110
111 mDisabledRole = BigEndian::HostSwap16(aMleCounters.mDisabledRole);
112 mDetachedRole = BigEndian::HostSwap16(aMleCounters.mDetachedRole);
113 mChildRole = BigEndian::HostSwap16(aMleCounters.mChildRole);
114 mRouterRole = BigEndian::HostSwap16(aMleCounters.mRouterRole);
115 mLeaderRole = BigEndian::HostSwap16(aMleCounters.mLeaderRole);
116 mAttachAttempts = BigEndian::HostSwap16(aMleCounters.mAttachAttempts);
117 mPartitionIdChanges = BigEndian::HostSwap16(aMleCounters.mPartitionIdChanges);
118 mBetterPartitionAttachAttempts = BigEndian::HostSwap16(aMleCounters.mBetterPartitionAttachAttempts);
119 mParentChanges = BigEndian::HostSwap16(aMleCounters.mParentChanges);
120 mTrackedTime = BigEndian::HostSwap64(aMleCounters.mTrackedTime);
121 mDisabledTime = BigEndian::HostSwap64(aMleCounters.mDisabledTime);
122 mDetachedTime = BigEndian::HostSwap64(aMleCounters.mDetachedTime);
123 mChildTime = BigEndian::HostSwap64(aMleCounters.mChildTime);
124 mRouterTime = BigEndian::HostSwap64(aMleCounters.mRouterTime);
125 mLeaderTime = BigEndian::HostSwap64(aMleCounters.mLeaderTime);
126 }
127
Read(MleCounters & aDiagMleCounters) const128 void MleCountersTlv::Read(MleCounters &aDiagMleCounters) const
129 {
130 aDiagMleCounters.mDisabledRole = BigEndian::HostSwap16(mDisabledRole);
131 aDiagMleCounters.mDetachedRole = BigEndian::HostSwap16(mDetachedRole);
132 aDiagMleCounters.mChildRole = BigEndian::HostSwap16(mChildRole);
133 aDiagMleCounters.mRouterRole = BigEndian::HostSwap16(mRouterRole);
134 aDiagMleCounters.mLeaderRole = BigEndian::HostSwap16(mLeaderRole);
135 aDiagMleCounters.mAttachAttempts = BigEndian::HostSwap16(mAttachAttempts);
136 aDiagMleCounters.mPartitionIdChanges = BigEndian::HostSwap16(mPartitionIdChanges);
137 aDiagMleCounters.mBetterPartitionAttachAttempts = BigEndian::HostSwap16(mBetterPartitionAttachAttempts);
138 aDiagMleCounters.mParentChanges = BigEndian::HostSwap16(mParentChanges);
139 aDiagMleCounters.mTrackedTime = BigEndian::HostSwap64(mTrackedTime);
140 aDiagMleCounters.mDisabledTime = BigEndian::HostSwap64(mDisabledTime);
141 aDiagMleCounters.mDetachedTime = BigEndian::HostSwap64(mDetachedTime);
142 aDiagMleCounters.mChildTime = BigEndian::HostSwap64(mChildTime);
143 aDiagMleCounters.mRouterTime = BigEndian::HostSwap64(mRouterTime);
144 aDiagMleCounters.mLeaderTime = BigEndian::HostSwap64(mLeaderTime);
145 }
146
147 } // namespace NetworkDiagnostic
148 } // namespace ot
149