From 69b18e14bc511cab9eabc4890592efa4a0b0f4d0 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sat, 24 Dec 2022 12:10:15 +0100 Subject: [PATCH 1/2] Initial Test --- .../jomjol_fileserver_ota/server_file.cpp | 20 +- .../jomjol_fileserver_ota/server_file.h | 2 +- .../jomjol_fileserver_ota/server_ota.cpp | 19 +- code/components/jomjol_helper/Helper.cpp | 11 + code/components/jomjol_wlan/read_wlanini.cpp | 8 +- code/components/jomjol_wlan/read_wlanini.h | 2 +- code/main/main.cpp | 14 +- code/main/server_main.cpp | 4 + code/main/softAP.cpp | 424 ++++++++++++++++++ code/main/softAP.h | 21 + sd-card/html/wlan_config.html | 105 +++++ 11 files changed, 614 insertions(+), 16 deletions(-) create mode 100644 code/main/softAP.cpp create mode 100644 code/main/softAP.h create mode 100644 sd-card/html/wlan_config.html diff --git a/code/components/jomjol_fileserver_ota/server_file.cpp b/code/components/jomjol_fileserver_ota/server_file.cpp index 8cf838125..1fd75a597 100644 --- a/code/components/jomjol_fileserver_ota/server_file.cpp +++ b/code/components/jomjol_fileserver_ota/server_file.cpp @@ -895,7 +895,7 @@ void delete_all_in_directory(std::string _directory) closedir(dir); } -std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main) +std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main, bool _initial_setup) { int i, sort_iter; mz_bool status; @@ -905,13 +905,9 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st char archive_filename[64]; std::string zw, ret = ""; std::string directory = ""; -// static const char* s_Test_archive_filename = "testhtml.zip"; ESP_LOGD(TAG, "miniz.c version: %s", MZ_VERSION); ESP_LOGD(TAG, "Zipfile: %s", _in_zip_file.c_str()); -// ESP_LOGD(TAG, "Target Dir ZIP: %s", _target_zip.c_str()); -// ESP_LOGD(TAG, "Target Dir BIN: %s", _target_bin.c_str()); -// ESP_LOGD(TAG, "Target Dir main: %s", _main.c_str()); // Now try to open the archive. memset(&zip_archive, 0, sizeof(zip_archive)); @@ -928,7 +924,6 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st sort_iter = 0; -// for (sort_iter = 0; sort_iter < 2; sort_iter++) { memset(&zip_archive, 0, sizeof(zip_archive)); status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0); @@ -966,6 +961,16 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st else { std::string _dir = getDirectory(zw); + if ((_dir == "config-initial") && !_initial_setup) + { + continue; + } + else + { + _dir = "config"; + std::string _s1 = "config-initial"; + FindReplace(zw, _s1, _dir); + } if (_dir.length() > 0) { @@ -1006,9 +1011,6 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st isokay = isokay && RenameFile(filename_zw, zw); if (!isokay) ESP_LOGE(TAG, "ERROR in Rename \"%s\" to \"%s\"", filename_zw.c_str(), zw.c_str()); -// isokay = isokay && DeleteFile(filename_zw); -// if (!isokay) -// ESP_LOGE(TAG, "ERROR in Delete \"%s\"", filename_zw.c_str()); if (isokay) ESP_LOGI(TAG, "Successfully extracted file \"%s\", size %u", archive_filename, (uint)uncomp_size); diff --git a/code/components/jomjol_fileserver_ota/server_file.h b/code/components/jomjol_fileserver_ota/server_file.h index 735f6ffb7..cae835124 100644 --- a/code/components/jomjol_fileserver_ota/server_file.h +++ b/code/components/jomjol_fileserver_ota/server_file.h @@ -9,7 +9,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path); void unzip(std::string _in_zip_file, std::string _target_directory); -std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main = "/sdcard/"); +std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main = "/sdcard/", bool _initial_setup = false); void delete_all_in_directory(std::string _directory); diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index af58be04e..7f4627050 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -47,7 +47,7 @@ static const char *TAG = "OTA"; esp_err_t handler_reboot(httpd_req_t *req); std::string _file_name_update; - +bool initial_setup = false; static void infinite_loop(void) @@ -75,7 +75,7 @@ void task_do_Update_ZIP(void *pvParameter) out = "/sdcard/html"; outbin = "/sdcard/firmware"; - retfirmware = unzip_new(_file_name_update, out+"/", outbin+"/"); + retfirmware = unzip_new(_file_name_update, out+"/", outbin+"/", "/sdcard/", initial_setup); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files unzipped."); if (retfirmware.length() > 0) @@ -83,6 +83,12 @@ void task_do_Update_ZIP(void *pvParameter) LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Found firmware.bin"); ota_update_task(retfirmware); } + + if (initial_setup) + { + + } + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update."); doReboot(); } @@ -105,6 +111,15 @@ void CheckUpdate() char zw[1024] = ""; fgets(zw, 1024, pfile); _file_name_update = std::string(zw); + if (fgets(zw, 1024, pfile)) + { + std::string _szw = std::string(zw); + if (_szw == "init") + { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Inital Setup triggered."); + initial_setup = true; } + } + fclose(pfile); DeleteFile("/sdcard/update.txt"); // Prevent Boot Loop!!! LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update during boot triggered - Update File: " + _file_name_update); diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index c52ce02cb..dc73bb07d 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -582,6 +582,17 @@ std::vector ZerlegeZeile(std::string input, std::string delimiter) } +std::string ReplaceString(std::string subject, const std::string& search, + const std::string& replace) { + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + return subject; +} + + /* Source: https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git/tree/lsmmc.c */ /* SD Card Manufacturer Database */ struct SDCard_Manufacturer_database { diff --git a/code/components/jomjol_wlan/read_wlanini.cpp b/code/components/jomjol_wlan/read_wlanini.cpp index 23822e24f..70f54c976 100644 --- a/code/components/jomjol_wlan/read_wlanini.cpp +++ b/code/components/jomjol_wlan/read_wlanini.cpp @@ -41,7 +41,7 @@ std::vector ZerlegeZeileWLAN(std::string input, std::string _delimiter = -void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_hostname, char *&_ipadr, char *&_gw, char *&_netmask, char *&_dns, int &_rssithreashold) +bool LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_hostname, char *&_ipadr, char *&_gw, char *&_netmask, char *&_dns, int &_rssithreashold) { std::string ssid = ""; std::string passphrase = ""; @@ -59,10 +59,13 @@ void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_ho fn = FormatFileName(fn); pFile = fopen(fn.c_str(), "r"); + if (!pFile) + return false; + ESP_LOGD(TAG, "file loaded"); if (pFile == NULL) - return; + return false; char zw[1024]; fgets(zw, 1024, pFile); @@ -193,6 +196,7 @@ void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_ho _rssithreashold = rssithreshold; RSSIThreashold = rssithreshold; + return true; } diff --git a/code/components/jomjol_wlan/read_wlanini.h b/code/components/jomjol_wlan/read_wlanini.h index fc21029fa..3a1182a82 100644 --- a/code/components/jomjol_wlan/read_wlanini.h +++ b/code/components/jomjol_wlan/read_wlanini.h @@ -5,7 +5,7 @@ #include -void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_hostname, char *&_ipadr, char *&_gw, char *&_netmask, char *&_dns, int &_rssithreashold); +bool LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_hostname, char *&_ipadr, char *&_gw, char *&_netmask, char *&_dns, int &_rssithreashold); bool ChangeHostName(std::string fn, std::string _newhostname); bool ChangeRSSIThreashold(std::string fn, int _newrssithreashold); diff --git a/code/main/main.cpp b/code/main/main.cpp index b495b0d03..1f1c98fb4 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -39,6 +39,8 @@ #include "../../include/defines.h" //#include "server_GPIO.h" +#include "softAP.h" + extern const char* GIT_TAG; extern const char* GIT_REV; extern const char* GIT_BRANCH; @@ -175,7 +177,16 @@ extern "C" void app_main(void) CheckUpdate(); char *ssid = NULL, *passwd = NULL, *hostname = NULL, *ip = NULL, *gateway = NULL, *netmask = NULL, *dns = NULL; int rssithreashold = 0; - LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns, rssithreashold); + if (!LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns, rssithreashold)) + { + // config.ini existiert nicht! --> mache einen AP statt eines STA! + wifi_init_softap(); + StartTaskWebServerAP(); + while(1) { // wait until reboot within task_do_Update_ZIP + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + }; LogFile.WriteToFile(ESP_LOG_INFO, TAG, "WLAN-Settings - RSSI-Threashold: " + to_string(rssithreashold)); @@ -323,3 +334,4 @@ extern "C" void app_main(void) LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Not starting flows!"); } } + diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index f028a6484..fd7a608ec 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -16,6 +16,8 @@ #include "server_tflite.h" #include "esp_log.h" +#include + #include "Helper.h" httpd_handle_t server = NULL; @@ -350,6 +352,7 @@ esp_err_t img_tmp_virtual_handler(httpd_req_t *req) + esp_err_t sysinfo_handler(httpd_req_t *req) { const char* resp_str; @@ -421,6 +424,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_register_uri_handler(server, &starttime_tmp_handle); + httpd_uri_t img_tmp_handle = { .uri = "/img_tmp/*", // Match all URIs of type /path/to/file .method = HTTP_GET, diff --git a/code/main/softAP.cpp b/code/main/softAP.cpp new file mode 100644 index 000000000..fd9d2d937 --- /dev/null +++ b/code/main/softAP.cpp @@ -0,0 +1,424 @@ +#include "softAP.h" + +/* WiFi softAP Example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_mac.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" + +#include "stdio.h" + +#include "ClassLogFile.h" +#include "server_help.h" +#include "defines.h" +#include "Helper.h" +#include "server_ota.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +/* The examples use WiFi configuration that you can set via project configuration menu. + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define EXAMPLE_ESP_WIFI_SSID "AIONEDGE" +#define EXAMPLE_ESP_WIFI_PASS "" +#define EXAMPLE_ESP_WIFI_CHANNEL 11 +#define EXAMPLE_MAX_STA_CONN 1 + +static const char *TAG = "wifi softAP"; + +static void wifi_event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_id == WIFI_EVENT_AP_STACONNECTED) { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", + MAC2STR(event->mac), event->aid); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", + MAC2STR(event->mac), event->aid); + } +} + +void wifi_init_softap(void) +{ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_ap(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + NULL)); + + wifi_config_t wifi_config = { }; + + strcpy((char*)wifi_config.ap.ssid, (const char*) EXAMPLE_ESP_WIFI_SSID); + strcpy((char*)wifi_config.ap.password, (const char*) EXAMPLE_ESP_WIFI_PASS); + wifi_config.ap.channel = EXAMPLE_ESP_WIFI_CHANNEL; + wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN; + wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; + + if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) { + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + } + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL); +} + + + + +esp_err_t test_handler(httpd_req_t *req) +{ + std::string message = "

AI-on-the-edge - BASIC SETUP

There is no wlan.ini, therefore no connection possible.

"; + message += ""; + message += ""; + message += ""; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + message = ""; + message += ""; + message += ""; + message += ""; + message += ""; + message += ""; + message += ""; + message += "/
WLAN-SSIDSSID of the WLAN
WLAN-PasswordATTENTION: the password will not be encrypted during the sending.
Hostname
Fixed IPLeave emtpy if set by router
gatewayLeave emtpy if set by router
netmaskLeave emtpy if set by router
DNSLeave emtpy if set by router
RSSI ThreasholdWLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)
"; + message += ""; + message += ""; + + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + message = ""; + message += ""; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + + httpd_resp_send_chunk(req, NULL, 0); + + return ESP_OK; +} + + +esp_err_t config_ini_handler(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_ota_update - Start"); +#endif + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "config_ini_handler"); + char _query[400]; + char _valuechar[100]; + std::string fn = "/sdcard/firmware/"; + std::string _task = ""; + std::string ssid = ""; + std::string pwd = ""; + std::string hn = ""; // hostname + std::string ip = ""; + std::string gw = ""; // gateway + std::string nm = ""; // nm + std::string dns = ""; + std::string rssi = ""; + + + if (httpd_req_get_url_query_str(req, _query, 400) == ESP_OK) + { + ESP_LOGD(TAG, "Query: %s", _query); + + if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "ssid is found: %s", _valuechar); + ssid = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "pwd", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "pwd is found: %s", _valuechar); + pwd = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "ssid is found: %s", _valuechar); + ssid = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "hn", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "hostname is found: %s", _valuechar); + hn = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "ip", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "ip is found: %s", _valuechar); + ip = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "gw", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "gateway is found: %s", _valuechar); + gw = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "nm", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "netmask is found: %s", _valuechar); + nm = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "dns", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "dns is found: %s", _valuechar); + dns = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "rssi", _valuechar, 30) == ESP_OK) + { + ESP_LOGD(TAG, "rssi is found: %s", _valuechar); + rssi = std::string(_valuechar); + } + }; + + FILE* configfilehandle = fopen("/sdcard/wlan.ini", "w"); + + if (ssid.length()) + ssid = "ssid = \"" + ssid + "\"\n"; + else + ssid = ";ssid = \"\"\n"; + + fputs(ssid.c_str(), configfilehandle); + + if (pwd.length()) + pwd = "password = \"" + pwd + "\"\n"; + else + pwd = ";password = \"\"\n"; + fputs(pwd.c_str(), configfilehandle); + + if (hn.length()) + hn = "hostname = \"" + hn + "\"\n"; + else + hn = ";hostname = \"\"\n"; + fputs(hn.c_str(), configfilehandle); + + if (ip.length()) + ip = "ip = \"" + ip + "\"\n"; + else + ip = ";ip = \"\"\n"; + fputs(ip.c_str(), configfilehandle); + + if (gw.length()) + gw = "gateway = \"" + gw + "\"\n"; + else + gw = ";gateway = \"\"\n"; + fputs(gw.c_str(), configfilehandle); + + if (nm.length()) + nm = "netmask = \"" + nm + "\"\n"; + else + nm = ";netmask = \"\"\n"; + fputs(nm.c_str(), configfilehandle); + + if (dns.length()) + dns = "dns = \"" + dns + "\"\n"; + else + dns = ";dns = \"\"\n"; + fputs(dns.c_str(), configfilehandle); + + if (rssi.length()) + rssi = "RSSIThreashold = \"" + rssi + "\"\n"; + else + rssi = ";rssi = \"\"\n"; + fputs(rssi.c_str(), configfilehandle); + + fflush(configfilehandle); + fclose(configfilehandle); + + std::string zw = "ota without parameter - should not be the case!"; + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, zw.c_str(), strlen(zw.c_str())); + httpd_resp_send_chunk(req, NULL, 0); + + ESP_LOGE(TAG, "end config.ini"); + + + return ESP_OK; +}; + + +esp_err_t upload_post_handlerAP(httpd_req_t *req) +{ + printf("Start des Post Handlers\n"); + MakeDir("/sdcard/config"); + MakeDir("/sdcard/firmware"); + MakeDir("/sdcard/html"); + MakeDir("/sdcard/img_tmp"); + MakeDir("/sdcard/log"); + printf("Nach Start des Post Handlers\n"); + + + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "upload_post_handlerAP"); + char filepath[FILE_PATH_MAX]; + FILE *fd = NULL; + + const char *filename = get_path_from_uri(filepath, "/sdcard", + req->uri + sizeof("/upload") - 1, sizeof(filepath)); + if (!filename) { + httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long"); + return ESP_FAIL; + } + + printf("filepath: %s, filename: %s\n", filepath, filename); + + DeleteFile(std::string(filepath)); + + + + fd = fopen(filepath, "w"); + if (!fd) { + ESP_LOGE(TAG, "Failed to create file: %s", filepath); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create file"); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "Receiving file: %s...", filename); + + char buf[1024]; + int received; + + int remaining = req->content_len; + + printf("remaining: %d\n", remaining); + + + + while (remaining > 0) { + + ESP_LOGI(TAG, "Remaining size: %d", remaining); + if ((received = httpd_req_recv(req, buf, MIN(remaining, 1024))) <= 0) { + if (received == HTTPD_SOCK_ERR_TIMEOUT) { + continue; + } + + fclose(fd); + unlink(filepath); + + ESP_LOGE(TAG, "File reception failed!"); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file"); + return ESP_FAIL; + } + + if (received && (received != fwrite(buf, 1, received, fd))) { + fclose(fd); + unlink(filepath); + + ESP_LOGE(TAG, "File write failed!"); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to write file to storage"); + return ESP_FAIL; + } + + remaining -= received; + } + + FILE* pfile = fopen("/sdcard/update.txt", "w"); + fwrite(filename, strlen(filename), 1, pfile); + fclose(pfile); + + + fclose(fd); + ESP_LOGI(TAG, "File reception complete"); + + httpd_resp_sendstr(req, "File uploaded successfully"); + return ESP_OK; +} + +httpd_handle_t start_webserverAP(void); + +void task_WebServerAP(void *pvParameter) +{ +// start_webserverAP(); +} + +void StartTaskWebServerAP() +{ + start_webserverAP(); +/* + BaseType_t xReturned; + xReturned = xTaskCreate(&task_WebServerAP, "task_WebServerAP", configMINIMAL_STACK_SIZE * 10, NULL, tskIDLE_PRIORITY+1, NULL); + while(1) { // wait until reboot within task_do_Update_ZIP + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +*/ +} + +httpd_handle_t start_webserverAP(void) +{ + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.uri_match_fn = httpd_uri_match_wildcard; + httpd_handle_t server = NULL; + if (httpd_start(&server, &config) == ESP_OK) { + // Do something + } + + httpd_uri_t config_ini_handle = { + .uri = "/config", // Match all URIs of type /path/to/file + .method = HTTP_GET, + .handler = config_ini_handler, + .user_ctx = NULL // Pass server data as context + }; + httpd_register_uri_handler(server, &config_ini_handle); + + /* URI handler for uploading files to server */ + httpd_uri_t file_uploadAP = { + .uri = "/upload/*", // Match all URIs of type /upload/path/to/file + .method = HTTP_POST, + .handler = upload_post_handlerAP, + .user_ctx = NULL // Pass server data as context + }; + httpd_register_uri_handler(server, &file_uploadAP); + + httpd_uri_t test_uri = { + .uri = "/test", + .method = HTTP_GET, + .handler = test_handler, + .user_ctx = NULL + }; + httpd_register_uri_handler(server, &test_uri); + + return NULL; +} + diff --git a/code/main/softAP.h b/code/main/softAP.h new file mode 100644 index 000000000..6a96b4c27 --- /dev/null +++ b/code/main/softAP.h @@ -0,0 +1,21 @@ +#ifndef SOFTAP_H +#define SOFTAP_H + +#include +#include +#include +#include +#include +#include +#include "nvs_flash.h" +#include "esp_netif.h" +#include "esp_eth.h" +#include "protocol_examples_common.h" +#include "esp_tls_crypto.h" +#include + +void wifi_init_softap(); + +void StartTaskWebServerAP(); + +#endif \ No newline at end of file diff --git a/sd-card/html/wlan_config.html b/sd-card/html/wlan_config.html new file mode 100644 index 000000000..afc10575c --- /dev/null +++ b/sd-card/html/wlan_config.html @@ -0,0 +1,105 @@ +
+ + + + + + + + +
WLAN-SSIDSSID of the WLAN
WLAN-PasswordATTENTION: the password will not be encrypted during the sending.
Hostname
Fixed IPLeave emtpy if set by router
gatewayLeave emtpy if set by router
netmaskLeave emtpy if set by router
DNSLeave emtpy if set by router
RSSI ThreasholdWLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)
+ + + + + + From 6ac4b47aa0ae25ac3d9e6628b73e18af11b20b6d Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Tue, 27 Dec 2022 10:07:25 +0100 Subject: [PATCH 2/2] Initial functional version. --- code/components/jomjol_helper/Helper.cpp | 11 ++ code/components/jomjol_helper/Helper.h | 2 + code/main/main.cpp | 13 +- code/main/softAP.cpp | 177 ++++++++++++++++------- code/main/softAP.h | 4 +- sd-card/html/wlan_config.html | 24 +-- 6 files changed, 146 insertions(+), 85 deletions(-) diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index dc73bb07d..08949a61c 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -301,6 +301,17 @@ bool RenameFile(string from, string to) return true; } +bool FileExists(string filename) +{ + FILE* fpSourceFile = fopen(filename.c_str(), "rb"); + if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + { + return false; + } + fclose(fpSourceFile); + return true; +} + bool DeleteFile(string fn) { diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index f56f6c9b9..a9ca517bc 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -18,6 +18,7 @@ bool CopyFile(string input, string output); bool DeleteFile(string fn); bool RenameFile(string from, string to); bool MakeDir(std::string _what); +bool FileExists(string filename); string RundeOutput(double _in, int _anzNachkomma); @@ -31,6 +32,7 @@ string getFileType(string filename); string getFileFullFileName(string filename); string getDirectory(string filename); + int mkdir_r(const char *dir, const mode_t mode); int removeFolder(const char* folderPath, const char* logTag); diff --git a/code/main/main.cpp b/code/main/main.cpp index 1f1c98fb4..ae805d876 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -175,18 +175,11 @@ extern "C" void app_main(void) CheckOTAUpdate(); CheckUpdate(); + CheckStartAPMode(); // if no wlan.ini and/or config.ini --> AP ist startet and this function does not exit anymore until reboot - char *ssid = NULL, *passwd = NULL, *hostname = NULL, *ip = NULL, *gateway = NULL, *netmask = NULL, *dns = NULL; int rssithreashold = 0; - if (!LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns, rssithreashold)) - { - // config.ini existiert nicht! --> mache einen AP statt eines STA! - wifi_init_softap(); - StartTaskWebServerAP(); - while(1) { // wait until reboot within task_do_Update_ZIP - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - }; + char *ssid = NULL, *passwd = NULL, *hostname = NULL, *ip = NULL, *gateway = NULL, *netmask = NULL, *dns = NULL; int rssithreashold = 0; + LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns, rssithreashold); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "WLAN-Settings - RSSI-Threashold: " + to_string(rssithreashold)); diff --git a/code/main/softAP.cpp b/code/main/softAP.cpp index fd9d2d937..f90143eca 100644 --- a/code/main/softAP.cpp +++ b/code/main/softAP.cpp @@ -31,11 +31,14 @@ If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ -#define EXAMPLE_ESP_WIFI_SSID "AIONEDGE" +#define EXAMPLE_ESP_WIFI_SSID "AI-on-the-Edge" #define EXAMPLE_ESP_WIFI_PASS "" #define EXAMPLE_ESP_WIFI_CHANNEL 11 #define EXAMPLE_MAX_STA_CONN 1 +bool isConfigINI = false; +bool isWlanINI = false; + static const char *TAG = "wifi softAP"; static void wifi_event_handler(void* arg, esp_event_base_t event_base, @@ -52,7 +55,7 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, } } -void wifi_init_softap(void) +void wifi_init_softAP(void) { ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); @@ -88,51 +91,99 @@ void wifi_init_softap(void) } - - -esp_err_t test_handler(httpd_req_t *req) +void SendHTTPResponse(httpd_req_t *req) { - std::string message = "

AI-on-the-edge - BASIC SETUP

There is no wlan.ini, therefore no connection possible.

"; - message += ""; - message += ""; - message += ""; + std::string message = "

AI-on-the-edge - BASIC SETUP

This is an access point with a minimal server to setup the minimum required files and information on the device and the SD-card. "; + message += "This mode is always startet if one of the following files is missing: /wlan.ini or the /config/config.ini.

"; + message += "The setup is done in 3 steps: 1. upload full inital configuration (sd-card content), 2. store WLAN acces information, 3. reboot (and connect to WLANs)

"; + message += "Please follow the below instructions.

"; httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); - message = "

"; - message += ""; - message += ""; - message += ""; - message += ""; - message += ""; - message += ""; - message += "/
WLAN-SSIDSSID of the WLAN
WLAN-PasswordATTENTION: the password will not be encrypted during the sending.
Hostname
Fixed IPLeave emtpy if set by router
gatewayLeave emtpy if set by router
netmaskLeave emtpy if set by router
DNSLeave emtpy if set by router
RSSI ThreasholdWLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)
"; - message += ""; - message += ""; + isWlanINI = FileExists("/sdcard/wlan.ini"); - httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + if (!isConfigINI) + { + message = "

1. Upload initial configuration to sd-card

"; + message += "The configuration file config.ini is missing and most propably the full configuration and html folder on the sd-card. "; + message += "This is normal after the first flashing of the firmware and an empty sd-card. Please upload \"remote_setup.zip\", which contains an full inital configuration.

"; + message += ""; + message += "

"; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + message = ""; + isConfigINI = true; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + return; + } + if (!isWlanINI) + { + message = "

2. WLAN access credentials

"; + message = "

"; + message += ""; + message += ""; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + +// message = ""; +// message += ""; +// message += ""; +// message += ""; +// message += ""; +// message += ""; +// httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + message = "/
WLAN-SSIDSSID of the WLAN
WLAN-PasswordATTENTION: the password will not be encrypted during the sending.
Hostname
Fixed IPLeave emtpy if set by router
gatewayLeave emtpy if set by router
netmaskLeave emtpy if set by router
DNSLeave emtpy if set by router
RSSI ThreasholdWLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)

"; + message += "

ATTENTION:

Be sure about the WLAN settings. They cannot be reset afterwards. If ssid or password is wrong, you need to take out the sd-card and manually change them in \"wlan.ini\"!

"; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + + message = ""; + message += ""; + httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); + return; + } - message = ""; - message += ""; httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); +} - message = "function upload() {"; - message += "var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {"; - message += "if (xhttp.readyState == 4) {stopProgressTimer();if (xhttp.status == 200) {extract();} }};"; - message += "var filePath = document.getElementById(\"newfile\").value.split(/[\\\\/]/).pop();"; - message += "var file = document.getElementById(\"newfile\").files[0];"; - message += "var upload_path = \"/upload/firmware/\" + filePath; xhttp.open(\"POST\", upload_path, true); xhttp.send(file);}"; - message += ""; - httpd_resp_send_chunk(req, message.c_str(), strlen(message.c_str())); - httpd_resp_send_chunk(req, NULL, 0); +esp_err_t test_handler(httpd_req_t *req) +{ + SendHTTPResponse(req); + httpd_resp_send_chunk(req, NULL, 0); return ESP_OK; } +esp_err_t reboot_handlerAP(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_ota_update - Start"); +#endif + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update."); + doReboot(); + return ESP_OK; +}; + + esp_err_t config_ini_handler(httpd_req_t *req) { #ifdef DEBUG_DETAIL_ON @@ -289,8 +340,6 @@ esp_err_t upload_post_handlerAP(httpd_req_t *req) MakeDir("/sdcard/log"); printf("Nach Start des Post Handlers\n"); - - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "upload_post_handlerAP"); char filepath[FILE_PATH_MAX]; FILE *fd = NULL; @@ -355,35 +404,25 @@ esp_err_t upload_post_handlerAP(httpd_req_t *req) } FILE* pfile = fopen("/sdcard/update.txt", "w"); - fwrite(filename, strlen(filename), 1, pfile); + std::string _s_zw= "/sdcard" + std::string(filename); + fwrite(_s_zw.c_str(), strlen(_s_zw.c_str()), 1, pfile); fclose(pfile); fclose(fd); ESP_LOGI(TAG, "File reception complete"); + httpd_resp_set_hdr(req, "Location", "/test"); + httpd_resp_set_status(req, "303 See Other"); + httpd_resp_set_hdr(req, "Location", "/test"); +// httpd_resp_sendstr(req, "File uploaded successfully"); + httpd_resp_send_chunk(req, NULL, 0); - httpd_resp_sendstr(req, "File uploaded successfully"); - return ESP_OK; -} - -httpd_handle_t start_webserverAP(void); + ESP_LOGI(TAG, "Update page send out"); -void task_WebServerAP(void *pvParameter) -{ -// start_webserverAP(); +// httpd_resp_sendstr(req, "File uploaded successfully"); + return ESP_OK; } -void StartTaskWebServerAP() -{ - start_webserverAP(); -/* - BaseType_t xReturned; - xReturned = xTaskCreate(&task_WebServerAP, "task_WebServerAP", configMINIMAL_STACK_SIZE * 10, NULL, tskIDLE_PRIORITY+1, NULL); - while(1) { // wait until reboot within task_do_Update_ZIP - vTaskDelay(1000 / portTICK_PERIOD_MS); - } -*/ -} httpd_handle_t start_webserverAP(void) { @@ -394,6 +433,14 @@ httpd_handle_t start_webserverAP(void) // Do something } + httpd_uri_t reboot_handle = { + .uri = "/reboot", // Match all URIs of type /path/to/file + .method = HTTP_GET, + .handler = reboot_handlerAP, + .user_ctx = NULL // Pass server data as context + }; + httpd_register_uri_handler(server, &reboot_handle); + httpd_uri_t config_ini_handle = { .uri = "/config", // Match all URIs of type /path/to/file .method = HTTP_GET, @@ -412,7 +459,7 @@ httpd_handle_t start_webserverAP(void) httpd_register_uri_handler(server, &file_uploadAP); httpd_uri_t test_uri = { - .uri = "/test", + .uri = "*", .method = HTTP_GET, .handler = test_handler, .user_ctx = NULL @@ -422,3 +469,21 @@ httpd_handle_t start_webserverAP(void) return NULL; } +void CheckStartAPMode() +{ + isConfigINI = FileExists("/sdcard/config/config.ini"); + isWlanINI = FileExists("/sdcard/wlan.ini"); + + if (!isConfigINI or !isWlanINI) + { + wifi_init_softAP(); + start_webserverAP(); + while(1) { // wait until reboot within task_do_Update_ZIP + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } + + +} + + diff --git a/code/main/softAP.h b/code/main/softAP.h index 6a96b4c27..d5523615e 100644 --- a/code/main/softAP.h +++ b/code/main/softAP.h @@ -14,8 +14,6 @@ #include "esp_tls_crypto.h" #include -void wifi_init_softap(); - -void StartTaskWebServerAP(); +void CheckStartAPMode(); #endif \ No newline at end of file diff --git a/sd-card/html/wlan_config.html b/sd-card/html/wlan_config.html index afc10575c..13b975b06 100644 --- a/sd-card/html/wlan_config.html +++ b/sd-card/html/wlan_config.html @@ -20,24 +20,16 @@ function upload() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { - if (xhttp.readyState == 4) { - stopProgressTimer(); - if (xhttp.status == 200) { - // alert("Upload successfull!") - // document.reload(); - extract(); - } - } - }; + if (xhttp.readyState == 4) {stopProgressTimer();if (xhttp.status == 200) {extract();} }}; var filePath = document.getElementById("newfile").value.split(/[\\\/]/).pop(); -// filePath = nameneu.split(/[\\\/]/).pop(); - var file = document.getElementById("newfile").files[0]; -// var file = fileInput[0]; - var upload_path = "/upload/firmware/" + filePath; - xhttp.open("POST", upload_path, true); - xhttp.send(file); - } + if (!file.name.includes("remote-setup")) + { + if (!confirm("The zip file name should contain \"...remote-setup...\". Are you sure that you have downloaded the correct file?")) + return; + } + + var upload_path = "/upload/firmware/" + filePath; xhttp.open("POST", upload_path, true); xhttp.send(file);} function extract() {