| /* |
| * Copyright (c) 2019, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @file |
| * This file includes definitions for Thread Radio Encapsulation Link (TREL). |
| */ |
| |
| #ifndef TREL_LINK_HPP_ |
| #define TREL_LINK_HPP_ |
| |
| #include "openthread-core-config.h" |
| |
| #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| |
| #include "common/encoding.hpp" |
| #include "common/locator.hpp" |
| #include "common/notifier.hpp" |
| #include "common/tasklet.hpp" |
| #include "common/timer.hpp" |
| #include "mac/mac_frame.hpp" |
| #include "mac/mac_types.hpp" |
| #include "radio/trel_interface.hpp" |
| #include "radio/trel_packet.hpp" |
| |
| namespace ot { |
| |
| class Neighbor; |
| |
| namespace Trel { |
| |
| /** |
| * @addtogroup core-trel |
| * |
| * @brief |
| * This module includes definitions for Thread Radio Encapsulation Link (TREL) |
| * |
| * @{ |
| * |
| */ |
| |
| /** |
| * This class represents a Thread Radio Encapsulation Link (TREL). |
| * |
| */ |
| class Link : public InstanceLocator |
| { |
| friend class ot::Instance; |
| friend class ot::Notifier; |
| friend class Interface; |
| |
| public: |
| static constexpr uint16_t kMtuSize = 1280 - 48 - sizeof(Header); ///< MTU size for TREL frame. |
| static constexpr uint8_t kFcsSize = 0; ///< FCS size for TREL frame. |
| |
| /** |
| * This constructor initializes the `Link` object. |
| * |
| * @param[in] aInstance A reference to the OpenThread instance. |
| * |
| */ |
| explicit Link(Instance &aInstance); |
| |
| /** |
| * This method sets the PAN Identifier. |
| * |
| * @param[in] aPanId A PAN Identifier. |
| * |
| */ |
| void SetPanId(Mac::PanId aPanId) { mPanId = aPanId; } |
| |
| /** |
| * This method notifies TREL radio link that device's extended MAC address has changed for it to update any |
| * internal address/state. |
| * |
| */ |
| void HandleExtAddressChange(void) { mInterface.HandleExtAddressChange(); } |
| |
| /** |
| * This method enables the TREL radio link. |
| * |
| */ |
| void Enable(void); |
| |
| /** |
| * This method disables the TREL radio link. |
| * |
| */ |
| void Disable(void); |
| |
| /** |
| * This method requests TREL radio link to transition to Sleep mode |
| * |
| */ |
| void Sleep(void); |
| |
| /** |
| * This method requests TREL radio link to transition to Receive mode on a given channel. |
| * |
| * `Mac::HandleReceivedFrame()` is used to notify MAC layer upon receiving a frame. |
| * |
| * @param[in] aChannel The channel to receive on. |
| * |
| */ |
| void Receive(uint8_t aChannel); |
| |
| /** |
| * This method gets the radio transmit frame for TREL radio link. |
| * |
| * @returns The transmit frame. |
| * |
| */ |
| Mac::TxFrame &GetTransmitFrame(void) { return mTxFrame; } |
| |
| /** |
| * This method requests a frame to be sent over TREL radio link. |
| * |
| * The frame should be already placed in `GetTransmitFrame()` frame. |
| * |
| * `Mac::RecordFrameTransmitStatus()` and `Mac::HandleTransmitDone()` are used to notify the success or error status |
| * of frame transmission upon completion of send. |
| * |
| */ |
| void Send(void); |
| |
| private: |
| static constexpr uint16_t kMaxHeaderSize = sizeof(Header); |
| static constexpr uint16_t k154AckFrameSize = 3 + kFcsSize; |
| static constexpr int8_t kRxRssi = -20; // The RSSI value used for received frames on TREL radio link. |
| static constexpr uint32_t kAckWaitWindow = 750; // (in msec) |
| |
| enum State : uint8_t |
| { |
| kStateDisabled, |
| kStateSleep, |
| kStateReceive, |
| kStateTransmit, |
| }; |
| |
| void AfterInit(void); |
| void SetState(State aState); |
| void BeginTransmit(void); |
| void InvokeSendDone(Error aError) { InvokeSendDone(aError, nullptr); } |
| void InvokeSendDone(Error aError, Mac::RxFrame *aAckFrame); |
| void ProcessReceivedPacket(Packet &aPacket); |
| void HandleAck(Packet &aAckPacket); |
| void SendAck(Packet &aRxPacket); |
| void ReportDeferredAckStatus(Neighbor &aNeighbor, Error aError); |
| void HandleTimer(Neighbor &aNeighbor); |
| void HandleNotifierEvents(Events aEvents); |
| |
| static void HandleTxTasklet(Tasklet &aTasklet); |
| void HandleTxTasklet(void); |
| |
| static void HandleTimer(Timer &aTimer); |
| void HandleTimer(void); |
| |
| static const char *StateToString(State aState); |
| |
| State mState; |
| uint8_t mRxChannel; |
| Mac::PanId mPanId; |
| uint32_t mTxPacketNumber; |
| Tasklet mTxTasklet; |
| TimerMilli mTimer; |
| Interface mInterface; |
| Mac::RxFrame mRxFrame; |
| Mac::TxFrame mTxFrame; |
| uint8_t mTxPacketBuffer[kMaxHeaderSize + kMtuSize]; |
| uint8_t mAckPacketBuffer[kMaxHeaderSize]; |
| uint8_t mAckFrameBuffer[k154AckFrameSize]; |
| }; |
| |
| /** |
| * This class defines all the neighbor info required for TREL link. |
| * |
| * `Neighbor` class publicly inherits from this class. |
| * |
| */ |
| class NeighborInfo |
| { |
| friend class Link; |
| |
| private: |
| uint32_t GetPendingTrelAckCount(void) const { return (mTrelPreviousPendingAcks + mTrelCurrentPendingAcks); } |
| |
| void DecrementPendingTrelAckCount(void) |
| { |
| if (mTrelPreviousPendingAcks != 0) |
| { |
| mTrelPreviousPendingAcks--; |
| } |
| else if (mTrelCurrentPendingAcks != 0) |
| { |
| mTrelCurrentPendingAcks--; |
| } |
| } |
| |
| uint32_t GetExpectedTrelAckNumber(void) const { return mTrelTxPacketNumber - GetPendingTrelAckCount(); } |
| |
| bool IsRxAckNumberValid(uint32_t aAckNumber) const |
| { |
| // Note that calculating the difference between `aAckNumber` |
| // and `GetExpectedTrelAckNumber` will correctly handle the |
| // roll-over of packet number value. |
| |
| return (GetPendingTrelAckCount() != 0) && (aAckNumber - GetExpectedTrelAckNumber() < GetPendingTrelAckCount()); |
| } |
| |
| uint32_t mTrelTxPacketNumber; // Next packet number to use for tx |
| uint16_t mTrelCurrentPendingAcks; // Number of pending acks for current interval. |
| uint16_t mTrelPreviousPendingAcks; // Number of pending acks for previous interval. |
| }; |
| |
| /** |
| * @} |
| * |
| */ |
| |
| } // namespace Trel |
| } // namespace ot |
| |
| #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| |
| #endif // TREL_LINK_HPP_ |