• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019-2021, 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) interface.
32  */
33 
34 #ifndef TREL_INTERFACE_HPP_
35 #define TREL_INTERFACE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
40 
41 #include <openthread/trel.h>
42 #include <openthread/platform/trel.h>
43 
44 #include "common/array.hpp"
45 #include "common/locator.hpp"
46 #include "common/tasklet.hpp"
47 #include "common/time.hpp"
48 #include "mac/mac_types.hpp"
49 #include "net/ip6_address.hpp"
50 #include "net/socket.hpp"
51 #include "radio/trel_packet.hpp"
52 #include "thread/mle_types.hpp"
53 
54 namespace ot {
55 namespace Trel {
56 
57 class Link;
58 
59 extern "C" void otPlatTrelHandleReceived(otInstance       *aInstance,
60                                          uint8_t          *aBuffer,
61                                          uint16_t          aLength,
62                                          const otSockAddr *aSenderAddr);
63 extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
64 
65 /**
66  * Represents a group of TREL counters.
67  */
68 typedef otTrelCounters Counters;
69 
70 /**
71  * Represents a TREL link interface.
72  */
73 class Interface : public InstanceLocator
74 {
75     friend class Link;
76     friend void otPlatTrelHandleReceived(otInstance       *aInstance,
77                                          uint8_t          *aBuffer,
78                                          uint16_t          aLength,
79                                          const otSockAddr *aSenderAddr);
80     friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
81 
82 public:
83     /**
84      * Represents information about a discovered TREL peer.
85      */
86     class Peer : public otTrelPeer
87     {
88         friend class Interface;
89         friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
90 
91     public:
92         /**
93          * Returns the Extended MAC Address of the discovered TREL peer.
94          *
95          * @returns The Extended MAC Address of the TREL peer.
96          */
GetExtAddress(void) const97         const Mac::ExtAddress &GetExtAddress(void) const { return static_cast<const Mac::ExtAddress &>(mExtAddress); }
98 
99         /**
100          * Returns the Extended PAN Identifier of the discovered TREL peer.
101          *
102          * @returns The Extended PAN Identifier of the TREL peer.
103          */
GetExtPanId(void) const104         const MeshCoP::ExtendedPanId &GetExtPanId(void) const
105         {
106             return static_cast<const MeshCoP::ExtendedPanId &>(mExtPanId);
107         }
108 
109         /**
110          * Returns the IPv6 socket address of the discovered TREL peer.
111          *
112          * @returns The IPv6 socket address of the TREL peer.
113          */
GetSockAddr(void) const114         const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); }
115 
116         /**
117          * Set the IPv6 socket address of the discovered TREL peer.
118          *
119          * @param[in] aSockAddr   The IPv6 socket address.
120          */
SetSockAddr(const Ip6::SockAddr & aSockAddr)121         void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; }
122 
123         /**
124          * Indicates whether the peer matches a given Extended Address.
125          *
126          * @param[in] aExtAddress   A Extended Address to match with.
127          *
128          * @retval TRUE if the peer matches @p aExtAddress.
129          * @retval FALSE if the peer does not match @p aExtAddress.
130          */
Matches(const Mac::ExtAddress & aExtAddress) const131         bool Matches(const Mac::ExtAddress &aExtAddress) const { return GetExtAddress() == aExtAddress; }
132 
133         /**
134          * Indicates whether the peer matches a given Socket Address.
135          *
136          * @param[in] aSockAddr   A Socket Address to match with.
137          *
138          * @retval TRUE if the peer matches @p aSockAddr.
139          * @retval FALSE if the peer does not match @p aSockAddr.
140          */
Matches(const Ip6::SockAddr & aSockAddr) const141         bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; }
142 
143     private:
144         class Info : public otPlatTrelPeerInfo
145         {
146         public:
IsRemoved(void) const147             bool                 IsRemoved(void) const { return mRemoved; }
GetTxtData(void) const148             const uint8_t       *GetTxtData(void) const { return mTxtData; }
GetTxtLength(void) const149             uint16_t             GetTxtLength(void) const { return mTxtLength; }
GetSockAddr(void) const150             const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); }
151         };
152 
SetExtAddress(const Mac::ExtAddress & aExtAddress)153         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
SetExtPanId(const MeshCoP::ExtendedPanId & aExtPanId)154         void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; }
155         void Log(const char *aAction) const;
156     };
157 
158     /**
159      * Represents an iterator for iterating over TREL peer table entries.
160      */
161     typedef otTrelPeerIterator PeerIterator;
162 
163     /**
164      * Enables or disables the TREL interface.
165      *
166      * @param[in] aEnable A boolean to enable/disable the TREL interface.
167      */
168     void SetEnabled(bool aEnable);
169 
170     /**
171      * Enables the TREL interface.
172      *
173      * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain
174      * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD,
175      * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages
176      * from peers.
177      */
178     void Enable(void);
179 
180     /**
181      * Disables the TREL interface.
182      *
183      * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and
184      * clears the TREL peer table.
185      */
186     void Disable(void);
187 
188     /**
189      * Indicates whether the TREL interface is enabled.
190      *
191      * @retval TRUE if the TREL interface is enabled.
192      * @retval FALSE if the TREL interface is disabled.
193      */
IsEnabled(void) const194     bool IsEnabled(void) const { return mEnabled; }
195 
196     /**
197      * Initializes a peer table iterator.
198      *
199      * @param[in] aIterator   The iterator to initialize.
200      */
InitIterator(PeerIterator & aIterator) const201     void InitIterator(PeerIterator &aIterator) const { aIterator = 0; }
202 
203     /**
204      * Iterates over the peer table entries.
205      *
206      * @param[in] aIterator   The iterator. MUST be initialized.
207      *
208      * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table.
209      */
210     const Peer *GetNextPeer(PeerIterator &aIterator) const;
211 
212     /**
213      * Returns the number of TREL peers.
214      *
215      * @returns  The number of TREL peers.
216      */
GetNumberOfPeers(void) const217     uint16_t GetNumberOfPeers(void) const { return mPeerTable.GetLength(); }
218 
219     /**
220      * Sets the filter mode (enables/disables filtering).
221      *
222      * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly
223      * intended for use during testing.
224      *
225      * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the
226      * TREL interface continues to be enabled.
227      *
228      * @param[in] aFiltered  TRUE to enable filter mode, FALSE to disable filter mode.
229      */
SetFilterEnabled(bool aEnable)230     void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; }
231 
232     /**
233      * Indicates whether or not the filter mode is enabled.
234      *
235      * @retval TRUE if the TREL filter mode is enabled.
236      * @retval FALSE if the TREL filter mode is disabled.
237      */
IsFilterEnabled(void) const238     bool IsFilterEnabled(void) const { return mFiltered; }
239 
240     /**
241      * Gets the TREL counters.
242      *
243      * The counters are initialized to zero when the TREL platform is initialized.
244      */
245     const Counters *GetCounters(void) const;
246 
247     /**
248      * Resets the TREL counters.
249      */
250     void ResetCounters(void);
251 
252     /**
253      * Returns the TREL UDP port.
254      *
255      * @returns The TREL UDP port.
256      */
GetUdpPort(void) const257     uint16_t GetUdpPort(void) const { return mUdpPort; }
258 
259     /**
260      * Finds the TREL peer associated with a given Extended Address.
261      *
262      * @param[in] aExtAddress  The extended address.
263      *
264      * @returns The peer associated with @ aExtAddress, or `nullptr` if not found.
265      */
266     Peer *FindPeer(const Mac::ExtAddress &aExtAddress);
267 
268     /**
269      * Notifies platform that a TREL packet is received from a peer using a different socket address than the one
270      * reported earlier.
271      *
272      * @param[in] aPeerSockAddr   The previously reported peer sock addr.
273      * @param[in] aRxSockAddr     The address of received packet from the same peer.
274      */
275     void NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr);
276 
277 private:
278 #if OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE != 0
279     static constexpr uint16_t kPeerTableSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE;
280 #else
281     static constexpr uint16_t kPeerTableExtraEntries = 32;
282     static constexpr uint16_t kPeerTableSize         = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries;
283 #endif
284     static const char kTxtRecordExtAddressKey[];
285     static const char kTxtRecordExtPanIdKey[];
286 
287     typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable;
288 
289     explicit Interface(Instance &aInstance);
290 
291     // Methods used by `Trel::Link`.
292     void  Init(void);
293     void  HandleExtAddressChange(void);
294     void  HandleExtPanIdChange(void);
295     Error Send(const Packet &aPacket, bool aIsDiscovery = false);
296 
297     // Callbacks from `otPlatTrel`.
298     void HandleReceived(uint8_t *aBuffer, uint16_t aLength, const Ip6::SockAddr &aSenderAddr);
299     void HandleDiscoveredPeerInfo(const Peer::Info &aInfo);
300 
301     void  RegisterService(void);
302     Error ParsePeerInfoTxtData(const Peer::Info       &aInfo,
303                                Mac::ExtAddress        &aExtAddress,
304                                MeshCoP::ExtendedPanId &aExtPanId) const;
305     Peer *GetNewPeerEntry(void);
306     void  RemovePeerEntry(Peer &aEntry);
307 
308     using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>;
309 
310     bool                mInitialized : 1;
311     bool                mEnabled : 1;
312     bool                mFiltered : 1;
313     RegisterServiceTask mRegisterServiceTask;
314     uint16_t            mUdpPort;
315     Packet              mRxPacket;
316     PeerTable           mPeerTable;
317 };
318 
319 } // namespace Trel
320 } // namespace ot
321 
322 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
323 
324 #endif // TREL_INTERFACE_HPP_
325