blob: 6cc11f79495c5ed01792d430a9d35a3ec99cde4c [file] [log] [blame]
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file defines the OpenThread TCP API.
*
*/
#ifndef OPENTHREAD_TCP_H_
#define OPENTHREAD_TCP_H_
#include <openthread/ip6.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup api-tcp
*
* @brief
* This module includes functions that control TCP communication.
*
* @{
*
*/
/**
* A linked buffer structure for use with TCP.
*
* A single otLinkedBuffer structure references an array of bytes in memory,
* via mData and mLength. The mNext field is used to form a chain of
* otLinkedBuffer structures.
*
*/
typedef struct otLinkedBuffer
{
struct otLinkedBuffer *mNext; ///< Pointer to the next linked buffer in the chain, or NULL if it is the end.
const uint8_t * mData; ///< Pointer to data referenced by this linked buffer.
size_t mLength; ///< Length of this linked buffer (number of bytes).
} otLinkedBuffer;
struct otTcpEndpoint;
typedef struct otTcpEndpoint otTcpEndpoint;
/**
* This callback informs the application that the TCP 3-way handshake is
* complete and that the connection is now established.
*
* @param[in] aEndpoint The TCP endpoint whose connection is now established.
*
*/
typedef void (*otTcpEstablished)(otTcpEndpoint *aEndpoint);
/**
* This callback informs the application that data in the provided
* @p aData have been acknowledged by the connection peer and that @p aData and
* the data it contains can be reclaimed by the application.
*
* The @p aData are guaranteed to be identical to those passed in to TCP via
* otTcpSendByReference(), including any extensions effected via
* otTcpSendByExtension().
*
* @param[in] aEndpoint The TCP endpoint for the connection.
* @param[in] aData A pointer to the otLinkedBuffer that can be reclaimed.
*
*/
typedef void (*otTcpSendDone)(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData);
/**
* This callback informs the application if forward progress has been made in
* transferring data from the send buffer to the recipient. This callback is
* not necessary for correct TCP operation. Most applications can just rely on
* the otTcpSendDone() callback to reclaim linked buffers once the TCP stack is
* done using them. The purpose of this callback is to support advanced
* applications that benefit from finer-grained information about how the
* the connection is making forward progress in transferring data to the
* connection peer.
*
* This callback's operation is closely tied to TCP's send buffer. The send
* buffer can be understood as having two regions. First, there is the
* "in-flight" region at the head (front) of the send buffer. It corresponds
* to data which has been sent to the recipient, but is not yet acknowledged.
* Second, there is the "backlog" region, which consists of all data in the
* send buffer that is not in the "in-flight" region. The "backlog" region
* corresponds to data that is queued for sending, but has not yet been sent.
*
* The callback is invoked in response to two types of events. First, the
* "in-flight" region of the send buffer may shrink (e.g., when the recipient
* acknowledges data that we sent earlier). Second, the "backlog" region of the
* send buffer may shrink (e.g., new data was sent out). These two conditions
* often occur at the same time, in response to an ACK segment from the
* connection peer, which is why they are combined in a single callback.
*
* The TCP stack only uses the @p aInSendBuffer bytes at the tail of the send
* buffer; when @p aInSendBuffer decreases by an amount x, it means that x
* additional bytes that were formerly at the head of the send buffer are no
* longer part of the send buffer and can now be reclaimed (i.e., overwritten)
* by the application. Note that the otLinkedBuffer structure itself can only
* be reclaimed once all bytes that it references are no longer part of the
* send buffer.
*
* This callback subsumes otTcpSendDone(), in the following sense: applications
* can determine when linked buffers can be reclaimed by comparing
* @p aInSendBuffer with how many bytes are in each linked buffer. However, we
* expect otTcpSendDone(), which directly conveys which otLinkedBuffers can be
* reclaimed, to be much simpler to use. If both callbacks are registered and
* are triggered by the same event (e.g., the same ACK segment received), then
* the otTcpSendDone() callback will be triggered first, followed by this
* callback.
*
* Additionally, this callback provides @p aBacklog, which indicates how many
* bytes of data in the send buffer are not yet in flight. For applications
* that only want to add data to the send buffer when there is an assurance
* that it will be sent out soon, it may be desirable to only send out data
* when @p aBacklog is suitably small (0 or close to 0). For example, an
* application may use @p aBacklog so that it can react to queue buildup by
* dropping or aggregating data to avoid creating a backlog of data.
*
* After a call to otTcpSendByReference() or otTcpSendByExtension() with a
* positive number of bytes, the otTcpForwardProgress() callback is guaranteed
* to be called, to indicate when the bytes that were added to the send buffer
* are sent out. The call to otTcpForwardProgress() may be made immediately
* after the bytes are added to the send buffer (if some of those bytes are
* immediately sent out, reducing the backlog), or sometime in the future (once
* the connection sends out some or all of the data, reducing the backlog). By
* "immediately," we mean that the callback is immediately scheduled for
* execution in a tasklet; to avoid reentrancy-related complexity, the
* otTcpForwardProgress() callback is never directly called from the
* otTcpSendByReference() or otTcpSendByExtension() functions.
*
* @param[in] aEndpoint The TCP endpoint for the connection.
* @param[in] aInSendBuffer The number of bytes in the send buffer (sum of "in-flight" and "backlog" regions).
* @param[in] aBacklog The number of bytes that are queued for sending but have not yet been sent (the "backlog"
* region).
*
*/
typedef void (*otTcpForwardProgress)(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog);
/**
* This callback indicates the number of bytes available for consumption from
* the receive buffer.
*
* It is called whenever bytes are added to the receive buffer and when the
* end of stream is reached. If the end of the stream has been reached (i.e.,
* if no more data will become available to read because the connection peer
* has closed their end of the connection for writing), then @p aEndOfStream is
* true. Finally, @p aBytesRemaining indicates how much capacity is left in the
* receive buffer to hold additional data that arrives.
*
* @param[in] aEndpoint The TCP endpoint for the connection.
* @param[in] aBytesAvailable The number of bytes in the connection's receive buffer.
* @param[in] aEndOfStream Indicates if additional data, beyond what is already in the connection's receive buffer,
* can be received.
* @param[in] aBytesRemaining The number of additional bytes that can be received before the receive buffer becomes
* full.
*
*/
typedef void (*otTcpReceiveAvailable)(otTcpEndpoint *aEndpoint,
size_t aBytesAvailable,
bool aEndOfStream,
size_t aBytesRemaining);
typedef enum otTcpDisconnectedReason
{
OT_TCP_DISCONNECTED_REASON_NORMAL,
OT_TCP_DISCONNECTED_REASON_REFUSED,
OT_TCP_DISCONNECTED_REASON_RESET,
OT_TCP_DISCONNECTED_REASON_TIME_WAIT,
OT_TCP_DISCONNECTED_REASON_TIMED_OUT,
} otTcpDisconnectedReason;
/**
* This callback indicates that the connection was broken and should no longer
* be used, or that a connection has entered the TIME-WAIT state.
*
* It can occur if a connection establishment attempt (initiated by calling
* otTcpConnect()) fails, or any point thereafter (e.g., if the connection
* times out or an RST segment is received from the connection peer). Once this
* callback fires, all resources that the application provided for this
* connection (i.e., any `otLinkedBuffers` and memory they reference, but not
* the TCP endpoint itself or space for the receive buffers) can be reclaimed.
* In the case of a connection entering the TIME-WAIT state, this callback is
* called twice, once upon entry into the TIME-WAIT state (with
* OT_TCP_DISCONNECTED_REASON_TIME_WAIT, and again when the TIME-WAIT state
* expires (with OT_TCP_DISCONNECTED_REASON_NORMAL).
*
* @param[in] aEndpoint The TCP endpoint whose connection has been lost.
* @param[in] aReason The reason why the connection was lost.
*
*/
typedef void (*otTcpDisconnected)(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason);
/**
* OT_TCP_ENDPOINT_TCB_SIZE_BASE and OT_TCP_ENDPOINT_TCB_NUM_POINTERS are
* chosen such that the mTcb field of otTcpEndpoint has the same size as
* struct tcpcb in TCPlp. This is necessary because the mTcb field, although
* opaque in its declaration, is treated as struct tcpcb in the TCP
* implementation.
*/
#define OT_TCP_ENDPOINT_TCB_SIZE_BASE 368
#define OT_TCP_ENDPOINT_TCB_NUM_PTR 36
/**
* This structure represents a TCP endpoint.
*
* An TCP endpoint acts an endpoint of TCP connection. It can be used to
* initiate TCP connections, and, once a TCP connection is established, send
* data to and receive data from the connection peer.
*
* The application should not inspect the fields of this structure directly; it
* should only interact with it via the TCP API functions whose signatures are
* provided in this file.
*
*/
struct otTcpEndpoint
{
union
{
uint8_t mSize[OT_TCP_ENDPOINT_TCB_SIZE_BASE + OT_TCP_ENDPOINT_TCB_NUM_PTR * sizeof(void *)];
uint64_t mAlign;
} mTcb;
struct otTcpEndpoint *mNext; ///< A pointer to the next TCP endpoint (internal use only)
void * mContext; ///< A pointer to application-specific context
otTcpEstablished mEstablishedCallback; ///< "Established" callback function
otTcpSendDone mSendDoneCallback; ///< "Send done" callback function
otTcpForwardProgress mForwardProgressCallback; ///< "Forward progress" callback function
otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function
otTcpDisconnected mDisconnectedCallback; ///< "Disconnected" callback function
uint32_t mTimers[4];
otLinkedBuffer mReceiveLinks[2];
otSockAddr mSockAddr;
uint8_t mPendingCallbacks;
};
/**
* This structure contains arguments to the otTcpEndpointInitialize() function.
*
*/
typedef struct otTcpEndpointInitializeArgs
{
void *mContext; ///< Pointer to application-specific context
otTcpEstablished mEstablishedCallback; ///< "Established" callback function
otTcpSendDone mSendDoneCallback; ///< "Send done" callback function
otTcpForwardProgress mForwardProgressCallback; ///< "Forward progress" callback function
otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function
otTcpDisconnected mDisconnectedCallback; ///< "Disconnected" callback function
void * mReceiveBuffer; ///< Pointer to memory provided to the system for the TCP receive buffer
size_t mReceiveBufferSize; ///< Size of memory provided to the system for the TCP receive buffer
} otTcpEndpointInitializeArgs;
/**
* @def OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS
*
* Recommended buffer size for TCP connections that traverse about 3 wireless
* hops or fewer.
*
* On platforms where memory is particularly constrained and in situations
* where high bandwidth is not necessary, it may be desirable to manually
* select a smaller buffer size.
*
*/
#define OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS 2599
/**
* @def OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS
*
* Recommended buffer size for TCP connections that traverse many wireless
* hops.
*
* If the TCP connection traverses a very large number of hops (more than 6 or
* so), then it may be advisable to select a large buffer size manually.
*
*/
#define OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS 4158
/**
* Initializes a TCP endpoint.
*
* Calling this function causes OpenThread to keep track of the TCP endpoint
* and store and retrieve TCP data inside the @p aEndpoint. The application
* should refrain from directly accessing or modifying the fields in
* @p aEndpoint. If the application needs to reclaim the memory backing
* @p aEndpoint, it should call otTcpEndpointDeinitialize().
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aEndpoint A pointer to a TCP endpoint structure.
* @param[in] aArgs A pointer to a structure of arguments.
*
* @retval OT_ERROR_NONE Successfully opened the TCP endpoint.
* @retval OT_ERROR_FAILED Failed to open the TCP endpoint.
*
*/
otError otTcpEndpointInitialize(otInstance * aInstance,
otTcpEndpoint * aEndpoint,
const otTcpEndpointInitializeArgs *aArgs);
/**
* Obtains the otInstance that was associated with @p aEndpoint upon
* initialization.
*
* @param[in] aEndpoint The TCP endpoint whose instance to obtain.
*
* @returns The otInstance pointer associated with @p aEndpoint.
*
*/
otInstance *otTcpEndpointGetInstance(otTcpEndpoint *aEndpoint);
/**
* Obtains the context pointer that was associated with @p aEndpoint upon
* initialization.
*
* @param[in] aEndpoint The TCP endpoint whose context to obtain.
*
* @returns The context pointer associated with @p aEndpoint.
*
*/
void *otTcpEndpointGetContext(otTcpEndpoint *aEndpoint);
/**
* Obtains a pointer to a TCP endpoint's local host and port.
*
* The contents of the host and port may be stale if this socket is not in a
* connected state and has not been bound after it was last disconnected.
*
* @param[in] aEndpoint The TCP endpoint whose local host and port to obtain.
*
* @returns The local host and port of @p aEndpoint.
*
*/
const otSockAddr *otTcpGetLocalAddress(const otTcpEndpoint *aEndpoint);
/**
* Obtains a pointer to a TCP endpoint's peer's host and port.
*
* The contents of the host and port may be stale if this socket is not in a
* connected state.
*
* @param[in] aEndpoint The TCP endpoint whose peer's host and port to obtain.
*
* @returns The host and port of the connection peer of @p aEndpoint.
*
*/
const otSockAddr *otTcpGetPeerAddress(const otTcpEndpoint *aEndpoint);
/**
* Binds the TCP endpoint to an IP address and port.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure to bind.
* @param[in] aSockName The address and port to which to bind this TCP endpoint.
*
* @retval OT_ERROR_NONE Successfully bound the TCP endpoint.
* @retval OT_ERROR_FAILED Failed to bind the TCP endpoint.
*
*/
otError otTcpBind(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName);
/**
* This enumeration defines flags passed to otTcpConnect().
*
*/
enum
{
OT_TCP_CONNECT_NO_FAST_OPEN = 1 << 0,
};
/**
* Records the remote host and port for this connection.
*
* By default TCP Fast Open is used. This means that this function merely
* records the remote host and port, and that the TCP connection establishment
* handshake only happens on the first call to otTcpSendByReference(). TCP Fast
* Open can be explicitly disabled using @p aFlags, in which case the TCP
* connection establishment handshake is initiated immediately.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure to connect.
* @param[in] aSockName The IP address and port of the host to which to connect.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval OT_ERROR_NONE Successfully completed the operation.
* @retval OT_ERROR_FAILED Failed to complete the operation.
*
*/
otError otTcpConnect(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName, uint32_t aFlags);
/**
* This enumeration defines flags passed to @p otTcpSendByReference.
*
*/
enum
{
OT_TCP_SEND_MORE_TO_COME = 1 << 0,
};
/**
* Adds data referenced by the linked buffer pointed to by @p aBuffer to the
* send buffer.
*
* Upon a successful call to this function, the linked buffer and data it
* references are owned by the TCP stack; they should not be modified by the
* application until a "send done" callback returns ownership of those objects
* to the application. It is acceptable to call this function to add another
* linked buffer to the send queue, even if the "send done" callback for a
* previous invocation of this function has not yet fired.
*
* Note that @p aBuffer should not be chained; its mNext field should be
* NULL. If additional data will be added right after this call, then the
* OT_TCP_SEND_MORE_TO_COME flag should be used as a hint to the TCP
* implementation.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data.
* @param[in] aBuffer A pointer to the linked buffer chain referencing data to add to the send buffer.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval OT_ERROR_NONE Successfully added data to the send buffer.
* @retval OT_ERROR_FAILED Failed to add data to the send buffer.
*
*/
otError otTcpSendByReference(otTcpEndpoint *aEndpoint, otLinkedBuffer *aBuffer, uint32_t aFlags);
/**
* Adds data to the send buffer by extending the length of the final
* otLinkedBuffer in the send buffer by the specified amount.
*
* If the send buffer is empty, then the operation fails.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data.
* @param[in] aNumBytes The number of bytes by which to extend the length of the final linked buffer.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval OT_ERROR_NONE Successfully added data to the send buffer.
* @retval OT_ERROR_FAILED Failed to add data to the send buffer.
*
*/
otError otTcpSendByExtension(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags);
/**
* Provides the application with a linked buffer chain referencing data
* currently in the TCP receive buffer.
*
* The linked buffer chain is valid until the "receive ready" callback is next
* invoked, or until the next call to otTcpReceiveContiguify() or
* otTcpCommitReceive().
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive
* data.
* @param[out] aBuffer A pointer to the linked buffer chain referencing data currently in the receive buffer.
*
* @retval OT_ERROR_NONE Successfully completed the operation.
* @retval OT_ERROR_FAILED Failed to complete the operation.
*
*/
otError otTcpReceiveByReference(otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer);
/**
* Reorganizes the receive buffer to be entirely contiguous in memory.
*
* This is optional; an application can simply traverse the linked buffer
* chain obtained by calling @p otTcpReceiveByReference. Some
* applications may wish to call this function to make the receive buffer
* contiguous to simplify their data processing, but this comes at the expense
* of CPU time to reorganize the data in the receive buffer.
*
* @param[in] aEndpoint A pointer to the TCP endpoint whose receive buffer to reorganize.
*
* @retval OT_ERROR_NONE Successfully completed the operation.
* @retval OT_ERROR_FAILED Failed to complete the operation.
*
*/
otError otTcpReceiveContiguify(otTcpEndpoint *aEndpoint);
/**
* Informs the TCP stack that the application has finished processing
* @p aNumBytes bytes of data at the start of the receive buffer and that the
* TCP stack need not continue maintaining those bytes in the receive buffer.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive
* data.
* @param[in] aNumBytes The number of bytes consumed.
* @param[in] aFlags Flags specifying options for this operation (none yet).
*
* @retval OT_ERROR_NONE Successfully completed the receive operation.
* @retval OT_ERROR_FAILED Failed to complete the receive operation.
*
*/
otError otTcpCommitReceive(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags);
/**
* Informs the connection peer that this TCP endpoint will not send more data.
*
* This should be used when the application has no more data to send to the
* connection peer. For this connection, future reads on the connection peer
* will result in the "end of stream" condition, and future writes on this
* connection endpoint will fail.
*
* The "end of stream" condition only applies after any data previously
* provided to the TCP stack to send out has been received by the connection
* peer.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint to shut down.
*
* @retval OT_ERROR_NONE Successfully queued the "end of stream" condition for transmission.
* @retval OT_ERROR_FAILED Failed to queue the "end of stream" condition for transmission.
*
*/
otError otTcpSendEndOfStream(otTcpEndpoint *aEndpoint);
/**
* Forcibly ends the TCP connection associated with this TCP endpoint.
*
* This immediately makes the TCP endpoint free for use for another connection
* and empties the send and receive buffers, transferring ownership of any data
* provided by the application in otTcpSendByReference() and
* otTcpSendByExtension() calls back to the application. The TCP endpoint's
* callbacks and memory for the receive buffer remain associated with the
* TCP endpoint.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint to abort.
*
* @retval OT_ERROR_NONE Successfully aborted the TCP endpoint's connection.
* @retval OT_ERROR_FAILED Failed to abort the TCP endpoint's connection.
*
*/
otError otTcpAbort(otTcpEndpoint *aEndpoint);
/**
* Deinitializes this TCP endpoint.
*
* This means that OpenThread no longer keeps track of this TCP endpoint and
* deallocates all resources it has internally allocated for this TCP endpoint.
* The application can reuse the memory backing the TCP endpoint as it sees fit.
*
* If it corresponds to a live TCP connection, the connection is terminated
* unceremoniously (as in otTcpAbort()). All resources the application has
* provided for this TCP endpoint (linked buffers for the send buffer, memory
* for the receive buffer, the @p aEndpoint structure itself, etc.) are
* immediately returned to the application.
*
* @param[in] aEndpoint A pointer to the TCP endpoint structure to deinitialize.
*
* @retval OT_ERROR_NONE Successfully deinitialized the TCP endpoint.
* @retval OT_ERROR_FAILED Failed to deinitialize the TCP endpoint.
*
*/
otError otTcpEndpointDeinitialize(otTcpEndpoint *aEndpoint);
struct otTcpListener;
typedef struct otTcpListener otTcpListener;
/**
* This enumeration defines incoming connection actions.
*
* This is used in otTcpAcceptReady() callback.
*
*/
typedef enum otTcpIncomingConnectionAction
{
OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT, ///< Accept the incoming connection.
OT_TCP_INCOMING_CONNECTION_ACTION_DEFER, ///< Defer (silently ignore) the incoming connection.
OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, ///< Refuse the incoming connection.
} otTcpIncomingConnectionAction;
/**
* This callback indicates that an incoming connection that matches this TCP
* listener has arrived.
*
* The typical response is for the application to accept the incoming
* connection. It does so by populating @p aAcceptInto with a pointer to the
* otTcpEndpoint into which to accept the incoming connection. This
* otTcpEndpoint must already be initialized using otTcpEndpointInitialize().
* Then, the application returns OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT.
*
* Alternatively, the application can decline to accept the incoming
* connection. There are two ways for the application to do this. First, if the
* application returns OT_TCP_INCOMING_CONNECTION_ACTION_DEFER, then OpenThread
* silently ignores the connection establishment request; the connection peer
* will likely retransmit the request, at which point the callback will be
* called again. This is valuable if resources are not presently available to
* accept the connection, but they may be available when the connection peer
* retransmits its connection establishment attempt. Second, if the application
* returns OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, then OpenThread sends a
* "connection refused" message to the host that attempted to establish a
* connection. If the application declines the incoming connection, it is not
* required to populate @p aAcceptInto.
*
* @param[in] aListener The TCP listener that matches the incoming connection.
* @param[in] aPeer The host and port from which the incoming connection originates.
* @param[out] aAcceptInto The TCP endpoint into which to accept the incoming connection.
*
* @returns Description of how to handle the incoming connection.
*
*/
typedef otTcpIncomingConnectionAction (*otTcpAcceptReady)(otTcpListener * aListener,
const otSockAddr *aPeer,
otTcpEndpoint ** aAcceptInto);
/**
* This callback indicates that the TCP connection is now ready for two-way
* communication.
*
* In the case of TCP Fast Open, this may be before the TCP
* connection handshake has actually completed. The application is provided
* with the context pointers both for the TCP listener that accepted the
* connection and the TCP endpoint into which it was accepted. The provided
* context is the one associated with the TCP listener.
*
* @param[in] aListener The TCP listener that matches the incoming connection.
* @param[in] aEndpoint The TCP endpoint into which the incoming connection was accepted.
* @param[in] aPeer the host and port from which the incoming connection originated.
*
*/
typedef void (*otTcpAcceptDone)(otTcpListener *aListener, otTcpEndpoint *aEndpoint, const otSockAddr *aPeer);
/**
* OT_TCP_LISTENER_TCB_SIZE_BASE and OT_TCP_LISTENER_TCB_NUM_POINTERS are
* chosen such that the mTcbListener field of otTcpListener has the same size
* as struct tcpcb_listen in TCPlp. This is necessary because the mTcbListen
* field, though opaque in its declaration, is treated as struct tcpcb in the
* TCP implementation.
*/
#define OT_TCP_LISTENER_TCB_SIZE_BASE 16
#define OT_TCP_LISTENER_TCB_NUM_PTR 3
/**
* This structure represents a TCP listener.
*
* A TCP listener is used to listen for and accept incoming TCP connections.
*
* The application should not inspect the fields of this structure directly; it
* should only interact with it via the TCP API functions whose signatures are
* provided in this file.
*
*/
struct otTcpListener
{
union
{
uint8_t mSize[OT_TCP_LISTENER_TCB_SIZE_BASE + OT_TCP_LISTENER_TCB_NUM_PTR * sizeof(void *)];
void * mAlign;
} mTcbListen;
struct otTcpListener *mNext; ///< A pointer to the next TCP listener (internal use only)
void * mContext; ///< A pointer to application-specific context
otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function
};
/**
* This structure contains arguments to the otTcpListenerInitialize() function.
*
*/
typedef struct otTcpListenerInitializeArgs
{
void *mContext; ///< Pointer to application-specific context
otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function
} otTcpListenerInitializeArgs;
/**
* Initializes a TCP listener.
*
* Calling this function causes OpenThread to keep track of the TCP listener
* and store and retrieve TCP data inside @p aListener. The application should
* refrain from directly accessing or modifying the fields in @p aListener. If
* the application needs to reclaim the memory backing @p aListener, it should
* call otTcpListenerDeinitialize().
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aListener A pointer to a TCP listener structure.
* @param[in] aArgs A pointer to a structure of arguments.
*
* @retval OT_ERROR_NONE Successfully opened the TCP listener.
* @retval OT_ERROR_FAILED Failed to open the TCP listener.
*
*/
otError otTcpListenerInitialize(otInstance * aInstance,
otTcpListener * aListener,
const otTcpListenerInitializeArgs *aArgs);
/**
* Obtains the otInstance that was associated with @p aListener upon
* initialization.
*
* @param[in] aListener The TCP listener whose instance to obtain.
*
* @returns The otInstance pointer associated with @p aListener.
*
*/
otInstance *otTcpListenerGetInstance(otTcpListener *aListener);
/**
* Obtains the context pointer that was associated with @p aListener upon
* initialization.
*
* @param[in] aListener The TCP listener whose context to obtain.
*
* @returns The context pointer associated with @p aListener.
*
*/
void *otTcpListenerGetContext(otTcpListener *aListener);
/**
* Causes incoming TCP connections that match the specified IP address and port
* to trigger this TCP listener's callbacks.
*
* @param[in] aListener A pointer to the TCP listener structure that should begin listening.
* @param[in] aSockName The address and port on which to listen for incoming connections.
*
* @retval OT_ERROR_NONE Successfully initiated listening on the TCP listener.
* @retval OT_ERROR_FAILED Failed to initiate listening on the TCP listener.
*
*/
otError otTcpListen(otTcpListener *aListener, const otSockAddr *aSockName);
/**
* Causes this TCP listener to stop listening for incoming connections.
*
* @param[in] aListener A pointer to the TCP listener structure that should stop listening.
*
* @retval OT_ERROR_NONE Successfully stopped listening on the TCP listener.
* @retval OT_ERROR_FAILED Failed to stop listening on the TCP listener.
*
*/
otError otTcpStopListening(otTcpListener *aListener);
/**
* Deinitializes this TCP listener.
*
* This means that OpenThread no longer keeps track of this TCP listener and
* deallocates all resources it has internally allocated for this TCP listener.
* The application can reuse the memory backing the TCP listener as it sees
* fit.
*
* If the TCP listener is currently listening, it stops listening.
*
* @param[in] aListener A pointer to the TCP listener structure to deinitialize.
*
* @retval OT_ERROR_NONE Successfully deinitialized the TCP listener.
* @retval OT_ERROR_FAILED Failed to deinitialize the TCP listener.
*
*/
otError otTcpListenerDeinitialize(otTcpListener *aListener);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_TCP_H_