93#define API_MSG_VAR_REF(name) API_VAR_REF(name)
94#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
95#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
96#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL)
97#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
99static err_t netconn_close_shutdown(
struct netconn *conn, u8_t how);
120#if LWIP_NETCONN_SEM_PER_THREAD
121 apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
142netconn_new_with_proto_and_callback(
enum netconn_type t, u8_t proto, netconn_callback callback)
144 struct netconn *conn;
145 API_MSG_VAR_DECLARE(msg);
146 API_MSG_VAR_ALLOC_RETURN_NULL(msg);
148 conn = netconn_alloc(t, callback);
152 API_MSG_VAR_REF(msg).msg.n.proto = proto;
153 API_MSG_VAR_REF(msg).conn = conn;
154 err = netconn_apimsg(lwip_netconn_do_newconn, &API_MSG_VAR_REF(msg));
156 LWIP_ASSERT(
"freeing conn without freeing pcb", conn->pcb.tcp == NULL);
157 LWIP_ASSERT(
"conn has no recvmbox",
sys_mbox_valid(&conn->recvmbox));
159 LWIP_ASSERT(
"conn->acceptmbox shouldn't exist", !
sys_mbox_valid(&conn->acceptmbox));
161#if !LWIP_NETCONN_SEM_PER_THREAD
162 LWIP_ASSERT(
"conn has no op_completed",
sys_sem_valid(&conn->op_completed));
167 API_MSG_VAR_FREE(msg);
171 API_MSG_VAR_FREE(msg);
185netconn_delete(
struct netconn *conn)
188 API_MSG_VAR_DECLARE(msg);
195 API_MSG_VAR_ALLOC(msg);
196 API_MSG_VAR_REF(msg).conn = conn;
197#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
200 API_MSG_VAR_REF(msg).msg.sd.time_started =
sys_now();
203 API_MSG_VAR_REF(msg).msg.sd.polls_left =
207 err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
208 API_MSG_VAR_FREE(msg);
231netconn_getaddr(
struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
233 API_MSG_VAR_DECLARE(msg);
236 LWIP_ERROR(
"netconn_getaddr: invalid conn", (conn != NULL),
return ERR_ARG;);
237 LWIP_ERROR(
"netconn_getaddr: invalid addr", (addr != NULL),
return ERR_ARG;);
238 LWIP_ERROR(
"netconn_getaddr: invalid port", (port != NULL),
return ERR_ARG;);
240 API_MSG_VAR_ALLOC(msg);
241 API_MSG_VAR_REF(msg).conn = conn;
242 API_MSG_VAR_REF(msg).msg.ad.local = local;
243#if LWIP_MPU_COMPATIBLE
244 err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg));
245 *addr = msg->msg.ad.ipaddr;
246 *port = msg->msg.ad.port;
248 msg.msg.ad.ipaddr = addr;
249 msg.msg.ad.port = port;
250 err = netconn_apimsg(lwip_netconn_do_getaddr, &msg);
252 API_MSG_VAR_FREE(msg);
269netconn_bind(
struct netconn *conn,
const ip_addr_t *addr, u16_t port)
271 API_MSG_VAR_DECLARE(msg);
274 LWIP_ERROR(
"netconn_bind: invalid conn", (conn != NULL),
return ERR_ARG;);
283#if LWIP_IPV4 && LWIP_IPV6
287 if ((netconn_get_ipv6only(conn) == 0) &&
288 ip_addr_cmp(addr, IP6_ADDR_ANY)) {
293 API_MSG_VAR_ALLOC(msg);
294 API_MSG_VAR_REF(msg).conn = conn;
295 API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
296 API_MSG_VAR_REF(msg).msg.bc.port = port;
297 err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg));
298 API_MSG_VAR_FREE(msg);
313netconn_connect(
struct netconn *conn,
const ip_addr_t *addr, u16_t port)
315 API_MSG_VAR_DECLARE(msg);
318 LWIP_ERROR(
"netconn_connect: invalid conn", (conn != NULL),
return ERR_ARG;);
327 API_MSG_VAR_ALLOC(msg);
328 API_MSG_VAR_REF(msg).conn = conn;
329 API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
330 API_MSG_VAR_REF(msg).msg.bc.port = port;
331 err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg));
332 API_MSG_VAR_FREE(msg);
345netconn_disconnect(
struct netconn *conn)
347 API_MSG_VAR_DECLARE(msg);
350 LWIP_ERROR(
"netconn_disconnect: invalid conn", (conn != NULL),
return ERR_ARG;);
352 API_MSG_VAR_ALLOC(msg);
353 API_MSG_VAR_REF(msg).conn = conn;
354 err = netconn_apimsg(lwip_netconn_do_disconnect, &API_MSG_VAR_REF(msg));
355 API_MSG_VAR_FREE(msg);
370netconn_listen_with_backlog(
struct netconn *conn, u8_t backlog)
373 API_MSG_VAR_DECLARE(msg);
379 LWIP_ERROR(
"netconn_listen: invalid conn", (conn != NULL),
return ERR_ARG;);
381 API_MSG_VAR_ALLOC(msg);
382 API_MSG_VAR_REF(msg).conn = conn;
383#if TCP_LISTEN_BACKLOG
384 API_MSG_VAR_REF(msg).msg.lb.backlog = backlog;
386 err = netconn_apimsg(lwip_netconn_do_listen, &API_MSG_VAR_REF(msg));
387 API_MSG_VAR_FREE(msg);
407netconn_accept(
struct netconn *conn,
struct netconn **new_conn)
411 struct netconn *newconn;
412#if TCP_LISTEN_BACKLOG
413 API_MSG_VAR_DECLARE(msg);
416 LWIP_ERROR(
"netconn_accept: invalid pointer", (new_conn != NULL),
return ERR_ARG;);
418 LWIP_ERROR(
"netconn_accept: invalid conn", (conn != NULL),
return ERR_ARG;);
420 if (ERR_IS_FATAL(conn->last_err)) {
423 return conn->last_err;
429#if TCP_LISTEN_BACKLOG
430 API_MSG_VAR_ALLOC(msg);
435#if TCP_LISTEN_BACKLOG
436 API_MSG_VAR_FREE(msg);
443 newconn = (
struct netconn *)accept_ptr;
445 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
447 if (accept_ptr == &netconn_aborted) {
450#if TCP_LISTEN_BACKLOG
451 API_MSG_VAR_FREE(msg);
455 if (newconn == NULL) {
460 NETCONN_SET_SAFE_ERR(conn,
ERR_CLSD);
461#if TCP_LISTEN_BACKLOG
462 API_MSG_VAR_FREE(msg);
466#if TCP_LISTEN_BACKLOG
468 API_MSG_VAR_REF(msg).conn = newconn;
470 netconn_apimsg(lwip_netconn_do_accepted, &API_MSG_VAR_REF(msg));
471 API_MSG_VAR_FREE(msg);
495netconn_recv_data(
struct netconn *conn,
void **new_buf)
500 API_MSG_VAR_DECLARE(msg);
501#if LWIP_MPU_COMPATIBLE
506 LWIP_ERROR(
"netconn_recv: invalid pointer", (new_buf != NULL),
return ERR_ARG;);
508 LWIP_ERROR(
"netconn_recv: invalid conn", (conn != NULL),
return ERR_ARG;);
510#if (LWIP_UDP || LWIP_RAW)
511 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
522 if (ERR_IS_FATAL(conn->last_err)) {
527 return conn->last_err;
530#if (LWIP_UDP || LWIP_RAW)
531 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
534 API_MSG_VAR_ALLOC(msg);
541#if (LWIP_UDP || LWIP_RAW)
542 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
545 API_MSG_VAR_FREE(msg);
555#if (LWIP_UDP || LWIP_RAW)
556 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
562 API_MSG_VAR_REF(msg).conn = conn;
564 API_MSG_VAR_REF(msg).msg.r.len = ((
struct pbuf *)buf)->tot_len;
566 API_MSG_VAR_REF(msg).msg.r.len = 1;
570 netconn_apimsg(lwip_netconn_do_recv, &API_MSG_VAR_REF(msg));
571 API_MSG_VAR_FREE(msg);
575 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
576 if (conn->pcb.ip == NULL) {
581 netconn_close_shutdown(conn, NETCONN_SHUT_RD);
585 len = ((
struct pbuf *)buf)->tot_len;
588#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
591#if (LWIP_UDP || LWIP_RAW)
593 LWIP_ASSERT(
"buf != NULL", buf != NULL);
594 len = netbuf_len((
struct netbuf*)buf);
599 SYS_ARCH_DEC(conn->recv_avail,
len);
602 API_EVENT(conn, NETCONN_EVT_RCVMINUS,
len);
622netconn_recv_tcp_pbuf(
struct netconn *conn,
struct pbuf **new_buf)
624 LWIP_ERROR(
"netconn_recv: invalid conn", (conn != NULL) &&
625 NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
return ERR_ARG;);
627 return netconn_recv_data(conn, (
void **)new_buf);
640netconn_recv(
struct netconn *conn,
struct netbuf **new_buf)
643 struct netbuf *buf = NULL;
647 LWIP_ERROR(
"netconn_recv: invalid pointer", (new_buf != NULL),
return ERR_ARG;);
649 LWIP_ERROR(
"netconn_recv: invalid conn", (conn != NULL),
return ERR_ARG;);
652#if (LWIP_UDP || LWIP_RAW)
653 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
656 struct pbuf *p = NULL;
664 err = netconn_recv_data(conn, (
void **)&p);
669 LWIP_ASSERT(
"p != NULL", p != NULL);
674 ip_addr_set_zero(&buf->addr);
680#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
684#if (LWIP_UDP || LWIP_RAW)
685 return netconn_recv_data(conn, (
void **)new_buf);
702netconn_sendto(
struct netconn *conn,
struct netbuf *buf,
const ip_addr_t *addr, u16_t port)
705 ip_addr_set(&buf->addr, addr);
707 return netconn_send(conn, buf);
721netconn_send(
struct netconn *conn,
struct netbuf *buf)
723 API_MSG_VAR_DECLARE(msg);
726 LWIP_ERROR(
"netconn_send: invalid conn", (conn != NULL),
return ERR_ARG;);
730 API_MSG_VAR_ALLOC(msg);
731 API_MSG_VAR_REF(msg).conn = conn;
732 API_MSG_VAR_REF(msg).msg.b = buf;
733 err = netconn_apimsg(lwip_netconn_do_send, &API_MSG_VAR_REF(msg));
734 API_MSG_VAR_FREE(msg);
754netconn_write_partly(
struct netconn *conn,
const void *dataptr,
size_t size,
755 u8_t apiflags,
size_t *bytes_written)
757 API_MSG_VAR_DECLARE(msg);
761 LWIP_ERROR(
"netconn_write: invalid conn", (conn != NULL),
return ERR_ARG;);
762 LWIP_ERROR(
"netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type)== NETCONN_TCP),
return ERR_VAL;);
766 dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
768 if (conn->send_timeout != 0) {
772 if (dontblock && !bytes_written) {
778 API_MSG_VAR_ALLOC(msg);
780 API_MSG_VAR_REF(msg).conn = conn;
781 API_MSG_VAR_REF(msg).msg.w.dataptr = dataptr;
782 API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags;
783 API_MSG_VAR_REF(msg).msg.w.len = size;
785 if (conn->send_timeout != 0) {
788 API_MSG_VAR_REF(msg).msg.w.time_started =
sys_now();
790 API_MSG_VAR_REF(msg).msg.w.time_started = 0;
797 err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg));
798 if ((err ==
ERR_OK) && (bytes_written != NULL)) {
801 *bytes_written = API_MSG_VAR_REF(msg).msg.w.len;
804 *bytes_written = size;
807 API_MSG_VAR_FREE(msg);
821netconn_close_shutdown(
struct netconn *conn, u8_t how)
823 API_MSG_VAR_DECLARE(msg);
827 LWIP_ERROR(
"netconn_close: invalid conn", (conn != NULL),
return ERR_ARG;);
829 API_MSG_VAR_ALLOC(msg);
830 API_MSG_VAR_REF(msg).conn = conn;
833 API_MSG_VAR_REF(msg).msg.sd.shut = how;
834#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
837 API_MSG_VAR_REF(msg).msg.sd.time_started =
sys_now();
839 API_MSG_VAR_REF(msg).msg.sd.polls_left =
843 err = netconn_apimsg(lwip_netconn_do_close, &API_MSG_VAR_REF(msg));
844 API_MSG_VAR_FREE(msg);
857netconn_close(
struct netconn *conn)
860 return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
873netconn_shutdown(
struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
875 return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
878#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
891netconn_join_leave_group(
struct netconn *conn,
892 const ip_addr_t *multiaddr,
893 const ip_addr_t *netif_addr,
894 enum netconn_igmp join_or_leave)
896 API_MSG_VAR_DECLARE(msg);
899 LWIP_ERROR(
"netconn_join_leave_group: invalid conn", (conn != NULL),
return ERR_ARG;);
901 API_MSG_VAR_ALLOC(msg);
905 if (multiaddr == NULL) {
906 multiaddr = IP4_ADDR_ANY;
908 if (netif_addr == NULL) {
909 netif_addr = IP4_ADDR_ANY;
913 API_MSG_VAR_REF(msg).conn = conn;
914 API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
915 API_MSG_VAR_REF(msg).msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr);
916 API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave;
917 err = netconn_apimsg(lwip_netconn_do_join_leave_group, &API_MSG_VAR_REF(msg));
918 API_MSG_VAR_FREE(msg);
937#if LWIP_IPV4 && LWIP_IPV6
939netconn_gethostbyname_addrtype(
const char *name, ip_addr_t *addr, u8_t dns_addrtype)
942netconn_gethostbyname(
const char *name, ip_addr_t *addr)
945 API_VAR_DECLARE(
struct dns_api_msg, msg);
946#if !LWIP_MPU_COMPATIBLE
952 LWIP_ERROR(
"netconn_gethostbyname: invalid name", (name != NULL),
return ERR_ARG;);
953 LWIP_ERROR(
"netconn_gethostbyname: invalid addr", (addr != NULL),
return ERR_ARG;);
954#if LWIP_MPU_COMPATIBLE
960 API_VAR_ALLOC(
struct dns_api_msg, MEMP_DNS_API_MSG, msg,
ERR_MEM);
961#if LWIP_MPU_COMPATIBLE
967 API_VAR_REF(msg).addr = API_VAR_REF(addr);
968 API_VAR_REF(msg).name = name;
970#if LWIP_IPV4 && LWIP_IPV6
971 API_VAR_REF(msg).dns_addrtype = dns_addrtype;
973#if LWIP_NETCONN_SEM_PER_THREAD
974 API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET();
976 err =
sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0);
978 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
983 cberr =
tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg));
985#if !LWIP_NETCONN_SEM_PER_THREAD
988 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
992#if !LWIP_NETCONN_SEM_PER_THREAD
996#if LWIP_MPU_COMPATIBLE
1001 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
1006#if LWIP_NETCONN_SEM_PER_THREAD
1008netconn_thread_init(
void)
1010 sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
1013 LWIP_NETCONN_THREAD_SEM_ALLOC();
1014 LWIP_ASSERT(
"LWIP_NETCONN_THREAD_SEM_ALLOC() failed",
sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
1019netconn_thread_cleanup(
void)
1021 sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
1024 LWIP_NETCONN_THREAD_SEM_FREE();
#define LWIP_DEBUGF(debug, message)
#define LWIP_UNUSED_ARG(x)
#define DNS_MAX_NAME_LENGTH
#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
int sys_mbox_valid(sys_mbox_t *mbox)
void sys_mbox_free(sys_mbox_t *mbox)
int sys_sem_valid(sys_sem_t *sem)
void sys_sem_free(sys_sem_t *sem)
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
#define sys_sem_wait(sem)
err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
void(* tcpip_callback_fn)(void *ctx)
#define tcpip_callback(f, ctx)