boot_serial; improve platform abstraction.
Pass function pointers to do reads/writes from uart.

Signed-off-by: Marko Kiiskila <marko@runtime.io>
diff --git a/boot/boot_serial/include/boot_serial/boot_serial.h b/boot/boot_serial/include/boot_serial/boot_serial.h
index b93c28f..3393213 100644
--- a/boot/boot_serial/include/boot_serial/boot_serial.h
+++ b/boot/boot_serial/include/boot_serial/boot_serial.h
@@ -24,12 +24,24 @@
 extern "C" {
 #endif
 
-/*
- * Start processing newtmgr commands for uploading image0 over serial.
- *
- * Open console serial port and wait for download command.
+/**
+ * Function pointers to read/write data from uart.
+ * read returns the number of bytes read, str points to buffer to fill,
+ *  cnt is the number of bytes to fill within buffer, *newline will be
+ *  set if newline is the last character.
+ * write takes as it's arguments pointer to data to write, and the count
+ *  of bytes.
  */
-void boot_serial_start(int max_input);
+struct boot_uart_funcs {
+    int (*read)(char *str, int cnt, int *newline);
+    void (*write)(const char *ptr, int cnt);
+};
+
+/**
+ * Start processing newtmgr commands for uploading image0 over serial.
+ * Assumes serial port is open and waits for download command.
+ */
+void boot_serial_start(const struct boot_uart_funcs *f);
 
 #ifdef __cplusplus
 }
diff --git a/boot/boot_serial/pkg.yml b/boot/boot_serial/pkg.yml
index 69d90e1..f1431c7 100644
--- a/boot/boot_serial/pkg.yml
+++ b/boot/boot_serial/pkg.yml
@@ -29,7 +29,6 @@
     - "@apache-mynewt-core/hw/hal"
     - "@apache-mynewt-core/kernel/os"
     - "@apache-mynewt-core/encoding/tinycbor"
-    - "@apache-mynewt-core/encoding/cborattr"
     - "@apache-mynewt-core/encoding/base64"
     - "@mcuboot/boot/mynewt/flash_map_backend"
     - "@mcuboot/boot/mynewt/boot_uart"
diff --git a/boot/boot_serial/src/CMakeLists.txt b/boot/boot_serial/src/CMakeLists.txt
index 7b0bf99..20feaa1 100644
--- a/boot/boot_serial/src/CMakeLists.txt
+++ b/boot/boot_serial/src/CMakeLists.txt
@@ -2,7 +2,4 @@
 
 zephyr_include_directories(${BOOT_DIR}/bootutil/include)
 
-zephyr_include_directories($ENV{ZEPHYR_BASE}/ext/lib/mgmt/mcumgr/cborattr/include)
-zephyr_sources($ENV{ZEPHYR_BASE}/ext/lib/mgmt/mcumgr/cborattr/src/cborattr.c)
-
 zephyr_link_libraries_ifdef(CONFIG_TINYCBOR TINYCBOR)
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index e67e68d..9b63043 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -32,7 +32,6 @@
 #include <misc/__assert.h>
 #include <flash.h>
 #include <crc16.h>
-#include <serial_adapter/serial_adapter.h>
 #include <base64.h>
 #include <cbor.h>
 #else
@@ -40,18 +39,12 @@
 #include <hal/hal_system.h>
 #include <os/endian.h>
 #include <os/os_cputime.h>
-#include <boot_uart/boot_uart.h>
 #include <crc/crc16.h>
 #include <base64/base64.h>
 #include <tinycbor/cbor.h>
 #include <tinycbor/cbor_buf_reader.h>
-
-#define console_write boot_uart_write
-#define console_read  boot_uart_read
-
 #endif /* __ZEPHYR__ */
 
-#include <cborattr/cborattr.h>
 #include <flash_map_backend/flash_map_backend.h>
 #include <hal/hal_flash.h>
 #include <os/os.h>
@@ -62,6 +55,7 @@
 #include "boot_serial/boot_serial.h"
 #include "boot_serial_priv.h"
 
+#define BOOT_SERIAL_INPUT_MAX   512
 #define BOOT_SERIAL_OUT_MAX	80
 
 #ifdef __ZEPHYR__
@@ -74,10 +68,10 @@
 #define ntohs(x) sys_be16_to_cpu(x)
 #define htons(x) sys_cpu_to_be16(x)
 
-static char in_buf[CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1];
-static char dec_buf[CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1];
 #endif
-
+static char in_buf[BOOT_SERIAL_INPUT_MAX + 1];
+static char dec_buf[BOOT_SERIAL_INPUT_MAX + 1];
+static const struct boot_uart_funcs *boot_uf;
 static uint32_t curr_off;
 static uint32_t img_size;
 static struct nmgr_hdr *bs_hdr;
@@ -484,7 +478,7 @@
 #endif
     crc = htons(crc);
 
-    console_write(pkt_start, sizeof(pkt_start));
+    boot_uf->write(pkt_start, sizeof(pkt_start));
 
     totlen = len + sizeof(*bs_hdr) + sizeof(crc);
     totlen = htons(totlen);
@@ -504,8 +498,8 @@
 #else
     totlen = base64_encode(buf, totlen, encoded_buf, 1);
 #endif
-    console_write(encoded_buf, totlen);
-    console_write("\n\r", 2);
+    boot_uf->write(encoded_buf, totlen);
+    boot_uf->write("\n\r", 2);
     BOOT_LOG_INF("TX");
 }
 
@@ -561,7 +555,7 @@
  * serial port.
  */
 void
-boot_serial_start(int max_input)
+boot_serial_start(const struct boot_uart_funcs *f)
 {
     int rc;
     int off;
@@ -569,24 +563,16 @@
     char *dec;
     int dec_off;
     int full_line;
+    int max_input;
 
-#ifdef __ZEPHYR__
-    rc = boot_console_init();
+    boot_uf = f;
     buf = in_buf;
     dec = dec_buf;
-    assert(max_input <= sizeof(in_buf) && max_input <= sizeof(dec_buf));
-#else
-    rc = boot_uart_open();
-    assert(rc == 0);
-
-    buf = os_malloc(max_input);
-    dec = os_malloc(max_input);
-    assert(buf && dec);
-#endif
+    max_input = sizeof(in_buf);
 
     off = 0;
     while (1) {
-        rc = console_read(buf + off, max_input - off, &full_line);
+        rc = f->read(buf + off, sizeof(in_buf) - off, &full_line);
         if (rc <= 0 && !full_line) {
             continue;
         }
diff --git a/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h b/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
index 29b6d00..6d69668 100644
--- a/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
+++ b/boot/mynewt/boot_uart/include/boot_uart/boot_uart.h
@@ -23,6 +23,6 @@
 int boot_uart_open(void);
 void boot_uart_close(void);
 int boot_uart_read(char *str, int cnt, int *newline);
-void boot_uart_write(char *ptr, int cnt);
+void boot_uart_write(const char *ptr, int cnt);
 
 #endif /* _BOOT_UART_H_ */
diff --git a/boot/mynewt/boot_uart/src/boot_uart.c b/boot/mynewt/boot_uart/src/boot_uart.c
index 5e2fbbe..ad6d772 100644
--- a/boot/mynewt/boot_uart/src/boot_uart.c
+++ b/boot/mynewt/boot_uart/src/boot_uart.c
@@ -150,14 +150,14 @@
  * sends, so we can drop the outgoing data here.
  */
 void
-boot_uart_write(char *ptr, int cnt)
+boot_uart_write(const char *ptr, int cnt)
 {
 }
 
 #else
 
 void
-boot_uart_write(char *ptr, int cnt)
+boot_uart_write(const char *ptr, int cnt)
 {
     int sr;
 
diff --git a/boot/mynewt/src/main.c b/boot/mynewt/src/main.c
index b504896..7521e3b 100755
--- a/boot/mynewt/src/main.c
+++ b/boot/mynewt/src/main.c
@@ -31,13 +31,14 @@
 #include <hal/hal_bsp.h>
 #include <hal/hal_system.h>
 #include <hal/hal_flash.h>
+#include <hal/hal_watchdog.h>
 #include <sysinit/sysinit.h>
 #ifdef MCUBOOT_SERIAL
 #include <hal/hal_gpio.h>
 #include <hal/hal_nvreg.h>
 #include <boot_serial/boot_serial.h>
 #endif
-#if defined(MCUBOOT_SERIAL) && MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
+#if defined(MCUBOOT_SERIAL)
 #include <boot_uart/boot_uart.h>
 #endif
 #include <console/console.h>
@@ -45,26 +46,42 @@
 #include "bootutil/bootutil.h"
 #include "bootutil/bootutil_log.h"
 
-#define BOOT_AREA_DESC_MAX    (256)
-#define AREA_DESC_MAX         (BOOT_AREA_DESC_MAX)
-
-#ifdef MCUBOOT_SERIAL
+#if defined(MCUBOOT_SERIAL)
+#define BOOT_SERIAL_REPORT_DUR  \
+    (MYNEWT_VAL(OS_CPUTIME_FREQ) / MYNEWT_VAL(BOOT_SERIAL_REPORT_FREQ))
 #define BOOT_SERIAL_INPUT_MAX (512)
-#endif
 
-/*
- * Temporary flash_device_base() implementation.
- *
- * TODO: remove this when mynewt needs to support flash_device_base()
- * for devices with nonzero base addresses.
- */
-int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+static int boot_read(char *str, int cnt, int *newline);
+static const struct boot_uart_funcs boot_uart_funcs = {
+    .read = boot_read,
+    .write = boot_uart_write
+};
+
+static int
+boot_read(char *str, int cnt, int *newline)
 {
-    *ret = 0;
-    return 0;
+#if MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN) != -1
+    static uint32_t tick = 0;
+
+    if (tick == 0) {
+        /*
+         * Configure GPIO line as output. This is a pin we toggle at the
+         * given frequency.
+         */
+        hal_gpio_init_out(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN), 0);
+        tick = os_cputime_get32();
+    } else {
+        if (os_cputime_get32() - tick > BOOT_SERIAL_REPORT_DUR) {
+            hal_gpio_toggle(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN));
+            tick = os_cputime_get32();
+        }
+    }
+#endif
+    hal_watchdog_tickle();
+
+    return boot_uart_read(str, cnt, newline);
 }
 
-#ifdef MCUBOOT_SERIAL
 #if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
 
 /** Don't include null-terminator in comparison. */
@@ -93,14 +110,14 @@
         MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) /
         (1000.0 / MYNEWT_VAL(OS_CPUTIME_FREQ));
 
-    rc = boot_serial_uart_open();
+    rc = boot_uart_open();
     assert(rc == 0);
 
     start_tick = os_cputime_get32();
 
     while (1) {
         /* Read a single character from the UART. */
-        rc = boot_serial_uart_read(&ch, 1, &newline);
+        rc = boot_uart_read(&ch, 1, &newline);
         if (rc > 0) {
             /* Eliminate the oldest character in the buffer to make room for
              * the new one.
@@ -115,14 +132,14 @@
                         MYNEWT_VAL(BOOT_SERIAL_DETECT_STRING),
                         BOOT_SERIAL_DETECT_STRING_LEN);
             if (rc == 0) {
-                boot_serial_uart_close();
+                boot_uart_close();
                 return true;
             }
         }
 
         /* Abort the listen on timeout. */
         if (os_cputime_get32() >= start_tick + timeout_dur) {
-            boot_serial_uart_close();
+            boot_uart_close();
             return false;
         }
     }
@@ -141,11 +158,8 @@
         MYNEWT_VAL(BOOT_SERIAL_NVREG_MAGIC)) {
 
         hal_nvreg_write(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX), 0);
-
-        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
-        assert(0);
+        goto serial_boot;
     }
-
 #endif
 
     /*
@@ -157,8 +171,7 @@
                      MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_CFG));
     if (hal_gpio_read(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN)) ==
                       MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_VAL)) {
-        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
-        assert(0);
+        goto serial_boot;
     }
 #endif
 
@@ -168,13 +181,29 @@
      */
 #if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
     if (serial_detect_uart_string()) {
-        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
-        assert(0);
+        goto serial_boot;
     }
 #endif
+    return;
+serial_boot:
+    boot_uart_open();
+    boot_serial_start(&boot_uart_funcs);
+    assert(0);
 }
 #endif
 
+/*
+ * Temporary flash_device_base() implementation.
+ *
+ * TODO: remove this when mynewt needs to support flash_device_base()
+ * for devices with nonzero base addresses.
+ */
+int flash_device_base(uint8_t fd_id, uintptr_t *ret)
+{
+    *ret = 0;
+    return 0;
+}
+
 int
 main(void)
 {
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index 07ca387..b8887e0 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -29,7 +29,13 @@
 #include "flash_map_backend/flash_map_backend.h"
 
 #ifdef CONFIG_MCUBOOT_SERIAL
-#include <boot_serial/boot_serial.h>
+#include "boot_serial/boot_serial.h"
+#include "serial_adapter/serial_adapter.h"
+
+const struct boot_uart_funcs boot_funcs = {
+    .read = console_read,
+    .write = console_write
+};
 #endif
 
 struct device *boot_flash_device;
@@ -121,7 +127,9 @@
 
     if (detect_value == CONFIG_BOOT_SERIAL_DETECT_PIN_VAL) {
         BOOT_LOG_INF("Enter the serial recovery mode");
-        boot_serial_start(CONFIG_BOOT_MAX_LINE_INPUT_LEN + 1);
+        rc = boot_console_init();
+        __ASSERT(rc, "Error initializing boot console.\n");
+        boot_serial_start(&boot_funcs);
         __ASSERT(0, "Bootloader serial process was terminated unexpectedly.\n");
     }
 #endif