3#if defined(USE_SOCKET_IMPL_LWIP_TCP) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || defined(USE_SOCKET_IMPL_BSD_SOCKETS)
15static constexpr uint32_t CONNECT_TIMEOUT_MS = 10000;
20static void set_stream_options(
Socket *sock,
const char *tag) {
23 sock->setblocking(
false);
24 int err = sock->setsockopt(IPPROTO_TCP, TCP_NODELAY, &yes,
sizeof(yes));
25 err |= sock->setsockopt(SOL_SOCKET, SO_KEEPALIVE, &yes,
sizeof(yes));
30 err |= sock->setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, &idle,
sizeof(idle));
31 err |= sock->setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, &interval,
sizeof(interval));
32 err |= sock->setsockopt(IPPROTO_TCP, TCP_KEEPCNT, &
count,
sizeof(
count));
35 ESP_LOGV(tag,
"Nodelay/keepalive not fully applied");
46 if (this->
sock_ ==
nullptr) {
56 std::max(this->reconnect_interval_ms_, CONNECT_TIMEOUT_MS)) {
57 this->
drop_(LOG_STR(
"Connect failed"), ETIMEDOUT);
61 this->
drop_(LOG_STR(
"Connect failed"), err);
67 ESP_LOGI(this->
tag_,
"Connected to %s:%u", this->
host_.
c_str(), this->port_);
87 if (this->
sock_ ==
nullptr) {
88 this->
drop_(LOG_STR(
"Connect failed"), errno);
91 set_stream_options(this->
sock_.get(), this->tag_);
95 if (this->
sock_->connect(
reinterpret_cast<struct
sockaddr *
>(&dest), dest_len) != 0 && errno != EINPROGRESS) {
96 this->
drop_(LOG_STR(
"Connect failed"), errno);
102 set_stream_options(sock.get(), this->tag_);
103 this->
sock_ = std::move(sock);
115 if (
count == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
116 this->
drop_(LOG_STR(
"Connection lost"),
count == 0 ? 0 : errno);
130 if (errno == EAGAIN || errno == EWOULDBLOCK) {
133 this->
drop_(LOG_STR(
"Connection lost"), errno);
150 this->
tx_len_ -=
static_cast<uint16_t
>(sent);
158 if (this->
sock_ !=
nullptr) {
159 this->
sock_->shutdown(SHUT_RDWR);
160 this->
sock_->close();
169 ESP_LOGW(this->
tag_,
"%s: %d", LOG_STR_ARG(what), err);
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
constexpr const char * c_str() const
void start(const char *host, uint16_t port, const char *tag)
Resolve host; tag names the failure log.
bool consume_failure()
Drop a failed lookup so the next start() tries again.
socklen_t to_sockaddr(struct sockaddr *dest, socklen_t destlen, uint16_t port) const
Write the stored address into dest. Returns 0 until ready() is true.
void forget()
Drop the stored address so the next start() resolves again.
uint32_t reconnect_interval_ms_
void drop_(const LogString *what, int err)
Close after a failure, log what and errno, schedule the next attempt.
ssize_t write_(const uint8_t *buf, size_t len)
The raw stream write behind flush_tx(); drops the link on a fatal error.
std::unique_ptr< Socket > sock_
uint8_t tx_[TX_BUFFER_SIZE]
uint32_t last_attempt_ms_
void close()
Close without scheduling a reconnect (shutdown).
ssize_t read(uint8_t *buf, size_t len)
Returns bytes moved, 0 when nothing can move now, -1 when the link dropped.
void begin(const char *tag)
Call from setup(). tag names this link's log lines.
void note_attempt()
Shared retry clock, also usable for a listen socket.
void adopt(std::unique_ptr< Socket > sock)
Take over an accepted socket (the server side of a bridge).
size_t queue(const uint8_t *data, size_t len)
Copy into the outgoing buffer; returns how many bytes fit.
ConnectPollResult poll_connect(Socket &sock, int &err_out)
Poll a connect() that returned EINPROGRESS.
@ CONNECT_POLL_RESULT_ERROR
@ CONNECT_POLL_RESULT_PENDING
std::unique_ptr< Socket > socket_loop_monitored(int domain, int type, int protocol)
Create a socket and monitor it for data in the main loop.
Application App
Global storage of Application pointer - only one Application can exist.