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 static constexpr uint32_t kTxDelayInterval = OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_INTERVAL; // In msec 338 339 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 340 static constexpr uint32_t kTimeInQueueMarkEcn = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL; 341 static constexpr uint32_t kTimeInQueueDropMsg = OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_DROP_MSG_INTERVAL; 342 #endif 343 344 enum MessageAction : uint8_t 345 { 346 kMessageReceive, // Indicates that the message was received. 347 kMessageTransmit, // Indicates that the message was sent. 348 kMessagePrepareIndirect, // Indicates that the message is being prepared for indirect tx. 349 kMessageDrop, // Indicates that the outbound message is dropped (e.g., dst unknown). 350 kMessageReassemblyDrop, // Indicates that the message is being dropped from reassembly list. 351 kMessageEvict, // Indicates that the message was evicted. 352 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 353 kMessageMarkEcn, // Indicates that ECN is marked on an outbound message by delay-aware queue management. 354 kMessageQueueMgmtDrop, // Indicates that an outbound message is dropped by delay-aware queue management. 355 #endif 356 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 357 kMessageFullQueueDrop, // Indicates message drop due to reaching max allowed frames in direct tx queue. 358 #endif 359 }; 360 361 enum AnycastType : uint8_t 362 { 363 kAnycastDhcp6Agent, 364 kAnycastNeighborDiscoveryAgent, 365 kAnycastService, 366 }; 367 368 #if OPENTHREAD_FTD 369 class FragmentPriorityList : public Clearable<FragmentPriorityList> 370 { 371 public: 372 class Entry : public Clearable<Entry> 373 { 374 friend class FragmentPriorityList; 375 376 public: 377 // Lifetime of an entry in seconds. 378 static constexpr uint8_t kLifetime = 379 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 380 OT_MAX(kReassemblyTimeout, OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_RETAIN_TIME); 381 #else 382 kReassemblyTimeout; 383 #endif 384 GetPriority(void) const385 Message::Priority GetPriority(void) const { return static_cast<Message::Priority>(mPriority); } IsExpired(void) const386 bool IsExpired(void) const { return (mLifetime == 0); } DecrementLifetime(void)387 void DecrementLifetime(void) { mLifetime--; } ResetLifetime(void)388 void ResetLifetime(void) { mLifetime = kLifetime; } 389 Matches(uint16_t aSrcRloc16,uint16_t aTag) const390 bool Matches(uint16_t aSrcRloc16, uint16_t aTag) const 391 { 392 return (mSrcRloc16 == aSrcRloc16) && (mDatagramTag == aTag); 393 } 394 395 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE ShouldDrop(void) const396 bool ShouldDrop(void) const { return mShouldDrop; } MarkToDrop(void)397 void MarkToDrop(void) { mShouldDrop = true; } 398 #endif 399 400 private: 401 uint16_t mSrcRloc16; 402 uint16_t mDatagramTag; 403 uint8_t mLifetime; 404 uint8_t mPriority : 2; 405 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 406 bool mShouldDrop : 1; 407 #endif 408 409 static_assert(Message::kNumPriorities <= 4, "mPriority as a 2-bit does not fit all `Priority` values"); 410 }; 411 412 Entry *AllocateEntry(uint16_t aSrcRloc16, uint16_t aTag, Message::Priority aPriority); 413 Entry *FindEntry(uint16_t aSrcRloc16, uint16_t aTag); 414 bool UpdateOnTimeTick(void); 415 416 private: 417 static constexpr uint16_t kNumEntries = 418 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 419 OT_MAX(OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES, 420 OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_FRAG_TAG_ENTRY_LIST_SIZE); 421 #else 422 OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES; 423 #endif 424 425 Entry mEntries[kNumEntries]; 426 }; 427 #endif // OPENTHREAD_FTD 428 429 void SendIcmpErrorIfDstUnreach(const Message & aMessage, 430 const Mac::Address &aMacSource, 431 const Mac::Address &aMacDest); 432 Error CheckReachability(const FrameData & aFrameData, 433 const Mac::Address &aMeshSource, 434 const Mac::Address &aMeshDest); 435 void UpdateRoutes(const FrameData &aFrameData, const Mac::Address &aMeshSource, const Mac::Address &aMeshDest); 436 Error FrameToMessage(const FrameData & aFrameData, 437 uint16_t aDatagramSize, 438 const Mac::Address &aMacSource, 439 const Mac::Address &aMacDest, 440 Message *& aMessage); 441 void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 442 void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); 443 Message *PrepareNextDirectTransmission(void); 444 void HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo); 445 void HandleFragment(FrameData & aFrameData, 446 const Mac::Address & aMacSource, 447 const Mac::Address & aMacDest, 448 const ThreadLinkInfo &aLinkInfo); 449 void HandleLowpanHC(const FrameData & aFrameData, 450 const Mac::Address & aMacSource, 451 const Mac::Address & aMacDest, 452 const ThreadLinkInfo &aLinkInfo); 453 uint16_t PrepareDataFrame(Mac::TxFrame & aFrame, 454 Message & aMessage, 455 const Mac::Address &aMacSource, 456 const Mac::Address &aMacDest, 457 bool aAddMeshHeader = false, 458 uint16_t aMeshSource = 0xffff, 459 uint16_t aMeshDest = 0xffff, 460 bool aAddFragHeader = false); 461 void PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest); 462 463 #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE 464 Error UpdateEcnOrDrop(Message &aMessage, bool aPreparingToSend = true); 465 Error RemoveAgedMessages(void); 466 #endif 467 #if (OPENTHREAD_CONFIG_MAX_FRAMES_IN_DIRECT_TX_QUEUE > 0) 468 bool IsDirectTxQueueOverMaxFrameThreshold(void) const; 469 void ApplyDirectTxQueueLimit(Message &aMessage); 470 #endif 471 void SendMesh(Message &aMessage, Mac::TxFrame &aFrame); 472 void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Headers &aIp6Headers); 473 Error UpdateIp6Route(Message &aMessage); 474 Error UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessage); 475 void EvaluateRoutingCost(uint16_t aDest, uint8_t &aBestCost, uint16_t &aBestDest) const; 476 Error AnycastRouteLookup(uint8_t aServiceId, AnycastType aType, uint16_t &aMeshDest) const; 477 Error UpdateMeshRoute(Message &aMessage); 478 bool UpdateReassemblyList(void); 479 void UpdateFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 480 uint16_t aFragmentLength, 481 uint16_t aSrcRloc16, 482 Message::Priority aPriority); 483 Error HandleDatagram(Message &aMessage, const ThreadLinkInfo &aLinkInfo, const Mac::Address &aMacSource); 484 void ClearReassemblyList(void); 485 void RemoveMessage(Message &aMessage); 486 void HandleDiscoverComplete(void); 487 488 void HandleReceivedFrame(Mac::RxFrame &aFrame); 489 Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames); 490 Neighbor * UpdateNeighborOnSentFrame(Mac::TxFrame & aFrame, 491 Error aError, 492 const Mac::Address &aMacDest, 493 bool aIsDataPoll = false); 494 void UpdateNeighborLinkFailures(Neighbor &aNeighbor, 495 Error aError, 496 bool aAllowNeighborRemove, 497 uint8_t aFailLimit = Mle::kFailedRouterTransmissions); 498 void HandleSentFrame(Mac::TxFrame &aFrame, Error aError); 499 void UpdateSendMessage(Error aFrameTxError, Mac::Address &aMacDest, Neighbor *aNeighbor); 500 void RemoveMessageIfNoPendingTx(Message &aMessage); 501 502 void HandleTimeTick(void); 503 static void ScheduleTransmissionTask(Tasklet &aTasklet); 504 void ScheduleTransmissionTask(void); 505 506 Error GetFramePriority(const FrameData & aFrameData, 507 const Mac::Address &aMacSource, 508 const Mac::Address &aMacDest, 509 Message::Priority & aPriority); 510 Error GetFragmentPriority(Lowpan::FragmentHeader &aFragmentHeader, 511 uint16_t aSrcRloc16, 512 Message::Priority & aPriority); 513 void GetForwardFramePriority(const FrameData & aFrameData, 514 const Mac::Address &aMeshSource, 515 const Mac::Address &aMeshDest, 516 Message::Priority & aPriority); 517 518 bool CalcIePresent(const Message *aMessage); 519 uint16_t CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent); 520 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 521 void AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame); 522 #endif 523 PauseMessageTransmissions(void)524 void PauseMessageTransmissions(void) { mTxPaused = true; } 525 void ResumeMessageTransmissions(void); 526 527 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 528 static void HandleTxDelayTimer(Timer &aTimer); 529 void HandleTxDelayTimer(void); 530 #endif 531 532 void LogMessage(MessageAction aAction, 533 const Message & aMessage, 534 Error aError = kErrorNone, 535 const Mac::Address *aAddress = nullptr); 536 void LogFrame(const char *aActionText, const Mac::Frame &aFrame, Error aError); 537 void LogFragmentFrameDrop(Error aError, 538 uint16_t aFrameLength, 539 const Mac::Address & aMacSource, 540 const Mac::Address & aMacDest, 541 const Lowpan::FragmentHeader &aFragmentHeader, 542 bool aIsSecure); 543 void LogLowpanHcFrameDrop(Error aError, 544 uint16_t aFrameLength, 545 const Mac::Address &aMacSource, 546 const Mac::Address &aMacDest, 547 bool aIsSecure); 548 549 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 550 const char *MessageActionToString(MessageAction aAction, Error aError); 551 const char *MessagePriorityToString(const Message &aMessage); 552 553 #if OPENTHREAD_FTD 554 Error LogMeshFragmentHeader(MessageAction aAction, 555 const Message & aMessage, 556 const Mac::Address *aMacAddress, 557 Error aError, 558 uint16_t & aOffset, 559 Mac::Address & aMeshSource, 560 Mac::Address & aMeshDest, 561 LogLevel aLogLevel); 562 void LogMeshIpHeader(const Message & aMessage, 563 uint16_t aOffset, 564 const Mac::Address &aMeshSource, 565 const Mac::Address &aMeshDest, 566 LogLevel aLogLevel); 567 void LogMeshMessage(MessageAction aAction, 568 const Message & aMessage, 569 const Mac::Address *aAddress, 570 Error aError, 571 LogLevel aLogLevel); 572 #endif 573 void LogIp6SourceDestAddresses(const Ip6::Headers &aHeaders, LogLevel aLogLevel); 574 void LogIp6Message(MessageAction aAction, 575 const Message & aMessage, 576 const Mac::Address *aAddress, 577 Error aError, 578 LogLevel aLogLevel); 579 #endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 580 581 PriorityQueue mSendQueue; 582 MessageQueue mReassemblyList; 583 uint16_t mFragTag; 584 uint16_t mMessageNextOffset; 585 586 Message *mSendMessage; 587 588 Mac::Address mMacSource; 589 Mac::Address mMacDest; 590 uint16_t mMeshSource; 591 uint16_t mMeshDest; 592 bool mAddMeshHeader : 1; 593 bool mEnabled : 1; 594 bool mTxPaused : 1; 595 bool mSendBusy : 1; 596 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_COLLISION_AVOIDANCE_DELAY_ENABLE 597 bool mDelayNextTx : 1; 598 TimerMilli mTxDelayTimer; 599 #endif 600 601 Tasklet mScheduleTransmissionTask; 602 603 otIpCounters mIpCounters; 604 605 #if OPENTHREAD_FTD 606 FragmentPriorityList mFragmentPriorityList; 607 IndirectSender mIndirectSender; 608 #endif 609 610 DataPollSender mDataPollSender; 611 }; 612 613 /** 614 * @} 615 * 616 */ 617 618 DefineCoreType(otThreadLinkInfo, ThreadLinkInfo); 619 620 } // namespace ot 621 622 #endif // MESH_FORWARDER_HPP_ 623