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