OTA preperations

This commit is contained in:
2021-08-09 12:57:40 +02:00
parent c52a72f485
commit 673f68d2c1
20 changed files with 79 additions and 192 deletions

6
.gitmodules vendored
View File

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

View File

@ -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 esp-idf updated: cd7cd9ddef...9e9abdf483

View File

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

View File

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

View File

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

View File

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

View File

@ -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)};

View File

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

View File

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