From f6f124a35ffc432d6b34820035080d7dfa86da57 Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Mon, 13 Mar 2017 13:32:01 -0600 Subject: [PATCH] uart_ow: prevent possible infinite loop in _ow_read_byte() With a broken device, or a broken interface circuit, it is possible for _ow_read_byte() to spin forever. This patch arranges for it to timeout after 5 seconds if it cannot read a valid byte from the UART. Signed-off-by: Jon Trulson Signed-off-by: Brendan Le Foll --- src/uart_ow/uart_ow.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/uart_ow/uart_ow.c b/src/uart_ow/uart_ow.c index 2b754d5..2d58354 100644 --- a/src/uart_ow/uart_ow.c +++ b/src/uart_ow/uart_ow.c @@ -35,7 +35,7 @@ #include #include #include - +#include #include "uart.h" #include "uart_ow.h" #include "mraa_internal.h" @@ -44,10 +44,21 @@ static mraa_result_t _ow_read_byte(mraa_uart_ow_context dev, uint8_t *ch) { - while (!mraa_uart_read(dev->uart, (char*) ch, 1)) - ; + time_t thetime = time(NULL); + // add 5 seconds -- our crude timeout + thetime += 5; - return MRAA_SUCCESS; + int rv; + do { + rv = mraa_uart_read(dev->uart, (char*) ch, 1); + } while (rv == 0 && (time(NULL) < thetime)); + + if (rv == 0) { + return MRAA_ERROR_NO_DATA_AVAILABLE; // we timed out + } + else { + return MRAA_SUCCESS; + } } // low-level write byte @@ -402,7 +413,9 @@ mraa_uart_ow_reset(mraa_uart_ow_context dev) /* pull the data line low */ _ow_write_byte(dev, 0xf0); - _ow_read_byte(dev, &rv); + if (_ow_read_byte(dev, &rv) != MRAA_SUCCESS) { + return MRAA_ERROR_NO_DATA_AVAILABLE; + } /* back up to high speed for normal data transmissions */ if (_ow_set_speed(dev, 1) != MRAA_SUCCESS) {