/* 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)
/* 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 ret;
    struct timeval tv;
    fd_set read_fds;
    int fd = ((mbedtls_net_context *) ctx)->fd;
    if( fd < 0 )
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
    FD_ZERO( &read_fds );
    FD_SET( fd, &read_fds );
    tv.tv_sec  = timeout / 1000;
    tv.tv_usec = ( timeout % 1000 ) * 1000;
    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
    if( ret == 0 )
        return( MBEDTLS_ERR_SSL_TIMEOUT );
    if( ret < 0 )
    {
        if( errno == EINTR )
            return( MBEDTLS_ERR_SSL_WANT_READ );
        return( MBEDTLS_ERR_NET_RECV_FAILED );
    }
    return( mbedtls_net_recv( ctx, buf, len ) );
}