boot_serial: zephyr: Add optional timeout to enter serial recovery

This PR adds the possibility to only enter the bootloader's
serial recovery mode when a mcumgr command is received within a
given timeout.

Signed-off-by: Wouter Cappelle <wouter.cappelle@crodeon.com>
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index 0d32431..b3a5ac7 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -618,6 +618,21 @@
 	  encryption mechanism used in this case is ECIES using primitives
 	  described under "ECIES-P256 encryption" in docs/encrypted_images.md.
 
+config BOOT_SERIAL_WAIT_FOR_DFU
+	bool "Wait for a prescribed duration to see if DFU is invoked by receiving a mcumgr comand"
+	depends on BOOT_SERIAL_UART
+	help
+	  If y, MCUboot waits for a prescribed duration of time to allow
+	  for DFU to be invoked. The serial recovery can be entered by receiving any
+	  mcumgr command.
+
+config BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT
+	int "Duration to wait for the serial DFU timeout in ms"
+	default 500
+	depends on BOOT_SERIAL_WAIT_FOR_DFU
+	help
+	  timeout in ms for MCUboot to wait to allow for DFU to be invoked.
+
 endif # MCUBOOT_SERIAL
 
 config BOOT_INTR_VEC_RELOC
diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
index 2539b5f..26d2bcb 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -189,6 +189,10 @@
 #define MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
 #endif
 
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+#define MCUBOOT_SERIAL_WAIT_FOR_DFU
+#endif
+
 /*
  * The option enables code, currently in boot_serial, that attempts
  * to erase flash progressively, as update fragments are received,
diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c
index cc726c5..cee7505 100644
--- a/boot/zephyr/main.c
+++ b/boot/zephyr/main.c
@@ -506,7 +506,28 @@
     }
 #endif
 
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+    /* Initialize the boot console, so we can already fill up our buffers while
+     * waiting for the boot image check to finish. This image check, can take
+     * some time, so it's better to reuse thistime to already receive the
+     * initial mcumgr command(s) into our buffers
+     */
+    rc = boot_console_init();
+    int timeout_in_ms = CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT;
+    uint32_t start = k_uptime_get_32();
+#endif
+
     FIH_CALL(boot_go, fih_rc, &rsp);
+
+#ifdef CONFIG_BOOT_SERIAL_WAIT_FOR_DFU
+    timeout_in_ms -= (k_uptime_get_32() - start);
+    if( timeout_in_ms <= 0 ) {
+        /* at least one check if time was expired */
+        timeout_in_ms = 1;
+    }
+   boot_serial_check_start(&boot_funcs,timeout_in_ms);
+#endif
+
     if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
         BOOT_LOG_ERR("Unable to find bootable image");
         FIH_PANIC;