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