• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016-2017, 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 a Thread `Neighbor`.
32  */
33 
34 #include "neighbor.hpp"
35 
36 #include "instance/instance.hpp"
37 
38 namespace ot {
39 
SetState(State aState)40 void Neighbor::SetState(State aState)
41 {
42     VerifyOrExit(mState != aState);
43     mState = static_cast<uint8_t>(aState);
44 
45 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
46     if (mState == kStateValid)
47     {
48         mConnectionStart = Uptime::MsecToSec(Get<Uptime>().GetUptime());
49     }
50 #endif
51 
52 exit:
53     return;
54 }
55 
56 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
GetConnectionTime(void) const57 uint32_t Neighbor::GetConnectionTime(void) const
58 {
59     return IsStateValid() ? Uptime::MsecToSec(Get<Uptime>().GetUptime()) - mConnectionStart : 0;
60 }
61 #endif
62 
Matches(const Neighbor & aNeighbor) const63 bool Neighbor::AddressMatcher::Matches(const Neighbor &aNeighbor) const
64 {
65     bool matches = false;
66 
67     VerifyOrExit(aNeighbor.MatchesFilter(mStateFilter));
68 
69     if (mShortAddress != Mac::kShortAddrInvalid)
70     {
71         VerifyOrExit(mShortAddress == aNeighbor.GetRloc16());
72     }
73 
74     if (mExtAddress != nullptr)
75     {
76         VerifyOrExit(*mExtAddress == aNeighbor.GetExtAddress());
77     }
78 
79     matches = true;
80 
81 exit:
82     return matches;
83 }
84 
SetFrom(const Neighbor & aNeighbor)85 void Neighbor::Info::SetFrom(const Neighbor &aNeighbor)
86 {
87     Clear();
88 
89     mExtAddress       = aNeighbor.GetExtAddress();
90     mAge              = Time::MsecToSec(TimerMilli::GetNow() - aNeighbor.GetLastHeard());
91     mRloc16           = aNeighbor.GetRloc16();
92     mLinkFrameCounter = aNeighbor.GetLinkFrameCounters().GetMaximum();
93     mMleFrameCounter  = aNeighbor.GetMleFrameCounter();
94     mLinkQualityIn    = aNeighbor.GetLinkQualityIn();
95     mAverageRssi      = aNeighbor.GetLinkInfo().GetAverageRss();
96     mLastRssi         = aNeighbor.GetLinkInfo().GetLastRss();
97     mLinkMargin       = aNeighbor.GetLinkInfo().GetLinkMargin();
98     mFrameErrorRate   = aNeighbor.GetLinkInfo().GetFrameErrorRate();
99     mMessageErrorRate = aNeighbor.GetLinkInfo().GetMessageErrorRate();
100     mRxOnWhenIdle     = aNeighbor.IsRxOnWhenIdle();
101     mFullThreadDevice = aNeighbor.IsFullThreadDevice();
102     mFullNetworkData  = (aNeighbor.GetNetworkDataType() == NetworkData::kFullSet);
103     mVersion          = aNeighbor.GetVersion();
104 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
105     mConnectionTime = aNeighbor.GetConnectionTime();
106 #endif
107 }
108 
Init(Instance & aInstance)109 void Neighbor::Init(Instance &aInstance)
110 {
111     InstanceLocatorInit::Init(aInstance);
112     mLinkInfo.Init(aInstance);
113     SetState(kStateInvalid);
114 }
115 
IsStateValidOrAttaching(void) const116 bool Neighbor::IsStateValidOrAttaching(void) const
117 {
118     bool rval = false;
119 
120     switch (GetState())
121     {
122     case kStateInvalid:
123     case kStateParentRequest:
124     case kStateParentResponse:
125         break;
126 
127     case kStateRestored:
128     case kStateChildIdRequest:
129     case kStateLinkRequest:
130     case kStateChildUpdateRequest:
131     case kStateValid:
132         rval = true;
133         break;
134     }
135 
136     return rval;
137 }
138 
MatchesFilter(StateFilter aFilter) const139 bool Neighbor::MatchesFilter(StateFilter aFilter) const
140 {
141     bool matches = false;
142 
143     switch (aFilter)
144     {
145     case kInStateValid:
146         matches = IsStateValid();
147         break;
148 
149     case kInStateValidOrRestoring:
150         matches = IsStateValidOrRestoring();
151         break;
152 
153     case kInStateChildIdRequest:
154         matches = IsStateChildIdRequest();
155         break;
156 
157     case kInStateValidOrAttaching:
158         matches = IsStateValidOrAttaching();
159         break;
160 
161     case kInStateInvalid:
162         matches = IsStateInvalid();
163         break;
164 
165     case kInStateAnyExceptInvalid:
166         matches = !IsStateInvalid();
167         break;
168 
169     case kInStateAnyExceptValidOrRestoring:
170         matches = !IsStateValidOrRestoring();
171         break;
172 
173     case kInStateAny:
174         matches = true;
175         break;
176     }
177 
178     return matches;
179 }
180 
181 #if OPENTHREAD_CONFIG_MULTI_RADIO
SetLastRxFragmentTag(uint16_t aTag)182 void Neighbor::SetLastRxFragmentTag(uint16_t aTag)
183 {
184     mLastRxFragmentTag     = (aTag == 0) ? 0xffff : aTag;
185     mLastRxFragmentTagTime = TimerMilli::GetNow();
186 }
187 
IsLastRxFragmentTagSet(void) const188 bool Neighbor::IsLastRxFragmentTagSet(void) const
189 {
190     return (mLastRxFragmentTag != 0) && (TimerMilli::GetNow() <= mLastRxFragmentTagTime + kLastRxFragmentTagTimeout);
191 }
192 #endif
193 
194 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
AggregateLinkMetrics(uint8_t aSeriesId,uint8_t aFrameType,uint8_t aLqi,int8_t aRss)195 void Neighbor::AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss)
196 {
197     for (LinkMetrics::SeriesInfo &entry : mLinkMetricsSeriesInfoList)
198     {
199         if (aSeriesId == 0 || aSeriesId == entry.GetSeriesId())
200         {
201             entry.AggregateLinkMetrics(aFrameType, aLqi, aRss);
202         }
203     }
204 }
205 
GetForwardTrackingSeriesInfo(const uint8_t & aSeriesId)206 LinkMetrics::SeriesInfo *Neighbor::GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
207 {
208     return mLinkMetricsSeriesInfoList.FindMatching(aSeriesId);
209 }
210 
AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo & aSeriesInfo)211 void Neighbor::AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo)
212 {
213     mLinkMetricsSeriesInfoList.Push(aSeriesInfo);
214 }
215 
RemoveForwardTrackingSeriesInfo(const uint8_t & aSeriesId)216 LinkMetrics::SeriesInfo *Neighbor::RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
217 {
218     return mLinkMetricsSeriesInfoList.RemoveMatching(aSeriesId);
219 }
220 
RemoveAllForwardTrackingSeriesInfo(void)221 void Neighbor::RemoveAllForwardTrackingSeriesInfo(void)
222 {
223     while (!mLinkMetricsSeriesInfoList.IsEmpty())
224     {
225         LinkMetrics::SeriesInfo *seriesInfo = mLinkMetricsSeriesInfoList.Pop();
226         Get<LinkMetrics::Subject>().Free(*seriesInfo);
227     }
228 }
229 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
230 
StateToString(State aState)231 const char *Neighbor::StateToString(State aState)
232 {
233     static const char *const kStateStrings[] = {
234         "Invalid",        // (0) kStateInvalid
235         "Restored",       // (1) kStateRestored
236         "ParentReq",      // (2) kStateParentRequest
237         "ParentRes",      // (3) kStateParentResponse
238         "ChildIdReq",     // (4) kStateChildIdRequest
239         "LinkReq",        // (5) kStateLinkRequest
240         "ChildUpdateReq", // (6) kStateChildUpdateRequest
241         "Valid",          // (7) kStateValid
242     };
243 
244     struct EnumCheck
245     {
246         InitEnumValidatorCounter();
247         ValidateNextEnum(kStateInvalid);
248         ValidateNextEnum(kStateRestored);
249         ValidateNextEnum(kStateParentRequest);
250         ValidateNextEnum(kStateParentResponse);
251         ValidateNextEnum(kStateChildIdRequest);
252         ValidateNextEnum(kStateLinkRequest);
253         ValidateNextEnum(kStateChildUpdateRequest);
254         ValidateNextEnum(kStateValid);
255     };
256 
257     return kStateStrings[aState];
258 }
259 
260 } // namespace ot
261