OTA preperations
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -43,3 +43,9 @@
|
|||||||
[submodule "components/esp-nimble-cpp"]
|
[submodule "components/esp-nimble-cpp"]
|
||||||
path = components/esp-nimble-cpp
|
path = components/esp-nimble-cpp
|
||||||
url = git@github.com:0xFEEDC0DE64/esp-nimble-cpp.git
|
url = git@github.com:0xFEEDC0DE64/esp-nimble-cpp.git
|
||||||
|
[submodule "components/espasyncota"]
|
||||||
|
path = components/espasyncota
|
||||||
|
url = git@github.com:0xFEEDC0DE64/espasyncota.git
|
||||||
|
[submodule "components/esphttpdutils"]
|
||||||
|
path = components/esphttpdutils
|
||||||
|
url = git@github.com:0xFEEDC0DE64/esphttpdutils.git
|
||||||
|
@ -41,8 +41,7 @@ add_definitions(
|
|||||||
-DDEVICE_PREFIX=bobbyquad
|
-DDEVICE_PREFIX=bobbyquad
|
||||||
-DAP_PASSWORD=Passwort_123
|
-DAP_PASSWORD=Passwort_123
|
||||||
-DFEATURE_WEBSERVER
|
-DFEATURE_WEBSERVER
|
||||||
# -DFEATURE_ARDUINOOTA
|
-DFEATURE_OTA
|
||||||
# -DFEATURE_WEBOTA
|
|
||||||
-DFEATURE_DPAD_5WIRESW
|
-DFEATURE_DPAD_5WIRESW
|
||||||
-DPINS_DPAD_5WIRESW_OUT=18
|
-DPINS_DPAD_5WIRESW_OUT=18
|
||||||
-DPINS_DPAD_5WIRESW_IN1=19
|
-DPINS_DPAD_5WIRESW_IN1=19
|
||||||
|
Submodule components/ArduinoJson updated: 73a34f7d92...475a650703
Submodule components/arduino-esp32 updated: ff9ec961c1...a84e0538ff
Submodule components/cpputils updated: 89bff1a8dc...faeacdcfbf
1
components/espasyncota
Submodule
1
components/espasyncota
Submodule
Submodule components/espasyncota added at b76c6c7bf2
Submodule components/espchrono updated: 7f8a185678...4d2e9305dc
Submodule components/espcpputils updated: 3a350f1189...1ef4a9ea56
1
components/esphttpdutils
Submodule
1
components/esphttpdutils
Submodule
Submodule components/esphttpdutils added at a78711317b
Submodule components/espwifistack updated: 79e5736649...717d877a44
Submodule components/expected updated: aa9b2b2d1f...30ee4ea505
Submodule components/fmt updated: 4b11c94036...d3c349f69d
2
esp-idf
2
esp-idf
Submodule esp-idf updated: cd7cd9ddef...9e9abdf483
@ -183,7 +183,7 @@ set(dependencies
|
|||||||
libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver
|
libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver
|
||||||
arduino-esp32 ArduinoJson esp-nimble-cpp
|
arduino-esp32 ArduinoJson esp-nimble-cpp
|
||||||
bobbycar-protocol cpputils cxx-ring-buffer date
|
bobbycar-protocol cpputils cxx-ring-buffer date
|
||||||
espchrono espcpputils espwifistack expected fmt TFT_eSPI
|
espasyncota espchrono espcpputils esphttpdutils espwifistack expected fmt TFT_eSPI
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(FEATURE_ARDUINOOTA) || defined(FEATURE_WEBOTA)
|
#ifdef FEATURE_OTA
|
||||||
#include <ArduinoOTA.h>
|
#include <espasyncota.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
@ -20,7 +20,7 @@ class StatusDisplay;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#if defined(FEATURE_ARDUINOOTA) || defined(FEATURE_WEBOTA)
|
#ifdef FEATURE_OTA
|
||||||
class UpdateDisplay : public Display, public DummyBack
|
class UpdateDisplay : public Display, public DummyBack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -36,8 +36,6 @@ public:
|
|||||||
bool m_finished;
|
bool m_finished;
|
||||||
unsigned int m_progress;
|
unsigned int m_progress;
|
||||||
unsigned int m_total;
|
unsigned int m_total;
|
||||||
ota_error_t m_error;
|
|
||||||
bool m_errorValid;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string m_title;
|
const std::string m_title;
|
||||||
@ -60,7 +58,6 @@ void UpdateDisplay::start()
|
|||||||
m_finished = false;
|
m_finished = false;
|
||||||
m_progress = 0;
|
m_progress = 0;
|
||||||
m_total = 1;
|
m_total = 1;
|
||||||
m_errorValid = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDisplay::initScreen()
|
void UpdateDisplay::initScreen()
|
||||||
|
@ -245,7 +245,7 @@ extern "C" void app_main()
|
|||||||
|
|
||||||
currentMode = &modes::defaultMode;
|
currentMode = &modes::defaultMode;
|
||||||
|
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
#ifdef FEATURE_OTA
|
||||||
bootLabel.redraw("ota");
|
bootLabel.redraw("ota");
|
||||||
initOta();
|
initOta();
|
||||||
printMemoryStats("initOta()");
|
printMemoryStats("initOta()");
|
||||||
@ -369,7 +369,7 @@ extern "C" void app_main()
|
|||||||
|
|
||||||
handleSerial();
|
handleSerial();
|
||||||
|
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
#ifdef FEATURE_OTA
|
||||||
handleOta();
|
handleOta();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
60
main/ota.h
60
main/ota.h
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
#ifdef FEATURE_OTA
|
||||||
#include <ArduinoOTA.h>
|
#include <espasyncota.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
@ -9,41 +9,41 @@
|
|||||||
#include "displays/updatedisplay.h"
|
#include "displays/updatedisplay.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
#ifdef FEATURE_OTA
|
||||||
void initOta()
|
void initOta()
|
||||||
{
|
{
|
||||||
ArduinoOTA
|
// ArduinoOTA
|
||||||
.onStart([]() {
|
// .onStart([]() {
|
||||||
std::string type;
|
// std::string type;
|
||||||
switch (ArduinoOTA.getCommand())
|
// switch (ArduinoOTA.getCommand())
|
||||||
{
|
// {
|
||||||
case U_FLASH: type = "sketch"; break;
|
// case U_FLASH: type = "sketch"; break;
|
||||||
case U_SPIFFS: type = "filesystem"; break;
|
// case U_SPIFFS: type = "filesystem"; break;
|
||||||
default: type = "unknown";
|
// default: type = "unknown";
|
||||||
}
|
// }
|
||||||
switchScreenImpl<UpdateDisplay>("Updating " + type);
|
// switchScreenImpl<UpdateDisplay>("Updating " + type);
|
||||||
})
|
// })
|
||||||
.onEnd([]() {
|
// .onEnd([]() {
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_finished = true;
|
// ((UpdateDisplay*)currentDisplay.get())->m_finished = true;
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
// ((UpdateDisplay*)currentDisplay.get())->redraw();
|
||||||
})
|
// })
|
||||||
.onProgress([](unsigned int progress, unsigned int total) {
|
// .onProgress([](unsigned int progress, unsigned int total) {
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_progress = progress;
|
// ((UpdateDisplay*)currentDisplay.get())->m_progress = progress;
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_total = total;
|
// ((UpdateDisplay*)currentDisplay.get())->m_total = total;
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
// ((UpdateDisplay*)currentDisplay.get())->redraw();
|
||||||
})
|
// })
|
||||||
.onError([](ota_error_t error) {
|
// .onError([](ota_error_t error) {
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_error = error;
|
// ((UpdateDisplay*)currentDisplay.get())->m_error = error;
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_errorValid = true;
|
// ((UpdateDisplay*)currentDisplay.get())->m_errorValid = true;
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
// ((UpdateDisplay*)currentDisplay.get())->redraw();
|
||||||
});
|
// });
|
||||||
|
|
||||||
ArduinoOTA.begin();
|
// ArduinoOTA.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOta()
|
void handleOta()
|
||||||
{
|
{
|
||||||
ArduinoOTA.handle();
|
// ArduinoOTA.handle();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
19
main/utils.h
19
main/utils.h
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
#include <driver/twai.h>
|
#include <driver/twai.h>
|
||||||
|
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
|
||||||
#include <ArduinoOTA.h>
|
|
||||||
#endif
|
|
||||||
#ifdef FEATURE_SERIAL
|
#ifdef FEATURE_SERIAL
|
||||||
#include <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
#endif
|
#endif
|
||||||
@ -123,22 +120,6 @@ std::string to_string(bobbycar::protocol::ControlMode value)
|
|||||||
return "Unknown ControlMode(" + std::to_string(int(value)) + ')';
|
return "Unknown ControlMode(" + std::to_string(int(value)) + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEATURE_ARDUINOOTA
|
|
||||||
std::string to_string(ota_error_t value)
|
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case OTA_AUTH_ERROR: return "OTA_AUTH_ERROR";
|
|
||||||
case OTA_BEGIN_ERROR: return "OTA_BEGIN_ERROR";
|
|
||||||
case OTA_CONNECT_ERROR: return "OTA_CONNECT_ERROR";
|
|
||||||
case OTA_RECEIVE_ERROR: return "OTA_RECEIVE_ERROR";
|
|
||||||
case OTA_END_ERROR: return "OTA_END_ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown ota_error_t(" + std::to_string(int(value)) + ')';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::array<std::reference_wrapper<bobbycar::protocol::serial::MotorState>, 2> motorsInController(Controller &controller)
|
std::array<std::reference_wrapper<bobbycar::protocol::serial::MotorState>, 2> motorsInController(Controller &controller)
|
||||||
{
|
{
|
||||||
return {std::ref(controller.command.left), std::ref(controller.command.right)};
|
return {std::ref(controller.command.left), std::ref(controller.command.right)};
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "displays/updatedisplay.h"
|
#include "displays/updatedisplay.h"
|
||||||
//#include "esputils.h"
|
//#include "esputils.h"
|
||||||
#include "buttons.h"
|
#include "buttons.h"
|
||||||
|
#include "esphttpdutils.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef FEATURE_WEBSERVER
|
#ifdef FEATURE_WEBSERVER
|
||||||
@ -111,100 +112,6 @@ void initWebserver()
|
|||||||
//if (result != ESP_OK)
|
//if (result != ESP_OK)
|
||||||
// return result;
|
// return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEATURE_WEBOTA
|
|
||||||
webServer.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
request->send(200, "text/html",
|
|
||||||
"<form method=\"POST\" action=\"/updateCode\" enctype=\"multipart/form-data\">"
|
|
||||||
"<input type=\"file\" name=\"update\">"
|
|
||||||
"<input type=\"submit\" value=\"Update Code\">"
|
|
||||||
"</form>"
|
|
||||||
"<form method=\"POST\" action=\"/updateData\" enctype=\"multipart/form-data\">"
|
|
||||||
"<input type=\"file\" name=\"update\">"
|
|
||||||
"<input type=\"submit\" value=\"Update Data\">"
|
|
||||||
"</form>");
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto handleUpdate = [](AsyncWebServerRequest *request){
|
|
||||||
shouldReboot = !Update.hasError();
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot ? "OK" : "FAIL");
|
|
||||||
response->addHeader("Connection", "close");
|
|
||||||
request->send(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto createHandleUpdtateUpload = [](size_t size, int command){
|
|
||||||
return [size, command](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
|
||||||
//ESP_UNUSED(request)
|
|
||||||
|
|
||||||
//Serial.printf("callback %u %u\r\n", index, len);
|
|
||||||
|
|
||||||
if (!index)
|
|
||||||
{
|
|
||||||
//Serial.printf("Update Start: %s\r\n", filename.c_str());
|
|
||||||
//Update.runAsync(true);
|
|
||||||
if (!Update.begin(size, command))
|
|
||||||
Update.printError(Serial);
|
|
||||||
|
|
||||||
std::string type;
|
|
||||||
if (ArduinoOTA.getCommand() == U_FLASH)
|
|
||||||
type = "sketch";
|
|
||||||
else if (ArduinoOTA.getCommand() == U_SPIFFS) // U_SPIFFS
|
|
||||||
type = "filesystem";
|
|
||||||
else
|
|
||||||
type = "unknown";
|
|
||||||
|
|
||||||
switchScreenImpl<UpdateDisplay>("Updating " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Update.hasError())
|
|
||||||
{
|
|
||||||
if (Update.write(data, len) == len)
|
|
||||||
{
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_progress = index;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_total = size;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Update.printError(Serial);
|
|
||||||
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_error = {};
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_errorValid = true;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_error = {};
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_errorValid = true;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (final)
|
|
||||||
{
|
|
||||||
if (Update.end(true))
|
|
||||||
{
|
|
||||||
//Serial.printf("Update Success: %uB\r\n", index + len);
|
|
||||||
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_finished = true;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Update.printError(Serial);
|
|
||||||
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_error = {};
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->m_errorValid = true;
|
|
||||||
((UpdateDisplay*)currentDisplay.get())->redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
webServer.on("/updateCode", HTTP_POST, handleUpdate, createHandleUpdtateUpload((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000, U_FLASH));
|
|
||||||
webServer.on("/updateData", HTTP_POST, handleUpdate, createHandleUpdtateUpload(UPDATE_SIZE_UNKNOWN, U_SPIFFS));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleWebserver()
|
void handleWebserver()
|
||||||
@ -359,7 +266,7 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
|
|||||||
if (const auto result = httpd_query_key_value(query.data(), indexParamName.data(), valueBufEncoded, 256); result == ESP_OK)
|
if (const auto result = httpd_query_key_value(query.data(), indexParamName.data(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
{
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
esphttpdutils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
std::string_view value{valueBuf};
|
std::string_view value{valueBuf};
|
||||||
|
|
||||||
@ -421,7 +328,7 @@ esp_err_t webserver_setValue_handler(httpd_req_t *req)
|
|||||||
if (const auto result = httpd_query_key_value(query.data(), valueParamName.data(), valueBufEncoded, 256); result == ESP_OK)
|
if (const auto result = httpd_query_key_value(query.data(), valueParamName.data(), valueBufEncoded, 256); result == ESP_OK)
|
||||||
{
|
{
|
||||||
char valueBuf[257];
|
char valueBuf[257];
|
||||||
espcpputils::urldecode(valueBuf, valueBufEncoded);
|
esphttpdutils::urldecode(valueBuf, valueBufEncoded);
|
||||||
|
|
||||||
std::string_view value{valueBuf};
|
std::string_view value{valueBuf};
|
||||||
|
|
||||||
|
@ -12,40 +12,35 @@ wifi_stack::config wifi_create_config()
|
|||||||
return wifi_stack::config {
|
return wifi_stack::config {
|
||||||
.wifiEnabled = true,
|
.wifiEnabled = true,
|
||||||
.hostname = deviceName,
|
.hostname = deviceName,
|
||||||
.wifis = std::array<wifi_stack::wifi_entry, 10> {
|
.sta = {
|
||||||
wifi_stack::wifi_entry { .ssid = "realraum", .key = "r3alraum" },
|
.wifis = std::array<wifi_stack::wifi_entry, 10> {
|
||||||
wifi_stack::wifi_entry { .ssid = "McDonalds Free WiFi", .key = "Passwort_123" },
|
wifi_stack::wifi_entry { .ssid = "realraum", .key = "r3alraum" },
|
||||||
wifi_stack::wifi_entry { .ssid = "***REMOVED***", .key = "***REMOVED***" },
|
wifi_stack::wifi_entry { .ssid = "McDonalds Free WiFi", .key = "Passwort_123" },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = "***REMOVED***", .key = "***REMOVED***" },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
wifi_stack::wifi_entry { .ssid = {}, .key = {} }
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} },
|
||||||
},
|
wifi_stack::wifi_entry { .ssid = {}, .key = {} }
|
||||||
.sta_ip = {
|
},
|
||||||
.staticIpEnabled = false,
|
.min_rssi = -90
|
||||||
// .staticIp = {},
|
|
||||||
// .staticGateway = {},
|
|
||||||
// .staticSubnet = {},
|
|
||||||
// .staticDns1 = {},
|
|
||||||
// .staticDns2 = {}
|
|
||||||
},
|
},
|
||||||
.ap = {
|
.ap = {
|
||||||
{
|
.ssid = deviceName,
|
||||||
.ssid = deviceName,
|
.key = STRING(AP_PASSWORD),
|
||||||
.key = STRING(AP_PASSWORD)
|
.static_ip = {
|
||||||
|
.ip = {10, 0, 0, 1},
|
||||||
|
.subnet = {255, 255, 255, 0},
|
||||||
|
.gateway = {10, 0, 0, 1},
|
||||||
},
|
},
|
||||||
.channel = 1,
|
.channel = 1,
|
||||||
.authmode = WIFI_AUTH_WPA2_PSK,
|
.authmode = WIFI_AUTH_WPA2_PSK,
|
||||||
.ssid_hidden = false,
|
.ssid_hidden = false,
|
||||||
.max_connection = 4,
|
.max_connection = 4,
|
||||||
.beacon_interval = 100,
|
.beacon_interval = 100
|
||||||
.ip = {10, 0, 0, 1},
|
}
|
||||||
.subnet = {255, 255, 255, 0}
|
|
||||||
},
|
|
||||||
.min_rssi = -90
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user