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