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