diff --git a/src/api/api_lib.c b/src/api/api_lib.c index dee21baf..0e0ac6fc 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -281,6 +281,32 @@ netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port) return err; } +/** + * @ingroup netconn_common + * Bind a netconn to a specific interface and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param if_idx the local interface index to bind the netconn to + * @return ERR_OK if bound, any other err_t on failure + */ +err_t +netconn_bind_if(struct netconn *conn, u8_t if_idx) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_bind_if: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).conn = conn; + API_MSG_VAR_REF(msg).msg.bc.if_idx = if_idx; + err = netconn_apimsg(lwip_netconn_do_bind_if, &API_MSG_VAR_REF(msg)); + API_MSG_VAR_FREE(msg); + + return err; +} + /** * @ingroup netconn_common * Connect a netconn to a specific remote IP address and port. diff --git a/src/api/api_msg.c b/src/api/api_msg.c index ed1c5821..15b2e2a6 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -1194,6 +1194,50 @@ lwip_netconn_do_bind(void *m) msg->err = err; TCPIP_APIMSG_ACK(msg); } +/** + * Bind a pcb contained in a netconn to an interface + * Called from netconn_bind_if. + * + * @param m the api_msg_msg pointing to the connection and containing + * the IP address and port to bind to + */ +void +lwip_netconn_do_bind_if(void *m) +{ + struct netif* netif; + struct api_msg *msg = (struct api_msg*)m; + err_t err; + + netif = netif_get_by_index(msg->msg.bc.if_idx); + + if ((netif != NULL) && (msg->conn->pcb.tcp != NULL)) { + err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + raw_bind_netif(msg->conn->pcb.raw, netif); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + udp_bind_netif(msg->conn->pcb.udp, netif); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + tcp_bind_netif(msg->conn->pcb.tcp, netif); + break; +#endif /* LWIP_TCP */ + default: + err = ERR_VAL; + break; + } + } else { + err = ERR_VAL; + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); +} #if LWIP_TCP /** diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 68c14373..ac2ad5ed 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -312,6 +312,7 @@ err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, #define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port); +err_t netconn_bind_if(struct netconn *conn, u8_t if_idx); err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port); err_t netconn_disconnect (struct netconn *conn); err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); diff --git a/src/include/lwip/priv/api_msg.h b/src/include/lwip/priv/api_msg.h index c64bbb65..d1bc009f 100644 --- a/src/include/lwip/priv/api_msg.h +++ b/src/include/lwip/priv/api_msg.h @@ -94,6 +94,7 @@ struct api_msg { struct { API_MSG_M_DEF_C(ip_addr_t, ipaddr); u16_t port; + u8_t if_idx; } bc; /** used for lwip_netconn_do_getaddr */ struct { @@ -189,6 +190,7 @@ int lwip_netconn_is_err_msg(void *msg, err_t *err); void lwip_netconn_do_newconn (void *m); void lwip_netconn_do_delconn (void *m); void lwip_netconn_do_bind (void *m); +void lwip_netconn_do_bind_if (void *m); void lwip_netconn_do_connect (void *m); void lwip_netconn_do_disconnect (void *m); void lwip_netconn_do_listen (void *m);