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/indirect_sender.hpp" 54 #include "thread/lowpan.hpp" 55 #include "thread/network_data_leader.hpp" 56 #include "thread/topology.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 * This class 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This class 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 * This constructor initializes the object. 178 * 179 * @param[in] aInstance A reference to the OpenThread instance. 180 * 181 */ 182 explicit MeshForwarder(Instance &aInstance); 183 184 /** 185 * This method enables mesh forwarding and the IEEE 802.15.4 MAC layer. 186 * 187 */ 188 void Start(void); 189 190 /** 191 * This method disables mesh forwarding and the IEEE 802.15.4 MAC layer. 192 * 193 */ 194 void Stop(void); 195 196 /** 197 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method 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 * This method frees unicast/multicast MLE Data Responses from Send Message Queue if any. 269 * 270 */ 271 void RemoveDataResponseMessages(void); 272 273 /** 274 * This method 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 * This method 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 * This method 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 * This method 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 * This method resets the IP level counters. 310 * 311 */ ResetCounters(void)312 void ResetCounters(void) { memset(&mIpCounters, 0, sizeof(mIpCounters)); } 313 314 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 315 /** 316 * This method handles a deferred ack. 317 * 318 * Some radio links can use deferred ack logic, where a tx request always report `HandleSentFrame()` quickly. The 319 * link layer would wait for the ack and report it at a later time using this method. 320 * 321 * The link layer is expected to call `HandleDeferredAck()` (with success or failure status) for every tx request 322 * on the radio link. 323 * 324 * @param[in] aNeighbor The neighbor for which the deferred ack status is being reported. 325 * @param[in] aError The deferred ack error status: `kErrorNone` to indicate a deferred ack was received, 326 * `kErrorNoAck` to indicate an ack timeout. 327 * 328 */ 329 void HandleDeferredAck(Neighbor &aNeighbor, Error aError); 330 #endif 331 332 private: 333 static constexpr uint8_t kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT; // in seconds. 334 static constexpr uint8_t kMeshHeaderFrameMtu = OT_RADIO_FRAME_MAX_SIZE; // Max MTU with a Mesh Header frame. 335 static constexpr uint8_t kMeshHeaderFrameFcsSize = sizeof(uint16_t); // Frame FCS size for Mesh Header frame. 336 337 // Hops left to use in lowpan mesh header: We use `kMaxRouteCost` as 338 // max hops between routers within Thread mesh. We then add two 339 // for possibility of source or destination being a child 340 // (requiring one hop) and one as additional guard increment. 341 static constexpr uint8_t kMeshHeaderHopsLeft = Mle::kMaxRouteCost + 3; 342 343 static constexpr uint32_t kTxDelayInterval = OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_INTERVAL; // In msec 344 345 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 346 static constexpr uint32_t kTimeInQueueMarkEcn = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL; 347 static constexpr uint32_t kTimeInQueueDropMsg = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_DROP_MSG_INTERVAL; 348 #endif 349 350 enum MessageAction : uint8_t 351 { 352 kMessageReceive, // Indicates that the message was received. 353 kMessageTransmit, // Indicates that the message was sent. 354 kMessagePrepareIndirect, // Indicates that the message is being prepared for indirect tx. 355 kMessageDrop, // Indicates that the outbound message is dropped (e.g., dst unknown). 356 kMessageReassemblyDrop, // Indicates that the message is being dropped from reassembly list. 357 kMessageEvict, // Indicates that the message was evicted. 358 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 359 kMessageMarkEcn, // Indicates that ECN is marked on an outbound message by delay-aware queue management. 360 kMessageQueueMgmtDrop, // Indicates that an outbound message is dropped by delay-aware queue management. 361 #endif 362 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 363 kMessageFullQueueDrop, // Indicates message drop due to reaching max allowed frames in direct tx queue. 364 #endif 365 }; 366 367 enum AnycastType : uint8_t 368 { 369 kAnycastDhcp6Agent, 370 kAnycastNeighborDiscoveryAgent, 371 kAnycastService, 372 }; 373 374 #if OPENTHREAD_FTD 375 class FragmentPriorityList : public Clearable<FragmentPriorityList> 376 { 377 public: 378 class Entry : public Clearable<Entry> 379 { 380 friend class FragmentPriorityList; 381 382 public: 383 // Lifetime of an entry in seconds. 384 static constexpr uint8_t kLifetime = 385 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 386 OT_MAX(kReassemblyTimeout, OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_RETAIN_TIME); 387 #else 388 kReassemblyTimeout; 389 #endif 390 GetPriority(void) const391 Message::Priority GetPriority(void) const { return static_cast<Message::Priority>(mPriority); } IsExpired(void) const392 bool IsExpired(void) const { return (mLifetime == 0); } DecrementLifetime(void)393 void DecrementLifetime(void) { mLifetime--; } ResetLifetime(void)394 void ResetLifetime(void) { mLifetime = kLifetime; } 395 Matches(uint16_t aSrcRloc16,uint16_t aTag) const396 bool Matches(uint16_t aSrcRloc16, uint16_t aTag) const 397 { 398 return (mSrcRloc16 == aSrcRloc16) && (mDatagramTag == aTag); 399 } 400 401 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE ShouldDrop(void) const402 bool ShouldDrop(void) const { return mShouldDrop; } MarkToDrop(void)403 void MarkToDrop(void) { mShouldDrop = true; } 404 #endif 405 406 private: 407 uint16_t mSrcRloc16; 408 uint16_t mDatagramTag; 409 uint8_t mLifetime; 410 uint8_t mPriority : 2; 411 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 412 bool mShouldDrop : 1; 413 #endif 414 415 static_assert(Message::kNumPriorities <= 4, "mPriority as a 2-bit does not fit all `Priority` values"); 416 }; 417 418 Entry *AllocateEntry(uint16_t aSrcRloc16, uint16_t aTag, Message::Priority aPriority); 419 Entry *FindEntry(uint16_t aSrcRloc16, uint16_t aTag); 420 bool UpdateOnTimeTick(void); 421 422 private: 423 static constexpr uint16_t kNumEntries = 424 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 425 OT_MAX(OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES, 426 OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_ENTRY_LIST_SIZE); 427 #else 428 OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES; 429 #endif 430 431 Entry mEntries[kNumEntries]; 432 }; 433 #endif // OPENTHREAD_FTD 434 435 void SendIcmpErrorIfDstUnreach(const Message &aMessage, const Mac::Addresses &aMacAddrs); 436 Error CheckReachability(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs); 437 void UpdateRoutes(const FrameData &aFrameData, const Mac::Addresses &aMeshAddrs); 438 Error FrameToMessage(const FrameData &aFrameData, 439 uint16_t aDatagramSize, 440 const Mac::Addresses &aMacAddrs, 441 Message *&aMessage); 442 void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 443 void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 444 Message *PrepareNextDirectTransmission(void); 445 void HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo); 446 void HandleFragment(FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo); 447 void HandleLowpanHC(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo); 448 449 void PrepareMacHeaders(Mac::TxFrame &aFrame, 450 Mac::Frame::Type aFrameType, 451 const Mac::Addresses &aMacAddr, 452 const Mac::PanIds &aPanIds, 453 Mac::Frame::SecurityLevel aSecurityLevel, 454 Mac::Frame::KeyIdMode aKeyIdMode, 455 const Message *aMessage); 456 457 uint16_t PrepareDataFrame(Mac::TxFrame &aFrame, 458 Message &aMessage, 459 const Mac::Addresses &aMacAddrs, 460 bool aAddMeshHeader = false, 461 uint16_t aMeshSource = 0xffff, 462 uint16_t aMeshDest = 0xffff, 463 bool aAddFragHeader = false); 464 void PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest); 465 466 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 467 Error UpdateEcnOrDrop(Message &aMessage, bool aPreparingToSend = true); 468 Error RemoveAgedMessages(void); 469 #endif 470 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 471 bool IsDirectTxQueueOverMaxFrameThreshold(void) const; 472 void ApplyDirectTxQueueLimit(Message &aMessage); 473 #endif 474 void SendMesh(Message &aMessage, Mac::TxFrame &aFrame); 475 void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Headers &aIp6Headers); 476 Error UpdateIp6Route(Message &aMessage); 477 Error UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage); 478 void EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const; 479 Error AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aMeshDest) const; 480 Error UpdateMeshRoute(Message &aMessage); 481 bool UpdateReassemblyList(void); 482 void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 483 uint16_t aFragmentLength, 484 uint16_t aSrcRloc16, 485 Message::Priority aPriority); 486 Error HandleDatagram(Message &aMessage, const ThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource); 487 void ClearReassemblyList(void); 488 void RemoveMessage(Message &aMessage); 489 void HandleDiscoverComplete(void); 490 491 void HandleReceivedFrame(Mac::RxFrame &aFrame); 492 Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames); 493 Neighbor *UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, 494 Error aError, 495 const Mac::Address &aMacDest, 496 bool aIsDataPoll = false); 497 void UpdateNeighborLinkFailures(Neighbor &aNeighbor, 498 Error aError, 499 bool aAllowNeighborRemove, 500 uint8_t aFailLimit = Mle::kFailedRouterTransmissions); 501 void HandleSentFrame(Mac::TxFrame &aFrame, Error aError); 502 void UpdateSendMessage(Error aFrameTxError, Mac::Address &aMacDest, Neighbor *aNeighbor); 503 void RemoveMessageIfNoPendingTx(Message &aMessage); 504 505 void HandleTimeTick(void); 506 void ScheduleTransmissionTask(void); 507 508 Error GetFramePriority(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, Message::Priority &aPriority); 509 Error GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 510 uint16_t aSrcRloc16, 511 Message::Priority &aPriority); 512 void GetForwardFramePriority(const FrameData &aFrameData, 513 const Mac::Addresses &aMeshAddrs, 514 Message::Priority &aPriority); 515 516 bool CalcIePresent(const Message *aMessage); 517 Mac::Frame::Version CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const; 518 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 519 void AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame); 520 #endif 521 PauseMessageTransmissions(void)522 void PauseMessageTransmissions(void) { mTxPaused = true; } 523 void ResumeMessageTransmissions(void); 524 525 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 526 void HandleTxDelayTimer(void); 527 #endif 528 529 void LogMessage(MessageAction aAction, 530 const Message &aMessage, 531 Error aError = kErrorNone, 532 const Mac::Address *aAddress = nullptr); 533 void LogFrame(const char *aActionText, const Mac::Frame &aFrame, Error aError); 534 void LogFragmentFrameDrop(Error aError, 535 uint16_t aFrameLength, 536 const Mac::Addresses &aMacAddrs, 537 const Lowpan::FragmentHeader &aFragmentHeader, 538 bool aIsSecure); 539 void LogLowpanHcFrameDrop(Error aError, uint16_t aFrameLength, const Mac::Addresses &aMacAddrs, bool aIsSecure); 540 541 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 542 const char *MessageActionToString(MessageAction aAction, Error aError); 543 const char *MessagePriorityToString(const Message &aMessage); 544 545 #if OPENTHREAD_FTD 546 Error LogMeshFragmentHeader(MessageAction aAction, 547 const Message &aMessage, 548 const Mac::Address *aMacAddress, 549 Error aError, 550 uint16_t &aOffset, 551 Mac::Addresses &aMeshAddrs, 552 LogLevel aLogLevel); 553 void LogMeshIpHeader(const Message &aMessage, 554 uint16_t aOffset, 555 const Mac::Addresses &aMeshAddrs, 556 LogLevel aLogLevel); 557 void LogMeshMessage(MessageAction aAction, 558 const Message &aMessage, 559 const Mac::Address *aAddress, 560 Error aError, 561 LogLevel aLogLevel); 562 #endif 563 void LogIp6SourceDestAddresses(const Ip6::Headers &aHeaders, LogLevel aLogLevel); 564 void LogIp6Message(MessageAction aAction, 565 const Message &aMessage, 566 const Mac::Address *aAddress, 567 Error aError, 568 LogLevel aLogLevel); 569 #endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 570 571 using TxTask = TaskletIn<MeshForwarder, &MeshForwarder::ScheduleTransmissionTask>; 572 573 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 574 using TxDelayTimer = TimerMilliIn<MeshForwarder, &MeshForwarder::HandleTxDelayTimer>; 575 #endif 576 577 PriorityQueue mSendQueue; 578 MessageQueue mReassemblyList; 579 uint16_t mFragTag; 580 uint16_t mMessageNextOffset; 581 582 Message *mSendMessage; 583 584 Mac::Addresses mMacAddrs; 585 uint16_t mMeshSource; 586 uint16_t mMeshDest; 587 bool mAddMeshHeader : 1; 588 bool mEnabled : 1; 589 bool mTxPaused : 1; 590 bool mSendBusy : 1; 591 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 592 bool mDelayNextTx : 1; 593 TxDelayTimer mTxDelayTimer; 594 #endif 595 596 TxTask mScheduleTransmissionTask; 597 598 otIpCounters mIpCounters; 599 600 #if OPENTHREAD_FTD 601 FragmentPriorityList mFragmentPriorityList; 602 IndirectSender mIndirectSender; 603 #endif 604 605 DataPollSender mDataPollSender; 606 }; 607 608 /** 609 * @} 610 * 611 */ 612 613 DefineCoreType(otThreadLinkInfo, ThreadLinkInfo); 614 615 } // namespace ot 616 617 #endif // MESH_FORWARDER_HPP_ 618