|
|
@ -9,7 +9,7 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com> |
|
|
|
#include "ArduinoOTA.h"
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// OTA
|
|
|
|
// Arduino OTA
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void _otaConfigure() { |
|
|
@ -20,51 +20,143 @@ void _otaConfigure() { |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
#if TERMINAL_SUPPORT && OTA_TERMINAL
|
|
|
|
void _otaLoop() { |
|
|
|
ArduinoOTA.handle(); |
|
|
|
} |
|
|
|
|
|
|
|
#include <ESP8266httpUpdate.h>
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Terminal OTA
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void _otaFrom(const char * url) { |
|
|
|
#if TERMINAL_SUPPORT
|
|
|
|
|
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Downloading from '%s'\n"), url); |
|
|
|
#if WEB_SUPPORT
|
|
|
|
wsSend_P(PSTR("{\"message\": 2}")); |
|
|
|
#endif
|
|
|
|
#include <ESPAsyncTCP.h>
|
|
|
|
AsyncClient * _ota_client; |
|
|
|
char * _ota_host; |
|
|
|
char * _ota_url; |
|
|
|
unsigned long _ota_size = 0; |
|
|
|
|
|
|
|
ESPhttpUpdate.rebootOnUpdate(false); |
|
|
|
t_httpUpdate_return ret; |
|
|
|
if (strncmp(url, "https", 5) == 0) { |
|
|
|
String fp = getSetting("otafp", OTA_GITHUB_FP); |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Using fingerprint: '%s'\n"), fp.c_str()); |
|
|
|
ret = ESPhttpUpdate.update(url, APP_VERSION, fp.c_str()); |
|
|
|
} else { |
|
|
|
ret = ESPhttpUpdate.update(url, APP_VERSION); |
|
|
|
} |
|
|
|
const char OTA_REQUEST_TEMPLATE[] PROGMEM = |
|
|
|
"GET %s HTTP/1.1\r\n" |
|
|
|
"Host: %s\r\n" |
|
|
|
"User-Agent: ESPurna\r\n" |
|
|
|
"Connection: close\r\n" |
|
|
|
"Content-Type: application/x-www-form-urlencoded\r\n" |
|
|
|
"Content-Length: 0\r\n\r\n\r\n"; |
|
|
|
|
|
|
|
switch(ret) { |
|
|
|
|
|
|
|
case HTTP_UPDATE_FAILED: |
|
|
|
DEBUG_MSG_P( |
|
|
|
PSTR("[OTA] Error (%d): %s\n"), |
|
|
|
ESPhttpUpdate.getLastError(), |
|
|
|
ESPhttpUpdate.getLastErrorString().c_str() |
|
|
|
); |
|
|
|
break; |
|
|
|
void _otaFrom(const char * host, unsigned int port, const char * url) { |
|
|
|
|
|
|
|
case HTTP_UPDATE_NO_UPDATES: |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] No updates available\n")); |
|
|
|
break; |
|
|
|
if (_ota_host) free(_ota_host); |
|
|
|
if (_ota_url) free(_ota_url); |
|
|
|
_ota_host = strdup(host); |
|
|
|
_ota_url = strdup(url); |
|
|
|
_ota_size = 0; |
|
|
|
|
|
|
|
case HTTP_UPDATE_OK: |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Done, restarting...\n")); |
|
|
|
#if WEB_SUPPORT
|
|
|
|
wsSend_P(PSTR("{\"action\": \"reload\"}")); |
|
|
|
#endif
|
|
|
|
if (_ota_client == NULL) { |
|
|
|
_ota_client = new AsyncClient(); |
|
|
|
} |
|
|
|
|
|
|
|
_ota_client->onDisconnect([](void *s, AsyncClient *c) { |
|
|
|
|
|
|
|
DEBUG_MSG_P(PSTR("\n")); |
|
|
|
|
|
|
|
if (Update.end(true)){ |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Success: %u bytes\n"), _ota_size); |
|
|
|
deferredReset(100, CUSTOM_RESET_OTA); |
|
|
|
break; |
|
|
|
} else { |
|
|
|
#ifdef DEBUG_PORT
|
|
|
|
Update.printError(DEBUG_PORT); |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Disconnected\n")); |
|
|
|
|
|
|
|
_ota_client->free(); |
|
|
|
delete _ota_client; |
|
|
|
_ota_client = NULL; |
|
|
|
free(_ota_host); |
|
|
|
_ota_host = NULL; |
|
|
|
free(_ota_url); |
|
|
|
_ota_url = NULL; |
|
|
|
|
|
|
|
}, 0); |
|
|
|
|
|
|
|
_ota_client->onTimeout([](void *s, AsyncClient *c, uint32_t time) { |
|
|
|
_ota_client->close(true); |
|
|
|
}, 0); |
|
|
|
|
|
|
|
_ota_client->onData([](void * arg, AsyncClient * c, void * data, size_t len) { |
|
|
|
|
|
|
|
char * p = (char *) data; |
|
|
|
|
|
|
|
if (_ota_size == 0) { |
|
|
|
|
|
|
|
Update.runAsync(true); |
|
|
|
if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) { |
|
|
|
#ifdef DEBUG_PORT
|
|
|
|
Update.printError(DEBUG_PORT); |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
p = strstr((char *)data, "\r\n\r\n") + 4; |
|
|
|
len = len - (p - (char *) data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!Update.hasError()) { |
|
|
|
if (Update.write((uint8_t *) p, len) != len) { |
|
|
|
#ifdef DEBUG_PORT
|
|
|
|
Update.printError(DEBUG_PORT); |
|
|
|
#endif
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
_ota_size += len; |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Progress: %u bytes\r"), _ota_size); |
|
|
|
|
|
|
|
|
|
|
|
}, NULL); |
|
|
|
|
|
|
|
_ota_client->onConnect([](void * arg, AsyncClient * client) { |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Downloading %s\n"), _ota_url); |
|
|
|
char buffer[strlen_P(OTA_REQUEST_TEMPLATE) + strlen(_ota_url) + strlen(_ota_host)]; |
|
|
|
snprintf_P(buffer, sizeof(buffer), OTA_REQUEST_TEMPLATE, _ota_url, _ota_host); |
|
|
|
client->write(buffer); |
|
|
|
|
|
|
|
}, NULL); |
|
|
|
|
|
|
|
|
|
|
|
bool connected = _ota_client->connect(host, port); |
|
|
|
if (!connected) { |
|
|
|
DEBUG_MSG_P(PSTR("[OTA] Connection failed\n")); |
|
|
|
_ota_client->close(true); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void _otaFrom(String url) { |
|
|
|
|
|
|
|
// Port from protocol
|
|
|
|
unsigned int port = 80; |
|
|
|
if (url.startsWith("https://")) port = 443; |
|
|
|
url = url.substring(url.indexOf("/") + 2); |
|
|
|
|
|
|
|
// Get host
|
|
|
|
String host = url.substring(0, url.indexOf("/")); |
|
|
|
|
|
|
|
// Explicit port
|
|
|
|
int p = host.indexOf(":"); |
|
|
|
if (p > 0) { |
|
|
|
port = host.substring(p + 1).toInt(); |
|
|
|
host = host.substring(0, p); |
|
|
|
} |
|
|
|
|
|
|
|
// Get URL
|
|
|
|
String uri = url.substring(url.indexOf("/")); |
|
|
|
|
|
|
|
_otaFrom(host.c_str(), port, uri.c_str()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void _otaInitCommands() { |
|
|
@ -75,17 +167,13 @@ void _otaInitCommands() { |
|
|
|
} else { |
|
|
|
DEBUG_MSG_P(PSTR("+OK\n")); |
|
|
|
String url = String(e->argv[1]); |
|
|
|
_otaFrom(url.c_str()); |
|
|
|
_otaFrom(url); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // TERMINAL_SUPPORT && OTA_TERMINAL
|
|
|
|
|
|
|
|
void _otaLoop() { |
|
|
|
ArduinoOTA.handle(); |
|
|
|
} |
|
|
|
#endif // TERMINAL_SUPPORT
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
@ -97,7 +185,7 @@ void otaSetup() { |
|
|
|
wsOnAfterParseRegister(_otaConfigure); |
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TERMINAL_SUPPORT && OTA_TERMINAL
|
|
|
|
#if TERMINAL_SUPPORT
|
|
|
|
_otaInitCommands(); |
|
|
|
#endif
|
|
|
|
|
|
|
|