Browse Source

Enabled terminal OTA again usinig async client

softuart
Xose Pérez 6 years ago
parent
commit
b3f0282655
2 changed files with 129 additions and 42 deletions
  1. +0
    -1
      code/espurna/config/general.h
  2. +129
    -41
      code/espurna/ota.ino

+ 0
- 1
code/espurna/config/general.h View File

@ -446,7 +446,6 @@ PROGMEM const char* const custom_reset_string[] = {
// -----------------------------------------------------------------------------
#define OTA_PORT 8266 // OTA port
#define OTA_TERMINAL 0 // Enable OTA from terminal
#define OTA_GITHUB_FP "D79F076110B39293E349AC89845B0380C19E2F8B"
// -----------------------------------------------------------------------------


+ 129
- 41
code/espurna/ota.ino View File

@ -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


Loading…
Cancel
Save