mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
added nonblocking accept/recv to netconn API (task #14396) (also added netconn_recv_udp_raw_netbuf_flags() and netconn_recv_tcp_pbuf_flags() to pass socket-like flags to nonblock for one call only)
This commit is contained in:
parent
593b211d1b
commit
5c3bb19923
@ -6,6 +6,9 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2017-03-02: Simon Goldschmidt
|
||||||
|
* netconn: added nonblocking accept/recv to netconn API (task #14396)
|
||||||
|
|
||||||
2017-02-28: Simon Goldschmidt
|
2017-02-28: Simon Goldschmidt
|
||||||
* Added LWIP_SINGLE_NETIF for small targets with only one netif
|
* Added LWIP_SINGLE_NETIF for small targets with only one netif
|
||||||
|
|
||||||
|
@ -413,16 +413,25 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
|||||||
API_MSG_VAR_ALLOC(msg);
|
API_MSG_VAR_ALLOC(msg);
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
|
|
||||||
#if LWIP_SO_RCVTIMEO
|
if (netconn_is_nonblocking(conn)) {
|
||||||
if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) {
|
||||||
#if TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
API_MSG_VAR_FREE(msg);
|
API_MSG_VAR_FREE(msg);
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
return ERR_TIMEOUT;
|
return ERR_WOULDBLOCK;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#if LWIP_SO_RCVTIMEO
|
||||||
|
if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||||
|
#if TCP_LISTEN_BACKLOG
|
||||||
|
API_MSG_VAR_FREE(msg);
|
||||||
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
|
return ERR_TIMEOUT;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);
|
sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);
|
||||||
#endif /* LWIP_SO_RCVTIMEO*/
|
#endif /* LWIP_SO_RCVTIMEO*/
|
||||||
|
}
|
||||||
newconn = (struct netconn *)accept_ptr;
|
newconn = (struct netconn *)accept_ptr;
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||||
@ -467,15 +476,21 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
|||||||
/**
|
/**
|
||||||
* @ingroup netconn_common
|
* @ingroup netconn_common
|
||||||
* Receive data: actual implementation that doesn't care whether pbuf or netbuf
|
* Receive data: actual implementation that doesn't care whether pbuf or netbuf
|
||||||
* is received
|
* is received (this is internal, it's just here for describing common errors)
|
||||||
*
|
*
|
||||||
* @param conn the netconn from which to receive data
|
* @param conn the netconn from which to receive data
|
||||||
* @param new_buf pointer where a new pbuf/netbuf is stored when received data
|
* @param new_buf pointer where a new pbuf/netbuf is stored when received data
|
||||||
|
* @param apiflags flags that control function behaviour. For now only:
|
||||||
|
* - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
|
||||||
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
||||||
* memory error or another error)
|
* memory error or another error)
|
||||||
|
* ERR_CONN if not connected
|
||||||
|
* ERR_CLSD if TCP connection has been closed
|
||||||
|
* ERR_WOULDBLOCK if the netconn is nonblocking but would block to wait for data
|
||||||
|
* ERR_TIMEOUT if the netconn has a receive timeout and no data was received
|
||||||
*/
|
*/
|
||||||
static err_t
|
static err_t
|
||||||
netconn_recv_data(struct netconn *conn, void **new_buf)
|
netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||||
{
|
{
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
u16_t len;
|
u16_t len;
|
||||||
@ -520,21 +535,35 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
|
|||||||
}
|
}
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
|
|
||||||
#if LWIP_SO_RCVTIMEO
|
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK)) {
|
||||||
if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
|
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
|
||||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||||
{
|
{
|
||||||
API_MSG_VAR_FREE(msg);
|
API_MSG_VAR_FREE(msg);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
return ERR_TIMEOUT;
|
return ERR_WOULDBLOCK;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#if LWIP_SO_RCVTIMEO
|
||||||
|
if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||||
|
#if LWIP_TCP
|
||||||
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
|
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
|
||||||
|
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||||
|
{
|
||||||
|
API_MSG_VAR_FREE(msg);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_TCP */
|
||||||
|
return ERR_TIMEOUT;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
|
sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
|
||||||
#endif /* LWIP_SO_RCVTIMEO*/
|
#endif /* LWIP_SO_RCVTIMEO*/
|
||||||
|
}
|
||||||
|
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
@ -600,7 +629,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
|
|||||||
* @param conn the netconn from which to receive data
|
* @param conn the netconn from which to receive data
|
||||||
* @param new_buf pointer where a new pbuf is stored when received data
|
* @param new_buf pointer where a new pbuf is stored when received data
|
||||||
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
||||||
* memory error or another error)
|
* memory error or another error, @see netconn_recv_data)
|
||||||
* ERR_ARG if conn is not a TCP netconn
|
* ERR_ARG if conn is not a TCP netconn
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
@ -609,7 +638,28 @@ netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
|
|||||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
||||||
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||||
|
|
||||||
return netconn_recv_data(conn, (void **)new_buf);
|
return netconn_recv_data(conn, (void **)new_buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup netconn_tcp
|
||||||
|
* Receive data (in form of a pbuf) from a TCP netconn
|
||||||
|
*
|
||||||
|
* @param conn the netconn from which to receive data
|
||||||
|
* @param new_buf pointer where a new pbuf is stored when received data
|
||||||
|
* @param apiflags flags that control function behaviour. For now only:
|
||||||
|
* - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
|
||||||
|
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
||||||
|
* memory error or another error, @see netconn_recv_data)
|
||||||
|
* ERR_ARG if conn is not a TCP netconn
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
|
||||||
|
{
|
||||||
|
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
||||||
|
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||||
|
|
||||||
|
return netconn_recv_data(conn, (void **)new_buf, apiflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -627,7 +677,27 @@ netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
|
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
|
||||||
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
|
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
|
||||||
|
|
||||||
return netconn_recv_data(conn, (void **)new_buf);
|
return netconn_recv_data(conn, (void **)new_buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive data (in form of a netbuf) from a UDP or RAW netconn
|
||||||
|
*
|
||||||
|
* @param conn the netconn from which to receive data
|
||||||
|
* @param new_buf pointer where a new netbuf is stored when received data
|
||||||
|
* @param apiflags flags that control function behaviour. For now only:
|
||||||
|
* - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data
|
||||||
|
* @return ERR_OK if data has been received, an error code otherwise (timeout,
|
||||||
|
* memory error or another error)
|
||||||
|
* ERR_ARG if conn is not a UDP/RAW netconn
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags)
|
||||||
|
{
|
||||||
|
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
|
||||||
|
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
|
||||||
|
|
||||||
|
return netconn_recv_data(conn, (void **)new_buf, apiflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -664,7 +734,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = netconn_recv_data(conn, (void **)&p);
|
err = netconn_recv_data(conn, (void **)&p, 0);
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
memp_free(MEMP_NETBUF, buf);
|
memp_free(MEMP_NETBUF, buf);
|
||||||
return err;
|
return err;
|
||||||
@ -685,7 +755,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
|
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
|
||||||
{
|
{
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
return netconn_recv_data(conn, (void **)new_buf);
|
return netconn_recv_data(conn, (void **)new_buf, 0);
|
||||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,9 @@ err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
|
|||||||
err_t netconn_accept(struct netconn *conn, struct netconn **new_conn);
|
err_t netconn_accept(struct netconn *conn, struct netconn **new_conn);
|
||||||
err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf);
|
err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf);
|
||||||
err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf);
|
err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf);
|
||||||
|
err_t netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags);
|
||||||
err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
|
err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
|
||||||
|
err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags);
|
||||||
err_t netconn_sendto(struct netconn *conn, struct netbuf *buf,
|
err_t netconn_sendto(struct netconn *conn, struct netbuf *buf,
|
||||||
const ip_addr_t *addr, u16_t port);
|
const ip_addr_t *addr, u16_t port);
|
||||||
err_t netconn_send(struct netconn *conn, struct netbuf *buf);
|
err_t netconn_send(struct netconn *conn, struct netbuf *buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user