1 /* 2 * Copyright (c) 2019, 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 Thread Radio Encapsulation Link (TREL). 32 */ 33 34 #ifndef TREL_LINK_HPP_ 35 #define TREL_LINK_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 40 41 #include "common/encoding.hpp" 42 #include "common/locator.hpp" 43 #include "common/tasklet.hpp" 44 #include "common/timer.hpp" 45 #include "mac/mac_frame.hpp" 46 #include "mac/mac_types.hpp" 47 #include "radio/trel_interface.hpp" 48 #include "radio/trel_packet.hpp" 49 50 namespace ot { 51 52 class Neighbor; 53 54 namespace Trel { 55 56 /** 57 * @addtogroup core-trel 58 * 59 * @brief 60 * This module includes definitions for Thread Radio Encapsulation Link (TREL) 61 * 62 * @{ 63 * 64 */ 65 66 /** 67 * This class represents a Thread Radio Encapsulation Link (TREL). 68 * 69 */ 70 class Link : public InstanceLocator 71 { 72 friend class ot::Instance; 73 friend class Interface; 74 75 public: 76 static constexpr uint16_t kMtuSize = 1280 - 48 - sizeof(Header); ///< MTU size for TREL frame. 77 static constexpr uint8_t kFcsSize = 0; ///< FCS size for TREL frame. 78 79 /** 80 * This constructor initializes the `Link` object. 81 * 82 * @param[in] aInstance A reference to the OpenThread instance. 83 * 84 */ 85 explicit Link(Instance &aInstance); 86 87 /** 88 * This method sets the PAN Identifier. 89 * 90 * @param[in] aPanId A PAN Identifier. 91 * 92 */ SetPanId(Mac::PanId aPanId)93 void SetPanId(Mac::PanId aPanId) { mPanId = aPanId; } 94 95 /** 96 * This method notifies TREL radio link that device's extended MAC address has changed for it to update any 97 * internal address/state. 98 * 99 */ HandleExtAddressChange(void)100 void HandleExtAddressChange(void) { mInterface.HandleExtAddressChange(); } 101 102 /** 103 * This method enables the TREL radio link. 104 * 105 */ 106 void Enable(void); 107 108 /** 109 * This method disables the TREL radio link. 110 * 111 */ 112 void Disable(void); 113 114 /** 115 * This method requests TREL radio link to transition to Sleep mode 116 * 117 */ 118 void Sleep(void); 119 120 /** 121 * This method requests TREL radio link to transition to Receive mode on a given channel. 122 * 123 * `Mac::HandleReceivedFrame()` is used to notify MAC layer upon receiving a frame. 124 * 125 * @param[in] aChannel The channel to receive on. 126 * 127 */ 128 void Receive(uint8_t aChannel); 129 130 /** 131 * This method gets the radio transmit frame for TREL radio link. 132 * 133 * @returns The transmit frame. 134 * 135 */ GetTransmitFrame(void)136 Mac::TxFrame &GetTransmitFrame(void) { return mTxFrame; } 137 138 /** 139 * This method requests a frame to be sent over TREL radio link. 140 * 141 * The frame should be already placed in `GetTransmitFrame()` frame. 142 * 143 * `Mac::RecordFrameTransmitStatus()` and `Mac::HandleTransmitDone()` are used to notify the success or error status 144 * of frame transmission upon completion of send. 145 * 146 */ 147 void Send(void); 148 149 private: 150 static constexpr uint16_t kMaxHeaderSize = sizeof(Header); 151 static constexpr uint16_t k154AckFrameSize = 3 + kFcsSize; 152 static constexpr int8_t kRxRssi = -20; // The RSSI value used for received frames on TREL radio link. 153 static constexpr uint32_t kAckWaitWindow = 750; // (in msec) 154 155 enum State : uint8_t 156 { 157 kStateDisabled, 158 kStateSleep, 159 kStateReceive, 160 kStateTransmit, 161 }; 162 163 void AfterInit(void); 164 void SetState(State aState); 165 void BeginTransmit(void); InvokeSendDone(Error aError)166 void InvokeSendDone(Error aError) { InvokeSendDone(aError, nullptr); } 167 void InvokeSendDone(Error aError, Mac::RxFrame *aAckFrame); 168 void ProcessReceivedPacket(Packet &aPacket); 169 void HandleAck(Packet &aAckPacket); 170 void SendAck(Packet &aRxPacket); 171 void ReportDeferredAckStatus(Neighbor &aNeighbor, Error aError); 172 void HandleTimer(Neighbor &aNeighbor); 173 174 static void HandleTxTasklet(Tasklet &aTasklet); 175 void HandleTxTasklet(void); 176 177 static void HandleTimer(Timer &aTimer); 178 void HandleTimer(void); 179 180 static const char *StateToString(State aState); 181 182 State mState; 183 uint8_t mRxChannel; 184 Mac::PanId mPanId; 185 uint32_t mTxPacketNumber; 186 Tasklet mTxTasklet; 187 TimerMilli mTimer; 188 Interface mInterface; 189 Mac::RxFrame mRxFrame; 190 Mac::TxFrame mTxFrame; 191 uint8_t mTxPacketBuffer[kMaxHeaderSize + kMtuSize]; 192 uint8_t mAckPacketBuffer[kMaxHeaderSize]; 193 uint8_t mAckFrameBuffer[k154AckFrameSize]; 194 }; 195 196 /** 197 * This class defines all the neighbor info required for TREL link. 198 * 199 * `Neighbor` class publicly inherits from this class. 200 * 201 */ 202 class NeighborInfo 203 { 204 friend class Link; 205 206 private: GetPendingTrelAckCount(void) const207 uint32_t GetPendingTrelAckCount(void) const { return (mTrelPreviousPendingAcks + mTrelCurrentPendingAcks); } 208 DecrementPendingTrelAckCount(void)209 void DecrementPendingTrelAckCount(void) 210 { 211 if (mTrelPreviousPendingAcks != 0) 212 { 213 mTrelPreviousPendingAcks--; 214 } 215 else if (mTrelCurrentPendingAcks != 0) 216 { 217 mTrelCurrentPendingAcks--; 218 } 219 } 220 GetExpectedTrelAckNumber(void) const221 uint32_t GetExpectedTrelAckNumber(void) const { return mTrelTxPacketNumber - GetPendingTrelAckCount(); } 222 IsRxAckNumberValid(uint32_t aAckNumber) const223 bool IsRxAckNumberValid(uint32_t aAckNumber) const 224 { 225 // Note that calculating the difference between `aAckNumber` 226 // and `GetExpectedTrelAckNumber` will correctly handle the 227 // roll-over of packet number value. 228 229 return (GetPendingTrelAckCount() != 0) && (aAckNumber - GetExpectedTrelAckNumber() < GetPendingTrelAckCount()); 230 } 231 232 uint32_t mTrelTxPacketNumber; // Next packet number to use for tx 233 uint16_t mTrelCurrentPendingAcks; // Number of pending acks for current interval. 234 uint16_t mTrelPreviousPendingAcks; // Number of pending acks for previous interval. 235 }; 236 237 /** 238 * @} 239 * 240 */ 241 242 } // namespace Trel 243 } // namespace ot 244 245 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 246 247 #endif // TREL_LINK_HPP_ 248