• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 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  * @brief
32  *   This file includes the platform abstraction for Thread Radio Encapsulation Link (TREL) using DNS-SD and UDP/IPv6.
33  */
34 
35 #ifndef OPENTHREAD_PLATFORM_TREL_H_
36 #define OPENTHREAD_PLATFORM_TREL_H_
37 
38 #include <stdint.h>
39 
40 #include <openthread/error.h>
41 #include <openthread/instance.h>
42 #include <openthread/ip6.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /**
49  * @addtogroup plat-trel
50  *
51  * @brief
52  *   This module includes the platform abstraction for Thread Radio Encapsulation Link (TREL) using DNS-SD and
53  *   UDP/IPv6.
54  *
55  * @{
56  */
57 
58 /**
59  * Initializes and enables TREL platform layer.
60  *
61  * Upon this call, the platform layer MUST perform the following:
62  *
63  * 1) TREL platform layer MUST open a UDP socket to listen for and receive TREL messages from peers. The socket is
64  * bound to an ephemeral port number chosen by the platform layer. The port number MUST be returned in @p aUdpPort.
65  * The socket is also bound to network interface(s) on which TREL is to be supported. The socket and the chosen port
66  * should stay valid while TREL is enabled.
67  *
68  * 2) Platform layer MUST initiate an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing
69  * domain to discover other devices supporting TREL. The ongoing browse will produce two different types of events:
70  * "add" events and "remove" events.  When the browse is started, it should produce an "add" event for every TREL peer
71  * currently present on the network.  Whenever a TREL peer goes offline, a "remove" event should be produced. "remove"
72  * events are not guaranteed, however. When a TREL service instance is discovered, a new ongoing DNS-SD query for an
73  * AAAA record should be started on the hostname indicated in the SRV record of the discovered instance. If multiple
74  * host IPv6 addressees are discovered for a peer, one with highest scope among all addresses MUST be reported (if
75  * there are multiple address at same scope, one must be selected randomly).
76  *
77  * TREL platform MUST signal back the discovered peer info using `otPlatTrelHandleDiscoveredPeerInfo()` callback. This
78  * callback MUST be invoked when a new peer is discovered, when there is a change in an existing entry (e.g., new
79  * TXT record or new port number or new IPv6 address), or when the peer is removed.
80  *
81  * @param[in]  aInstance  The OpenThread instance.
82  * @param[out] aUdpPort   A pointer to return the selected port number by platform layer.
83  */
84 void otPlatTrelEnable(otInstance *aInstance, uint16_t *aUdpPort);
85 
86 /**
87  * Disables TREL platform layer.
88  *
89  * After this call, the platform layer MUST stop DNS-SD browse on the service name "_trel._udp", stop advertising the
90  * TREL DNS-SD service (from `otPlatTrelRegisterService()`) and MUST close the UDP socket used to receive TREL messages.
91  *
92  * @pram[in]  aInstance  The OpenThread instance.
93  */
94 void otPlatTrelDisable(otInstance *aInstance);
95 
96 /**
97  * Represents a TREL peer info discovered using DNS-SD browse on the service name "_trel._udp".
98  */
99 typedef struct otPlatTrelPeerInfo
100 {
101     /**
102      * This boolean flag indicates whether the entry is being removed or added.
103      *
104      * - TRUE indicates that peer is removed.
105      * - FALSE indicates that it is a new entry or an update to an existing entry.
106      */
107     bool mRemoved;
108 
109     /**
110      * The TXT record data (encoded as specified by DNS-SD) from the SRV record of the discovered TREL peer service
111      * instance.
112      */
113     const uint8_t *mTxtData;
114 
115     uint16_t mTxtLength; ///< Number of bytes in @p mTxtData buffer.
116 
117     /**
118      * The TREL peer socket address (IPv6 address and port number).
119      *
120      * The port number is determined from the SRV record of the discovered TREL peer service instance. The IPv6 address
121      * is determined from the DNS-SD query for AAAA records on the hostname indicated in the SRV record of the
122      * discovered service instance. If multiple host IPv6 addressees are discovered, one with highest scope is used.
123      */
124     otSockAddr mSockAddr;
125 } otPlatTrelPeerInfo;
126 
127 /**
128  * This is a callback function from platform layer to report a discovered TREL peer info.
129  *
130  * @note The @p aInfo structure and its content (e.g., the `mTxtData` buffer) does not need to persist after returning
131  * from this call. OpenThread code will make a copy of all the info it needs.
132  *
133  * @param[in] aInstance   The OpenThread instance.
134  * @param[in] aInfo       A pointer to the TREL peer info.
135  */
136 extern void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo);
137 
138 /**
139  * Notifies platform that a TREL packet is received from a peer using a different socket address than the one reported
140  * earlier from `otPlatTrelHandleDiscoveredPeerInfo()`.
141  *
142  * Ideally the platform underlying DNS-SD should detect changes to advertised port and addresses by peers, however,
143  * there are situations where this is not detected reliably. This function signals to the platform layer than we
144  * received a packet from a peer with it using a different port or address. This can be used by the playroom layer to
145  * restart/confirm the DNS-SD service/address resolution for the peer service and/or take any other relevant actions.
146  *
147  * @param[in] aInstance      The OpenThread instance.
148  * @param[in] aPeerSockAddr  The address of the peer, reported from `otPlatTrelHandleDiscoveredPeerInfo()` call.
149  * @param[in] aRxSockAddr    The address of received packet from the same peer (differs from @p aPeerSockAddr).
150  */
151 void otPlatTrelNotifyPeerSocketAddressDifference(otInstance       *aInstance,
152                                                  const otSockAddr *aPeerSockAddr,
153                                                  const otSockAddr *aRxSockAddr);
154 
155 /**
156  * Registers a new service to be advertised using DNS-SD [RFC6763].
157  *
158  * The service name is "_trel._udp". The platform should use its own hostname, which when combined with the service
159  * name and the local DNS-SD domain name will produce the full service instance name, for example
160  * "example-host._trel._udp.local.".
161  *
162  * The domain under which the service instance name appears will be 'local' for mDNS, and will be whatever domain is
163  * used for service registration in the case of a non-mDNS local DNS-SD service.
164  *
165  * A subsequent call to this function updates the previous service. It is used to update the TXT record data and/or the
166  * port number.
167  *
168  * The @p aTxtData buffer is not persisted after the return from this function. The platform layer MUST NOT keep the
169  * pointer and instead copy the content if needed.
170  *
171  * @param[in] aInstance   The OpenThread instance.
172  * @param[in] aPort       The port number to include in the SRV record of the advertised service.
173  * @param[in] aTxtData    A pointer to the TXT record data (encoded) to be include in the advertised service.
174  * @param[in] aTxtLength  The length of @p aTxtData (number of bytes).
175  */
176 void otPlatTrelRegisterService(otInstance *aInstance, uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength);
177 
178 /**
179  * Requests a TREL UDP packet to be sent to a given destination.
180  *
181  * @param[in] aInstance        The OpenThread instance structure.
182  * @param[in] aUdpPayload      A pointer to UDP payload.
183  * @param[in] aUdpPayloadLen   The payload length (number of bytes).
184  * @param[in] aDestSockAddr    The destination socket address.
185  */
186 void otPlatTrelSend(otInstance       *aInstance,
187                     const uint8_t    *aUdpPayload,
188                     uint16_t          aUdpPayloadLen,
189                     const otSockAddr *aDestSockAddr);
190 
191 /**
192  * Is a callback from platform to notify of a received TREL UDP packet.
193  *
194  * @note The buffer content (up to its specified length) may get changed during processing by OpenThread core (e.g.,
195  * decrypted in place), so the platform implementation should expect that after returning from this function the
196  * @p aBuffer content may have been altered.
197  *
198  * @param[in] aInstance        The OpenThread instance structure.
199  * @param[in] aBuffer          A buffer containing the received UDP payload.
200  * @param[in] aLength          UDP payload length (number of bytes).
201  * @param[in] aSockAddr        The sender address.
202  */
203 extern void otPlatTrelHandleReceived(otInstance       *aInstance,
204                                      uint8_t          *aBuffer,
205                                      uint16_t          aLength,
206                                      const otSockAddr *aSenderAddr);
207 
208 /**
209  * Represents a group of TREL related counters in the platform layer.
210  */
211 typedef struct otPlatTrelCounters
212 {
213     uint64_t mTxPackets; ///< Number of packets successfully transmitted through TREL.
214     uint64_t mTxBytes;   ///< Sum of size of packets successfully transmitted through TREL.
215     uint64_t mTxFailure; ///< Number of packet transmission failures through TREL.
216     uint64_t mRxPackets; ///< Number of packets received through TREL.
217     uint64_t mRxBytes;   ///< Sum of size of packets received through TREL.
218 } otPlatTrelCounters;
219 
220 /**
221  * Gets the pointer to the TREL counters in the platform layer.
222  *
223  * @param[in] aInstance        The OpenThread instance structure.
224  */
225 const otPlatTrelCounters *otPlatTrelGetCounters(otInstance *aInstance);
226 
227 /**
228  * Resets the TREL counters in the platform layer.
229  *
230  * @param[in] aInstance        The OpenThread instance structure.
231  */
232 void otPlatTrelResetCounters(otInstance *aInstance);
233 
234 /**
235  * @}
236  */
237 
238 #ifdef __cplusplus
239 } // end of extern "C"
240 #endif
241 
242 #endif // OPENTHREAD_PLATFORM_TREL_H_
243