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, uint8_t *aBuffer, uint16_t aLength);
60 extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
61 
62 /**
63  * Represents a group of TREL counters.
64  *
65  */
66 typedef otTrelCounters Counters;
67 
68 /**
69  * Represents a TREL link interface.
70  *
71  */
72 class Interface : public InstanceLocator
73 {
74     friend class Link;
75     friend void otPlatTrelHandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength);
76     friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
77 
78 public:
79     /**
80      * Represents information about a discovered TREL peer.
81      *
82      */
83     class Peer : public otTrelPeer
84     {
85         friend class Interface;
86         friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
87 
88     public:
89         /**
90          * Returns the Extended MAC Address of the discovered TREL peer.
91          *
92          * @returns The Extended MAC Address of the TREL peer.
93          *
94          */
GetExtAddress(void) const95         const Mac::ExtAddress &GetExtAddress(void) const { return static_cast<const Mac::ExtAddress &>(mExtAddress); }
96 
97         /**
98          * Returns the Extended PAN Identifier of the discovered TREL peer.
99          *
100          * @returns The Extended PAN Identifier of the TREL peer.
101          *
102          */
GetExtPanId(void) const103         const MeshCoP::ExtendedPanId &GetExtPanId(void) const
104         {
105             return static_cast<const MeshCoP::ExtendedPanId &>(mExtPanId);
106         }
107 
108         /**
109          * Returns the IPv6 socket address of the discovered TREL peer.
110          *
111          * @returns The IPv6 socket address of the TREP peer.
112          *
113          */
GetSockAddr(void) const114         const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); }
115 
116         /**
117          * Indicates whether the peer matches a given Extended Address.
118          *
119          * @param[in] aExtAddress   A Extended Address to match with.
120          *
121          * @retval TRUE if the peer matches @p aExtAddress.
122          * @retval FALSE if the peer does not match @p aExtAddress.
123          *
124          */
Matches(const Mac::ExtAddress & aExtAddress) const125         bool Matches(const Mac::ExtAddress &aExtAddress) const { return GetExtAddress() == aExtAddress; }
126 
127         /**
128          * Indicates whether the peer matches a given Socket Address.
129          *
130          * @param[in] aSockAddr   A Socket Address to match with.
131          *
132          * @retval TRUE if the peer matches @p aSockAddr.
133          * @retval FALSE if the peer does not match @p aSockAddr.
134          *
135          */
Matches(const Ip6::SockAddr & aSockAddr) const136         bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; }
137 
138     private:
139         class Info : public otPlatTrelPeerInfo
140         {
141         public:
IsRemoved(void) const142             bool                 IsRemoved(void) const { return mRemoved; }
GetTxtData(void) const143             const uint8_t       *GetTxtData(void) const { return mTxtData; }
GetTxtLength(void) const144             uint16_t             GetTxtLength(void) const { return mTxtLength; }
GetSockAddr(void) const145             const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); }
146         };
147 
SetExtAddress(const Mac::ExtAddress & aExtAddress)148         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
SetExtPanId(const MeshCoP::ExtendedPanId & aExtPanId)149         void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; }
SetSockAddr(const Ip6::SockAddr & aSockAddr)150         void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; }
151         void Log(const char *aAction) const;
152     };
153 
154     /**
155      * Represents an iterator for iterating over TREL peer table entries.
156      *
157      */
158     typedef otTrelPeerIterator PeerIterator;
159 
160     /**
161      * Enables or disables the TREL interface.
162      *
163      * @param[in] aEnable A boolean to enable/disable the TREL interface.
164      */
165     void SetEnabled(bool aEnable);
166 
167     /**
168      * Enables the TREL interface.
169      *
170      * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain
171      * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD,
172      * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages
173      * from peers.
174      *
175      */
176     void Enable(void);
177 
178     /**
179      * Disables the TREL interface.
180      *
181      * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and
182      * clears the TREL peer table.
183      *
184      */
185     void Disable(void);
186 
187     /**
188      * Indicates whether the TREL interface is enabled.
189      *
190      * @retval TRUE if the TREL interface is enabled.
191      * @retval FALSE if the TREL interface is disabled.
192      *
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      *
201      */
InitIterator(PeerIterator & aIterator) const202     void InitIterator(PeerIterator &aIterator) const { aIterator = 0; }
203 
204     /**
205      * Iterates over the peer table entries.
206      *
207      * @param[in] aIterator   The iterator. MUST be initialized.
208      *
209      * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table.
210      *
211      */
212     const Peer *GetNextPeer(PeerIterator &aIterator) const;
213 
214     /**
215      * Returns the number of TREL peers.
216      *
217      * @returns  The number of TREL peers.
218      *
219      */
GetNumberOfPeers(void) const220     uint16_t GetNumberOfPeers(void) const { return mPeerTable.GetLength(); }
221 
222     /**
223      * Sets the filter mode (enables/disables filtering).
224      *
225      * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly
226      * intended for use during testing.
227      *
228      * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the
229      * TREL interface continues to be enabled.
230      *
231      * @param[in] aFiltered  TRUE to enable filter mode, FALSE to disable filter mode.
232      *
233      */
SetFilterEnabled(bool aEnable)234     void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; }
235 
236     /**
237      * Indicates whether or not the filter mode is enabled.
238      *
239      * @retval TRUE if the TREL filter mode is enabled.
240      * @retval FALSE if the TREL filter mode is disabled.
241      *
242      */
IsFilterEnabled(void) const243     bool IsFilterEnabled(void) const { return mFiltered; }
244 
245     /**
246      * Gets the TREL counters.
247      *
248      * The counters are initialized to zero when the TREL platform is initialized.
249      *
250      */
251     const Counters *GetCounters(void) const;
252 
253     /**
254      * Resets the TREL counters.
255      *
256      */
257     void ResetCounters(void);
258 
259 private:
260 #if OPENTHREAD_COFNIG_TREL_PEER_TABLE_SIZE != 0
261     static constexpr uint16_t kPeerTableSize = OPENTHREAD_COFNIG_TREL_PEER_TABLE_SIZE;
262 #else
263     static constexpr uint16_t kPeerTableExtraEntries = 32;
264     static constexpr uint16_t kPeerTableSize         = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries;
265 #endif
266     static const char kTxtRecordExtAddressKey[];
267     static const char kTxtRecordExtPanIdKey[];
268 
269     typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable;
270 
271     explicit Interface(Instance &aInstance);
272 
273     // Methods used by `Trel::Link`.
274     void  Init(void);
275     void  HandleExtAddressChange(void);
276     void  HandleExtPanIdChange(void);
277     Error Send(const Packet &aPacket, bool aIsDiscovery = false);
278 
279     // Callbacks from `otPlatTrel`.
280     void HandleReceived(uint8_t *aBuffer, uint16_t aLength);
281     void HandleDiscoveredPeerInfo(const Peer::Info &aInfo);
282 
283     void  RegisterService(void);
284     Error ParsePeerInfoTxtData(const Peer::Info       &aInfo,
285                                Mac::ExtAddress        &aExtAddress,
286                                MeshCoP::ExtendedPanId &aExtPanId) const;
287     Peer *GetNewPeerEntry(void);
288     void  RemovePeerEntry(Peer &aEntry);
289 
290     using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>;
291 
292     bool                mInitialized : 1;
293     bool                mEnabled : 1;
294     bool                mFiltered : 1;
295     RegisterServiceTask mRegisterServiceTask;
296     uint16_t            mUdpPort;
297     Packet              mRxPacket;
298     PeerTable           mPeerTable;
299 };
300 
301 } // namespace Trel
302 } // namespace ot
303 
304 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
305 
306 #endif // TREL_INTERFACE_HPP_
307