Add polling function for network contexts
This commit adds a function `mbedtls_net_poll` to the network module
allowing to check if a network context is available for read or write.
diff --git a/library/error.c b/library/error.c
index db42381..8977cc4 100644
--- a/library/error.c
+++ b/library/error.c
@@ -654,6 +654,10 @@
mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
+ if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
+ mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
+ if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
+ mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 80be6ec..edd0844 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -434,6 +434,58 @@
}
/*
+ * Check if data is available on the socket
+ */
+
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
+{
+ int ret;
+ struct timeval tv;
+
+ fd_set read_fds;
+ fd_set write_fds;
+
+ int fd = ctx->fd;
+
+ if( fd < 0 )
+ return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+ FD_ZERO( &read_fds );
+ if( rw & MBEDTLS_NET_POLL_READ )
+ {
+ rw &= ~MBEDTLS_NET_POLL_READ;
+ FD_SET( fd, &read_fds );
+ }
+
+ FD_ZERO( &write_fds );
+ if( rw & MBEDTLS_NET_POLL_WRITE )
+ {
+ rw &= ~MBEDTLS_NET_POLL_WRITE;
+ FD_SET( fd, &write_fds );
+ }
+
+ if( rw != 0 )
+ return( MBEDTLS_ERR_NET_BAD_INPUT_DATA );
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+ ret = select( fd + 1, &read_fds, &write_fds, NULL,
+ timeout == (uint32_t) -1u ? NULL : &tv );
+
+ if( ret < 0 )
+ return( MBEDTLS_ERR_NET_POLL_FAILED );
+
+ ret = 0;
+ if( FD_ISSET( fd, &read_fds ) )
+ ret |= MBEDTLS_NET_POLL_READ;
+ if( FD_ISSET( fd, &write_fds ) )
+ ret |= MBEDTLS_NET_POLL_WRITE;
+
+ return( ret );
+}
+
+/*
* Portable usleep helper
*/
void mbedtls_net_usleep( unsigned long usec )
@@ -492,8 +544,8 @@
/*
* Read at most 'len' characters, blocking for at most 'timeout' ms
*/
-int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
- uint32_t timeout )
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
+ size_t len, uint32_t timeout )
{
int ret;
struct timeval tv;