From 83f65c0d3af7cbef775e5d8d19b8ecefe6cf9c3e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 10 May 2016 14:37:36 -0500 Subject: [PATCH] Add rudimentary support for server side mirrored from: https://developer.mbed.org/teams/NetworkSocketAPI/code/LWIPInterface/ --- net/LWIPInterface/LWIPInterface.cpp | 65 ++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/net/LWIPInterface/LWIPInterface.cpp b/net/LWIPInterface/LWIPInterface.cpp index c37a52463a..9f13b5ccd5 100644 --- a/net/LWIPInterface/LWIPInterface.cpp +++ b/net/LWIPInterface/LWIPInterface.cpp @@ -139,6 +139,7 @@ struct lwip_socket { struct tcp_pcb *tcp; }; + struct tcp_pcb *npcb; struct pbuf *rx_chain; Semaphore *sem; @@ -238,9 +239,25 @@ int LWIPInterface::socket_bind(void *handle, const SocketAddress &address) return NSAPI_ERROR_DEVICE_ERROR; } +static err_t tcp_accept_irq(void *arg, struct tcp_pcb *tpcb, err_t err); + int LWIPInterface::socket_listen(void *handle, int backlog) { - return NSAPI_ERROR_UNSUPPORTED; + struct lwip_socket *s = (struct lwip_socket *)handle; + + if (s->tcp->state != LISTEN) { + struct tcp_pcb *server = tcp_listen(s->tcp); + if (!server) { + return NSAPI_ERROR_NO_SOCKET; + } + + s->tcp = server; + s->npcb = 0; + } + + tcp_arg(s->tcp, s); + tcp_accept(s->tcp, tcp_accept_irq); + return 0; } static err_t tcp_sent_irq(void *arg, struct tcp_pcb *tpcb, uint16_t len); @@ -277,9 +294,53 @@ int LWIPInterface::socket_connect(void *handle, const SocketAddress &addr) return 0; } +static err_t tcp_refuse_irq(void *handle, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + return ERR_WOULDBLOCK; +} + +static err_t tcp_accept_irq(void *handle, struct tcp_pcb *npcb, err_t err) +{ + struct lwip_socket *s = (struct lwip_socket *)handle; + if (s->npcb) { + tcp_abort(npcb); + return ERR_ABRT; + } + + tcp_recv(npcb, tcp_refuse_irq); + s->npcb = npcb; + + if (s->callback) { + s->callback(s->data); + } + + return ERR_OK; +} + int LWIPInterface::socket_accept(void **handle, void *server) { - return NSAPI_ERROR_UNSUPPORTED; + struct lwip_socket *s = (struct lwip_socket *)server; + if (!s->npcb) { + return NSAPI_ERROR_WOULD_BLOCK; + } + + struct lwip_socket *ns = new struct lwip_socket; + if (!ns) { + return NSAPI_ERROR_NO_SOCKET; + } + + memset(ns, 0, sizeof *ns); + + ns->tcp = s->npcb; + s->npcb = 0; + + tcp_accepted(ns->tcp); + tcp_arg(ns->tcp, ns); + //tcp_err(ns->tcp, tcp_error_irq); + tcp_sent(ns->tcp, tcp_sent_irq); + tcp_recv(ns->tcp, tcp_recv_irq); + *handle = ns; + return 0; } static struct pbuf *pbuf_consume(struct pbuf *p, size_t consume, bool free_partial)