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 defines the OpenThread TCP API.
33  *
34  */
35 
36 #ifndef OPENTHREAD_TCP_H_
37 #define OPENTHREAD_TCP_H_
38 
39 #include <openthread/ip6.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /**
46  * @addtogroup api-tcp
47  *
48  * @brief
49  *   This module includes functions that control TCP communication.
50  *
51  * @{
52  *
53  */
54 
55 /**
56  * A linked buffer structure for use with TCP.
57  *
58  * A single otLinkedBuffer structure references an array of bytes in memory,
59  * via mData and mLength. The mNext field is used to form a chain of
60  * otLinkedBuffer structures.
61  *
62  */
63 typedef struct otLinkedBuffer
64 {
65     struct otLinkedBuffer *mNext;   ///< Pointer to the next linked buffer in the chain, or NULL if it is the end.
66     const uint8_t *        mData;   ///< Pointer to data referenced by this linked buffer.
67     uint16_t               mLength; ///< Length of this linked buffer (number of bytes).
68 } otLinkedBuffer;
69 
70 struct otTcpEndpoint;
71 typedef struct otTcpEndpoint otTcpEndpoint;
72 
73 /**
74  * This callback informs the application that the TCP 3-way handshake is
75  * complete and that the connection is now established.
76  *
77  * @param[in]  aEndpoint  The TCP endpoint whose connection is now established.
78  *
79  */
80 typedef void (*otTcpEstablished)(otTcpEndpoint *aEndpoint);
81 
82 /**
83  * This callback informs the application that data in the provided
84  * @p aData have been acknowledged by the connection peer and that @p aData and
85  * the data it contains can be reclaimed by the application.
86  *
87  * The @p aData are guaranteed to be identical to those passed in to TCP via
88  * otTcpSendByReference(), including any extensions effected via
89  * otTcpSendByExtension().
90  *
91  * @param[in]  aEndpoint  The TCP endpoint for the connection.
92  * @param[in]  aData      A pointer to the otLinkedBuffer that can be reclaimed.
93  *
94  */
95 typedef void (*otTcpSendDone)(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData);
96 
97 /**
98  * This callback informs the application that the first @p aNumBytes in the
99  * send buffer have been acknowledged by the connection peer and that their
100  * underlying memory can be reclaimed by the application.
101  *
102  * This callback is not necessary for correct TCP operation. Most applications
103  * can just rely on the otTcpSendDone() callback. If an application wants
104  * fine-grained feedback as memory in the send buffer becomes available again
105  * (instead of waiting for an entire linked buffer's worth of data becomes
106  * available) or some indication as to whether the connection is making forward
107  * progress, it can register this callback.
108  *
109  * @param[in]  aEndpoint  The TCP endpoint for the connection.
110  * @param[in]  aNumBytes  The number of bytes newly acknowledged by the connection peer.
111  *
112  */
113 typedef void (*otTcpBytesAcked)(otTcpEndpoint *aEndpoint, size_t aNumBytes);
114 
115 /**
116  * This callback informs the application that if data is added to the send
117  * buffer, some of it will be transmitted immediately without delay, as opposed
118  * to being queued for transmission once the peer ACKs some data.
119  *
120  * After a call to otTcpSendByReference() or otTcpSendByExtension(), the
121  * otTcpSendReady() callback is guaranteed to be called, either immediately (if
122  * the connection is already ready) or sometime in the future (once the
123  * connection becomes ready for more data).
124  *
125  * This callback is not necessary for correct TCP operation. If more data is
126  * added to the send buffer than can be transmitted without delay, it will
127  * simply be queued for transmission at a later time. This callback should be
128  * used only in cases where some assurance is desired that data added to the
129  * send buffer will be sent soon (e.g., TCP won't wait for the recipient to
130  * ACK some other data first before sending this data out). For example, you
131  * may use this callback if you'd rather have your data be dropped than develop
132  * a backlog of data in your send buffer. But for most applications, where this
133  * isn't a concern, it's expected that one would not use this callback at all.
134  *
135  * @param[in]  aEndpoint  The TCP endpoint for the connection.
136  *
137  */
138 typedef void (*otTcpSendReady)(otTcpEndpoint *aEndpoint);
139 
140 /**
141  * This callback indicates the number of bytes available for consumption from
142  * the receive buffer.
143  *
144  * It is called whenever bytes are added to the receive buffer and when the
145  * end of stream is reached. If the end of the stream has been reached (i.e.,
146  * if no more data will become available to read because the connection peer
147  * has closed their end of the connection for writing), then @p aEndOfStream is
148  * true. Finally, @p aBytesRemaining indicates how much capacity is left in the
149  * receive buffer to hold additional data that arrives.
150  *
151  * @param[in]  aEndpoint        The TCP endpoint for the connection.
152  * @param[in]  aBytesAvailable  The number of bytes in the connection's receive buffer.
153  * @param[in]  aEndOfStream     Indicates if additional data, beyond what is already in the connection's receive buffer,
154  *                              can be received.
155  * @param[in]  aBytesRemaining  The number of additional bytes that can be received before the receive buffer becomes
156  *                              full.
157  *
158  */
159 typedef void (*otTcpReceiveAvailable)(otTcpEndpoint *aEndpoint,
160                                       size_t         aBytesAvailable,
161                                       bool           aEndOfStream,
162                                       size_t         aBytesRemaining);
163 
164 typedef enum otTcpDisconnectedReason
165 {
166     OT_TCP_DISCONNECTED_REASON_NORMAL,
167     OT_TCP_DISCONNECTED_REASON_REFUSED,
168     OT_TCP_DISCONNECTED_REASON_RESET,
169     OT_TCP_DISCONNECTED_REASON_TIME_WAIT,
170     OT_TCP_DISCONNECTED_REASON_TIMED_OUT,
171 } otTcpDisconnectedReason;
172 
173 /**
174  * This callback indicates that the connection was broken and should no longer
175  * be used, or that a connection has entered the TIME-WAIT state.
176  *
177  * It can occur if a connection establishment attempt (initiated by calling
178  * otTcpConnect()) fails, or any point thereafter (e.g., if the connection
179  * times out or an RST segment is received from the connection peer). Once this
180  * callback fires, all resources that the application provided for this
181  * connection (i.e., any `otLinkedBuffers` and memory they reference, but not
182  * the TCP endpoint itself or space for the receive buffers) can be reclaimed.
183  * In the case of a connection entering the TIME-WAIT state, this callback is
184  * called twice, once upon entry into the TIME-WAIT state (with
185  * OT_TCP_DISCONNECTED_REASON_TIME_WAIT, and again when the TIME-WAIT state
186  * expires (with OT_TCP_DISCONNECTED_REASON_NORMAL).
187  *
188  * @param[in]  aEndpoint  The TCP endpoint whose connection has been lost.
189  * @param[in]  aReason    The reason why the connection was lost.
190  *
191  */
192 typedef void (*otTcpDisconnected)(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason);
193 
194 /**
195  * This structure represents a TCP endpoint.
196  *
197  * An TCP endpoint acts an endpoint of TCP connection. It can be used to
198  * initiate TCP connections, and, once a TCP connection is established, send
199  * data to and receive data from the connection peer.
200  *
201  * The application should not inspect the fields of this structure directly; it
202  * should only interact with it via the TCP API functions whose signatures are
203  * provided in this file.
204  *
205  */
206 struct otTcpEndpoint
207 {
208     struct otTcpEndpoint *mNext;     ///< A pointer to the next TCP endpoint (internal use only)
209     otInstance *          mInstance; ///< A pointer to the OpenThread instance associated with this TCP endpoint
210     void *                mContext;  ///< A pointer to application-specific context
211 
212     otTcpEstablished      mEstablishedCallback;      ///< "Established" callback function
213     otTcpSendDone         mSendDoneCallback;         ///< "Send done" callback function
214     otTcpSendReady        mSendReadyCallback;        ///< "Send ready" callback function
215     otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function
216     otTcpDisconnected     mDisconnectedCallback;     ///< "Disconnected" callback function
217 
218     uint32_t mTimers[4];
219 
220     /* Other implementation-defined fields go here. */
221 };
222 
223 /**
224  * This structure contains arguments to the otTcpEndpointInitialize() function.
225  *
226  */
227 typedef struct otTcpEndpointInitializeArgs
228 {
229     void *mContext; ///< Pointer to application-specific context
230 
231     otTcpEstablished      mEstablishedCallback;      ///< "Established" callback function
232     otTcpSendDone         mSendDoneCallback;         ///< "Send done" callback function
233     otTcpBytesAcked       mBytesAckedCallback;       ///< "Bytes acked" callback
234     otTcpSendReady        mSendReadyCallback;        ///< "Send ready" callback function
235     otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function
236     otTcpDisconnected     mDisconnectedCallback;     ///< "Disconnected" callback function
237 
238     void * mReceiveBuffer;     ///< Pointer to memory provided to the system for the TCP receive buffer
239     size_t mReceiveBufferSize; ///< Size of memory provided to the system for the TCP receive buffer
240 } otTcpEndpointInitializeArgs;
241 
242 /**
243  * @def OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS
244  *
245  * Recommended buffer size for TCP connections that traverse about 3 wireless
246  * hops or fewer.
247  *
248  * On platforms where memory is particularly constrained and in situations
249  * where high bandwidth is not necessary, it may be desirable to manually
250  * select a smaller buffer size.
251  *
252  */
253 #define OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS 2599
254 
255 /**
256  * @def OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS
257  *
258  * Recommended buffer size for TCP connections that traverse many wireless
259  * hops.
260  *
261  * If the TCP connection traverses a very large number of hops (more than 6 or
262  * so), then it may be advisable to select a large buffer size manually.
263  *
264  */
265 #define OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS 4158
266 
267 /**
268  * Initializes a TCP endpoint.
269  *
270  * Calling this function causes OpenThread to keep track of the TCP endpoint
271  * and store and retrieve TCP data inside the @p aEndpoint. The application
272  * should refrain from directly accessing or modifying the fields in
273  * @p aEndpoint. If the application needs to reclaim the memory backing
274  * @p aEndpoint, it should call otTcpEndpointDeinitialize().
275  *
276  * @param[in]  aInstance  A pointer to an OpenThread instance.
277  * @param[in]  aEndpoint  A pointer to a TCP endpoint structure.
278  * @param[in]  aArgs      A pointer to a structure of arguments.
279  *
280  * @retval OT_ERROR_NONE    Successfully opened the TCP endpoint.
281  * @retval OT_ERROR_FAILED  Failed to open the TCP endpoint.
282  *
283  */
284 otError otTcpEndpointInitialize(otInstance *aInstance, otTcpEndpoint *aEndpoint, otTcpEndpointInitializeArgs *aArgs);
285 
286 /**
287  * Obtains the otInstance that was associated with @p aEndpoint upon
288  * initialization.
289  *
290  * @param[in]  aEndpoint  The TCP endpoint whose instance to obtain.
291  *
292  * @returns  The otInstance pointer associated with @p aEndpoint.
293  *
294  */
295 otInstance *otTcpEndpointGetInstance(otTcpEndpoint *aEndpoint);
296 
297 /**
298  * Obtains the context pointer that was associated with @p aEndpoint upon
299  * initialization.
300  *
301  * @param[in]  aEndpoint  The TCP endpoint whose context to obtain.
302  *
303  * @returns  The context pointer associated with @p aEndpoint.
304  *
305  */
306 void *otTcpEndpointGetContext(otTcpEndpoint *aEndpoint);
307 
308 /**
309  * Obtains a pointer to a TCP endpoint's local host and port.
310  *
311  * The contents of the host and port may be stale if this socket is not in a
312  * connected state and has not been bound after it was last disconnected.
313  *
314  * @param[in]  aEndpoint  The TCP endpoint whose local host and port to obtain.
315  *
316  * @returns  The local host and port of @p aEndpoint.
317  *
318  */
319 const otSockAddr *otTcpGetLocalAddress(const otTcpEndpoint *aEndpoint);
320 
321 /**
322  * Obtains a pointer to a TCP endpoint's peer's host and port.
323  *
324  * The contents of the host and port may be stale if this socket is not in a
325  * connected state.
326  *
327  * @param[in]  aEndpoint  The TCP endpoint whose peer's host and port to obtain.
328  *
329  * @returns  The host and port of the connection peer of @p aEndpoint.
330  *
331  */
332 const otSockAddr *otTcpGetPeerAddress(const otTcpEndpoint *aEndpoint);
333 
334 /**
335  * Binds the TCP endpoint to an IP address and port.
336  *
337  * @param[in]  aEndpoint   A pointer to the TCP endpoint structure to bind.
338  * @param[in]  aSockName   The address and port to which to bind this TCP endpoint.
339  *
340  * @retval OT_ERROR_NONE    Successfully bound the TCP endpoint.
341  * @retval OT_ERROR_FAILED  Failed to bind the TCP endpoint.
342  *
343  */
344 otError otTcpBind(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName);
345 
346 /**
347  * This enumeration defines flags passed to otTcpConnect().
348  *
349  */
350 enum
351 {
352     OT_TCP_CONNECT_NO_FAST_OPEN = 1 << 0,
353 };
354 
355 /**
356  * Records the remote host and port for this connection.
357  *
358  * By default TCP Fast Open is used. This means that this function merely
359  * records the remote host and port, and that the TCP connection establishment
360  * handshake only happens on the first call to otTcpSendByReference(). TCP Fast
361  * Open can be explicitly disabled using @p aFlags, in which case the TCP
362  * connection establishment handshake is initiated immediately.
363  *
364  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure to connect.
365  * @param[in]  aSockName  The IP address and port of the host to which to connect.
366  * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
367  *
368  * @retval OT_ERROR_NONE    Successfully completed the operation.
369  * @retval OT_ERROR_FAILED  Failed to complete the operation.
370  *
371  */
372 otError otTcpConnect(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName, uint32_t aFlags);
373 
374 /**
375  * This enumeration defines flags passed to @p otTcpSendByReference.
376  *
377  */
378 enum
379 {
380     OT_TCP_SEND_MORE_TO_COME = 1 << 0,
381 };
382 
383 /**
384  * Adds data referenced by the linked buffer pointed to by @p aBuffer to the
385  * send buffer.
386  *
387  * Upon a successful call to this function, the linked buffer and data it
388  * references are owned by the TCP stack; they should not be modified by the
389  * application until a "send done" callback returns ownership of those objects
390  * to the application. It is acceptable to call this function to add another
391  * linked buffer to the send queue, even if the "send done" callback for a
392  * previous invocation of this function has not yet fired.
393  *
394  * Note that @p aBuffer should not be chained; its mNext field should be
395  * NULL. If additional data will be added right after this call, then the
396  * OT_TCP_SEND_MORE_TO_COME flag should be used as a hint to the TCP
397  * implementation.
398  *
399  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data.
400  * @param[in]  aBuffer    A pointer to the linked buffer chain referencing data to add to the send buffer.
401  * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
402  *
403  * @retval OT_ERROR_NONE    Successfully added data to the send buffer.
404  * @retval OT_ERROR_FAILED  Failed to add data to the send buffer.
405  *
406  */
407 otError otTcpSendByReference(otTcpEndpoint *aEndpoint, otLinkedBuffer *aBuffer, uint32_t aFlags);
408 
409 /**
410  * Adds data to the send buffer by extending the length of the final
411  * otLinkedBuffer in the send buffer by the specified amount.
412  *
413  * If the send buffer is empty, then the operation fails.
414  *
415  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data.
416  * @param[in]  aNumBytes  The number of bytes by which to extend the length of the final linked buffer.
417  * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
418  *
419  * @retval OT_ERROR_NONE    Successfully added data to the send buffer.
420  * @retval OT_ERROR_FAILED  Failed to add data to the send buffer.
421  *
422  */
423 otError otTcpSendByExtension(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags);
424 
425 /**
426  * Provides the application with a linked buffer chain referencing data
427  * currently in the TCP receive buffer.
428  *
429  * The linked buffer chain is valid until the "receive ready" callback is next
430  * invoked, or until the next call to otTcpReceiveContiguify() or
431  * otTcpCommitReceive().
432  *
433  * @param[in]   aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive
434  *                         data.
435  * @param[out]  aBuffer    A pointer to the linked buffer chain referencing data currently in the receive buffer.
436  *
437  * @retval OT_ERROR_NONE    Successfully completed the operation.
438  * @retval OT_ERROR_FAILED  Failed to complete the operation.
439  *
440  */
441 otError otTcpReceiveByReference(const otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer);
442 
443 /**
444  * Reorganizes the receive buffer to be entirely contiguous in memory.
445  *
446  * This is optional; an application can simply traverse the linked buffer
447  * chain obtained by calling @p otTcpReceiveByReference. Some
448  * applications may wish to call this function to make the receive buffer
449  * contiguous to simplify their data processing, but this comes at the expense
450  * of CPU time to reorganize the data in the receive buffer.
451  *
452  * @param[in]   aEndpoint  A pointer to the TCP endpoint whose receive buffer to reorganize.
453  *
454  * @retval OT_ERROR_NONE    Successfully completed the operation.
455  * @retval OT_ERROR_FAILED  Failed to complete the operation.
456  *
457  */
458 otError otTcpReceiveContiguify(otTcpEndpoint *aEndpoint);
459 
460 /**
461  * Informs the TCP stack that the application has finished processing
462  * @p aNumBytes bytes of data at the start of the receive buffer and that the
463  * TCP stack need not continue maintaining those bytes in the receive buffer.
464  *
465  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive
466  *                        data.
467  * @param[in]  aNumBytes  The number of bytes consumed.
468  * @param[in]  aFlags     Flags specifying options for this operation (none yet).
469  *
470  * @retval OT_ERROR_NONE    Successfully completed the receive operation.
471  * @retval OT_ERROR_FAILED  Failed to complete the receive operation.
472  *
473  */
474 otError otTcpCommitReceive(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags);
475 
476 /**
477  * Informs the connection peer that this TCP endpoint will not send more data.
478  *
479  * This should be used when the application has no more data to send to the
480  * connection peer. For this connection, future reads on the connection peer
481  * will result in the "end of stream" condition, and future writes on this
482  * connection endpoint will fail.
483  *
484  * The "end of stream" condition only applies after any data previously
485  * provided to the TCP stack to send out has been received by the connection
486  * peer.
487  *
488  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint to shut down.
489  *
490  * @retval OT_ERROR_NONE    Successfully queued the "end of stream" condition for transmission.
491  * @retval OT_ERROR_FAILED  Failed to queue the "end of stream" condition for transmission.
492  *
493  */
494 otError otTcpSendEndOfStream(otTcpEndpoint *aEndpoint);
495 
496 /**
497  * Forcibly ends the TCP connection associated with this TCP endpoint.
498  *
499  * This immediately makes the TCP endpoint free for use for another connection
500  * and empties the send and receive buffers, transferring ownership of any data
501  * provided by the application in otTcpSendByReference() calls back to
502  * the application. The TCP endpoint's callbacks and memory for the receive
503  * buffer remain associated with the TCP endpoint.
504  *
505  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure representing the TCP endpoint to abort.
506  *
507  * @retval OT_ERROR_NONE    Successfully aborted the TCP endpoint's connection.
508  * @retval OT_ERROR_FAILED  Failed to abort the TCP endpoint's connection.
509  *
510  */
511 otError otTcpAbort(otTcpEndpoint *aEndpoint);
512 
513 /**
514  * Deinitializes this TCP endpoint.
515  *
516  * This means that OpenThread no longer keeps track of this TCP endpoint and
517  * deallocates all resources it has internally allocated for this TCP endpoint.
518  * The application can reuse the memory backing the TCP endpoint as it sees fit.
519  *
520  * If it corresponds to a live TCP connection, the connection is terminated
521  * unceremoniously (as in otTcpAbort()). All resources the application has
522  * provided for this TCP endpoint (linked buffers for the send buffer, memory
523  * for the receive buffer, the @p aEndpoint structure itself, etc.) are
524  * immediately returned to the application.
525  *
526  * @param[in]  aEndpoint  A pointer to the TCP endpoint structure to deinitialize.
527  *
528  * @retval OT_ERROR_NONE    Successfully deinitialized the TCP endpoint.
529  * @retval OT_ERROR_FAILED  Failed to deinitialize the TCP endpoint.
530  *
531  */
532 otError otTcpEndpointDeinitialize(otTcpEndpoint *aEndpoint);
533 
534 struct otTcpListener;
535 typedef struct otTcpListener otTcpListener;
536 
537 /**
538  * This enumeration defines incoming connection actions.
539  *
540  * This is used in otTcpAcceptReady() callback.
541  *
542  */
543 typedef enum otTcpIncomingConnectionAction
544 {
545     OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT, ///< Accept the incoming connection.
546     OT_TCP_INCOMING_CONNECTION_ACTION_DEFER,  ///< Defer (silently ignore) the incoming connection.
547     OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, ///< Refuse the incoming connection.
548 } otTcpIncomingConnectionAction;
549 
550 /**
551  * This callback indicates that an incoming connection that matches this TCP
552  * listener has arrived.
553  *
554  * The typical response is for the application to accept the incoming
555  * connection. It does so by populating @p aAcceptInto with a pointer to the
556  * otTcpEndpoint into which to accept the incoming connection. This
557  * otTcpEndpoint must already be initialized using otTcpEndpointInitialize().
558  * Then, the application returns OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT.
559  *
560  * Alternatively, the application can decline to accept the incoming
561  * connection. There are two ways for the application to do this. First, if the
562  * application returns OT_TCP_INCOMING_CONNECTION_ACTION_DEFER, then OpenThread
563  * silently ignores the connection establishment request; the connection peer
564  * will likely retransmit the request, at which point the callback will be
565  * called again. This is valuable if resources are not presently available to
566  * accept the connection, but they may be available when the connection peer
567  * retransmits its connection establishment attempt. Second, if the application
568  * returns OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, then OpenThread sends a
569  * "connection refused" message to the host that attempted to establish a
570  * connection. If the application declines the incoming connection, it is not
571  * required to populate @p aAcceptInto.
572  *
573  * @param[in]   aListener    The TCP listener that matches the incoming connection.
574  * @param[in]   aPeer        The host and port from which the incoming connection originates.
575  * @param[out]  aAcceptInto  The TCP endpoint into which to accept the incoming connection.
576  *
577  * @returns  Description of how to handle the incoming connection.
578  *
579  */
580 typedef otTcpIncomingConnectionAction (*otTcpAcceptReady)(otTcpListener *   aListener,
581                                                           const otSockAddr *aPeer,
582                                                           otTcpEndpoint **  aAcceptInto);
583 
584 /**
585  * This callback indicates that the TCP connection is now ready for two-way
586  * communication.
587  *
588  * In the case of TCP Fast Open, this may be before the TCP
589  * connection handshake has actually completed. The application is provided
590  * with the context pointers both for the TCP listener that accepted the
591  * connection and the TCP endpoint into which it was accepted. The provided
592  * context is the one associated with the TCP listener.
593  *
594  * @param[in]  aListener  The TCP listener that matches the incoming connection.
595  * @param[in]  aEndpoint  The TCP endpoint into which the incoming connection was accepted.
596  * @param[in]  aPeer      the host and port from which the incoming connection originated.
597  *
598  */
599 typedef void (*otTcpAcceptDone)(otTcpListener *aListener, otTcpEndpoint *aEndpoint, const otSockAddr *aPeer);
600 
601 /**
602  * This structure represents a TCP listener.
603  *
604  * A TCP listener is used to listen for and accept incoming TCP connections.
605  *
606  * The application should not inspect the fields of this structure directly; it
607  * should only interact with it via the TCP API functions whose signatures are
608  * provided in this file.
609  *
610  */
611 struct otTcpListener
612 {
613     struct otTcpListener *mNext;     ///< A pointer to the next TCP listener (internal use only)
614     otInstance *          mInstance; ///< A pointer to the OpenThread instance associated with this TCP listener
615     void *                mContext;  ///< A pointer to application-specific context
616 
617     otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
618     otTcpAcceptDone  mAcceptDoneCallback;  ///< "Accept done" callback function
619 
620     /* Other implementation-defined fields go here. */
621 };
622 
623 /**
624  * This structure contains arguments to the otTcpListenerInitialize() function.
625  *
626  */
627 typedef struct otTcpListenerInitializeArgs
628 {
629     void *mContext; ///< Pointer to application-specific context
630 
631     otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
632     otTcpAcceptDone  mAcceptDoneCallback;  ///< "Accept done" callback function
633 } otTcpListenerInitializeArgs;
634 
635 /**
636  * Initializes a TCP listener.
637  *
638  * Calling this function causes OpenThread to keep track of the TCP listener
639  * and store and retrieve TCP data inside @p aListener. The application should
640  * refrain from directly accessing or modifying the fields in @p aListener. If
641  * the application needs to reclaim the memory backing @p aListener, it should
642  * call otTcpListenerDeinitialize().
643  *
644  * @param[in]  aInstance  A pointer to an OpenThread instance.
645  * @param[in]  aListener  A pointer to a TCP listener structure.
646  * @param[in]  aArgs      A pointer to a structure of arguments.
647  *
648  * @retval OT_ERROR_NONE    Successfully opened the TCP listener.
649  * @retval OT_ERROR_FAILED  Failed to open the TCP listener.
650  *
651  */
652 otError otTcpListenerInitialize(otInstance *aInstance, otTcpListener *aListener, otTcpListenerInitializeArgs *aArgs);
653 
654 /**
655  * Obtains the otInstance that was associated with @p aListener upon
656  * initialization.
657  *
658  * @param[in]  aListener  The TCP listener whose instance to obtain.
659  *
660  * @returns  The otInstance pointer associated with @p aListener.
661  *
662  */
663 otInstance *otTcpListenerGetInstance(otTcpListener *aListener);
664 
665 /**
666  * Obtains the context pointer that was associated with @p aListener upon
667  * initialization.
668  *
669  * @param[in]  aListener  The TCP listener whose context to obtain.
670  *
671  * @returns  The context pointer associated with @p aListener.
672  *
673  */
674 void *otTcpListenerGetContext(otTcpListener *aListener);
675 
676 /**
677  * Causes incoming TCP connections that match the specified IP address and port
678  * to trigger this TCP listener's callbacks.
679  *
680  * @param[in]  aListener  A pointer to the TCP listener structure that should begin listening.
681  * @param[in]  aSockName  The address and port on which to listen for incoming connections.
682  *
683  * @retval OT_ERROR_NONE    Successfully initiated listening on the TCP listener.
684  * @retval OT_ERROR_FAILED  Failed to initiate listening on the TCP listener.
685  *
686  */
687 otError otTcpListen(otTcpListener *aListener, const otSockAddr *aSockName);
688 
689 /**
690  * Causes this TCP listener to stop listening for incoming connections.
691  *
692  * @param[in]  aListener  A pointer to the TCP listener structure that should stop listening.
693  *
694  * @retval OT_ERROR_NONE    Successfully stopped listening on the TCP listener.
695  * @retval OT_ERROR_FAILED  Failed to stop listening on the TCP listener.
696  *
697  */
698 otError otTcpStopListening(otTcpListener *aListener);
699 
700 /**
701  * Deinitializes this TCP listener.
702  *
703  * This means that OpenThread no longer keeps track of this TCP listener and
704  * deallocates all resources it has internally allocated for this TCP listener.
705  * The application can reuse the memory backing the TCP listener as it sees
706  * fit.
707  *
708  * If the TCP listener is currently listening, it stops listening.
709  *
710  * @param[in]  aListener  A pointer to the TCP listener structure to deinitialize.
711  *
712  * @retval OT_ERROR_NONE    Successfully deinitialized the TCP listener.
713  * @retval OT_ERROR_FAILED  Failed to deinitialize the TCP listener.
714  *
715  */
716 otError otTcpListenerDeinitialize(otTcpListener *aListener);
717 
718 /**
719  * @}
720  *
721  */
722 
723 #ifdef __cplusplus
724 } // extern "C"
725 #endif
726 
727 #endif // OPENTHREAD_TCP_H_
728