Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / TCPEndPoint.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *      This header file defines the <tt>Inet::TCPEndPoint</tt>
22  *      class, where the CHIP Inet Layer encapsulates methods for
23  *      interacting with TCP transport endpoints (SOCK_DGRAM sockets
24  *      on Linux and BSD-derived systems) or LwIP TCP protocol
25  *      control blocks, as the system is configured accordingly.
26  */
27
28 #pragma once
29
30 #include <inet/EndPointBasis.h>
31 #include <inet/IPAddress.h>
32
33 #include <system/SystemPacketBuffer.h>
34
35 #include <utility>
36
37 namespace chip {
38
39 namespace Transport {
40 class TCPTest;
41 };
42
43 namespace Inet {
44
45 class InetLayer;
46
47 /**
48  * @brief   Objects of this class represent TCP transport endpoints.
49  *
50  * @details
51  *  CHIP Inet Layer encapsulates methods for interacting with TCP transport
52  *  endpoints (SOCK_STREAM sockets on Linux and BSD-derived systems) or LwIP
53  *  TCP protocol control blocks, as the system is configured accordingly.
54  */
55 class DLL_EXPORT TCPEndPoint : public EndPointBasis
56 {
57     friend class InetLayer;
58     friend class ::chip::Transport::TCPTest;
59
60 public:
61     /** Control switch indicating whether the application is receiving data. */
62     bool ReceiveEnabled;
63
64     /**
65      * @brief   Basic dynamic state of the underlying endpoint.
66      *
67      * @details
68      *  Objects are initialized in the "ready" state, proceed to subsequent
69      *  states corresponding to a simplification of the states of the TCP
70      *  transport state machine.
71      *
72      * @note
73      *  The \c kBasisState_Closed state enumeration is mapped to \c kState_Ready for historical binary-compatibility reasons. The
74      *  existing \c kState_Closed exists to identify separately the distinction between "not opened yet" and "previously opened now
75      *  closed" that existed previously in the \c kState_Ready and \c kState_Closed states.
76      */
77     enum
78     {
79         kState_Ready           = kBasisState_Closed, /**< Endpoint initialized, but not bound. */
80         kState_Bound           = 1,                  /**< Endpoint bound, but not listening. */
81         kState_Listening       = 2,                  /**< Endpoint receiving connections. */
82         kState_Connecting      = 3,                  /**< Endpoint attempting to connect. */
83         kState_Connected       = 4,                  /**< Endpoint connected, ready for tx/rx. */
84         kState_SendShutdown    = 5,                  /**< Endpoint initiated its half-close. */
85         kState_ReceiveShutdown = 6,                  /**< Endpoint responded to half-close. */
86         kState_Closing         = 7,                  /**< Endpoint closing bidirectionally. */
87         kState_Closed          = 8                   /**< Endpoint closed, ready for release. */
88     } State;
89
90     /**
91      * @brief   Bind the endpoint to an interface IP address.
92      *
93      * @param[in]   addrType    the protocol version of the IP address
94      * @param[in]   addr        the IP address (must be an interface address)
95      * @param[in]   port        the TCP port
96      * @param[in]   reuseAddr   option to share binding with other endpoints
97      *
98      * @retval  INET_NO_ERROR               success: endpoint bound to address
99      * @retval  INET_ERROR_INCORRECT_STATE  endpoint has been bound previously
100      * @retval  INET_NO_MEMORY              insufficient memory for endpoint
101      *
102      * @retval  INET_ERROR_WRONG_PROTOCOL_TYPE
103      *      \c addrType does not match \c IPVer.
104      *
105      * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
106      *      \c addrType is \c kIPAddressType_Any, or the type of \c addr is not
107      *      equal to \c addrType.
108      *
109      * @retval  other                   another system or platform error
110      *
111      * @details
112      *  Binds the endpoint to the specified network interface IP address.
113      *
114      *  On LwIP, this method must not be called with the LwIP stack lock
115      *  already acquired.
116      */
117     INET_ERROR Bind(IPAddressType addrType, const IPAddress & addr, uint16_t port, bool reuseAddr = false);
118
119     /**
120      * @brief   Prepare the endpoint to receive TCP messages.
121      *
122      * @param[in]   backlog     maximum depth of connection acceptance queue
123      *
124      * @retval  INET_NO_ERROR   success: endpoint ready to receive messages.
125      * @retval  INET_ERROR_INCORRECT_STATE  endpoint is already listening.
126      *
127      * @details
128      *  If \c State is already \c kState_Listening, then no operation is
129      *  performed, otherwise the \c State is set to \c kState_Listening and
130      *  the endpoint is prepared to received TCP messages, according to the
131      *  semantics of the platform.
132      *
133      *  On some platforms, the \c backlog argument is not used (the depth of
134      *  the queue is fixed; only one connection may be accepted at a time).
135      *
136      *  On LwIP systems, this method must not be called with the LwIP stack
137      *  lock already acquired
138      */
139     INET_ERROR Listen(uint16_t backlog);
140
141     /**
142      * @brief   Initiate a TCP connection.
143      *
144      * @param[in]   addr        the destination IP address
145      * @param[in]   port        the destination TCP port
146      * @param[in]   intfId      an optional network interface indicator
147      *
148      * @retval  INET_NO_ERROR       success: \c msg is queued for transmit.
149      * @retval  INET_ERROR_NOT_IMPLEMENTED  system implementation not complete.
150      *
151      * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
152      *      the destination address and the bound interface address do not
153      *      have matching protocol versions or address type, or the destination
154      *      address is an IPv6 link-local address and \c intfId is not specified.
155      *
156      * @retval  other                   another system or platform error
157      *
158      * @details
159      *      If possible, then this method initiates a TCP connection to the
160      *      destination \c addr (with \c intfId used as the scope
161      *      identifier for IPv6 link-local destinations) and \c port.
162      */
163     INET_ERROR Connect(const IPAddress & addr, uint16_t port, InterfaceId intfId = INET_NULL_INTERFACEID);
164
165     /**
166      * @brief   Extract IP address and TCP port of remote endpoint.
167      *
168      * @param[out]  retAddr     IP address of remote endpoint.
169      * @param[out]  retPort     TCP port of remote endpoint.
170      *
171      * @retval  INET_NO_ERROR           success: address and port extracted.
172      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
173      * @retval  INET_ERROR_CONNECTION_ABORTED   TCP connection no longer open.
174      *
175      * @details
176      *  Do not use \c NULL pointer values for either argument.
177      */
178     INET_ERROR GetPeerInfo(IPAddress * retAddr, uint16_t * retPort) const;
179
180     /**
181      * @brief   Extract IP address and TCP port of local endpoint.
182      *
183      * @param[out]  retAddr     IP address of local endpoint.
184      * @param[out]  retPort     TCP port of local endpoint.
185      *
186      * @retval  INET_NO_ERROR           success: address and port extracted.
187      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
188      * @retval  INET_ERROR_CONNECTION_ABORTED   TCP connection no longer open.
189      *
190      * @details
191      *  Do not use \c NULL pointer values for either argument.
192      */
193     INET_ERROR GetLocalInfo(IPAddress * retAddr, uint16_t * retPort);
194
195     /**
196      * @brief   Send message text on TCP connection.
197      *
198      * @param[out]  data    Message text to send.
199      * @param[out]  push    If \c true, then send immediately, otherwise queue.
200      *
201      * @retval  INET_NO_ERROR           success: address and port extracted.
202      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
203      */
204     INET_ERROR Send(chip::System::PacketBufferHandle data, bool push = true);
205
206     /**
207      * @brief   Disable reception.
208      *
209      * @details
210      *  Disable all event handlers. Data sent to an endpoint that disables
211      *  reception will be acknowledged until the receive window is exhausted.
212      */
213     void DisableReceive();
214
215     /**
216      * @brief   Enable reception.
217      *
218      * @details
219      *  Enable all event handlers. Data sent to an endpoint that disables
220      *  reception will be acknowledged until the receive window is exhausted.
221      */
222     void EnableReceive();
223
224     /**
225      *  @brief EnableNoDelay
226      */
227     INET_ERROR EnableNoDelay();
228
229     /**
230      * @brief
231      *    Enable TCP keepalive probes on the associated TCP connection.
232      *
233      *  @param[in] interval
234      *    The interval (in seconds) between keepalive probes.  This value also controls
235      *    the time between last data packet sent and the transmission of the first keepalive
236      *    probe.
237      *
238      *  @param[in] timeoutCount
239      *    The maximum number of unacknowledged probes before the connection will be deemed
240      *    to have failed.
241      *
242      * @retval  INET_NO_ERROR           success: address and port extracted.
243      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
244      * @retval  INET_ERROR_CONNECTION_ABORTED   TCP connection no longer open.
245      * @retval  INET_ERROR_NOT_IMPLEMENTED  system implementation not complete.
246      *
247      * @retval  other                   another system or platform error
248      *
249      *  @note
250      *    This method can only be called when the endpoint is in one of the connected states.
251      *
252      *    This method can be called multiple times to adjust the keepalive interval or timeout
253      *    count.
254      *
255      * @details
256      *  Start automatically  transmitting TCP "keep-alive" probe segments every
257      *  \c interval seconds. The connection will abort automatically after
258      *  receiving a negative response, or after sending \c timeoutCount
259      *  probe segments without receiving a positive response.
260      *
261      *  See RFC 1122, section 4.2.3.6 for specification details.
262      */
263     INET_ERROR EnableKeepAlive(uint16_t interval, uint16_t timeoutCount);
264
265     /**
266      * @brief   Disable the TCP "keep-alive" option.
267      *
268      * @retval  INET_NO_ERROR           success: address and port extracted.
269      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
270      * @retval  INET_ERROR_CONNECTION_ABORTED   TCP connection no longer open.
271      * @retval  INET_ERROR_NOT_IMPLEMENTED  system implementation not complete.
272      *
273      * @retval  other                   another system or platform error
274      */
275     INET_ERROR DisableKeepAlive();
276
277     /**
278      * @brief   Set the TCP TCP_USER_TIMEOUT socket option.
279      *
280      * @param[in]   userTimeoutMillis    Tcp user timeout value in milliseconds.
281      *
282      * @retval  INET_NO_ERROR           success: address and port extracted.
283      * @retval  INET_ERROR_NOT_IMPLEMENTED  system implementation not complete.
284      *
285      * @retval  other                   another system or platform error
286      *
287      * @details
288      *  When the value is greater than 0, it specifies the maximum amount of
289      *  time in milliseconds that transmitted data may remain
290      *  unacknowledged before TCP will forcibly close the
291      *  corresponding connection. If the option value is specified as 0,
292      *  TCP will to use the system default.
293      *  See RFC 5482, for further details.
294      */
295     INET_ERROR SetUserTimeout(uint32_t userTimeoutMillis);
296
297     /**
298      * @brief   Acknowledge receipt of message text.
299      *
300      * @param[in]   len     number of bytes to acknowledge.
301      *
302      * @retval  INET_NO_ERROR           success: reception acknowledged.
303      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
304      * @retval  INET_ERROR_CONNECTION_ABORTED   TCP connection no longer open.
305      *
306      * @details
307      *  Use this method to acknowledge reception of all or part of the data
308      *  received. The operational semantics are undefined if \c len is larger
309      *  than the total outstanding unacknowledged received data.
310      */
311     INET_ERROR AckReceive(uint16_t len);
312
313     /**
314      * @brief   Set the receive queue, for testing.
315      *
316      * @param[out]  data    Message text to push.
317      *
318      * @retval  INET_NO_ERROR           success: reception acknowledged.
319      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
320      *
321      * @details
322      *  This method may only be called by data reception event handlers to
323      *  put data on the receive queue for unit test purposes.
324      */
325     INET_ERROR SetReceivedDataForTesting(chip::System::PacketBufferHandle data);
326
327     /**
328      * @brief   Extract the length of the data awaiting first transmit.
329      *
330      * @return  Number of untransmitted bytes in the transmit queue.
331      */
332     uint32_t PendingSendLength();
333
334     /**
335      * @brief   Extract the length of the unacknowledged receive data.
336      *
337      * @return  Number of bytes in the receive queue that have not yet been
338      *      acknowledged with <tt>AckReceive(uint16_t len)</tt>.
339      */
340     uint32_t PendingReceiveLength();
341
342     /**
343      * @brief   Initiate TCP half close, in other words, finished with sending.
344      *
345      * @retval  INET_NO_ERROR           success: address and port extracted.
346      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
347      *
348      * @retval  other                   another system or platform error
349      */
350     INET_ERROR Shutdown();
351
352     /**
353      * @brief   Initiate TCP full close, in other words, finished with both send and
354      *  receive.
355      *
356      * @retval  INET_NO_ERROR           success: address and port extracted.
357      * @retval  INET_ERROR_INCORRECT_STATE  TCP connection not established.
358      *
359      * @retval  other                   another system or platform error
360      */
361     INET_ERROR Close();
362
363     /**
364      * @brief   Abortively close the endpoint, in other words, send RST packets.
365      */
366     void Abort();
367
368     /**
369      * @brief   Initiate (or continue) TCP full close, ignoring errors.
370      *
371      * @details
372      *  The object is returned to the free pool, and all remaining user
373      *  references are subsequently invalid.
374      */
375     void Free();
376
377     /**
378      * @brief   Extract whether TCP connection is established.
379      */
380     bool IsConnected() const;
381
382     void SetConnectTimeout(uint32_t connTimeoutMsecs);
383
384 #if INET_TCP_IDLE_CHECK_INTERVAL > 0
385     /**
386      * @brief   Set timer event for idle activity.
387      *
388      * @param[in]   timeoutMS The timeout in milliseconds
389      *
390      * @details
391      *  Set the idle timer interval to \c timeoutMS milliseconds. A zero
392      *  time interval implies the idle timer is disabled.
393      */
394     void SetIdleTimeout(uint32_t timeoutMS);
395 #endif // INET_TCP_IDLE_CHECK_INTERVAL > 0
396
397     /**
398      * @brief   Note activity, in other words, reset the idle timer.
399      *
400      * @details
401      *  Reset the idle timer to zero.
402      */
403     void MarkActive();
404
405     /**
406      * @brief   Obtain an identifier for the endpoint.
407      *
408      * @return  Returns an opaque unique identifier for use logs.
409      */
410     uint16_t LogId();
411
412     /**
413      * @brief   Type of connection establishment event handling function.
414      *
415      * @param[in]   endPoint    The TCP endpoint associated with the event.
416      * @param[in]   err         \c INET_NO_ERROR if success, else another code.
417      *
418      * @details
419      *  Provide a function of this type to the \c OnConnectComplete delegate
420      *  member to process connection establishment events on \c endPoint. The
421      *  \c err argument distinguishes successful connections from failures.
422      */
423     typedef void (*OnConnectCompleteFunct)(TCPEndPoint * endPoint, INET_ERROR err);
424
425     /**
426      * The endpoint's connection establishment event handling function
427      * delegate.
428      */
429     OnConnectCompleteFunct OnConnectComplete;
430
431     /**
432      * @brief   Type of data reception event handling function.
433      *
434      * @param[in]   endPoint        The TCP endpoint associated with the event.
435      * @param[in]   data            The data received.
436      *
437      * @retval      INET_NO_ERROR   If the received data can be handled by higher layers.
438      * @retval      other           If the received data can not be used, and higher layers will not see it.
439      *
440      * @details
441      *  Provide a function of this type to the \c OnDataReceived delegate
442      *  member to process data reception events on \c endPoint where \c data
443      *  is the message text received.
444      *
445      *  If this function returns an error, the connection will be closed, since higher layers
446      *  are not able to process the data for a better response.
447      */
448     typedef INET_ERROR (*OnDataReceivedFunct)(TCPEndPoint * endPoint, chip::System::PacketBufferHandle data);
449
450     /**
451      * The endpoint's message text reception event handling function delegate.
452      */
453     OnDataReceivedFunct OnDataReceived;
454
455     /**
456      * @brief   Type of data transmission event handling function.
457      *
458      * @param[in]   endPoint    The TCP endpoint associated with the event.
459      * @param[in]   len         Number of bytes added to the transmit window.
460      *
461      * @details
462      *  Provide a function of this type to the \c OnDataSent delegate
463      *  member to process data transmission events on \c endPoint where \c len
464      *  is the length of the message text added to the TCP transmit window,
465      *  which are eligible for sending by the underlying network stack.
466      */
467     typedef void (*OnDataSentFunct)(TCPEndPoint * endPoint, uint16_t len);
468
469     /**
470      * The endpoint's message text transmission event handling function
471      * delegate.
472      */
473     OnDataSentFunct OnDataSent;
474
475     /**
476      * @brief   Type of connection establishment event handling function.
477      *
478      * @param[in]   endPoint    The TCP endpoint associated with the event.
479      * @param[in]   err         \c INET_NO_ERROR if success, else another code.
480      *
481      * @details
482      *  Provide a function of this type to the \c OnConnectionClosed delegate
483      *  member to process connection termination events on \c endPoint. The
484      *  \c err argument distinguishes successful terminations from failures.
485      */
486     typedef void (*OnConnectionClosedFunct)(TCPEndPoint * endPoint, INET_ERROR err);
487
488     /** The endpoint's close event handling function delegate. */
489     OnConnectionClosedFunct OnConnectionClosed;
490
491     /**
492      * @brief   Type of half-close reception event handling function.
493      *
494      * @param[in]   endPoint    The TCP endpoint associated with the event.
495      *
496      * @details
497      *  Provide a function of this type to the \c OnPeerClose delegate member
498      *  to process connection termination events on \c endPoint.
499      */
500     typedef void (*OnPeerCloseFunct)(TCPEndPoint * endPoint);
501
502     /** The endpoint's half-close receive event handling function delegate. */
503     OnPeerCloseFunct OnPeerClose;
504
505     /**
506      * @brief   Type of connection received event handling function.
507      *
508      * @param[in]   listeningEndPoint   The listening TCP endpoint.
509      * @param[in]   conEndPoint         The newly received TCP endpoint.
510      * @param[in]   peerAddr            The IP address of the remote peer.
511      * @param[in]   peerPort            The TCP port of the remote peer.
512      *
513      * @details
514      *  Provide a function of this type to the \c OnConnectionReceived delegate
515      *  member to process connection reception events on \c listeningEndPoint.
516      *  The newly received endpoint \c conEndPoint is located at IP address
517      *  \c peerAddr and TCP port \c peerPort.
518      */
519     typedef void (*OnConnectionReceivedFunct)(TCPEndPoint * listeningEndPoint, TCPEndPoint * conEndPoint,
520                                               const IPAddress & peerAddr, uint16_t peerPort);
521
522     /** The endpoint's connection receive event handling function delegate. */
523     OnConnectionReceivedFunct OnConnectionReceived;
524
525     /**
526      * @brief   Type of connection acceptance error event handling function.
527      *
528      * @param[in]   endPoint    The TCP endpoint associated with the event.
529      * @param[in]   err         The reason for the error.
530      *
531      * @details
532      *  Provide a function of this type to the \c OnAcceptError delegate
533      *  member to process connection acceptance error events on \c endPoint. The
534      *  \c err argument provides specific detail about the type of the error.
535      */
536     typedef void (*OnAcceptErrorFunct)(TCPEndPoint * endPoint, INET_ERROR err);
537
538     /**
539      * The endpoint's connection acceptance event handling function delegate.
540      */
541     OnAcceptErrorFunct OnAcceptError;
542
543 #if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
544     /**
545      * @brief   Type of TCP SendIdle changed signal handling function.
546      *
547      * @param[in]   endPoint    The TCP endpoint associated with the event.
548      *
549      * @param[in]   isIdle      True if the send channel of the TCP endpoint
550      *                          is Idle, otherwise false.
551      * @details
552      *  Provide a function of this type to the \c OnTCPSendIdleChanged delegate
553      *  member to process the event of the send channel of the TCPEndPoint
554      *  changing state between being idle and not idle.
555      */
556     typedef void (*OnTCPSendIdleChangedFunct)(TCPEndPoint * endPoint, bool isIdle);
557
558     /** The event handling function delegate of the endpoint signaling when the
559      *  idleness of the TCP connection's send channel changes. This is utilized
560      *  by upper layers to take appropriate actions based on whether sent data
561      *  has been reliably delivered to the peer. */
562     OnTCPSendIdleChangedFunct OnTCPSendIdleChanged;
563 #endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
564
565     /**
566      * Size of the largest TCP packet that can be received.
567      */
568     constexpr static size_t kMaxReceiveMessageSize = System::PacketBuffer::kMaxSizeWithoutReserve;
569
570 private:
571     static chip::System::ObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> sPool;
572
573     chip::System::PacketBufferHandle mRcvQueue;
574     chip::System::PacketBufferHandle mSendQueue;
575 #if INET_TCP_IDLE_CHECK_INTERVAL > 0
576     uint16_t mIdleTimeout;       // in units of INET_TCP_IDLE_CHECK_INTERVAL; zero means no timeout
577     uint16_t mRemainingIdleTime; // in units of INET_TCP_IDLE_CHECK_INTERVAL
578 #endif                           // INET_TCP_IDLE_CHECK_INTERVAL > 0
579
580     uint32_t mConnectTimeoutMsecs; // This is the timeout to wait for a Connect call to succeed or
581                                    // return an error; zero means use system defaults.
582
583 #if INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
584     uint32_t mUserTimeoutMillis; // The configured TCP user timeout value in milliseconds.
585                                  // If 0, assume not set.
586 #if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
587     bool mIsTCPSendIdle; // Indicates whether the send channel of the TCPEndPoint is Idle.
588
589     uint16_t mTCPSendQueueRemainingPollCount; // The current remaining number of TCP SendQueue polls before
590                                               // the TCP User timeout period is reached.
591
592     uint32_t mTCPSendQueuePollPeriodMillis; // The configured period of active polling of the TCP
593                                             // SendQueue. If 0, assume not set.
594     void SetTCPSendIdleAndNotifyChange(bool aIsSendIdle);
595
596 #endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
597
598     bool mUserTimeoutTimerRunning; // Indicates whether the TCP UserTimeout timer has been started.
599
600     static void TCPUserTimeoutHandler(chip::System::Layer * aSystemLayer, void * aAppState, chip::System::Error aError);
601
602     void StartTCPUserTimeoutTimer();
603
604     void StopTCPUserTimeoutTimer();
605
606     void RestartTCPUserTimeoutTimer();
607
608     void ScheduleNextTCPUserTimeoutPoll(uint32_t aTimeOut);
609
610 #if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
611     uint16_t MaxTCPSendQueuePolls(void);
612 #endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS
613
614 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
615     uint32_t mBytesWrittenSinceLastProbe; // This counts the number of bytes written on the TCP socket since the
616                                           // last probe into the TCP outqueue was made.
617
618     uint32_t mLastTCPKernelSendQueueLen; // This is the measured size(in bytes) of the kernel TCP send queue
619                                          // at the end of the last user timeout window.
620     INET_ERROR CheckConnectionProgress(bool & IsProgressing);
621 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
622
623 #endif // INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
624
625     TCPEndPoint();                    // not defined
626     TCPEndPoint(const TCPEndPoint &); // not defined
627     ~TCPEndPoint();                   // not defined
628
629     void Init(InetLayer * inetLayer);
630     INET_ERROR DriveSending();
631     void DriveReceiving();
632     void HandleConnectComplete(INET_ERROR err);
633     void HandleAcceptError(INET_ERROR err);
634     INET_ERROR DoClose(INET_ERROR err, bool suppressCallback);
635     static bool IsConnected(int state);
636
637     static void TCPConnectTimeoutHandler(chip::System::Layer * aSystemLayer, void * aAppState, chip::System::Error aError);
638
639     void StartConnectTimerIfSet();
640     void StopConnectTimer();
641
642 #if CHIP_SYSTEM_CONFIG_USE_LWIP
643     struct BufferOffset
644     {
645         BufferOffset(System::PacketBufferHandle && aBuffer) : buffer(std::move(aBuffer)), offset(0) {}
646         BufferOffset(BufferOffset && aOther)
647         {
648             buffer = std::move(aOther.buffer);
649             offset = aOther.offset;
650         }
651         chip::System::PacketBufferHandle buffer;
652         uint16_t offset;
653     };
654
655     uint16_t mUnackedLength; // Amount sent but awaiting ACK. Used as a form of reference count
656                              // to hang-on to backing packet buffers until they are no longer needed.
657
658     uint16_t RemainingToSend();
659     BufferOffset FindStartOfUnsent();
660     INET_ERROR GetPCB(IPAddressType addrType);
661     void HandleDataSent(uint16_t len);
662     void HandleDataReceived(chip::System::PacketBufferHandle buf);
663     void HandleIncomingConnection(TCPEndPoint * pcb);
664     void HandleError(INET_ERROR err);
665
666     static err_t LwIPHandleConnectComplete(void * arg, struct tcp_pcb * tpcb, err_t lwipErr);
667     static err_t LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tcpConPCB, err_t lwipErr);
668     static err_t LwIPHandleDataReceived(void * arg, struct tcp_pcb * tpcb, struct pbuf * p, err_t err);
669     static err_t LwIPHandleDataSent(void * arg, struct tcp_pcb * tpcb, u16_t len);
670     static void LwIPHandleError(void * arg, err_t err);
671
672 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
673
674 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
675     INET_ERROR GetSocket(IPAddressType addrType);
676     SocketEvents PrepareIO();
677     void HandlePendingIO();
678     void ReceiveData();
679     void HandleIncomingConnection();
680     INET_ERROR BindSrcAddrFromIntf(IPAddressType addrType, InterfaceId intfId);
681 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
682 };
683
684 #if INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
685 inline uint16_t TCPEndPoint::MaxTCPSendQueuePolls(void)
686 {
687     // If the UserTimeout is configured less than or equal to the poll interval,
688     // return 1 to poll at least once instead of returning zero and timing out
689     // immediately.
690     return (mUserTimeoutMillis > mTCPSendQueuePollPeriodMillis) ? (mUserTimeoutMillis / mTCPSendQueuePollPeriodMillis) : 1;
691 }
692 #endif // INET_CONFIG_ENABLE_TCP_SEND_IDLE_CALLBACKS && INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT
693
694 inline bool TCPEndPoint::IsConnected() const
695 {
696     return IsConnected(State);
697 }
698
699 inline uint16_t TCPEndPoint::LogId()
700 {
701     return static_cast<uint16_t>(reinterpret_cast<intptr_t>(this));
702 }
703
704 inline void TCPEndPoint::MarkActive()
705 {
706 #if INET_TCP_IDLE_CHECK_INTERVAL > 0
707     mRemainingIdleTime = mIdleTimeout;
708 #endif // INET_TCP_IDLE_CHECK_INTERVAL > 0
709 }
710
711 } // namespace Inet
712 } // namespace chip