4 #ifdef USE_SOCKET_IMPL_LWIP_TCP 7 #include "lwip/netif.h" 20 static const char *
const TAG =
"socket.lwip";
24 #define LWIP_LOG(msg, ...) ESP_LOGVV(TAG, "socket %p: " msg, this, ##__VA_ARGS__) 26 #define LWIP_LOG(msg, ...) 29 class LWIPRawImpl :
public Socket {
31 LWIPRawImpl(
sa_family_t family,
struct tcp_pcb *pcb) : pcb_(pcb), family_(family) {}
32 ~LWIPRawImpl()
override {
33 if (pcb_ !=
nullptr) {
34 LWIP_LOG(
"tcp_abort(%p)", pcb_);
41 LWIP_LOG(
"init(%p)", pcb_);
43 tcp_accept(pcb_, LWIPRawImpl::s_accept_fn);
44 tcp_recv(pcb_, LWIPRawImpl::s_recv_fn);
45 tcp_err(pcb_, LWIPRawImpl::s_err_fn);
48 std::unique_ptr<Socket> accept(
struct sockaddr *addr,
socklen_t *addrlen)
override {
49 if (pcb_ ==
nullptr) {
53 if (accepted_sockets_.empty()) {
57 std::unique_ptr<LWIPRawImpl> sock = std::move(accepted_sockets_.front());
58 accepted_sockets_.pop();
59 if (addr !=
nullptr) {
60 sock->getpeername(addr, addrlen);
62 LWIP_LOG(
"accept(%p)", sock.get());
63 return std::unique_ptr<Socket>(std::move(sock));
66 if (pcb_ ==
nullptr) {
70 if (name ==
nullptr) {
77 if (family_ == AF_INET) {
83 port = ntohs(addr4->sin_port);
84 ip.type = IPADDR_TYPE_V4;
85 ip.u_addr.ip4.addr = addr4->sin_addr.s_addr;
86 LWIP_LOG(
"tcp_bind(%p ip=%s port=%u)", pcb_, ip4addr_ntoa(&ip.u_addr.ip4), port);
87 }
else if (family_ == AF_INET6) {
93 port = ntohs(addr6->sin6_port);
94 ip.type = IPADDR_TYPE_ANY;
95 memcpy(&ip.u_addr.ip6.addr, &addr6->sin6_addr.un.u8_addr, 16);
96 LWIP_LOG(
"tcp_bind(%p ip=%s port=%u)", pcb_, ip6addr_ntoa(&ip.u_addr.ip6), port);
102 if (family_ != AF_INET) {
107 port = ntohs(addr4->sin_port);
108 ip.addr = addr4->sin_addr.s_addr;
109 LWIP_LOG(
"tcp_bind(%p ip=%u port=%u)", pcb_, ip.addr, port);
111 err_t err = tcp_bind(pcb_, &ip, port);
112 if (err == ERR_USE) {
113 LWIP_LOG(
" -> err ERR_USE");
117 if (err == ERR_VAL) {
118 LWIP_LOG(
" -> err ERR_VAL");
123 LWIP_LOG(
" -> err %d", err);
129 int close()
override {
130 if (pcb_ ==
nullptr) {
134 LWIP_LOG(
"tcp_close(%p)", pcb_);
135 err_t err = tcp_close(pcb_);
137 LWIP_LOG(
" -> err %d", err);
140 errno = err == ERR_MEM ? ENOMEM : EIO;
146 int shutdown(
int how)
override {
147 if (pcb_ ==
nullptr) {
151 bool shut_rx =
false, shut_tx =
false;
152 if (how == SHUT_RD) {
154 }
else if (how == SHUT_WR) {
156 }
else if (how == SHUT_RDWR) {
157 shut_rx = shut_tx =
true;
162 LWIP_LOG(
"tcp_shutdown(%p shut_rx=%d shut_tx=%d)", pcb_, shut_rx ? 1 : 0, shut_tx ? 1 : 0);
163 err_t err = tcp_shutdown(pcb_, shut_rx, shut_tx);
165 LWIP_LOG(
" -> err %d", err);
166 errno = err == ERR_MEM ? ENOMEM : EIO;
173 if (pcb_ ==
nullptr) {
177 if (name ==
nullptr || addrlen ==
nullptr) {
181 return this->ip2sockaddr_(&pcb_->local_ip, pcb_->local_port, name, addrlen);
183 std::string getpeername()
override {
184 if (pcb_ ==
nullptr) {
188 char buffer[50] = {};
189 if (IP_IS_V4_VAL(pcb_->remote_ip)) {
190 inet_ntoa_r(pcb_->remote_ip, buffer,
sizeof(buffer));
193 else if (IP_IS_V6_VAL(pcb_->remote_ip)) {
194 inet6_ntoa_r(pcb_->remote_ip, buffer,
sizeof(buffer));
197 return std::string(buffer);
200 if (pcb_ ==
nullptr) {
204 if (name ==
nullptr || addrlen ==
nullptr) {
208 return this->ip2sockaddr_(&pcb_->local_ip, pcb_->local_port, name, addrlen);
210 std::string getsockname()
override {
211 if (pcb_ ==
nullptr) {
215 char buffer[50] = {};
216 if (IP_IS_V4_VAL(pcb_->local_ip)) {
217 inet_ntoa_r(pcb_->local_ip, buffer,
sizeof(buffer));
220 else if (IP_IS_V6_VAL(pcb_->local_ip)) {
221 inet6_ntoa_r(pcb_->local_ip, buffer,
sizeof(buffer));
224 return std::string(buffer);
226 int getsockopt(
int level,
int optname,
void *optval,
socklen_t *optlen)
override {
227 if (pcb_ ==
nullptr) {
231 if (optlen ==
nullptr || optval ==
nullptr) {
235 if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
243 *
reinterpret_cast<int *
>(optval) = 1;
247 if (level == IPPROTO_TCP && optname == TCP_NODELAY) {
252 *
reinterpret_cast<int *
>(optval) = nodelay_;
260 int setsockopt(
int level,
int optname,
const void *optval,
socklen_t optlen)
override {
261 if (pcb_ ==
nullptr) {
265 if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
275 if (level == IPPROTO_TCP && optname == TCP_NODELAY) {
280 int val = *
reinterpret_cast<const int *
>(optval);
288 int listen(
int backlog)
override {
289 if (pcb_ ==
nullptr) {
293 LWIP_LOG(
"tcp_listen_with_backlog(%p backlog=%d)", pcb_, backlog);
294 struct tcp_pcb *listen_pcb = tcp_listen_with_backlog(pcb_, backlog);
295 if (listen_pcb ==
nullptr) {
304 LWIP_LOG(
"tcp_arg(%p)", pcb_);
306 tcp_accept(pcb_, LWIPRawImpl::s_accept_fn);
309 ssize_t read(
void *buf,
size_t len)
override {
310 if (pcb_ ==
nullptr) {
314 if (rx_closed_ && rx_buf_ ==
nullptr) {
320 if (rx_buf_ ==
nullptr) {
326 uint8_t *buf8 =
reinterpret_cast<uint8_t *
>(buf);
327 while (len && rx_buf_ !=
nullptr) {
328 size_t pb_len = rx_buf_->len;
329 size_t pb_left = pb_len - rx_buf_offset_;
332 size_t copysize = std::min(len, pb_left);
333 memcpy(buf8, reinterpret_cast<uint8_t *>(rx_buf_->payload) + rx_buf_offset_, copysize);
335 if (pb_left == copysize) {
337 if (rx_buf_->next ==
nullptr) {
343 auto *old_buf = rx_buf_;
344 rx_buf_ = rx_buf_->next;
350 rx_buf_offset_ += copysize;
352 LWIP_LOG(
"tcp_recved(%p %u)", pcb_, copysize);
353 tcp_recved(pcb_, copysize);
367 ssize_t readv(
const struct iovec *iov,
int iovcnt)
override {
369 for (
int i = 0; i < iovcnt; i++) {
370 ssize_t err = read(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len);
378 if ((
size_t) err != iov[i].iov_len)
383 ssize_t internal_write(
const void *buf,
size_t len) {
384 if (pcb_ ==
nullptr) {
390 if (buf ==
nullptr) {
394 auto space = tcp_sndbuf(pcb_);
399 size_t to_send = std::min((
size_t) space, len);
400 LWIP_LOG(
"tcp_write(%p buf=%p %u)", pcb_, buf, to_send);
401 err_t err = tcp_write(pcb_, buf, to_send, TCP_WRITE_FLAG_COPY);
402 if (err == ERR_MEM) {
403 LWIP_LOG(
" -> err ERR_MEM");
408 LWIP_LOG(
" -> err %d", err);
414 int internal_output() {
415 LWIP_LOG(
"tcp_output(%p)", pcb_);
416 err_t err = tcp_output(pcb_);
417 if (err == ERR_ABRT) {
418 LWIP_LOG(
" -> err ERR_ABRT");
426 LWIP_LOG(
" -> err %d", err);
432 ssize_t write(
const void *buf,
size_t len)
override {
433 ssize_t written = internal_write(buf, len);
440 int err = internal_output();
446 ssize_t writev(
const struct iovec *iov,
int iovcnt)
override {
448 for (
int i = 0; i < iovcnt; i++) {
449 ssize_t err = internal_write(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len);
457 if ((
size_t) err != iov[i].iov_len)
464 int err = internal_output();
470 ssize_t sendto(
const void *buf,
size_t len,
int flags,
const struct sockaddr *to,
socklen_t tolen)
override {
475 int setblocking(
bool blocking)
override {
476 if (pcb_ ==
nullptr) {
488 err_t accept_fn(
struct tcp_pcb *newpcb, err_t err) {
489 LWIP_LOG(
"accept(newpcb=%p err=%d)", newpcb, err);
490 if (err != ERR_OK || newpcb ==
nullptr) {
497 auto sock = make_unique<LWIPRawImpl>(family_, newpcb);
499 accepted_sockets_.push(std::move(sock));
502 void err_fn(err_t err) {
503 LWIP_LOG(
"err(err=%d)", err);
511 err_t recv_fn(
struct pbuf *pb, err_t err) {
512 LWIP_LOG(
"recv(pb=%p err=%d)", pb, err);
523 if (rx_buf_ ==
nullptr) {
528 pbuf_cat(rx_buf_, pb);
533 static err_t s_accept_fn(
void *arg,
struct tcp_pcb *newpcb, err_t err) {
534 LWIPRawImpl *arg_this =
reinterpret_cast<LWIPRawImpl *
>(arg);
535 return arg_this->accept_fn(newpcb, err);
538 static void s_err_fn(
void *arg, err_t err) {
539 LWIPRawImpl *arg_this =
reinterpret_cast<LWIPRawImpl *
>(arg);
540 arg_this->err_fn(err);
543 static err_t s_recv_fn(
void *arg,
struct tcp_pcb *pcb,
struct pbuf *pb, err_t err) {
544 LWIPRawImpl *arg_this =
reinterpret_cast<LWIPRawImpl *
>(arg);
545 return arg_this->recv_fn(pb, err);
550 if (family_ == AF_INET) {
560 inet_addr_from_ip4addr(&addr->
sin_addr, ip_2_ip4(ip));
564 else if (family_ == AF_INET6) {
578 ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&mapped), ip_2_ip4(ip));
579 inet6_addr_from_ip6addr(&addr->
sin6_addr, ip_2_ip6(&mapped));
581 inet6_addr_from_ip6addr(&addr->
sin6_addr, ip_2_ip6(ip));
589 struct tcp_pcb *pcb_;
590 std::queue<std::unique_ptr<LWIPRawImpl>> accepted_sockets_;
591 bool rx_closed_ =
false;
592 pbuf *rx_buf_ =
nullptr;
593 size_t rx_buf_offset_ = 0;
596 bool nodelay_ =
false;
600 std::unique_ptr<Socket>
socket(
int domain,
int type,
int protocol) {
601 auto *pcb = tcp_new();
604 auto *sock =
new LWIPRawImpl((
sa_family_t) domain, pcb);
606 return std::unique_ptr<Socket>{sock};
612 #endif // USE_SOCKET_IMPL_LWIP_TCP
Implementation of SPI Controller mode.
struct in6_addr sin6_addr
std::unique_ptr< Socket > socket(int domain, int type, int protocol)
Create a socket of the given domain, type and protocol.