/** * Bind a pcb contained in a netconn * Called from netconn_bind. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to bind to */ void lwip_netconn_do_bind(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_VAL; if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Connect a pcb contained inside a netconn * Called from netconn_connect. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to connect to */ void lwip_netconn_do_connect(struct api_msg_msg *msg) { if (msg->conn->pcb.tcp == NULL) { /* This may happen when calling netconn_connect() a second time */ msg->err = ERR_CLSD; if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ sys_sem_signal(&msg->conn->op_completed); return; } } else { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: /* Prevent connect while doing any other action. */ if (msg->conn->state != NETCONN_NONE) { msg->err = ERR_ISCONN; } else { setup_tcp(msg->conn); msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port, lwip_netconn_do_connected); if (msg->err == ERR_OK) { u8_t non_blocking = netconn_is_nonblocking(msg->conn); msg->conn->state = NETCONN_CONNECT; SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); if (non_blocking) { msg->err = ERR_INPROGRESS; } else { msg->conn->current_msg = msg; /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), * when the connection is established! */ return; } } } /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ sys_sem_signal(&msg->conn->op_completed); return; #endif /* LWIP_TCP */ default: LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); break; } } /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), so use TCPIP_APIMSG_ACK() here. */ TCPIP_APIMSG_ACK(msg); }
/** * Call netif_set_addr() inside the tcpip_thread context. */ static err_t netifapi_do_netif_set_addr(struct tcpip_api_call_data *m) { struct netifapi_msg *msg = (struct netifapi_msg*)m; netif_set_addr( msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw)); return ERR_OK; }
/** * Execute a DNS query * Called from netconn_gethostbyname * * @param arg the dns_api_msg pointing to the query */ void lwip_netconn_do_gethostbyname(void *arg) { struct dns_api_msg *msg = (struct dns_api_msg*)arg; API_EXPR_DEREF(msg->err) = dns_gethostbyname(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg); if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { /* on error or immediate success, wake up the application * task waiting in netconn_gethostbyname */ sys_sem_signal(API_EXPR_REF(msg->sem)); } }
/** * Call netif_set_addr() inside the tcpip_thread context. */ static void netifapi_do_netif_set_addr(void *m) { struct netifapi_msg *msg = (struct netifapi_msg*)m; netif_set_addr( msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw)); msg->err = ERR_OK; TCPIP_NETIFAPI_ACK(msg); }
/** * Call netif_set_addr() inside the tcpip_thread context. */ static err_t netifapi_do_netif_set_addr(struct tcpip_api_call_data *m) { /* cast through void* to silence alignment warnings. * We know it works because the structs have been instantiated as struct netifapi_msg */ struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; netif_set_addr( msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw)); return ERR_OK; }
/** * Call netif_add() inside the tcpip_thread context. */ static err_t netifapi_do_netif_add(struct tcpip_api_call_data *m) { struct netifapi_msg *msg = (struct netifapi_msg*)m; if (!netif_add( msg->netif, #if LWIP_IPV4 API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw), #endif /* LWIP_IPV4 */ msg->msg.add.state, msg->msg.add.init, msg->msg.add.input)) { return ERR_IF; } else { return ERR_OK; } }
/** * Call netif_add() inside the tcpip_thread context. */ static void netifapi_do_netif_add(void *m) { struct netifapi_msg *msg = (struct netifapi_msg*)m; if (!netif_add( msg->netif, #if LWIP_IPV4 API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw), #endif /* LWIP_IPV4 */ msg->msg.add.state, msg->msg.add.init, msg->msg.add.input)) { msg->err = ERR_IF; } else { msg->err = ERR_OK; } TCPIP_NETIFAPI_ACK(msg); }
/** * Call netif_add() inside the tcpip_thread context. */ static err_t netifapi_do_netif_add(struct tcpip_api_call_data *m) { /* cast through void* to silence alignment warnings. * We know it works because the structs have been instantiated as struct netifapi_msg */ struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; if (!netif_add( msg->netif, #if LWIP_IPV4 API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw), #endif /* LWIP_IPV4 */ msg->msg.add.state, msg->msg.add.init, msg->msg.add.input)) { return ERR_IF; } else { return ERR_OK; } }
/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP #if LWIP_IPV6 && LWIP_IPV6_MLD if (PCB_ISIPV6(msg->conn->pcb.udp)) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } } else #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ { #if LWIP_IGMP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } #endif /* LWIP_IGMP */ } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ } } else { msg->err = ERR_CONN; } } TCPIP_APIMSG_ACK(msg); }
/** * Callback function that is called when DNS name is resolved * (or on timeout). A waiting application thread is waked up by * signaling the semaphore. */ static void lwip_netconn_do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { struct dns_api_msg *msg = (struct dns_api_msg*)arg; /* we trust the internal implementation to be correct :-) */ LWIP_UNUSED_ARG(name); if (ipaddr == NULL) { /* timeout or memory error */ API_EXPR_DEREF(msg->err) = ERR_VAL; } else { /* address was resolved */ API_EXPR_DEREF(msg->err) = ERR_OK; API_EXPR_DEREF(msg->addr) = *ipaddr; } /* wake up the application task waiting in netconn_gethostbyname */ sys_sem_signal(API_EXPR_REF(msg->sem)); }
/** * Callback function that is called when DNS name is resolved * (or on timeout). A waiting application thread is waked up by * signaling the semaphore. */ static void lwip_netconn_do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { struct dns_api_msg *msg = (struct dns_api_msg*)arg; LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); LWIP_UNUSED_ARG(name); if (ipaddr == NULL) { /* timeout or memory error */ API_EXPR_DEREF(msg->err) = ERR_VAL; } else { /* address was resolved */ API_EXPR_DEREF(msg->err) = ERR_OK; API_EXPR_DEREF(msg->addr) = *ipaddr; } /* wake up the application task waiting in netconn_gethostbyname */ sys_sem_signal(API_EXPR_REF(msg->sem)); }
/** * Call pppol2tp_create() inside the tcpip_thread context. */ static err_t pppapi_do_pppol2tp_create(struct tcpip_api_call_data *m) { /* cast through void* to silence alignment warnings. * We know it works because the structs have been instantiated as struct pppapi_msg */ struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; msg->msg.ppp = pppol2tp_create(msg->msg.msg.l2tpcreate.pppif, msg->msg.msg.l2tpcreate.netif, API_EXPR_REF(msg->msg.msg.l2tpcreate.ipaddr), msg->msg.msg.l2tpcreate.port, #if PPPOL2TP_AUTH_SUPPORT msg->msg.msg.l2tpcreate.secret, msg->msg.msg.l2tpcreate.secret_len, #else /* PPPOL2TP_AUTH_SUPPORT */ NULL, 0, #endif /* PPPOL2TP_AUTH_SUPPORT */ msg->msg.msg.l2tpcreate.link_status_cb, msg->msg.msg.l2tpcreate.ctx_cb); return ERR_OK; }