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) 99 static 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();
142 netconn_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);
185 netconn_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);
231 netconn_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);
269 netconn_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);
313 netconn_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);
345 netconn_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);
370 netconn_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);
407 netconn_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);
495 netconn_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);
622 netconn_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);
640 netconn_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);
702 netconn_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);
721 netconn_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);
754 netconn_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);
821 netconn_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);
857 netconn_close(
struct netconn *conn)
860 return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
873 netconn_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) 891 netconn_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 939 netconn_gethostbyname_addrtype(
const char *name, ip_addr_t *addr, u8_t dns_addrtype)
942 netconn_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 1008 netconn_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()));
1019 netconn_thread_cleanup(
void)
1021 sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
1024 LWIP_NETCONN_THREAD_SEM_FREE();
void sys_sem_free(sys_sem_t *sem)
#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT
void(* tcpip_callback_fn)(void *ctx)
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
void memp_free(memp_t type, void *mem)
#define sys_sem_wait(sem)
void sys_mbox_free(sys_mbox_t *mbox)
int sys_mbox_valid(sys_mbox_t *mbox)
#define tcpip_callback(f, ctx)
#define DNS_MAX_NAME_LENGTH
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
#define LWIP_DEBUGF(debug, message)
#define LWIP_UNUSED_ARG(x)
void * memp_malloc(memp_t type)
int sys_sem_valid(sys_sem_t *sem)