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 Thread `Router` and `Parent`. 32 */ 33 34 #ifndef ROUTER_HPP_ 35 #define ROUTER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "thread/neighbor.hpp" 40 41 namespace ot { 42 43 class Parent; 44 45 /** 46 * Represents a Thread Router 47 */ 48 class Router : public Neighbor 49 { 50 public: 51 /** 52 * Represents diagnostic information for a Thread Router. 53 */ 54 class Info : public otRouterInfo, public Clearable<Info> 55 { 56 public: 57 /** 58 * Sets the `Info` instance from a given `Router`. 59 * 60 * @param[in] aRouter A router. 61 */ 62 void SetFrom(const Router &aRouter); 63 64 /** 65 * Sets the `Info` instance from a given `Parent`. 66 * 67 * @param[in] aParent A parent. 68 */ 69 void SetFrom(const Parent &aParent); 70 }; 71 72 /** 73 * Initializes the `Router` object. 74 * 75 * @param[in] aInstance A reference to OpenThread instance. 76 */ Init(Instance & aInstance)77 void Init(Instance &aInstance) { Neighbor::Init(aInstance); } 78 79 /** 80 * Clears the router entry. 81 */ 82 void Clear(void); 83 84 /** 85 * Sets the `Router` entry from a `Parent` 86 */ 87 void SetFrom(const Parent &aParent); 88 89 /** 90 * Restarts the Link Accept timeout (setting it to max value). 91 * 92 * This method is used after sending a Link Request to the router to restart the timeout and start waiting to 93 * receive a Link Accept response. 94 */ RestartLinkAcceptTimeout(void)95 void RestartLinkAcceptTimeout(void) { mLinkAcceptTimeout = Mle::kLinkAcceptTimeout; } 96 97 /** 98 * Clears the Link Accept timeout value (setting it to zero). 99 * 100 * This method is used when we successfully receive and process a Link Accept. 101 */ ClearLinkAcceptTimeout(void)102 void ClearLinkAcceptTimeout(void) { mLinkAcceptTimeout = 0; } 103 104 /** 105 * Indicates whether or not we are waiting to receive a Link Accept from this router (timeout is non-zero). 106 * 107 * @retval TRUE Waiting to receive a Link Accept response. 108 * @retval FALSE Not waiting to receive a Link Accept response. 109 */ IsWaitingForLinkAccept(void) const110 bool IsWaitingForLinkAccept(void) const { return (mLinkAcceptTimeout > 0); } 111 112 /** 113 * Decrements the Link Accept timeout value (in seconds). 114 * 115 * Caller MUST ensure the current value is non-zero by checking `IsWaitingForLinkAccept()`. 116 * 117 * @returns The decremented timeout value. 118 */ DecrementLinkAcceptTimeout(void)119 uint8_t DecrementLinkAcceptTimeout(void) { return --mLinkAcceptTimeout; } 120 121 /** 122 * Sets the counter tracking the number of Link Request attempts during link re-establishment to its maximum value 123 * `Mle::kLinkRequestAttempts`. 124 */ SetLinkRequestAttemptsToMax(void)125 void SetLinkRequestAttemptsToMax(void) { mLinkRequestAttempts = Mle::kLinkRequestAttempts; } 126 127 /** 128 * Indicates whether there are remaining Link Request attempts (during link re-establishment). 129 * 130 * @retval TRUE There are remaining Link Request attempts. 131 * @retval FALSE There are no more Link Request attempts (the counter is zero). 132 */ HasRemainingLinkRequestAttempts(void) const133 bool HasRemainingLinkRequestAttempts(void) const { return mLinkRequestAttempts > 0; } 134 135 /** 136 * Decrements the counter tracking the number of remaining Link Request attempts during link re-establishment. 137 * 138 * Caller MUST ensure the current counter is non-zero by checking `HasRemainingLinkRequestAttempts()`. 139 */ DecrementLinkRequestAttempts(void)140 void DecrementLinkRequestAttempts(void) { mLinkRequestAttempts--; } 141 142 /** 143 * Gets the router ID of the next hop to this router. 144 * 145 * @returns The router ID of the next hop to this router. 146 */ GetNextHop(void) const147 uint8_t GetNextHop(void) const { return mNextHop; } 148 149 /** 150 * Gets the link quality out value for this router. 151 * 152 * @returns The link quality out value for this router. 153 */ GetLinkQualityOut(void) const154 LinkQuality GetLinkQualityOut(void) const { return GetLinkInfo().GetLinkQualityOut(); } 155 156 /** 157 * Sets the link quality out value for this router. 158 * 159 * @param[in] aLinkQuality The link quality out value for this router. 160 */ SetLinkQualityOut(LinkQuality aLinkQuality)161 void SetLinkQualityOut(LinkQuality aLinkQuality) { GetLinkInfo().SetLinkQualityOut(aLinkQuality); } 162 163 /** 164 * Gets the two-way link quality value (minimum of link quality in and out). 165 * 166 * @returns The two-way link quality value. 167 */ 168 LinkQuality GetTwoWayLinkQuality(void) const; 169 170 /** 171 * Get the route cost to this router. 172 * 173 * @returns The route cost to this router. 174 */ GetCost(void) const175 uint8_t GetCost(void) const { return mCost; } 176 177 /** 178 * Sets the next hop and cost to this router. 179 * 180 * @param[in] aNextHop The Router ID of the next hop to this router. 181 * @param[in] aCost The cost to this router. 182 * 183 * @retval TRUE If there was a change, i.e., @p aNextHop or @p aCost were different from their previous values. 184 * @retval FALSE If no change to next hop and cost values (new values are the same as before). 185 */ 186 bool SetNextHopAndCost(uint8_t aNextHop, uint8_t aCost); 187 188 /** 189 * Sets the next hop to this router as invalid and clears the cost. 190 * 191 * @retval TRUE If there was a change (next hop was valid before). 192 * @retval FALSE No change to next hop (next hop was invalid before). 193 */ 194 bool SetNextHopToInvalid(void); 195 196 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 197 /** 198 * Indicates whether or not this router can be selected as parent. 199 * 200 * @retval TRUE The router is selectable as parent. 201 * @retval FALSE The router is not selectable as parent. 202 */ IsSelectableAsParent(void) const203 bool IsSelectableAsParent(void) const { return mIsSelectableAsParent; } 204 205 /** 206 * Sets whether or not this router is selectable as parent. 207 * 208 * @param[in] aIsSelectable Boolean indicating whether or not router is selectable as parent. 209 */ SetSelectableAsParent(bool aIsSelectable)210 void SetSelectableAsParent(bool aIsSelectable) { mIsSelectableAsParent = aIsSelectable; } 211 212 /** 213 * Restarts timeout to block reselecting this router as parent (setting it to `kParentReselectTimeout`). 214 */ RestartParentReselectTimeout(void)215 void RestartParentReselectTimeout(void) { mParentReselectTimeout = Mle::kParentReselectTimeout; } 216 217 /** 218 * Gets the remaining timeout duration in seconds to block reselecting this router parent. 219 * 220 * @returns The remaining timeout duration in seconds. 221 */ GetParentReselectTimeout(void) const222 uint16_t GetParentReselectTimeout(void) const { return mParentReselectTimeout; } 223 224 /** 225 * Decrements the reselect timeout duration (if non-zero). 226 */ DecrementParentReselectTimeout(void)227 void DecrementParentReselectTimeout(void) { (mParentReselectTimeout > 0) ? mParentReselectTimeout-- : 0; } 228 #endif 229 230 private: 231 static_assert(Mle::kLinkAcceptTimeout < 4, "kLinkAcceptTimeout won't fit in mLinkAcceptTimeout (2-bit field)"); 232 static_assert(Mle::kLinkRequestAttempts < 4, "kLinkRequestAttempts won't fit in mLinkRequestAttempts (2-bit field"); 233 234 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 235 static_assert(Mle::kParentReselectTimeout <= (1U << 15) - 1, 236 "kParentReselectTimeout won't fit in mParentReselectTimeout (15-bit filed)"); 237 #endif 238 239 uint8_t mNextHop; // The next hop towards this router 240 uint8_t mLinkRequestAttempts : 2; // Number of Link Request attempts 241 uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept 242 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 243 uint8_t mCost : 4; // The cost to this router via neighbor router 244 #else 245 uint8_t mCost; 246 #endif 247 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 248 uint16_t mIsSelectableAsParent : 1; 249 uint16_t mParentReselectTimeout : 15; 250 #endif 251 }; 252 253 /** 254 * Represent parent of a child node. 255 */ 256 class Parent : public Router 257 { 258 public: 259 /** 260 * Initializes the `Parent`. 261 * 262 * @param[in] aInstance A reference to OpenThread instance. 263 */ Init(Instance & aInstance)264 void Init(Instance &aInstance) 265 { 266 Neighbor::Init(aInstance); 267 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 268 mCslAccuracy.Init(); 269 #endif 270 } 271 272 /** 273 * Clears the parent entry. 274 */ 275 void Clear(void); 276 277 /** 278 * Gets route cost from parent to leader. 279 * 280 * @returns The route cost from parent to leader 281 */ GetLeaderCost(void) const282 uint8_t GetLeaderCost(void) const { return mLeaderCost; } 283 284 /** 285 * Sets route cost from parent to leader. 286 * 287 * @param[in] aLeaderCost The route cost. 288 */ SetLeaderCost(uint8_t aLeaderCost)289 void SetLeaderCost(uint8_t aLeaderCost) { mLeaderCost = aLeaderCost; } 290 291 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 292 /** 293 * Gets the CSL accuracy (clock accuracy and uncertainty). 294 * 295 * @returns The CSL accuracy. 296 */ GetCslAccuracy(void) const297 const Mac::CslAccuracy &GetCslAccuracy(void) const { return mCslAccuracy; } 298 299 /** 300 * Sets CSL accuracy. 301 * 302 * @param[in] aCslAccuracy The CSL accuracy. 303 */ SetCslAccuracy(const Mac::CslAccuracy & aCslAccuracy)304 void SetCslAccuracy(const Mac::CslAccuracy &aCslAccuracy) { mCslAccuracy = aCslAccuracy; } 305 #endif 306 307 private: 308 uint8_t mLeaderCost; 309 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 310 Mac::CslAccuracy mCslAccuracy; // CSL accuracy (clock accuracy in ppm and uncertainty). 311 #endif 312 }; 313 314 DefineCoreType(otRouterInfo, Router::Info); 315 316 } // namespace ot 317 318 #endif // ROUTER_HPP_ 319