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 forwarding IPv6 datagrams across the Thread mesh. 32 */ 33 34 #ifndef MESH_FORWARDER_HPP_ 35 #define MESH_FORWARDER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/as_core_type.hpp" 40 #include "common/clearable.hpp" 41 #include "common/frame_data.hpp" 42 #include "common/locator.hpp" 43 #include "common/log.hpp" 44 #include "common/non_copyable.hpp" 45 #include "common/tasklet.hpp" 46 #include "common/time_ticker.hpp" 47 #include "mac/channel_mask.hpp" 48 #include "mac/data_poll_sender.hpp" 49 #include "mac/mac.hpp" 50 #include "mac/mac_frame.hpp" 51 #include "net/ip6.hpp" 52 #include "thread/address_resolver.hpp" 53 #include "thread/child.hpp" 54 #include "thread/indirect_sender.hpp" 55 #include "thread/lowpan.hpp" 56 #include "thread/network_data_leader.hpp" 57 58 namespace ot { 59 60 namespace Mle { 61 class DiscoverScanner; 62 } 63 64 namespace Utils { 65 class HistoryTracker; 66 } 67 68 /** 69 * @addtogroup core-mesh-forwarding 70 * 71 * @brief 72 * This module includes definitions for mesh forwarding within Thread. 73 * 74 * @{ 75 */ 76 77 /** 78 * Represents link-specific information for messages received from the Thread radio. 79 * 80 */ 81 class ThreadLinkInfo : public otThreadLinkInfo, public Clearable<ThreadLinkInfo> 82 { 83 public: 84 /** 85 * Returns the IEEE 802.15.4 Source PAN ID. 86 * 87 * @returns The IEEE 802.15.4 Source PAN ID. 88 * 89 */ GetPanId(void) const90 Mac::PanId GetPanId(void) const { return mPanId; } 91 92 /** 93 * Returns the IEEE 802.15.4 Channel. 94 * 95 * @returns The IEEE 802.15.4 Channel. 96 * 97 */ GetChannel(void) const98 uint8_t GetChannel(void) const { return mChannel; } 99 100 /** 101 * Returns whether the Destination PAN ID is broadcast. 102 * 103 * @retval TRUE If Destination PAN ID is broadcast. 104 * @retval FALSE If Destination PAN ID is not broadcast. 105 * 106 */ IsDstPanIdBroadcast(void) const107 bool IsDstPanIdBroadcast(void) const { return mIsDstPanIdBroadcast; } 108 109 /** 110 * Indicates whether or not link security is enabled. 111 * 112 * @retval TRUE If link security is enabled. 113 * @retval FALSE If link security is not enabled. 114 * 115 */ IsLinkSecurityEnabled(void) const116 bool IsLinkSecurityEnabled(void) const { return mLinkSecurity; } 117 118 /** 119 * Returns the Received Signal Strength (RSS) in dBm. 120 * 121 * @returns The Received Signal Strength (RSS) in dBm. 122 * 123 */ GetRss(void) const124 int8_t GetRss(void) const { return mRss; } 125 126 /** 127 * Returns the frame/radio Link Quality Indicator (LQI) value. 128 * 129 * @returns The Link Quality Indicator value. 130 * 131 */ GetLqi(void) const132 uint8_t GetLqi(void) const { return mLqi; } 133 134 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 135 /** 136 * Returns the Time Sync Sequence. 137 * 138 * @returns The Time Sync Sequence. 139 * 140 */ GetTimeSyncSeq(void) const141 uint8_t GetTimeSyncSeq(void) const { return mTimeSyncSeq; } 142 143 /** 144 * Returns the time offset to the Thread network time (in microseconds). 145 * 146 * @returns The time offset to the Thread network time (in microseconds). 147 * 148 */ GetNetworkTimeOffset(void) const149 int64_t GetNetworkTimeOffset(void) const { return mNetworkTimeOffset; } 150 #endif 151 152 /** 153 * Sets the `ThreadLinkInfo` from a given received frame. 154 * 155 * @param[in] aFrame A received frame. 156 * 157 */ 158 void SetFrom(const Mac::RxFrame &aFrame); 159 }; 160 161 /** 162 * Implements mesh forwarding within Thread. 163 * 164 */ 165 class MeshForwarder : public InstanceLocator, private NonCopyable 166 { 167 friend class Mac::Mac; 168 friend class Instance; 169 friend class DataPollSender; 170 friend class IndirectSender; 171 friend class Ip6::Ip6; 172 friend class Mle::DiscoverScanner; 173 friend class TimeTicker; 174 175 public: 176 /** 177 * Initializes the object. 178 * 179 * @param[in] aInstance A reference to the OpenThread instance. 180 * 181 */ 182 explicit MeshForwarder(Instance &aInstance); 183 184 /** 185 * Enables mesh forwarding and the IEEE 802.15.4 MAC layer. 186 * 187 */ 188 void Start(void); 189 190 /** 191 * Disables mesh forwarding and the IEEE 802.15.4 MAC layer. 192 * 193 */ 194 void Stop(void); 195 196 /** 197 * Submits a message to the mesh forwarder for forwarding. 198 * 199 * @param[in] aMessage A reference to the message. 200 * 201 * @retval kErrorNone Successfully enqueued the message. 202 * @retval kErrorAlready The message was already enqueued. 203 * @retval kErrorDrop The message could not be sent and should be dropped. 204 * 205 */ 206 Error SendMessage(Message &aMessage); 207 208 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 209 /** 210 * Sends an empty data frame to the parent. 211 * 212 * @retval kErrorNone Successfully enqueued an empty message. 213 * @retval kErrorInvalidState Device is not in Rx-Off-When-Idle mode or it has no parent. 214 * @retval kErrorNoBufs Insufficient message buffers available. 215 * 216 */ 217 Error SendEmptyMessage(void); 218 #endif 219 220 /** 221 * Is called by the address resolver when an EID-to-RLOC mapping has been resolved. 222 * 223 * @param[in] aEid A reference to the EID that has been resolved. 224 * @param[in] aError kErrorNone on success and kErrorDrop otherwise. 225 * 226 */ 227 void HandleResolved(const Ip6::Address &aEid, Error aError); 228 229 /** 230 * Indicates whether or not rx-on-when-idle mode is enabled. 231 * 232 * @retval TRUE The rx-on-when-idle mode is enabled. 233 * @retval FALSE The rx-on-when-idle-mode is disabled. 234 * 235 */ 236 bool GetRxOnWhenIdle(void) const; 237 238 /** 239 * Sets the rx-on-when-idle mode 240 * 241 * @param[in] aRxOnWhenIdle TRUE to enable, FALSE otherwise. 242 * 243 */ 244 void SetRxOnWhenIdle(bool aRxOnWhenIdle); 245 246 /** 247 * Sets the scan parameters for MLE Discovery Request messages. 248 * 249 * @param[in] aScanChannels A reference to channel mask indicating which channels to scan. 250 * If @p aScanChannels is empty, then all channels are used instead. 251 * 252 */ 253 void SetDiscoverParameters(const Mac::ChannelMask &aScanChannels); 254 255 #if OPENTHREAD_FTD 256 /** 257 * Frees any messages queued for an existing child. 258 * 259 * @param[in] aChild A reference to the child. 260 * @param[in] aSubType The message sub-type to remove. 261 * Use Message::kSubTypeNone remove all messages for @p aChild. 262 * 263 */ 264 void RemoveMessages(Child &aChild, Message::SubType aSubType); 265 #endif 266 267 /** 268 * Frees unicast/multicast MLE Data Responses from Send Message Queue if any. 269 * 270 */ 271 void RemoveDataResponseMessages(void); 272 273 /** 274 * Evicts the message with lowest priority in the send queue. 275 * 276 * @param[in] aPriority The highest priority level of the evicted message. 277 * 278 * @retval kErrorNone Successfully evicted a low priority message. 279 * @retval kErrorNotFound No low priority messages available to evict. 280 * 281 */ 282 Error EvictMessage(Message::Priority aPriority); 283 284 /** 285 * Returns a reference to the send queue. 286 * 287 * @returns A reference to the send queue. 288 * 289 */ GetSendQueue(void) const290 const PriorityQueue &GetSendQueue(void) const { return mSendQueue; } 291 292 /** 293 * Returns a reference to the reassembly queue. 294 * 295 * @returns A reference to the reassembly queue. 296 * 297 */ GetReassemblyQueue(void) const298 const MessageQueue &GetReassemblyQueue(void) const { return mReassemblyList; } 299 300 /** 301 * Returns a reference to the IP level counters. 302 * 303 * @returns A reference to the IP level counters. 304 * 305 */ GetCounters(void) const306 const otIpCounters &GetCounters(void) const { return mIpCounters; } 307 308 /** 309 * Resets the IP level counters. 310 * 311 */ ResetCounters(void)312 void ResetCounters(void) { memset(&mIpCounters, 0, sizeof(mIpCounters)); } 313 314 #if OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE 315 /** 316 * Gets the time-in-queue histogram for messages in the TX queue. 317 * 318 * Histogram of the time-in-queue of messages in the transmit queue is collected. The time-in-queue is tracked for 319 * direct transmissions only and is measured as the duration from when a message is added to the transmit queue 320 * until it is passed to the MAC layer for transmission or dropped. 321 * 322 * The histogram is returned as an array of `uint32_t` values with `aNumBins` entries. The first entry in the array 323 * (at index 0) represents the number of messages with a time-in-queue less than `aBinInterval`. The second entry 324 * represents the number of messages with a time-in-queue greater than or equal to `aBinInterval`, but less than 325 * `2 * aBinInterval`. And so on. The last entry represents the number of messages with time-in-queue greater than 326 * or * equal to `(aNumBins - 1) * aBinInterval`. 327 * 328 * The collected statistics can be reset by calling `ResetTimeInQueueStat()`. The histogram information is 329 * collected since the OpenThread instance was initialized or since the last time statistics collection was reset 330 * by calling the `ResetTimeInQueueStat()`. 331 * 332 * @param[out] aNumBins Reference to return the number of bins in histogram (array length). 333 * @param[out] aBinInterval Reference to return the histogram bin interval length in milliseconds. 334 * 335 * @returns A pointer to an array of @p aNumBins entries representing the collected histogram info. 336 * 337 */ GetTimeInQueueHistogram(uint16_t & aNumBins,uint32_t & aBinInterval) const338 const uint32_t *GetTimeInQueueHistogram(uint16_t &aNumBins, uint32_t &aBinInterval) const 339 { 340 return mTxQueueStats.GetHistogram(aNumBins, aBinInterval); 341 } 342 343 /** 344 * Gets the maximum time-in-queue for messages in the TX queue. 345 * 346 * The time-in-queue is tracked for direct transmissions only and is measured as the duration from when a message 347 * is added to the transmit queue until it is passed to the MAC layer for transmission or dropped. 348 * 349 * The collected statistics can be reset by calling `ResetTimeInQueueStat()`. 350 * 351 * @returns The maximum time-in-queue in milliseconds for all messages in the TX queue (so far). 352 * 353 */ GetMaxTimeInQueue(void) const354 uint32_t GetMaxTimeInQueue(void) const { return mTxQueueStats.GetMaxInterval(); } 355 356 /** 357 * Resets the TX queue time-in-queue statistics. 358 * 359 */ ResetTimeInQueueStat(void)360 void ResetTimeInQueueStat(void) { mTxQueueStats.Clear(); } 361 #endif 362 363 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 364 /** 365 * Handles a deferred ack. 366 * 367 * Some radio links can use deferred ack logic, where a tx request always report `HandleSentFrame()` quickly. The 368 * link layer would wait for the ack and report it at a later time using this method. 369 * 370 * The link layer is expected to call `HandleDeferredAck()` (with success or failure status) for every tx request 371 * on the radio link. 372 * 373 * @param[in] aNeighbor The neighbor for which the deferred ack status is being reported. 374 * @param[in] aError The deferred ack error status: `kErrorNone` to indicate a deferred ack was received, 375 * `kErrorNoAck` to indicate an ack timeout. 376 * 377 */ 378 void HandleDeferredAck(Neighbor &aNeighbor, Error aError); 379 #endif 380 381 private: 382 static constexpr uint8_t kFailedRouterTransmissions = 4; 383 static constexpr uint8_t kFailedCslDataPollTransmissions = 15; 384 385 static constexpr uint8_t kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT; // in seconds. 386 static constexpr uint8_t kMeshHeaderFrameMtu = OT_RADIO_FRAME_MAX_SIZE; // Max MTU with a Mesh Header frame. 387 static constexpr uint8_t kMeshHeaderFrameFcsSize = sizeof(uint16_t); // Frame FCS size for Mesh Header frame. 388 389 // Hops left to use in lowpan mesh header: We use `kMaxRouteCost` as 390 // max hops between routers within Thread mesh. We then add two 391 // for possibility of source or destination being a child 392 // (requiring one hop) and one as additional guard increment. 393 static constexpr uint8_t kMeshHeaderHopsLeft = Mle::kMaxRouteCost + 3; 394 395 static constexpr uint32_t kTxDelayInterval = OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_INTERVAL; // In msec 396 397 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 398 static constexpr uint32_t kTimeInQueueMarkEcn = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL; 399 static constexpr uint32_t kTimeInQueueDropMsg = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_DROP_MSG_INTERVAL; 400 #endif 401 402 enum MessageAction : uint8_t 403 { 404 kMessageReceive, // Indicates that the message was received. 405 kMessageTransmit, // Indicates that the message was sent. 406 kMessagePrepareIndirect, // Indicates that the message is being prepared for indirect tx. 407 kMessageDrop, // Indicates that the outbound message is dropped (e.g., dst unknown). 408 kMessageReassemblyDrop, // Indicates that the message is being dropped from reassembly list. 409 kMessageEvict, // Indicates that the message was evicted. 410 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 411 kMessageMarkEcn, // Indicates that ECN is marked on an outbound message by delay-aware queue management. 412 kMessageQueueMgmtDrop, // Indicates that an outbound message is dropped by delay-aware queue management. 413 #endif 414 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 415 kMessageFullQueueDrop, // Indicates message drop due to reaching max allowed frames in direct tx queue. 416 #endif 417 }; 418 419 enum AnycastType : uint8_t 420 { 421 kAnycastDhcp6Agent, 422 kAnycastNeighborDiscoveryAgent, 423 kAnycastService, 424 }; 425 426 #if OPENTHREAD_FTD 427 class FragmentPriorityList : public Clearable<FragmentPriorityList> 428 { 429 public: 430 class Entry : public Clearable<Entry> 431 { 432 friend class FragmentPriorityList; 433 434 public: 435 // Lifetime of an entry in seconds. 436 static constexpr uint8_t kLifetime = 437 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 438 OT_MAX(kReassemblyTimeout, OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_RETAIN_TIME); 439 #else 440 kReassemblyTimeout; 441 #endif 442 GetPriority(void) const443 Message::Priority GetPriority(void) const { return static_cast<Message::Priority>(mPriority); } IsExpired(void) const444 bool IsExpired(void) const { return (mLifetime == 0); } DecrementLifetime(void)445 void DecrementLifetime(void) { mLifetime--; } ResetLifetime(void)446 void ResetLifetime(void) { mLifetime = kLifetime; } 447 Matches(uint16_t aSrcRloc16,uint16_t aTag) const448 bool Matches(uint16_t aSrcRloc16, uint16_t aTag) const 449 { 450 return (mSrcRloc16 == aSrcRloc16) && (mDatagramTag == aTag); 451 } 452 453 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE ShouldDrop(void) const454 bool ShouldDrop(void) const { return mShouldDrop; } MarkToDrop(void)455 void MarkToDrop(void) { mShouldDrop = true; } 456 #endif 457 458 private: 459 uint16_t mSrcRloc16; 460 uint16_t mDatagramTag; 461 uint8_t mLifetime; 462 uint8_t mPriority : 2; 463 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 464 bool mShouldDrop : 1; 465 #endif 466 467 static_assert(Message::kNumPriorities <= 4, "mPriority as a 2-bit does not fit all `Priority` values"); 468 }; 469 470 Entry *AllocateEntry(uint16_t aSrcRloc16, uint16_t aTag, Message::Priority aPriority); 471 Entry *FindEntry(uint16_t aSrcRloc16, uint16_t aTag); 472 bool UpdateOnTimeTick(void); 473 474 private: 475 static constexpr uint16_t kNumEntries = 476 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 477 OT_MAX(OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES, 478 OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_ENTRY_LIST_SIZE); 479 #else 480 OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES; 481 #endif 482 483 Entry mEntries[kNumEntries]; 484 }; 485 #endif // OPENTHREAD_FTD 486 487 #if OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE 488 class TxQueueStats : public Clearable<TxQueueStats> 489 { 490 public: 491 const uint32_t *GetHistogram(uint16_t &aNumBins, uint32_t &aBinInterval) const; GetMaxInterval(void) const492 uint32_t GetMaxInterval(void) const { return mMaxInterval; } 493 void UpdateFor(const Message &aMessage); 494 495 private: 496 static constexpr uint32_t kHistMaxInterval = OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_HISTOGRAM_MAX_INTERVAL; 497 static constexpr uint32_t kHistBinInterval = OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_HISTOGRAM_BIN_INTERVAL; 498 static constexpr uint16_t kNumHistBins = (kHistMaxInterval + kHistBinInterval - 1) / kHistBinInterval; 499 500 uint32_t mMaxInterval; 501 uint32_t mHistogram[kNumHistBins]; 502 }; 503 #endif 504 505 void SendIcmpErrorIfDstUnreach(const Message &aMessage, const Mac::Addresses &aMacAddrs); 506 Error CheckReachability(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs); 507 void UpdateRoutes(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs); 508 Error FrameToMessage(const FrameData &aFrameData, 509 uint16_t aDatagramSize, 510 const Mac::Addresses &aMacAddrs, 511 Message *&aMessage); 512 void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 513 void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 514 Message *PrepareNextDirectTransmission(void); 515 void HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo); 516 void HandleFragment(FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo); 517 void HandleLowpanHC(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo); 518 519 void PrepareMacHeaders(Mac::TxFrame &aFrame, 520 Mac::Frame::Type aFrameType, 521 const Mac::Addresses &aMacAddr, 522 const Mac::PanIds &aPanIds, 523 Mac::Frame::SecurityLevel aSecurityLevel, 524 Mac::Frame::KeyIdMode aKeyIdMode, 525 const Message *aMessage); 526 uint16_t PrepareDataFrame(Mac::TxFrame &aFrame, 527 Message &aMessage, 528 const Mac::Addresses &aMacAddrs, 529 bool aAddMeshHeader, 530 uint16_t aMeshSource, 531 uint16_t aMeshDest, 532 bool aAddFragHeader); 533 uint16_t PrepareDataFrameWithNoMeshHeader(Mac::TxFrame &aFrame, Message &aMessage, const Mac::Addresses &aMacAddrs); 534 void PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest); 535 536 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 537 Error UpdateEcnOrDrop(Message &aMessage, bool aPreparingToSend); 538 Error RemoveAgedMessages(void); 539 #endif 540 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 541 bool IsDirectTxQueueOverMaxFrameThreshold(void) const; 542 void ApplyDirectTxQueueLimit(Message &aMessage); 543 #endif 544 void SendMesh(Message &aMessage, Mac::TxFrame &aFrame); 545 void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Headers &aIp6Headers); 546 Error UpdateIp6Route(Message &aMessage); 547 Error UpdateIp6RouteFtd(const Ip6::Header &aIp6Header, Message &aMessage); 548 void EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const; 549 Error AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aMeshDest) const; 550 Error UpdateMeshRoute(Message &aMessage); 551 bool UpdateReassemblyList(void); 552 void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 553 uint16_t aFragmentLength, 554 uint16_t aSrcRloc16, 555 Message::Priority aPriority); 556 Error HandleDatagram(Message &aMessage, const ThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource); 557 void ClearReassemblyList(void); 558 void RemoveMessage(Message &aMessage); 559 void HandleDiscoverComplete(void); 560 561 void HandleReceivedFrame(Mac::RxFrame &aFrame); 562 Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames); 563 Neighbor *UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, 564 Error aError, 565 const Mac::Address &aMacDest, 566 bool aIsDataPoll); 567 void UpdateNeighborLinkFailures(Neighbor &aNeighbor, Error aError, bool aAllowNeighborRemove, uint8_t aFailLimit); 568 void HandleSentFrame(Mac::TxFrame &aFrame, Error aError); 569 void UpdateSendMessage(Error aFrameTxError, Mac::Address &aMacDest, Neighbor *aNeighbor); 570 void RemoveMessageIfNoPendingTx(Message &aMessage); 571 572 void HandleTimeTick(void); 573 void ScheduleTransmissionTask(void); 574 575 Error GetFramePriority(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, Message::Priority &aPriority); 576 Error GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 577 uint16_t aSrcRloc16, 578 Message::Priority &aPriority); 579 void GetForwardFramePriority(const FrameData &aFrameData, 580 const Mac::Addresses &aMeshAddrs, 581 Message::Priority &aPriority); 582 583 bool CalcIePresent(const Message *aMessage); 584 Mac::Frame::Version CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const; 585 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 586 void AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame); 587 #endif 588 PauseMessageTransmissions(void)589 void PauseMessageTransmissions(void) { mTxPaused = true; } 590 void ResumeMessageTransmissions(void); 591 592 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 593 void HandleTxDelayTimer(void); 594 #endif 595 596 void LogMessage(MessageAction aAction, const Message &aMessage); 597 void LogMessage(MessageAction aAction, const Message &aMessage, Error aError); 598 void LogMessage(MessageAction aAction, const Message &aMessage, Error aError, const Mac::Address *aAddress); 599 void LogFrame(const char *aActionText, const Mac::Frame &aFrame, Error aError); 600 void LogFragmentFrameDrop(Error aError, 601 uint16_t aFrameLength, 602 const Mac::Addresses &aMacAddrs, 603 const Lowpan::FragmentHeader &aFragmentHeader, 604 bool aIsSecure); 605 void LogLowpanHcFrameDrop(Error aError, uint16_t aFrameLength, const Mac::Addresses &aMacAddrs, bool aIsSecure); 606 607 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 608 const char *MessageActionToString(MessageAction aAction, Error aError); 609 const char *MessagePriorityToString(const Message &aMessage); 610 611 #if OPENTHREAD_FTD 612 Error LogMeshFragmentHeader(MessageAction aAction, 613 const Message &aMessage, 614 const Mac::Address *aMacAddress, 615 Error aError, 616 uint16_t &aOffset, 617 Mac::Addresses &aMeshAddrs, 618 LogLevel aLogLevel); 619 void LogMeshIpHeader(const Message &aMessage, 620 uint16_t aOffset, 621 const Mac::Addresses &aMeshAddrs, 622 LogLevel aLogLevel); 623 void LogMeshMessage(MessageAction aAction, 624 const Message &aMessage, 625 const Mac::Address *aAddress, 626 Error aError, 627 LogLevel aLogLevel); 628 #endif 629 void LogIp6SourceDestAddresses(const Ip6::Headers &aHeaders, LogLevel aLogLevel); 630 void LogIp6Message(MessageAction aAction, 631 const Message &aMessage, 632 const Mac::Address *aAddress, 633 Error aError, 634 LogLevel aLogLevel); 635 #endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 636 637 using TxTask = TaskletIn<MeshForwarder, &MeshForwarder::ScheduleTransmissionTask>; 638 639 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 640 using TxDelayTimer = TimerMilliIn<MeshForwarder, &MeshForwarder::HandleTxDelayTimer>; 641 #endif 642 643 PriorityQueue mSendQueue; 644 MessageQueue mReassemblyList; 645 uint16_t mFragTag; 646 uint16_t mMessageNextOffset; 647 648 Message *mSendMessage; 649 650 Mac::Addresses mMacAddrs; 651 uint16_t mMeshSource; 652 uint16_t mMeshDest; 653 bool mAddMeshHeader : 1; 654 bool mEnabled : 1; 655 bool mTxPaused : 1; 656 bool mSendBusy : 1; 657 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 658 bool mDelayNextTx : 1; 659 TxDelayTimer mTxDelayTimer; 660 #endif 661 662 TxTask mScheduleTransmissionTask; 663 664 otIpCounters mIpCounters; 665 666 #if OPENTHREAD_FTD 667 FragmentPriorityList mFragmentPriorityList; 668 IndirectSender mIndirectSender; 669 #endif 670 671 DataPollSender mDataPollSender; 672 673 #if OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE 674 TxQueueStats mTxQueueStats; 675 #endif 676 }; 677 678 /** 679 * @} 680 * 681 */ 682 683 DefineCoreType(otThreadLinkInfo, ThreadLinkInfo); 684 685 } // namespace ot 686 687 #endif // MESH_FORWARDER_HPP_ 688