• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Represents a Thread Radio Encapsulation Link (TREL).
68  */
69 class Link : public InstanceLocator
70 {
71     friend class ot::Instance;
72     friend class ot::Notifier;
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      * Used as input by `CheckPeerAddrOnRxSuccess()` to determine whether the peer socket address can be updated based
81      * on a received TREL packet from the peer if there is a discrepancy.
82      */
83     enum PeerSockAddrUpdateMode : uint8_t
84     {
85         kAllowPeerSockAddrUpdate,    ///< Peer socket address can be updated.
86         kDisallowPeerSockAddrUpdate, ///< Peer socket address cannot be updated.
87     };
88 
89     /**
90      * Initializes the `Link` object.
91      *
92      * @param[in]  aInstance  A reference to the OpenThread instance.
93      */
94     explicit Link(Instance &aInstance);
95 
96     /**
97      * Sets the PAN Identifier.
98      *
99      * @param[in] aPanId   A PAN Identifier.
100      */
SetPanId(Mac::PanId aPanId)101     void SetPanId(Mac::PanId aPanId) { mPanId = aPanId; }
102 
103     /**
104      * Notifies TREL radio link that device's extended MAC address has changed for it to update any
105      * internal address/state.
106      */
HandleExtAddressChange(void)107     void HandleExtAddressChange(void) { mInterface.HandleExtAddressChange(); }
108 
109     /**
110      * Enables the TREL radio link.
111      */
112     void Enable(void);
113 
114     /**
115      * Disables the TREL radio link.
116      */
117     void Disable(void);
118 
119     /**
120      * Requests TREL radio link to transition to Sleep mode
121      */
122     void Sleep(void);
123 
124     /**
125      * Requests TREL radio link to transition to Receive mode on a given channel.
126      *
127      * `Mac::HandleReceivedFrame()` is used to notify MAC layer upon receiving a frame.
128      *
129      * @param[in] aChannel   The channel to receive on.
130      */
131     void Receive(uint8_t aChannel);
132 
133     /**
134      * Gets the radio transmit frame for TREL radio link.
135      *
136      * @returns The transmit frame.
137      */
GetTransmitFrame(void)138     Mac::TxFrame &GetTransmitFrame(void) { return mTxFrame; }
139 
140     /**
141      * 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     void Send(void);
149 
150     /**
151      * Checks the address/port from the last received TREL packet against the ones recorded in the corresponding `Peer`
152      * entry and acts if there is a discrepancy.
153      *
154      * This method signals to the platform about the discrepancy. Based on @p aMode, it may also update the `Peer`
155      * entry information directly to match the new address/port information.
156      *
157      * @param[in] aMode   Determines whether to update the `Peer` entry if there is a discrepancy.
158      */
159     void CheckPeerAddrOnRxSuccess(PeerSockAddrUpdateMode aMode);
160 
161 private:
162     static constexpr uint16_t kMaxHeaderSize   = sizeof(Header);
163     static constexpr uint16_t k154AckFrameSize = 3 + kFcsSize;
164     static constexpr int8_t   kRxRssi          = -20; // The RSSI value used for received frames on TREL radio link.
165     static constexpr uint32_t kAckWaitWindow   = 750; // (in msec)
166     static constexpr uint16_t kFcfFramePending = 1 << 4;
167 
168     typedef Interface::Peer Peer;
169 
170     enum State : uint8_t
171     {
172         kStateDisabled,
173         kStateSleep,
174         kStateReceive,
175         kStateTransmit,
176     };
177 
178     void AfterInit(void);
179     void SetState(State aState);
180     void BeginTransmit(void);
InvokeSendDone(Error aError)181     void InvokeSendDone(Error aError) { InvokeSendDone(aError, nullptr); }
182     void InvokeSendDone(Error aError, Mac::RxFrame *aAckFrame);
183     void ProcessReceivedPacket(Packet &aPacket, const Ip6::SockAddr &aSockAddr);
184     void HandleAck(Packet &aAckPacket);
185     void SendAck(Packet &aRxPacket);
186     void ReportDeferredAckStatus(Neighbor &aNeighbor, Error aError);
187     void HandleTimer(Neighbor &aNeighbor);
188     void HandleNotifierEvents(Events aEvents);
189     void HandleTxTasklet(void);
190     void HandleTimer(void);
191 
192     static const char *StateToString(State aState);
193 
194     using TxTasklet    = TaskletIn<Link, &Link::HandleTxTasklet>;
195     using TimeoutTimer = TimerMilliIn<Link, &Link::HandleTimer>;
196 
197     State         mState;
198     uint8_t       mRxChannel;
199     Mac::PanId    mPanId;
200     uint32_t      mTxPacketNumber;
201     TxTasklet     mTxTasklet;
202     TimeoutTimer  mTimer;
203     Interface     mInterface;
204     Ip6::SockAddr mRxPacketSenderAddr;
205     Peer         *mRxPacketPeer;
206     Mac::RxFrame  mRxFrame;
207     Mac::TxFrame  mTxFrame;
208     uint8_t       mTxPacketBuffer[kMaxHeaderSize + kMtuSize];
209     uint8_t       mAckPacketBuffer[kMaxHeaderSize];
210     uint8_t       mAckFrameBuffer[k154AckFrameSize];
211 };
212 
213 /**
214  * Defines all the neighbor info required for TREL link.
215  *
216  * `Neighbor` class publicly inherits from this class.
217  */
218 class NeighborInfo
219 {
220     friend class Link;
221 
222 private:
GetPendingTrelAckCount(void) const223     uint32_t GetPendingTrelAckCount(void) const { return (mTrelPreviousPendingAcks + mTrelCurrentPendingAcks); }
224 
DecrementPendingTrelAckCount(void)225     void DecrementPendingTrelAckCount(void)
226     {
227         if (mTrelPreviousPendingAcks != 0)
228         {
229             mTrelPreviousPendingAcks--;
230         }
231         else if (mTrelCurrentPendingAcks != 0)
232         {
233             mTrelCurrentPendingAcks--;
234         }
235     }
236 
GetExpectedTrelAckNumber(void) const237     uint32_t GetExpectedTrelAckNumber(void) const { return mTrelTxPacketNumber - GetPendingTrelAckCount(); }
238 
IsRxAckNumberValid(uint32_t aAckNumber) const239     bool IsRxAckNumberValid(uint32_t aAckNumber) const
240     {
241         // Note that calculating the difference between `aAckNumber`
242         // and `GetExpectedTrelAckNumber` will correctly handle the
243         // roll-over of packet number value.
244 
245         return (GetPendingTrelAckCount() != 0) && (aAckNumber - GetExpectedTrelAckNumber() < GetPendingTrelAckCount());
246     }
247 
248     uint32_t mTrelTxPacketNumber;      // Next packet number to use for tx
249     uint16_t mTrelCurrentPendingAcks;  // Number of pending acks for current interval.
250     uint16_t mTrelPreviousPendingAcks; // Number of pending acks for previous interval.
251 };
252 
253 /**
254  * @}
255  */
256 
257 } // namespace Trel
258 } // namespace ot
259 
260 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
261 
262 #endif // TREL_LINK_HPP_
263