From 9c49134d613c7e3854b6a0242fda9362e66793c1 Mon Sep 17 00:00:00 2001
From: Johan Kanflo <johan.kanflo@bitfuse.net>
Date: Thu, 7 Apr 2016 20:29:28 +0200
Subject: [PATCH] Updated rboot to #75ca33b including the flash write bug.

---
 examples/ota_basic/ota_basic.c                |   6 +-
 extras/rboot-ota/ota-tftp.c                   |   5 +-
 extras/rboot-ota/rboot-api.c                  | 214 ++++++++++++++++++
 extras/rboot-ota/rboot-api.h                  | 136 +++++++++++
 .../{rboot-ota.c => rboot-integration.c}      |  72 +-----
 extras/rboot-ota/rboot-integration.h          |  34 +++
 extras/rboot-ota/rboot-ota.h                  |  55 -----
 extras/rboot-ota/rboot.h                      | 111 +++++++++
 extras/rboot-ota/readme.txt                   |   2 +-
 9 files changed, 505 insertions(+), 130 deletions(-)
 create mode 100644 extras/rboot-ota/rboot-api.c
 create mode 100644 extras/rboot-ota/rboot-api.h
 rename extras/rboot-ota/{rboot-ota.c => rboot-integration.c} (69%)
 create mode 100644 extras/rboot-ota/rboot-integration.h
 delete mode 100644 extras/rboot-ota/rboot-ota.h
 create mode 100644 extras/rboot-ota/rboot.h

diff --git a/examples/ota_basic/ota_basic.c b/examples/ota_basic/ota_basic.c
index 9189f02..d55c03a 100644
--- a/examples/ota_basic/ota_basic.c
+++ b/examples/ota_basic/ota_basic.c
@@ -14,13 +14,15 @@
 #include "ssid_config.h"
 
 #include "ota-tftp.h"
-#include "rboot-ota.h"
+#include "rboot-integration.h"
+#include "rboot.h"
+#include "rboot-api.h"
 
 void user_init(void)
 {
     uart_set_baud(0, 115200);
 
-    rboot_config_t conf = rboot_get_config();
+    rboot_config conf = rboot_get_config();
     printf("\r\n\r\nOTA Basic demo.\r\nCurrently running on flash slot %d / %d.\r\n\r\n",
            conf.current_rom, conf.count);
 
diff --git a/extras/rboot-ota/ota-tftp.c b/extras/rboot-ota/ota-tftp.c
index f8140f6..d772927 100644
--- a/extras/rboot-ota/ota-tftp.c
+++ b/extras/rboot-ota/ota-tftp.c
@@ -22,7 +22,8 @@
 #include <espressif/esp_system.h>
 
 #include "ota-tftp.h"
-#include "rboot-ota.h"
+#include "rboot.h"
+#include "rboot-api.h"
 
 #define TFTP_FIRMWARE_FILE "firmware.bin"
 #define TFTP_OCTET_MODE "octet" /* non-case-sensitive */
@@ -112,7 +113,7 @@ static void tftp_task(void *listen_port)
         netbuf_delete(netbuf);
 
         /* Find next free slot - this requires flash unmapping so best done when no packets in flight */
-        rboot_config_t conf;
+        rboot_config conf;
         conf = rboot_get_config();
         int slot = (conf.current_rom + 1) % conf.count;
 
diff --git a/extras/rboot-ota/rboot-api.c b/extras/rboot-ota/rboot-api.c
new file mode 100644
index 0000000..7fe5340
--- /dev/null
+++ b/extras/rboot-ota/rboot-api.c
@@ -0,0 +1,214 @@
+//////////////////////////////////////////////////
+// rBoot OTA and config API for ESP8266.
+// Copyright 2015 Richard A Burton
+// richardaburton@gmail.com
+// See license.txt for license terms.
+// OTA code based on SDK sample from Espressif.
+//////////////////////////////////////////////////
+
+#include <rboot.h>
+#include <string.h>
+//#include <c_types.h>
+//#include <spi_flash.h>
+
+// detect rtos sdk (not ideal method!)
+#ifdef IRAM_ATTR
+#define os_free(s)   vPortFree(s)
+#define os_malloc(s) pvPortMalloc(s)
+#else
+#include <mem.h>
+#endif
+
+#ifdef RBOOT_INTEGRATION
+#include <rboot-integration.h>
+#endif
+
+#include "rboot-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BOOT_CONFIG_CHKSUM) || defined(BOOT_RTC_ENABLED)
+// calculate checksum for block of data
+// from start up to (but excluding) end
+static uint8 calc_chksum(uint8 *start, uint8 *end) {
+	uint8 chksum = CHKSUM_INIT;
+	while(start < end) {
+		chksum ^= *start;
+		start++;
+	}
+	return chksum;
+}
+#endif
+
+// get the rboot config
+rboot_config ICACHE_FLASH_ATTR rboot_get_config(void) {
+	rboot_config conf;
+	spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)&conf, sizeof(rboot_config));
+	return conf;
+}
+
+// write the rboot config
+// preserves the contents of the rest of the sector,
+// so the rest of the sector can be used to store user data
+// updates checksum automatically (if enabled)
+bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf) {
+	uint8 *buffer;
+	buffer = (uint8*)os_malloc(SECTOR_SIZE);
+	if (!buffer) {
+		//os_printf("No ram!\r\n");
+		return false;
+	}
+	
+#ifdef BOOT_CONFIG_CHKSUM
+	conf->chksum = calc_chksum((uint8*)conf, (uint8*)&conf->chksum);
+#endif
+	
+	spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
+	memcpy(buffer, conf, sizeof(rboot_config));
+	vPortEnterCritical();
+	spi_flash_erase_sector(BOOT_CONFIG_SECTOR);
+	vPortExitCritical();
+	taskYIELD();
+	vPortEnterCritical();
+	//spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
+	spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
+	vPortExitCritical();	
+	os_free(buffer);
+	return true;
+}
+
+// get current boot rom
+uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void) {
+	rboot_config conf;
+	conf = rboot_get_config();
+	return conf.current_rom;
+}
+
+// set current boot rom
+bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom) {
+	rboot_config conf;
+	conf = rboot_get_config();
+	if (rom >= conf.count) return false;
+	conf.current_rom = rom;
+	return rboot_set_config(&conf);
+}
+
+// create the write status struct, based on supplied start address
+rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr) {
+	rboot_write_status status = {0};
+	status.start_addr = start_addr;
+	status.start_sector = start_addr / SECTOR_SIZE;
+	status.last_sector_erased = status.start_sector - 1;
+	//status.max_sector_count = 200;
+	//os_printf("init addr: 0x%08x\r\n", start_addr);
+	
+	return status;
+}
+
+// function to do the actual writing to flash
+// call repeatedly with more data (max len per write is the flash sector size (4k))
+bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len) {
+	
+	bool ret = false;
+	uint8 *buffer;
+	int32 lastsect;
+	
+	if (data == NULL || len == 0) {
+		return true;
+	}
+	
+	// get a buffer
+	buffer = (uint8 *)os_malloc(len + status->extra_count);
+	if (!buffer) {
+		//os_printf("No ram!\r\n");
+		return false;
+	}
+
+	// copy in any remaining bytes from last chunk
+	memcpy(buffer, status->extra_bytes, status->extra_count);
+	// copy in new data
+	memcpy(buffer + status->extra_count, data, len);
+
+	// calculate length, must be multiple of 4
+	// save any remaining bytes for next go
+	len += status->extra_count;
+	status->extra_count = len % 4;
+	len -= status->extra_count;
+	memcpy(status->extra_bytes, buffer + len, status->extra_count);
+
+	// check data will fit
+	//if (status->start_addr + len < (status->start_sector + status->max_sector_count) * SECTOR_SIZE) {
+
+		// erase any additional sectors needed by this chunk
+		lastsect = ((status->start_addr + len) - 1) / SECTOR_SIZE;
+		while (lastsect > status->last_sector_erased) {
+			status->last_sector_erased++;
+			spi_flash_erase_sector(status->last_sector_erased);
+		}
+
+		// write current chunk
+		//os_printf("write addr: 0x%08x, len: 0x%04x\r\n", status->start_addr, len);
+		if (spi_flash_write(status->start_addr, (uint32 *)((void*)buffer), len) == SPI_FLASH_RESULT_OK) {
+			ret = true;
+			status->start_addr += len;
+		}
+	//}
+
+	os_free(buffer);
+	return ret;
+}
+
+#ifdef BOOT_RTC_ENABLED
+bool ICACHE_FLASH_ATTR rboot_get_rtc_data(rboot_rtc_data *rtc) {
+	if (system_rtc_mem_read(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data))) {
+		return (rtc->chksum == calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum));
+	}
+	return false;
+}
+
+bool ICACHE_FLASH_ATTR rboot_set_rtc_data(rboot_rtc_data *rtc) {
+	// calculate checksum
+	rtc->chksum = calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum);
+	return system_rtc_mem_write(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data));
+}
+
+bool ICACHE_FLASH_ATTR rboot_set_temp_rom(uint8 rom) {
+	rboot_rtc_data rtc;
+	// invalid data in rtc?
+	if (!rboot_get_rtc_data(&rtc)) {
+		// set basics
+		rtc.magic = RBOOT_RTC_MAGIC;
+		rtc.last_mode = MODE_STANDARD;
+		rtc.last_rom = 0;
+	}
+	// set next boot to temp mode with specified rom
+	rtc.next_mode = MODE_TEMP_ROM;
+	rtc.temp_rom = rom;
+
+	return rboot_set_rtc_data(&rtc);
+}
+
+bool ICACHE_FLASH_ATTR rboot_get_last_boot_rom(uint8 *rom) {
+	rboot_rtc_data rtc;
+	if (rboot_get_rtc_data(&rtc)) {
+		*rom = rtc.last_rom;
+		return true;
+	}
+	return false;
+}
+
+bool ICACHE_FLASH_ATTR rboot_get_last_boot_mode(uint8 *mode) {
+	rboot_rtc_data rtc;
+	if (rboot_get_rtc_data(&rtc)) {
+		*mode = rtc.last_mode;
+		return true;
+	}
+	return false;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extras/rboot-ota/rboot-api.h b/extras/rboot-ota/rboot-api.h
new file mode 100644
index 0000000..5a39b4d
--- /dev/null
+++ b/extras/rboot-ota/rboot-api.h
@@ -0,0 +1,136 @@
+#ifndef __RBOOT_API_H__
+#define __RBOOT_API_H__
+
+/** @defgroup rboot rBoot API
+ *  @brief      rBoot for ESP8266 API allows runtime code to access the rBoot configuration.
+ *              Configuration may be read to use within the main firmware or updated to
+ *              affect next boot behavior.
+ *  @copyright  2015 Richard A Burton
+ *  @author     richardaburton@gmail.com
+ *  @author     OTA code based on SDK sample from Espressif
+ *  @license    See licence.txt for license terms.
+ *  @{
+*/
+
+#include <rboot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**	@brief  Structure defining flash write status
+ *  @note   The user application should not modify the contents of this
+ *          structure.
+ *	@see    rboot_write_flash
+*/
+typedef struct {
+	uint32 start_addr;
+	uint32 start_sector;
+	//uint32 max_sector_count;
+	int32 last_sector_erased;
+	uint8 extra_count;
+	uint8 extra_bytes[4];
+} rboot_write_status;
+
+/**	@brief	Read rBoot configuration from flash
+ *	@retval rboot_config Copy of the rBoot configuration
+ *  @note   Returns rboot_config (defined in rboot.h) allowing you to modify any values
+ *          in it, including the ROM layout.
+*/
+rboot_config ICACHE_FLASH_ATTR rboot_get_config(void);
+
+/**	@brief	Write rBoot configuration to flash memory
+ *	@param	conf pointer to a rboot_config structure containing configuration to save
+ *	@retval bool True on success
+ *  @note   Saves the rboot_config structure back to configuration sector (BOOT_CONFIG_SECTOR)
+ *          of the flash, while maintaining the contents of the rest of the sector.
+ *          You can use the rest of this sector for your app settings, as long as you
+ *          protect this structure when you do so.
+*/
+bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf);
+
+/** @brief  Get index of current ROM
+ *  @retval uint8 Index of the current ROM
+ *  @note   Get the currently selected boot ROM (this will be the currently
+ *          running ROM, as long as you haven't changed it since boot or rBoot
+ *          booted the rom in temporary boot mode, see rboot_get_last_boot_rom).
+*/
+uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void);
+
+/**	@brief	Set the index of current ROM
+ *	@param	rom The index of the ROM to use on next boot
+ *	@retval	bool True on success
+ *  @note   Set the current boot ROM, which will be used when next restarted.
+ *  @note   This function re-writes the whole configuration to flash memory (not just the current ROM index)
+*/
+bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom);
+
+/**	@brief  Initialise flash write process
+ *	@param  start_addr Address on the SPI flash to begin write to
+ *  @note   Call once before starting to pass data to write to flash memory with rboot_write_flash function.
+ *          start_addr is the address on the SPI flash to write from. Returns a status structure which
+ *          must be passed back on each write. The contents of the structure should not
+ *          be modified by the calling code.
+*/
+rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr);
+
+/**	@brief  Write data to flash memory
+ *	@param  status Pointer to rboot_write_status structure defining the write status
+ *  @param  data Pointer to a block of uint8 data elements to be written to flash
+ *  @param  len Quantity of uint8 data elements to write to flash
+ *  @note   Call repeatedly to write data to the flash, starting at the address
+ *  specified on the prior call to rboot_write_init. Current write position is
+ *  tracked automatically. This method is likely to be called each time a packet
+ *  of OTA data is received over the network.
+ *  @note   Call rboot_write_init before calling this function to get the rboot_write_status structure
+*/
+bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len);
+
+#ifdef BOOT_RTC_ENABLED
+/** @brief  Get rBoot status/control data from RTC data area
+ *  @param  rtc Pointer to a rboot_rtc_data structure to be populated
+ *  @retval bool True on success, false if no data/invalid checksum (in which
+ *          case do not use the contents of the structure)
+*/
+bool ICACHE_FLASH_ATTR rboot_get_rtc_data(rboot_rtc_data *rtc);
+
+/** @brief  Set rBoot status/control data in RTC data area
+ *  @param  rtc pointer to a rboot_rtc_data structure
+ *  @retval bool True on success
+ *  @note   The checksum will be calculated automatically for you.
+*/
+bool ICACHE_FLASH_ATTR rboot_set_rtc_data(rboot_rtc_data *rtc);
+
+/** @brief  Set temporary rom for next boot
+ *  @param  rom Rom slot number for next boot
+ *  @retval bool True on success
+ *  @note   This call will tell rBoot to temporarily boot the specified rom on
+ *          the next boot. This is does not update the stored rBoot config on
+ *          the flash, so after another reset it will boot back to the original
+ *          rom.
+*/
+bool ICACHE_FLASH_ATTR rboot_set_temp_rom(uint8 rom);
+
+/** @brief  Get the last booted rom slot number
+ *  @param  rom Pointer to rom slot number variable to populate
+ *  @retval bool True on success, false if no data/invalid checksum
+ *  @note   This will find the currently running rom, even if booted as a
+ *          temporary rom.
+*/
+bool ICACHE_FLASH_ATTR rboot_get_last_boot_rom(uint8 *rom);
+
+/** @brief  Get the last boot mode
+ *  @param  mode Pointer to mode variable to populate
+ *  @retval bool True on success, false if no data/invalid checksum
+ *  @note   This will indicate the type of boot: MODE_STANDARD, MODE_GPIO_ROM or
+ *          MODE_TEMP_ROM.
+*/
+bool ICACHE_FLASH_ATTR rboot_get_last_boot_mode(uint8 *mode);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif
diff --git a/extras/rboot-ota/rboot-ota.c b/extras/rboot-ota/rboot-integration.c
similarity index 69%
rename from extras/rboot-ota/rboot-ota.c
rename to extras/rboot-ota/rboot-integration.c
index c8b27c4..266d566 100644
--- a/extras/rboot-ota/rboot-ota.c
+++ b/extras/rboot-ota/rboot-integration.c
@@ -10,17 +10,10 @@
 #include <FreeRTOS.h>
 #include <task.h>
 
-#include "rboot-ota.h"
+#include <rboot.h>
 
 #define ROM_MAGIC_OLD 0xe9
 #define ROM_MAGIC_NEW 0xea
-#define CHECKSUM_INIT 0xef
-
-#if 0
-#define RBOOT_DEBUG(f_, ...) printf((f_), __VA_ARGS__)
-#else
-#define RBOOT_DEBUG(f_, ...)
-#endif
 
 typedef struct __attribute__((packed)) {
     uint8_t magic;
@@ -35,67 +28,6 @@ typedef struct __attribute__((packed)) {
 } section_header_t;
 
 
-// get the rboot config
-rboot_config_t rboot_get_config() {
-	rboot_config_t conf;
-	sdk_spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)&conf, sizeof(rboot_config_t));
-	return conf;
-}
-
-// write the rboot config
-// preserves contents of rest of sector, so rest
-// of sector can be used to store user data
-// updates checksum automatically, if enabled
-bool rboot_set_config(rboot_config_t *conf) {
-	uint8_t *buffer;
-#ifdef RBOOT_CONFIG_CHKSUM
-	uint8_t chksum;
-	uint8_t *ptr;
-#endif
-
-	buffer = (uint8_t*)malloc(SECTOR_SIZE);
-	if (!buffer) {
-		printf("rboot_set_config: Failed to allocate sector buffer\r\n");
-		return false;
-	}
-
-#ifdef BOOT_CONFIG_CHKSUM
-	chksum = CHKSUM_INIT;
-	for (ptr = (uint8_t*)conf; ptr < &conf->chksum; ptr++) {
-		chksum ^= *ptr;
-	}
-	conf->chksum = chksum;
-#endif
-
-	sdk_spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)buffer, SECTOR_SIZE);
-	memcpy(buffer, conf, sizeof(rboot_config_t));
-        vPortEnterCritical();
-	sdk_spi_flash_erase_sector(BOOT_CONFIG_SECTOR);
-        vPortExitCritical();
-        taskYIELD();
-        vPortEnterCritical();
-	sdk_spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)buffer, SECTOR_SIZE);
-        vPortExitCritical();
-	free(buffer);
-	return true;
-}
-
-// get current boot rom
-uint8_t rboot_get_current_rom() {
-	rboot_config_t conf;
-	conf = rboot_get_config();
-	return conf.current_rom;
-}
-
-// set current boot rom
-bool rboot_set_current_rom(uint8_t rom) {
-	rboot_config_t conf;
-	conf = rboot_get_config();
-	if (rom >= conf.count) return false;
-	conf.current_rom = rom;
-	return rboot_set_config(&conf);
-}
-
 // Check that a valid-looking rboot image is found at this offset on the flash, and
 // takes up 'expected_length' bytes.
 bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message)
@@ -120,7 +52,7 @@ bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **
 
     int remaining_sections = image_header.section_count;
 
-    uint8_t checksum = CHECKSUM_INIT;
+    uint8_t checksum = CHKSUM_INIT;
 
     while(remaining_sections > 0 && offset < end_offset)
     {
diff --git a/extras/rboot-ota/rboot-integration.h b/extras/rboot-ota/rboot-integration.h
new file mode 100644
index 0000000..00c1bcb
--- /dev/null
+++ b/extras/rboot-ota/rboot-integration.h
@@ -0,0 +1,34 @@
+// The rboot project provides this file for making rboot fit other projects
+
+#ifndef __RBOOT_INTEGRATION_H__
+#define __RBOOT_INTEGRATION_H__
+#include <stdint.h>
+#include <stdbool.h>
+#include <espressif/spi_flash.h>
+#include <espressif/esp_system.h>
+#include <FreeRTOS.h>
+#include <task.h>
+
+#define uint8 uint8_t
+#define uint16 uint16_t
+#define uint32 uint32_t
+#define int32 int32_t
+#define ICACHE_FLASH_ATTR
+#define spi_flash_read sdk_spi_flash_read
+#define spi_flash_erase_sector sdk_spi_flash_erase_sector
+#define spi_flash_write sdk_spi_flash_write
+#define os_malloc malloc
+#define os_free free
+#define system_rtc_mem_read sdk_system_rtc_mem_read
+#define system_rtc_mem_write sdk_system_rtc_mem_write
+
+#if 0
+#define RBOOT_DEBUG(f_, ...) printf((f_), __VA_ARGS__)
+#else
+#define RBOOT_DEBUG(f_, ...)
+#endif
+
+// Check that a valid-looking rboot image is found at this offset on the flash, and
+// takes up 'expected_length' bytes.
+bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message);
+#endif // __RBOOT_INTEGRATION_H__
diff --git a/extras/rboot-ota/rboot-ota.h b/extras/rboot-ota/rboot-ota.h
deleted file mode 100644
index 5586a30..0000000
--- a/extras/rboot-ota/rboot-ota.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __RBOOT_OTA_H__
-#define __RBOOT_OTA_H__
-/* rboot-ota client API
- *
- * Ported from https://github.com/raburton/esp8266/ to esp-open-rtos
- *
- * BSD Licensed as per the file LICENSE in the top-level directory.
- * Copyright (c) 2015 Richard A Burton & SuperHouse Pty Ltd
- */
-#include <stdint.h>
-#include <stdbool.h>
-#include <rboot-config.h>
-
-/* rboot config block structure (stored in flash offset 0x1000)
- *
- * Structure taken from rboot.h revision a4724ede22
- * The version of rboot you're using has to match this structure
- */
-typedef struct {
-        uint8_t magic;               // our magic
-        uint8_t version;             // config struct version
-        uint8_t mode;                        // boot loader mode
-        uint8_t current_rom;         // currently selected rom
-        uint8_t gpio_rom;            // rom to use for gpio boot
-        uint8_t count;               // number of roms in use
-        uint8_t unused[2];           // padding
-        uint32_t roms[RBOOT_MAX_ROMS]; // flash addresses of the roms
-#ifdef RBOOT_CONFIG_CHKSUM
-        uint8_t chksum;              // config chksum
-#endif
-} rboot_config_t;
-
-
-#define SECTOR_SIZE 0x1000
-#define BOOT_CONFIG_SECTOR 1
-
-// timeout for the initial connect (in ms)
-#define OTA_CONNECT_TIMEOUT  10000
-
-// timeout for the download and flash to complete (in ms), once connected
-#define OTA_DOWNLOAD_TIMEOUT 20000
-
-#define UPGRADE_FLAG_IDLE		0x00
-#define UPGRADE_FLAG_START		0x01
-#define UPGRADE_FLAG_FINISH		0x02
-
-#define FLASH_BY_ADDR 0xff
-
-rboot_config_t rboot_get_config();
-bool rboot_set_config(rboot_config_t *conf);
-uint8_t rboot_get_current_rom();
-bool rboot_set_current_rom(uint8_t rom);
-bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message);
-
-#endif
diff --git a/extras/rboot-ota/rboot.h b/extras/rboot-ota/rboot.h
new file mode 100644
index 0000000..e09aa7e
--- /dev/null
+++ b/extras/rboot-ota/rboot.h
@@ -0,0 +1,111 @@
+#ifndef __RBOOT_H__
+#define __RBOOT_H__
+
+//////////////////////////////////////////////////
+// rBoot open source boot loader for ESP8266.
+// Copyright 2015 Richard A Burton
+// richardaburton@gmail.com
+// See license.txt for license terms.
+//////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RBOOT_INTEGRATION
+
+// uncomment to use only c code
+// if you aren't using gcc you may need to do this
+//#define BOOT_NO_ASM
+
+// uncomment to have a checksum on the boot config
+//#define BOOT_CONFIG_CHKSUM
+
+// uncomment to enable big flash support (>1MB)
+#define BOOT_BIG_FLASH
+
+// uncomment to enable 2 way communication between
+// rBoot and the user app via the esp rtc data area
+#define BOOT_RTC_ENABLED
+
+// uncomment to enable GPIO booting
+//#define BOOT_GPIO_ENABLED
+
+// uncomment to include .irom0.text section in the checksum
+// roms must be built with esptool2 using -iromchksum option
+//#define BOOT_IROM_CHKSUM
+
+// uncomment to add a boot delay, allows you time to connect
+// a terminal before rBoot starts to run and output messages
+// value is in microseconds
+//#define BOOT_DELAY_MICROS 2000000
+
+// increase if required
+#define MAX_ROMS 4
+
+#define CHKSUM_INIT 0xef
+
+#define SECTOR_SIZE 0x1000
+#define BOOT_CONFIG_SECTOR 1
+
+#define BOOT_CONFIG_MAGIC 0xe1
+#define BOOT_CONFIG_VERSION 0x01
+
+#define MODE_STANDARD 0x00
+#define MODE_GPIO_ROM 0x01
+#define MODE_TEMP_ROM 0x02
+
+#define RBOOT_RTC_MAGIC 0x2334ae68
+#define RBOOT_RTC_READ 1
+#define RBOOT_RTC_WRITE 0
+#define RBOOT_RTC_ADDR 64
+
+#ifdef RBOOT_INTEGRATION
+#include <rboot-integration.h>
+#endif
+
+/** @brief  Structure containing rBoot configuration
+ *  @note   ROM addresses must be multiples of 0x1000 (flash sector aligned).
+ *          Without BOOT_BIG_FLASH only the first 8Mbit (1MB) of the chip will
+ *          be memory mapped so ROM slots containing .irom0.text sections must
+ *          remain below 0x100000. Slots beyond this will only be accessible via
+ *          spi read calls, so use these for stored resources, not code. With
+ *          BOOT_BIG_FLASH the flash will be mapped in chunks of 8MBit (1MB), so
+ *          ROMs can be anywhere, but must not straddle two 8MBit (1MB) blocks.
+ *  @ingroup rboot
+*/
+typedef struct {
+	uint8 magic;           ///< Our magic, identifies rBoot configuration - should be BOOT_CONFIG_MAGIC
+	uint8 version;         ///< Version of configuration structure - should be BOOT_CONFIG_VERSION
+	uint8 mode;            ///< Boot loader mode (MODE_STANDARD | MODE_GPIO_ROM)
+	uint8 current_rom;     ///< Currently selected ROM (will be used for next standard boot)
+	uint8 gpio_rom;        ///< ROM to use for GPIO boot (hardware switch) with mode set to MODE_GPIO_ROM
+	uint8 count;           ///< Quantity of ROMs available to boot
+	uint8 unused[2];       ///< Padding (not used)
+	uint32 roms[MAX_ROMS]; ///< Flash addresses of each ROM
+#ifdef BOOT_CONFIG_CHKSUM
+	uint8 chksum;          ///< Checksum of this configuration structure (if BOOT_CONFIG_CHKSUM defined)
+#endif
+} rboot_config;
+
+#ifdef BOOT_RTC_ENABLED
+/** @brief  Structure containing rBoot status/control data
+ *  @note   This structure is used to, optionally, communicate between rBoot and
+ *          the user app. It is stored in the ESP RTC data area.
+ *  @ingroup rboot
+*/
+typedef struct {
+	uint32 magic;           ///< Magic, identifies rBoot RTC data - should be RBOOT_RTC_MAGIC
+	uint8 next_mode;        ///< The next boot mode, defaults to MODE_STANDARD - can be set to MODE_TEMP_ROM
+	uint8 last_mode;        ///< The last (this) boot mode - can be MODE_STANDARD, MODE_GPIO_ROM or MODE_TEMP_ROM
+	uint8 last_rom;         ///< The last (this) boot rom number
+	uint8 temp_rom;         ///< The next boot rom number when next_mode set to MODE_TEMP_ROM
+	uint8 chksum;           ///< Checksum of this structure this will be updated for you passed to the API
+} rboot_rtc_data;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extras/rboot-ota/readme.txt b/extras/rboot-ota/readme.txt
index 8721112..e5513e9 100644
--- a/extras/rboot-ota/readme.txt
+++ b/extras/rboot-ota/readme.txt
@@ -1,4 +1,4 @@
-*NOTE: This rboot-ota and the TFTP server ota-tftp.h are specific to esp-open-rtos. The below Makefile is from the upstream rboot-ota project.*
+*NOTE: This rboot-ota and the TFTP server ota-tftp.h are specific to esp-open-rtos. The below Makefile is from the upstream rboot-ota project and the rboot code is taken from #75ca33b.*
 
 For more details on OTA in esp-open-rtos, see https://github.com/SuperHouse/esp-open-rtos/wiki/OTA-Update-Configuration