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 * Gets the router ID of the next hop to this router. 123 * 124 * @returns The router ID of the next hop to this router. 125 */ GetNextHop(void) const126 uint8_t GetNextHop(void) const { return mNextHop; } 127 128 /** 129 * Gets the link quality out value for this router. 130 * 131 * @returns The link quality out value for this router. 132 */ GetLinkQualityOut(void) const133 LinkQuality GetLinkQualityOut(void) const { return static_cast<LinkQuality>(mLinkQualityOut); } 134 135 /** 136 * Sets the link quality out value for this router. 137 * 138 * @param[in] aLinkQuality The link quality out value for this router. 139 */ SetLinkQualityOut(LinkQuality aLinkQuality)140 void SetLinkQualityOut(LinkQuality aLinkQuality) { mLinkQualityOut = aLinkQuality; } 141 142 /** 143 * Gets the two-way link quality value (minimum of link quality in and out). 144 * 145 * @returns The two-way link quality value. 146 */ 147 LinkQuality GetTwoWayLinkQuality(void) const; 148 149 /** 150 * Get the route cost to this router. 151 * 152 * @returns The route cost to this router. 153 */ GetCost(void) const154 uint8_t GetCost(void) const { return mCost; } 155 156 /** 157 * Sets the next hop and cost to this router. 158 * 159 * @param[in] aNextHop The Router ID of the next hop to this router. 160 * @param[in] aCost The cost to this router. 161 * 162 * @retval TRUE If there was a change, i.e., @p aNextHop or @p aCost were different from their previous values. 163 * @retval FALSE If no change to next hop and cost values (new values are the same as before). 164 */ 165 bool SetNextHopAndCost(uint8_t aNextHop, uint8_t aCost); 166 167 /** 168 * Sets the next hop to this router as invalid and clears the cost. 169 * 170 * @retval TRUE If there was a change (next hop was valid before). 171 * @retval FALSE No change to next hop (next hop was invalid before). 172 */ 173 bool SetNextHopToInvalid(void); 174 175 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 176 /** 177 * Indicates whether or not this router can be selected as parent. 178 * 179 * @retval TRUE The router is selectable as parent. 180 * @retval FALSE The router is not selectable as parent. 181 */ IsSelectableAsParent(void) const182 bool IsSelectableAsParent(void) const { return mIsSelectableAsParent; } 183 184 /** 185 * Sets whether or not this router is selectable as parent. 186 * 187 * @param[in] aIsSelectable Boolean indicating whether or not router is selectable as parent. 188 */ SetSelectableAsParent(bool aIsSelectable)189 void SetSelectableAsParent(bool aIsSelectable) { mIsSelectableAsParent = aIsSelectable; } 190 191 /** 192 * Restarts timeout to block reselecting this router as parent (setting it to `kParentReselectTimeout`). 193 */ RestartParentReselectTimeout(void)194 void RestartParentReselectTimeout(void) { mParentReselectTimeout = Mle::kParentReselectTimeout; } 195 196 /** 197 * Gets the remaining timeout duration in seconds to block reselecting this router parent. 198 * 199 * @returns The remaining timeout duration in seconds. 200 */ GetParentReselectTimeout(void) const201 uint16_t GetParentReselectTimeout(void) const { return mParentReselectTimeout; } 202 203 /** 204 * Decrements the reselect timeout duration (if non-zero). 205 */ DecrementParentReselectTimeout(void)206 void DecrementParentReselectTimeout(void) { (mParentReselectTimeout > 0) ? mParentReselectTimeout-- : 0; } 207 #endif 208 209 private: 210 static_assert(Mle::kLinkAcceptTimeout < 4, "kLinkAcceptTimeout won't fit in mLinkAcceptTimeout (2-bit field)"); 211 212 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 213 static_assert(Mle::kParentReselectTimeout <= (1U << 15) - 1, 214 "kParentReselectTimeout won't fit in mParentReselectTimeout (15-bit filed)"); 215 #endif 216 217 uint8_t mNextHop; // The next hop towards this router 218 uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept 219 uint8_t mLinkQualityOut : 2; // The link quality out for this router (learned from received Route TLV) 220 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 221 uint8_t mCost : 4; // The cost to this router via neighbor router 222 #else 223 uint8_t mCost; 224 #endif 225 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 226 uint16_t mIsSelectableAsParent : 1; 227 uint16_t mParentReselectTimeout : 15; 228 #endif 229 }; 230 231 /** 232 * Represent parent of a child node. 233 */ 234 class Parent : public Router 235 { 236 public: 237 /** 238 * Initializes the `Parent`. 239 * 240 * @param[in] aInstance A reference to OpenThread instance. 241 */ Init(Instance & aInstance)242 void Init(Instance &aInstance) 243 { 244 Neighbor::Init(aInstance); 245 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 246 mCslAccuracy.Init(); 247 #endif 248 } 249 250 /** 251 * Clears the parent entry. 252 */ 253 void Clear(void); 254 255 /** 256 * Gets route cost from parent to leader. 257 * 258 * @returns The route cost from parent to leader 259 */ GetLeaderCost(void) const260 uint8_t GetLeaderCost(void) const { return mLeaderCost; } 261 262 /** 263 * Sets route cost from parent to leader. 264 * 265 * @param[in] aLeaderCost The route cost. 266 */ SetLeaderCost(uint8_t aLeaderCost)267 void SetLeaderCost(uint8_t aLeaderCost) { mLeaderCost = aLeaderCost; } 268 269 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 270 /** 271 * Gets the CSL accuracy (clock accuracy and uncertainty). 272 * 273 * @returns The CSL accuracy. 274 */ GetCslAccuracy(void) const275 const Mac::CslAccuracy &GetCslAccuracy(void) const { return mCslAccuracy; } 276 277 /** 278 * Sets CSL accuracy. 279 * 280 * @param[in] aCslAccuracy The CSL accuracy. 281 */ SetCslAccuracy(const Mac::CslAccuracy & aCslAccuracy)282 void SetCslAccuracy(const Mac::CslAccuracy &aCslAccuracy) { mCslAccuracy = aCslAccuracy; } 283 #endif 284 285 private: 286 uint8_t mLeaderCost; 287 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 288 Mac::CslAccuracy mCslAccuracy; // CSL accuracy (clock accuracy in ppm and uncertainty). 289 #endif 290 }; 291 292 DefineCoreType(otRouterInfo, Router::Info); 293 294 } // namespace ot 295 296 #endif // ROUTER_HPP_ 297