mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-11-03 14:33:37 +03:00 
			
		
		
		
	Merge pull request #1188 from Links2004/httpUpdate
allow SPIFFS update over http
This commit is contained in:
		@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * httpUpdateSPIFFS.ino
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: 05.12.2015
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ESP8266WiFi.h>
 | 
				
			||||||
 | 
					#include <ESP8266WiFiMulti.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ESP8266HTTPClient.h>
 | 
				
			||||||
 | 
					#include <ESP8266httpUpdate.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USE_SERIAL Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ESP8266WiFiMulti WiFiMulti;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    USE_SERIAL.begin(115200);
 | 
				
			||||||
 | 
					    // USE_SERIAL.setDebugOutput(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    USE_SERIAL.println();
 | 
				
			||||||
 | 
					    USE_SERIAL.println();
 | 
				
			||||||
 | 
					    USE_SERIAL.println();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(uint8_t t = 4; t > 0; t--) {
 | 
				
			||||||
 | 
					        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
 | 
				
			||||||
 | 
					        USE_SERIAL.flush();
 | 
				
			||||||
 | 
					        delay(1000);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WiFiMulti.addAP("SSID", "PASSWORD");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					    // wait for WiFi connection
 | 
				
			||||||
 | 
					    if((WiFiMulti.run() == WL_CONNECTED)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        USE_SERIAL.println("Update SPIFFS...");
 | 
				
			||||||
 | 
					        t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs("https://server/spiffs.bin");
 | 
				
			||||||
 | 
					        if(ret == HTTP_UPDATE_OK) {
 | 
				
			||||||
 | 
					            USE_SERIAL.println("Update sketch...");
 | 
				
			||||||
 | 
					            ret = ESPhttpUpdate.update("https://server/file.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch(ret) {
 | 
				
			||||||
 | 
					                case HTTP_UPDATE_FAILED:
 | 
				
			||||||
 | 
					                    USE_SERIAL.println("HTTP_UPDATE_FAILD");
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case HTTP_UPDATE_NO_UPDATES:
 | 
				
			||||||
 | 
					                    USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES");
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case HTTP_UPDATE_OK:
 | 
				
			||||||
 | 
					                    USE_SERIAL.println("HTTP_UPDATE_OK");
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,9 +23,11 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "ESP8266httpUpdate.h"
 | 
					#include "ESP8266httpUpdate.h"
 | 
				
			||||||
 | 
					#include <StreamString.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" uint32_t _SPIFFS_start;
 | 
				
			||||||
 | 
					extern "C" uint32_t _SPIFFS_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) {
 | 
					ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -46,6 +48,19 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(const char * url, const char * cur
 | 
				
			|||||||
    return handleUpdate(&http, current_version);
 | 
					    return handleUpdate(&http, current_version);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param url const char *
 | 
				
			||||||
 | 
					 * @param current_version const char *
 | 
				
			||||||
 | 
					 * @param httpsFingerprint const char *
 | 
				
			||||||
 | 
					 * @return t_httpUpdate_return
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					t_httpUpdate_return ESP8266HTTPUpdate::updateSpiffs(const char * url, const char * current_version, const char * httpsFingerprint) {
 | 
				
			||||||
 | 
					    HTTPClient http;
 | 
				
			||||||
 | 
					    http.begin(url, httpsFingerprint);
 | 
				
			||||||
 | 
					    return handleUpdate(&http, current_version, false, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param host const char *
 | 
					 * @param host const char *
 | 
				
			||||||
@@ -73,7 +88,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(String host, uint16_t port, String
 | 
				
			|||||||
 * @param current_version const char *
 | 
					 * @param current_version const char *
 | 
				
			||||||
 * @return t_httpUpdate_return
 | 
					 * @return t_httpUpdate_return
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version) {
 | 
					t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version, bool reboot, bool spiffs) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t_httpUpdate_return ret = HTTP_UPDATE_FAILED;
 | 
					    t_httpUpdate_return ret = HTTP_UPDATE_FAILED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,6 +100,12 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
    http->addHeader("x-ESP8266-chip-size", String(ESP.getFlashChipRealSize()));
 | 
					    http->addHeader("x-ESP8266-chip-size", String(ESP.getFlashChipRealSize()));
 | 
				
			||||||
    http->addHeader("x-ESP8266-sdk-version", ESP.getSdkVersion());
 | 
					    http->addHeader("x-ESP8266-sdk-version", ESP.getSdkVersion());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(spiffs) {
 | 
				
			||||||
 | 
					        http->addHeader("x-ESP8266-mode", "spiffs");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        http->addHeader("x-ESP8266-mode", "sketch");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(current_version && current_version[0] != 0x00) {
 | 
					    if(current_version && current_version[0] != 0x00) {
 | 
				
			||||||
        http->addHeader("x-ESP8266-version", current_version);
 | 
					        http->addHeader("x-ESP8266-version", current_version);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -99,6 +120,12 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
    int code = http->GET();
 | 
					    int code = http->GET();
 | 
				
			||||||
    int len = http->getSize();
 | 
					    int len = http->getSize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(code <= 0) {
 | 
				
			||||||
 | 
					        DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http->errorToString(code).c_str());
 | 
				
			||||||
 | 
					        http->end();
 | 
				
			||||||
 | 
					        return HTTP_UPDATE_FAILED;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n");
 | 
					    DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n");
 | 
				
			||||||
    DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n");
 | 
					    DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n");
 | 
				
			||||||
    DEBUG_HTTP_UPDATE("[httpUpdate]  - code: %d\n", code);
 | 
					    DEBUG_HTTP_UPDATE("[httpUpdate]  - code: %d\n", code);
 | 
				
			||||||
@@ -117,11 +144,24 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch(code) {
 | 
					    switch(code) {
 | 
				
			||||||
        case 200:  ///< OK (Start Update)
 | 
					        case HTTP_CODE_OK:  ///< OK (Start Update)
 | 
				
			||||||
            if(len > 0) {
 | 
					            if(len > 0) {
 | 
				
			||||||
                if(len > ESP.getFreeSketchSpace()) {
 | 
					                bool startUpdate = true;
 | 
				
			||||||
                    ret = HTTP_UPDATE_FAILED;
 | 
					                if(spiffs) {
 | 
				
			||||||
 | 
					                    size_t spiffsSize = ((size_t) &_SPIFFS_end - (size_t) &_SPIFFS_start);
 | 
				
			||||||
 | 
					                    if(len > (int) spiffsSize) {
 | 
				
			||||||
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] spiffsSize to low (%d) needed: %d\n", spiffsSize, len);
 | 
				
			||||||
 | 
					                        startUpdate = false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if(len > (int) ESP.getFreeSketchSpace()) {
 | 
				
			||||||
                        DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len);
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len);
 | 
				
			||||||
 | 
					                        startUpdate = false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(!startUpdate) {
 | 
				
			||||||
 | 
					                    ret = HTTP_UPDATE_FAILED;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    WiFiClient * tcp = http->getStreamPtr();
 | 
					                    WiFiClient * tcp = http->getStreamPtr();
 | 
				
			||||||
@@ -131,11 +171,25 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    delay(100);
 | 
					                    delay(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if(runUpdate(*tcp, len, http->header("x-MD5"))) {
 | 
					                    int command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if(spiffs) {
 | 
				
			||||||
 | 
					                        command = U_SPIFFS;
 | 
				
			||||||
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate spiffs...\n");
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        command = U_FLASH;
 | 
				
			||||||
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
 | 
				
			||||||
                        ret = HTTP_UPDATE_OK;
 | 
					                        ret = HTTP_UPDATE_OK;
 | 
				
			||||||
                        DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
 | 
				
			||||||
                        http->end();
 | 
					                        http->end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if(reboot) {
 | 
				
			||||||
                            ESP.restart();
 | 
					                            ESP.restart();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        ret = HTTP_UPDATE_FAILED;
 | 
					                        ret = HTTP_UPDATE_FAILED;
 | 
				
			||||||
                        DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n");
 | 
					                        DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n");
 | 
				
			||||||
@@ -146,19 +200,18 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
                DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n");
 | 
					                DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case 304:
 | 
					        case HTTP_CODE_NOT_MODIFIED:
 | 
				
			||||||
            ///< Not Modified (No updates)
 | 
					            ///< Not Modified (No updates)
 | 
				
			||||||
            ret = HTTP_UPDATE_NO_UPDATES;
 | 
					            ret = HTTP_UPDATE_NO_UPDATES;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case 403:
 | 
					 | 
				
			||||||
            ///< Forbidden
 | 
					 | 
				
			||||||
            // todo handle login
 | 
					 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            ret = HTTP_UPDATE_FAILED;
 | 
					            ret = HTTP_UPDATE_FAILED;
 | 
				
			||||||
            DEBUG_HTTP_UPDATE("[httpUpdate] Code is (%d)\n", code);
 | 
					            DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code);
 | 
				
			||||||
 | 
					            //http->writeToStream(&Serial1);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http->end();
 | 
					    http->end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
@@ -171,10 +224,14 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
 | 
				
			|||||||
 * @param md5 String
 | 
					 * @param md5 String
 | 
				
			||||||
 * @return true if Update ok
 | 
					 * @return true if Update ok
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5) {
 | 
					bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(!Update.begin(size)) {
 | 
					    StreamString error;
 | 
				
			||||||
        DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed!\n");
 | 
					
 | 
				
			||||||
 | 
					    if(!Update.begin(size, command)) {
 | 
				
			||||||
 | 
					        Update.printError(error);
 | 
				
			||||||
 | 
					        error.trim(); // remove line ending
 | 
				
			||||||
 | 
					        DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed! (%s)\n", error.c_str());
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -183,12 +240,16 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(Update.writeStream(in) != size) {
 | 
					    if(Update.writeStream(in) != size) {
 | 
				
			||||||
        DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed!\n");
 | 
					        Update.printError(error);
 | 
				
			||||||
 | 
					        error.trim(); // remove line ending
 | 
				
			||||||
 | 
					        DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str());
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(!Update.end()) {
 | 
					    if(!Update.end()) {
 | 
				
			||||||
        DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed!\n");
 | 
					        Update.printError(error);
 | 
				
			||||||
 | 
					        error.trim(); // remove line ending
 | 
				
			||||||
 | 
					        DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed! (%s)\n", error.c_str());
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,9 +53,11 @@ class ESP8266HTTPUpdate {
 | 
				
			|||||||
        t_httpUpdate_return update(const char * host, uint16_t port, const char * url = "/", const char * current_version = "", bool https = false, const char * httpsFingerprint = "");
 | 
					        t_httpUpdate_return update(const char * host, uint16_t port, const char * url = "/", const char * current_version = "", bool https = false, const char * httpsFingerprint = "");
 | 
				
			||||||
        t_httpUpdate_return update(String host, uint16_t port, String url = "/", String current_version = "", bool https = false, String httpsFingerprint = "");
 | 
					        t_httpUpdate_return update(String host, uint16_t port, String url = "/", String current_version = "", bool https = false, String httpsFingerprint = "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        t_httpUpdate_return updateSpiffs(const char * url, const char * current_version = "", const char * httpsFingerprint = "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
        t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version);
 | 
					        t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version, bool reboot = true, bool spiffs = false);
 | 
				
			||||||
        bool runUpdate(Stream& in, uint32_t size, String md5);
 | 
					        bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern ESP8266HTTPUpdate ESPhttpUpdate;
 | 
					extern ESP8266HTTPUpdate ESPhttpUpdate;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user