1 /*
2  *  Copyright (c) 2016, 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 defines the OpenThread UDP API.
33  *
34  */
35 
36 #ifndef OPENTHREAD_UDP_H_
37 #define OPENTHREAD_UDP_H_
38 
39 #include <openthread/ip6.h>
40 #include <openthread/message.h>
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /**
47  * @addtogroup api-udp
48  *
49  * @brief
50  *   This module includes functions that control UDP communication.
51  *
52  * @{
53  *
54  */
55 
56 /**
57  * This callback allows OpenThread to provide specific handlers for certain UDP messages.
58  *
59  * @retval  true    The message is handled by this receiver and should not be further processed.
60  * @retval  false   The message is not handled by this receiver.
61  *
62  */
63 typedef bool (*otUdpHandler)(void *aContext, const otMessage *aMessage, const otMessageInfo *aMessageInfo);
64 
65 /**
66  * Represents a UDP receiver.
67  *
68  */
69 typedef struct otUdpReceiver
70 {
71     struct otUdpReceiver *mNext;    ///< A pointer to the next UDP receiver (internal use only).
72     otUdpHandler          mHandler; ///< A function pointer to the receiver callback.
73     void                 *mContext; ///< A pointer to application-specific context.
74 } otUdpReceiver;
75 
76 /**
77  * Adds a UDP receiver.
78  *
79  * @param[in]   aInstance       A pointer to an OpenThread instance.
80  * @param[in]   aUdpReceiver    A pointer to the UDP receiver.
81  *
82  * @retval  OT_ERROR_NONE       The receiver is successfully added.
83  * @retval  OT_ERROR_ALREADY    The UDP receiver was already added.
84  *
85  */
86 otError otUdpAddReceiver(otInstance *aInstance, otUdpReceiver *aUdpReceiver);
87 
88 /**
89  * Removes a UDP receiver.
90  *
91  * @param[in]   aInstance       A pointer to an OpenThread instance.
92  * @param[in]   aUdpReceiver    A pointer to the UDP receiver.
93  *
94  * @retval  OT_ERROR_NONE       The receiver is successfully removed.
95  * @retval  OT_ERROR_NOT_FOUND  The UDP receiver was not added.
96  *
97  */
98 otError otUdpRemoveReceiver(otInstance *aInstance, otUdpReceiver *aUdpReceiver);
99 
100 /**
101  * Sends a UDP message without socket.
102  *
103  * @param[in]  aInstance     A pointer to an OpenThread instance.
104  * @param[in]  aMessage      A pointer to a message without UDP header.
105  * @param[in]  aMessageInfo  A pointer to a message info associated with @p aMessage.
106  *
107  * @retval OT_ERROR_NONE          Successfully enqueued the message into an output interface.
108  * @retval OT_ERROR_NO_BUFS       Insufficient available buffer to add the IPv6 headers.
109  * @retval OT_ERROR_INVALID_ARGS  Invalid arguments are given.
110  *
111  */
112 otError otUdpSendDatagram(otInstance *aInstance, otMessage *aMessage, otMessageInfo *aMessageInfo);
113 
114 /**
115  * This callback allows OpenThread to inform the application of a received UDP message.
116  *
117  */
118 typedef void (*otUdpReceive)(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
119 
120 /**
121  * Represents a UDP socket.
122  *
123  */
124 typedef struct otUdpSocket
125 {
126     otSockAddr          mSockName; ///< The local IPv6 socket address.
127     otSockAddr          mPeerName; ///< The peer IPv6 socket address.
128     otUdpReceive        mHandler;  ///< A function pointer to the application callback.
129     void               *mContext;  ///< A pointer to application-specific context.
130     void               *mHandle;   ///< A handle to platform's UDP.
131     struct otUdpSocket *mNext;     ///< A pointer to the next UDP socket (internal use only).
132 } otUdpSocket;
133 
134 /**
135  * Defines the OpenThread network interface identifiers.
136  *
137  */
138 typedef enum otNetifIdentifier
139 {
140     OT_NETIF_UNSPECIFIED = 0, ///< Unspecified network interface.
141     OT_NETIF_THREAD,          ///< The Thread interface.
142     OT_NETIF_BACKBONE,        ///< The Backbone interface.
143 } otNetifIdentifier;
144 
145 /**
146  * Allocate a new message buffer for sending a UDP message.
147  *
148  * @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
149  * OT_MESSAGE_PRIORITY_NORMAL by default.
150  *
151  * @param[in]  aInstance  A pointer to an OpenThread instance.
152  * @param[in]  aSettings  A pointer to the message settings or NULL to use default settings.
153  *
154  * @returns A pointer to the message buffer or NULL if no message buffers are available or parameters are invalid.
155  *
156  * @sa otMessageFree
157  *
158  */
159 otMessage *otUdpNewMessage(otInstance *aInstance, const otMessageSettings *aSettings);
160 
161 /**
162  * Open a UDP/IPv6 socket.
163  *
164  * @param[in]  aInstance  A pointer to an OpenThread instance.
165  * @param[in]  aSocket    A pointer to a UDP socket structure.
166  * @param[in]  aCallback  A pointer to the application callback function.
167  * @param[in]  aContext   A pointer to application-specific context.
168  *
169  * @retval OT_ERROR_NONE    Successfully opened the socket.
170  * @retval OT_ERROR_FAILED  Failed to open the socket.
171  *
172  */
173 otError otUdpOpen(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCallback, void *aContext);
174 
175 /**
176  * Check if a UDP socket is open.
177  *
178  * @param[in]  aInstance  A pointer to an OpenThread instance.
179  * @param[in]  aSocket    A pointer to a UDP socket structure.
180  *
181  * @returns Whether the UDP socket is open.
182  *
183  */
184 bool otUdpIsOpen(otInstance *aInstance, const otUdpSocket *aSocket);
185 
186 /**
187  * Close a UDP/IPv6 socket.
188  *
189  * @param[in]  aInstance  A pointer to an OpenThread instance.
190  * @param[in]  aSocket    A pointer to a UDP socket structure.
191  *
192  * @retval OT_ERROR_NONE   Successfully closed the socket.
193  * @retval OT_ERROR_FAILED Failed to close UDP Socket.
194  *
195  */
196 otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket);
197 
198 /**
199  * Bind a UDP/IPv6 socket.
200  *
201  * @param[in]  aInstance  A pointer to an OpenThread instance.
202  * @param[in]  aSocket    A pointer to a UDP socket structure.
203  * @param[in]  aSockName  A pointer to an IPv6 socket address structure.
204  * @param[in]  aNetif     The network interface to bind.
205  *
206  * @retval OT_ERROR_NONE   Bind operation was successful.
207  * @retval OT_ERROR_FAILED Failed to bind UDP socket.
208  *
209  */
210 otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName, otNetifIdentifier aNetif);
211 
212 /**
213  * Connect a UDP/IPv6 socket.
214  *
215  * @param[in]  aInstance  A pointer to an OpenThread instance.
216  * @param[in]  aSocket    A pointer to a UDP socket structure.
217  * @param[in]  aSockName  A pointer to an IPv6 socket address structure.
218  *
219  * @retval OT_ERROR_NONE   Connect operation was successful.
220  * @retval OT_ERROR_FAILED Failed to connect UDP socket.
221  *
222  */
223 otError otUdpConnect(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName);
224 
225 /**
226  * Send a UDP/IPv6 message.
227  *
228  * @param[in]  aInstance     A pointer to an OpenThread instance.
229  * @param[in]  aSocket       A pointer to a UDP socket structure.
230  * @param[in]  aMessage      A pointer to a message buffer.
231  * @param[in]  aMessageInfo  A pointer to a message info structure.
232  *
233  * If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer
234  * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage,
235  * including freeing @p aMessage if the message buffer is no longer needed.
236  *
237  * @retval OT_ERROR_NONE           The message is successfully scheduled for sending.
238  * @retval OT_ERROR_INVALID_ARGS   Invalid arguments are given.
239  * @retval OT_ERROR_NO_BUFS        Insufficient available buffer to add the UDP and IPv6 headers.
240  *
241  */
242 otError otUdpSend(otInstance *aInstance, otUdpSocket *aSocket, otMessage *aMessage, const otMessageInfo *aMessageInfo);
243 
244 /**
245  * Gets the head of linked list of UDP Sockets.
246  *
247  * @param[in]  aInstance  A pointer to an OpenThread instance.
248  *
249  * @returns A pointer to the head of UDP Socket linked list.
250  *
251  */
252 otUdpSocket *otUdpGetSockets(otInstance *aInstance);
253 
254 /**
255  * @}
256  *
257  */
258 
259 /**
260  * @addtogroup api-udp-forward
261  *
262  * @brief
263  *   This module includes functions for UDP forward feature.
264  *
265  *   The functions in this module are available when udp-forward feature (`OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE`) is
266  *   enabled.
267  *
268  * @{
269  *
270  */
271 
272 /**
273  * Pointer delivers the UDP packet to host and host should send the packet through its own network stack.
274  *
275  * @param[in]  aMessage   A pointer to the UDP Message.
276  * @param[in]  aPeerPort  The destination UDP port.
277  * @param[in]  aPeerAddr  A pointer to the destination IPv6 address.
278  * @param[in]  aSockPort  The source UDP port.
279  * @param[in]  aContext   A pointer to application-specific context.
280  *
281  */
282 typedef void (*otUdpForwarder)(otMessage    *aMessage,
283                                uint16_t      aPeerPort,
284                                otIp6Address *aPeerAddr,
285                                uint16_t      aSockPort,
286                                void         *aContext);
287 
288 /**
289  * Set UDP forward callback to deliver UDP packets to host.
290  *
291  * @param[in]  aInstance            A pointer to an OpenThread instance.
292  * @param[in]  aForwarder           A pointer to a function called to forward UDP packet to host.
293  * @param[in]  aContext             A pointer to application-specific context.
294  *
295  */
296 void otUdpForwardSetForwarder(otInstance *aInstance, otUdpForwarder aForwarder, void *aContext);
297 
298 /**
299  * Handle a UDP packet received from host.
300  *
301  * @param[in]  aInstance            A pointer to an OpenThread instance.
302  * @param[in]  aMessage             A pointer to the UDP Message.
303  * @param[in]  aPeerPort            The source UDP port.
304  * @param[in]  aPeerAddr            A pointer to the source address.
305  * @param[in]  aSockPort            The destination UDP port.
306  *
307  * @warning No matter the call success or fail, the message is freed.
308  *
309  */
310 void otUdpForwardReceive(otInstance         *aInstance,
311                          otMessage          *aMessage,
312                          uint16_t            aPeerPort,
313                          const otIp6Address *aPeerAddr,
314                          uint16_t            aSockPort);
315 
316 /**
317  * Determines if the given UDP port is exclusively opened by OpenThread API.
318  *
319  * @param[in]  aInstance            A pointer to an OpenThread instance.
320  * @param[in]  port                 UDP port number to verify.
321  *
322  * @retval true    The port is being used exclusively by OpenThread.
323  * @retval false   The port is not used by any of the OpenThread API or is shared (e.g. is Backbone socket).
324  *
325  */
326 bool otUdpIsPortInUse(otInstance *aInstance, uint16_t port);
327 
328 /**
329  * @}
330  *
331  */
332 
333 #ifdef __cplusplus
334 } // extern "C"
335 #endif
336 
337 #endif // OPENTHREAD_UDP_H_
338