You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
8.7 KiB
194 lines
8.7 KiB
5 years ago
|
/**
|
||
|
* Declaration of AutoConnectUpdate class.
|
||
|
* The AutoConnectUpdate class is a class for updating sketch binary
|
||
|
* via OTA and inherits the HTTPUpdate class of the arduino core.
|
||
|
* It declares the class implementations of both core libraries as
|
||
|
* HTTPUpdateClass to absorb differences between ESP8266 and ESP32
|
||
|
* class definitions.
|
||
|
* The AutoConnectUpdate class add ons three features to the HTTPupdate
|
||
|
* class.
|
||
|
* 1. Dialog pages for operating the update.
|
||
|
* The dialog pages are all AutoConnectAux, and they select available
|
||
|
* sketch binary, display during update processing, and display
|
||
|
* update results.
|
||
|
* 2. Daialog pages handler
|
||
|
* In the dialog page, AUTOCONNECT_URI_UPDATE, AUTOCONNECT_URI_UPDATE_ACT,
|
||
|
* AUTOCONNECT_URI_UPDATE_RESULT are assigned and there is a page
|
||
|
* handler for each.
|
||
|
* 3. Attach to the AutoConnect.
|
||
|
* Attaching the AutoConnectUpdate class to AutoConnect makes the
|
||
|
* sketch binary update function available, and the operation dialog
|
||
|
* pages are incorporated into the AutoConnect menu.
|
||
|
* @file AutoConnectUpdate.h
|
||
|
* @author hieromon@gmail.com
|
||
|
* @version 1.0.0
|
||
|
* @date 2019-08-15
|
||
|
* @copyright MIT license.
|
||
|
*/
|
||
|
|
||
|
#ifndef _AUTOCONNECTUPDATE_H_
|
||
|
#define _AUTOCONNECTUPDATE_H_
|
||
|
|
||
|
#include "AutoConnectDefs.h"
|
||
|
#ifdef AUTOCONNECT_USE_UPDATE
|
||
|
#ifndef AUTOCONNECT_USE_JSON
|
||
|
#define AUTOCONNECT_USE_JSON
|
||
|
#endif
|
||
|
#include <memory>
|
||
|
#define NO_GLOBAL_HTTPUPDATE
|
||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||
|
#include <ESP8266HTTPClient.h>
|
||
|
#include <ESP8266httpUpdate.h>
|
||
|
using HTTPUpdateClass = ESP8266HTTPUpdate;
|
||
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||
|
#include <HTTPClient.h>
|
||
|
#include <HTTPUpdate.h>
|
||
|
using HTTPUpdateClass = HTTPUpdate;
|
||
|
#endif
|
||
|
// #include <WebSocketsServer.h>
|
||
|
// Quote the true AutoConnectUpdate class according to AUTOCONNECT_USE_UPDATE.
|
||
|
#define AutoConnectUpdate AutoConnectUpdateAct
|
||
|
#else // !AUTOCONNECT_USE_UPDATE!
|
||
|
#define AutoConnectUpdate AutoConnectUpdateVoid
|
||
|
#endif
|
||
|
#include "AutoConnect.h"
|
||
|
|
||
|
// Support LED flashing only the board with built-in LED.
|
||
|
#if defined(BUILTIN_LED) || defined(LED_BUILTIN)
|
||
|
#define AC_SETLED(s) do {setLedPin(AUTOCONNECT_TICKER_PORT, s);} while(0)
|
||
|
#else
|
||
|
#define AC_SETLED(s) do {} while(0)
|
||
|
#endif
|
||
|
|
||
|
// Indicate an update process loop
|
||
|
typedef enum AC_UPDATESTATUS {
|
||
|
UPDATE_RESET, /**< Update process ended, need to reset */
|
||
|
UPDATE_IDLE, /**< Update process has not started */
|
||
|
UPDATE_START, /**< Update process has been started */
|
||
|
UPDATE_PROGRESS, /**< Update process has been started */
|
||
|
UPDATE_SUCCESS, /**< Update successfully completed */
|
||
|
UPDATE_NOAVAIL, /**< No available update */
|
||
|
UPDATE_FAIL /**< Update fails */
|
||
|
} AC_UPDATESTATUS_t;
|
||
|
|
||
|
class AutoConnectUpdateVoid {
|
||
|
public:
|
||
|
explicit AutoConnectUpdateVoid(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT, const uint8_t ledOn = LOW) {
|
||
|
AC_UNUSED(host);
|
||
|
AC_UNUSED(port);
|
||
|
AC_UNUSED(uri);
|
||
|
AC_UNUSED(timeout);
|
||
|
AC_UNUSED(ledOn);
|
||
|
}
|
||
|
AutoConnectUpdateVoid(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT, const uint8_t ledOn = LOW) {
|
||
|
AC_UNUSED(portal);
|
||
|
AC_UNUSED(host);
|
||
|
AC_UNUSED(port);
|
||
|
AC_UNUSED(uri);
|
||
|
AC_UNUSED(timeout);
|
||
|
AC_UNUSED(ledOn);
|
||
|
}
|
||
|
virtual ~AutoConnectUpdateVoid() {}
|
||
|
virtual void attach(AutoConnect& portal) { AC_UNUSED(portal); }
|
||
|
virtual void enable(void) {}
|
||
|
virtual void disable(const bool activate = false) { AC_UNUSED(activate); }
|
||
|
virtual void handleUpdate(void) {}
|
||
|
virtual bool isEnabled(void) { return false; }
|
||
|
virtual AC_UPDATESTATUS_t status(void) { return UPDATE_IDLE; }
|
||
|
virtual AC_UPDATESTATUS_t update(void) { return UPDATE_IDLE; }
|
||
|
};
|
||
|
|
||
|
#ifdef AUTOCONNECT_USE_UPDATE
|
||
|
|
||
|
class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClass {
|
||
|
public:
|
||
|
explicit AutoConnectUpdateAct(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT, const uint8_t ledOn = AUTOCONNECT_UPDATE_LEDON)
|
||
|
: HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _amount(0), _binSize(0), _enable(false), _dialog(UPDATEDIALOG_LOADER), _status(UPDATE_IDLE), _binName(String()), _webServer(nullptr) {
|
||
|
AC_SETLED(ledOn); /**< LED blinking during the update that is the default. */
|
||
|
rebootOnUpdate(false); /**< Default reboot mode */
|
||
|
}
|
||
|
AutoConnectUpdateAct(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT, const uint8_t ledOn = AUTOCONNECT_UPDATE_LEDON)
|
||
|
: HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _amount(0), _binSize(0), _enable(false), _dialog(UPDATEDIALOG_LOADER), _status(UPDATE_IDLE), _binName(String()), _webServer(nullptr) {
|
||
|
AC_SETLED(ledOn);
|
||
|
rebootOnUpdate(false);
|
||
|
attach(portal);
|
||
|
}
|
||
|
~AutoConnectUpdateAct();
|
||
|
void attach(AutoConnect& portal) override; /**< Attach the update class to AutoConnect */
|
||
|
void enable(void) override; /**< Enable the AutoConnectUpdateAct */
|
||
|
void disable(const bool activte = false) override; /**< Disable the AutoConnectUpdateAct */
|
||
|
void handleUpdate(void) override; /**< Behaves the update process */
|
||
|
bool isEnabled(void) override { return _auxCatalog ? _auxCatalog->isMenu() : false; } /**< Returns current updater effectiveness */
|
||
|
AC_UPDATESTATUS_t status(void) override { return _status; } /**< reports the current update behavior status */
|
||
|
AC_UPDATESTATUS_t update(void) override; /**< behaves update */
|
||
|
|
||
|
String host; /**< Available URL of Update Server */
|
||
|
uint16_t port; /**< Port number of the update server */
|
||
|
String uri; /**< The path on the update server that contains the sketch binary to be updated */
|
||
|
|
||
|
// Indicate the type of progress dialog
|
||
|
typedef enum {
|
||
|
UPDATEDIALOG_LOADER, /**< Cyclic loader icon */
|
||
|
UPDATEDIALOG_METER /**< Progress meter */
|
||
|
} AC_UPDATEDIALOG_t;
|
||
|
|
||
|
protected:
|
||
|
// Attribute definition of the element to be placed on the update page.
|
||
|
typedef struct {
|
||
|
const ACElement_t type;
|
||
|
const char* name; /**< Name to assign to AutoConnectElement */
|
||
|
const char* value; /**< Value owned by an element */
|
||
|
const char* peculiar; /**< Specific ornamentation for the element */
|
||
|
} ACElementProp_t;
|
||
|
|
||
|
// Attributes to treat included update pages as AutoConnectAux.
|
||
|
typedef struct {
|
||
|
const char* uri; /**< URI for the page */
|
||
|
const char* title; /**< Menu title of update page */
|
||
|
const bool menu; /**< Whether to display in menu */
|
||
|
const ACElementProp_t* element;
|
||
|
} ACPage_t;
|
||
|
|
||
|
template<typename T, size_t N> constexpr
|
||
|
size_t lengthOf(T(&)[N]) noexcept { return N; }
|
||
|
void _buildAux(AutoConnectAux* aux, const AutoConnectUpdateAct::ACPage_t* page, const size_t elementNum);
|
||
|
String _onCatalog(AutoConnectAux& catalog, PageArgument& args);
|
||
|
String _onUpdate(AutoConnectAux& update, PageArgument& args);
|
||
|
String _onResult(AutoConnectAux& result, PageArgument& args);
|
||
|
void _inProgress(size_t amount, size_t size); /**< UpdateClass::THandlerFunction_Progress */
|
||
|
|
||
|
std::unique_ptr<AutoConnectAux> _auxCatalog; /**< A catalog page for internally generated update binaries */
|
||
|
std::unique_ptr<AutoConnectAux> _auxProgress; /**< An update in-progress page */
|
||
|
std::unique_ptr<AutoConnectAux> _auxResult; /**< A update result page */
|
||
|
|
||
|
size_t _amount; /**< Received amount bytes */
|
||
|
size_t _binSize; /**< Updater binary size */
|
||
|
|
||
|
private:
|
||
|
void _progress(void); /**< A Handler that returns progress status to the web client */
|
||
|
|
||
|
bool _enable; /**< Validation status of the Update class */
|
||
|
AC_UPDATEDIALOG_t _dialog; /**< The type of updating dialog displayed on the client */
|
||
|
AC_UPDATESTATUS_t _status; /**< Status of update processing during the cycle of receiving a request */
|
||
|
String _binName; /**< .bin name to update */
|
||
|
WebServerClass* _webServer; /**< Hosted WebServer for XMLHttpRequest */
|
||
|
|
||
|
static const ACPage_t _pageCatalog PROGMEM;
|
||
|
static const ACElementProp_t _elmCatalog[] PROGMEM;
|
||
|
|
||
|
static const ACPage_t _pageProgress PROGMEM;
|
||
|
static const ACElementProp_t _elmProgress[] PROGMEM;
|
||
|
|
||
|
static const ACPage_t _pageResult PROGMEM;
|
||
|
static const ACElementProp_t _elmResult[] PROGMEM;
|
||
|
|
||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||
|
friend ESP8266WebServer;
|
||
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||
|
friend class WebServer;
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#endif // !AUTOCONNECT_USE_UPDATE
|
||
|
#endif // _AUTOCONNECTUPDATE_H_
|