OTA Update functionality

This commit is contained in:
Siwat Sirichai 2024-01-01 22:13:54 +07:00
parent f1db2c0487
commit 5302c4c758
5 changed files with 285 additions and 221 deletions

View file

@ -22,6 +22,9 @@ void ESPMegaWebServer::begin()
this->server->on("/config", HTTP_GET, bindedConfigHandler);
auto bindedSaveConfigHandler = std::bind(&ESPMegaWebServer::saveConfigHandler, this, std::placeholders::_1);
this->server->on("/config", HTTP_POST, bindedSaveConfigHandler);
auto bindedOtaRequestHandler = std::bind(&ESPMegaWebServer::otaRequestHandler, this, std::placeholders::_1);
auto bindedOtaUploadHandler = std::bind(&ESPMegaWebServer::otaUploadHandler, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6);
this->server->on("/ota_update", HTTP_POST, bindedOtaRequestHandler, bindedOtaUploadHandler);
}
void ESPMegaWebServer::loop()
@ -36,8 +39,8 @@ void ESPMegaWebServer::bindFRAM(FRAM *fram)
void ESPMegaWebServer::loadCredentialsFromFRAM()
{
this->fram->read(301, (uint8_t*)this->webUsername, 32);
this->fram->read(333, (uint8_t*)this->webPassword, 32);
this->fram->read(301, (uint8_t *)this->webUsername, 32);
this->fram->read(333, (uint8_t *)this->webPassword, 32);
// Verify if credentials are valid
// A valid username and password is null terminated
// Scan for null terminator
@ -49,7 +52,7 @@ void ESPMegaWebServer::loadCredentialsFromFRAM()
{
validUsername = true;
break;
}
}
}
for (int i = 0; i < 32; i++)
{
@ -65,7 +68,7 @@ void ESPMegaWebServer::loadCredentialsFromFRAM()
return;
}
// A valid username and password is at least 1 character long
if(strlen(this->webUsername) == 0 || strlen(this->webPassword) == 0)
if (strlen(this->webUsername) == 0 || strlen(this->webPassword) == 0)
{
this->resetCredentials();
return;
@ -74,8 +77,8 @@ void ESPMegaWebServer::loadCredentialsFromFRAM()
void ESPMegaWebServer::saveCredentialsToFRAM()
{
this->fram->write(301, (uint8_t*)this->webUsername, 32);
this->fram->write(333, (uint8_t*)this->webPassword, 32);
this->fram->write(301, (uint8_t *)this->webUsername, 32);
this->fram->write(333, (uint8_t *)this->webPassword, 32);
}
void ESPMegaWebServer::resetCredentials()
@ -86,32 +89,34 @@ void ESPMegaWebServer::resetCredentials()
this->saveCredentialsToFRAM();
}
char* ESPMegaWebServer::getWebUsername()
char *ESPMegaWebServer::getWebUsername()
{
return this->webUsername;
}
char* ESPMegaWebServer::getWebPassword()
char *ESPMegaWebServer::getWebPassword()
{
return this->webPassword;
}
void ESPMegaWebServer::setWebUsername(const char* username)
void ESPMegaWebServer::setWebUsername(const char *username)
{
strcpy(this->webUsername, username);
}
void ESPMegaWebServer::setWebPassword(const char* password)
void ESPMegaWebServer::setWebPassword(const char *password)
{
strcpy(this->webPassword, password);
}
void ESPMegaWebServer::dashboardHandler(AsyncWebServerRequest *request)
{
request->authenticate(this->webUsername, this->webPassword);
if (!request->authenticate(this->webUsername, this->webPassword))
{
return request->requestAuthentication();
}
auto bindedDashboardProcessor = std::bind(&ESPMegaWebServer::dashboardProcessor, this, std::placeholders::_1);
request->send_P(200, "text/html", ota_html, bindedDashboardProcessor);
}
String ESPMegaWebServer::dashboardProcessor(const String &var)
@ -154,7 +159,10 @@ String ESPMegaWebServer::dashboardProcessor(const String &var)
void ESPMegaWebServer::configHandler(AsyncWebServerRequest *request)
{
request->authenticate(this->webUsername, this->webPassword);
if (!request->authenticate(this->webUsername, this->webPassword))
{
return request->requestAuthentication();
}
auto bindedConfigProcessor = std::bind(&ESPMegaWebServer::configProcessor, this, std::placeholders::_1);
request->send_P(200, "text/html", config_html, bindedConfigProcessor);
}
@ -191,7 +199,8 @@ String ESPMegaWebServer::configProcessor(const String &var)
{
return String(mqttConfig->mqtt_port);
}
else if (var == "bms_useauth") {
else if (var == "bms_useauth")
{
return mqttConfig->mqtt_useauth ? "checked=\"checked\"" : "";
}
else if (var == "bms_username")
@ -217,14 +226,60 @@ String ESPMegaWebServer::configProcessor(const String &var)
return "";
}
void ESPMegaWebServer::otaHandler(AsyncWebServerRequest *request)
void ESPMegaWebServer::otaRequestHandler(AsyncWebServerRequest *request)
{
// Prepare to receive firmware
if (!request->authenticate(this->webUsername, this->webPassword))
{
return request->requestAuthentication();
}
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
response->addHeader("Connection", "close");
request->send(response);
// Restart ESPMega
ESP.restart();
}
void ESPMegaWebServer::saveConfigHandler(AsyncWebServerRequest *request) {
/**
void ESPMegaWebServer::otaUploadHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
{
// Receive firmware
if (!request->authenticate(this->webUsername, this->webPassword))
{
return request->requestAuthentication();
}
if (index == 0)
{
ESP_LOGI("ESPMegaWebServer", "OTA Update Start");
if (!Update.begin(UPDATE_SIZE_UNKNOWN))
{ // start with max available size
ESP_LOGE("ESPMegaWebServer", "OTA Update Start Error");
Update.printError(Serial);
}
}
if (Update.write(data, len) != len)
{
ESP_LOGE("ESPMegaWebServer", "OTA Update Write Error");
Update.printError(Serial);
} else {
ESP_LOGI("ESPMegaWebServer", "OTA Update Write Success: %uB", index + len);
}
if (final)
{
if (Update.end(true))
{ // true to set the size to the current progress
ESP_LOGI("ESPMegaWebServer", "OTA Update Success: %uB", index + len);
}
else
{
ESP_LOGE("ESPMegaWebServer", "OTA Update End Error");
Update.printError(Serial);
}
}
}
void ESPMegaWebServer::saveConfigHandler(AsyncWebServerRequest *request)
{
/**
* Request POST body should be a JSON object
* containing the following fields:
* ip_address: String, the IP address of the device
@ -243,7 +298,8 @@ void ESPMegaWebServer::saveConfigHandler(AsyncWebServerRequest *request) {
*/
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, request->getParam("plain")->value());
if (error) {
if (error)
{
request->send(400, "text/plain", "Invalid JSON");
return;
}
@ -251,22 +307,26 @@ void ESPMegaWebServer::saveConfigHandler(AsyncWebServerRequest *request) {
// Network Config
NetworkConfig networkConfig;
IPAddress ip;
if (!ip.fromString(root["ip_address"].as<String>())) {
if (!ip.fromString(root["ip_address"].as<String>()))
{
request->send(400, "text/plain", "Invalid IP Address");
return;
}
networkConfig.ip = ip;
if (!ip.fromString(root["netmask"].as<String>())) {
if (!ip.fromString(root["netmask"].as<String>()))
{
request->send(400, "text/plain", "Invalid Netmask");
return;
}
networkConfig.subnet = ip;
if (!ip.fromString(root["gateway"].as<String>())) {
if (!ip.fromString(root["gateway"].as<String>()))
{
request->send(400, "text/plain", "Invalid Gateway");
return;
}
networkConfig.gateway = ip;
if (!ip.fromString(root["dns"].as<String>())) {
if (!ip.fromString(root["dns"].as<String>()))
{
request->send(400, "text/plain", "Invalid DNS");
return;
}
@ -276,7 +336,8 @@ void ESPMegaWebServer::saveConfigHandler(AsyncWebServerRequest *request) {
MqttConfig mqttConfig;
strcpy(mqttConfig.mqtt_server, root["bms_ip"].as<String>().c_str());
uint16_t mqttPort = root["bms_port"].as<int>();
if (mqttConfig.mqtt_port <= 0 || mqttConfig.mqtt_port > 65535) {
if (mqttConfig.mqtt_port <= 0 || mqttConfig.mqtt_port > 65535)
{
request->send(400, "text/plain", "Invalid MQTT Port");
return;
}