diff --git a/include/hasp_conf.h b/include/hasp_conf.h index 59ef00c1..723b070d 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -214,7 +214,12 @@ /* Workarounds for PC build */ #if HASP_TARGET_PC #ifndef __FlashStringHelper -#define __FlashStringHelper char +typedef char __FlashStringHelper; +#endif + +#if defined(__cplusplus) && !defined(String) +#include +using String = std::string; #endif #ifndef F diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 80c699ab..db7ffdf4 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -460,10 +460,12 @@ void dispatch_config(const char* topic, const char* payload, uint8_t source) } if(strcasecmp_P(topic, PSTR("debug")) == 0) { +#if HASP_TARGET_ARDUINO if(update) debugSetConfig(settings); else debugGetConfig(settings); +#endif } else if(strcasecmp_P(topic, PSTR("gui")) == 0) { @@ -734,7 +736,7 @@ void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id) void dispatch_parse_jsonl(const char*, const char* payload, uint8_t source) { if(source != TAG_MQTT) saved_jsonl_page = haspPages.get(); -#if HASP_USE_CONFIG > 0 +#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO CharStream stream((char*)payload); // stream.setTimeout(10); dispatch_parse_jsonl(stream, saved_jsonl_page); @@ -1510,7 +1512,7 @@ void dispatchSetup() dispatch_add_command(PSTR("unzip"), filesystemUnzip); #endif #endif -#if HASP_USE_CONFIG > 0 +#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO dispatch_add_command(PSTR("setupap"), oobeFakeSetup); #endif /* WARNING: remember to expand the commands array when adding new commands */ diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index d3e55b1e..559c3f0a 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -8,7 +8,9 @@ #include "hasp_config.h" #include "hasp_debug.h" #include "hasp_gui.h" +#if HASP_TARGET_ARDUINO #include "hal/hasp_hal.h" +#endif // #include "hasp_ota.h" included in conf // #include "hasp_filesystem.h" included in conf @@ -21,7 +23,9 @@ #include "EEPROM.h" #endif +#if HASP_USE_EEPROM > 0 #include "StreamUtils.h" // For EEPromStream +#endif extern uint16_t dispatchTelePeriod; extern uint32_t dispatchLastMillis; @@ -29,6 +33,7 @@ extern uint32_t dispatchLastMillis; extern gui_conf_t gui_settings; extern dispatch_conf_t dispatch_settings; +#if HASP_TARGET_ARDUINO void confDebugSet(const __FlashStringHelper* fstr_name) { /*char buffer[128]; @@ -36,6 +41,7 @@ void confDebugSet(const __FlashStringHelper* fstr_name) debugPrintln(buffer);*/ LOG_VERBOSE(TAG_CONF, F(D_BULLET "%S set"), fstr_name); } +#endif void confDebugSet(const char* fstr_name) { /*char buffer[128]; @@ -44,6 +50,7 @@ void confDebugSet(const char* fstr_name) LOG_VERBOSE(TAG_CONF, F(D_BULLET "%s set"), fstr_name); } +#if HASP_TARGET_ARDUINO bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name) { if(!setting.isNull()) { @@ -130,6 +137,7 @@ bool configSet(char *value, size_t size, const JsonVariant& setting, const __Fla } return false; } +#endif bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name) { @@ -207,7 +215,9 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n void configSetupDebug(JsonDocument& settings) { +#if HASP_TARGET_ARDUINO debugSetup(settings[FPSTR(FP_DEBUG)]); +#endif debugStart(); // Debug started, now we can use it; HASP header sent } @@ -239,9 +249,9 @@ void configMaskPasswords(JsonDocument& settings) DeserializationError configParseFile(String& configFile, JsonDocument& settings) { + DeserializationError result = DeserializationError::InvalidInput; #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 File file = HASP_FS.open(configFile, "r"); - DeserializationError result; if(file) { // size_t size = file.size(); @@ -254,30 +264,51 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings) return result; } return DeserializationError::InvalidInput; +#elif HASP_TARGET_PC + lv_fs_if_init(); + lv_fs_file_t f; + lv_fs_res_t res; + lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD); + if(res == LV_FS_RES_OK) { + uint32_t size = 0, read = 0; + if(lv_fs_size(&f, &size) == LV_FS_RES_OK && size != 0) { + char* buf = (char*)malloc(size + 1); + if(lv_fs_read(&f, buf, size, &read) == LV_FS_RES_OK && read == size) { + result = deserializeJson(settings, buf); + } + } + lv_fs_close(&f); + return result; + } + LOG_ERROR(TAG_HASP, F("Opening config.json from FS failed %d"), res); + return result; #else - return DeserializationError::InvalidInput; + return result; #endif } DeserializationError configRead(JsonDocument& settings, bool setupdebug) { - String configFile((char*)0); + String configFile; configFile.reserve(32); configFile = String(FPSTR(FP_HASP_CONFIG_FILE)); DeserializationError error; -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 + if(setupdebug) configSetupDebug(settings); // Now we can use log + +#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 || HASP_TARGET_PC error = configParseFile(configFile, settings); if(!error) { String output, wifiPass, mqttPass, httpPass, wgPrivKey; /* Load Debug params */ if(setupdebug) { - configSetupDebug(settings); // Now we can use log LOG_INFO(TAG_CONF, F("SPI flash FS mounted")); +#if HASP_TARGET_ARDUINO filesystemInfo(); filesystemList(); +#endif } LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str()); @@ -304,9 +335,6 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug) #endif - // File does not exist or error reading file - if(setupdebug) configSetupDebug(settings); // Now we can use log - #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 LOG_ERROR(TAG_CONF, F(D_FILE_LOAD_FAILED), configFile.c_str()); #endif @@ -360,11 +388,11 @@ void configBackupToEeprom() */ void configWrite() { - String configFile((char*)0); + String configFile; configFile.reserve(32); configFile = String(FPSTR(FP_HASP_CONFIG_FILE)); - String settingsChanged((char*)0); + String settingsChanged; settingsChanged.reserve(128); settingsChanged = F(D_CONFIG_CHANGED); @@ -462,6 +490,7 @@ void configWrite() } #endif +#if HASP_TARGET_ARDUINO module = FPSTR(FP_DEBUG); if(settings[module].as().isNull()) settings.createNestedObject(module); changed = debugGetConfig(settings[module]); @@ -470,6 +499,7 @@ void configWrite() configOutput(settings[module], TAG_DEBG); writefile = true; } +#endif if(settings[FPSTR(FP_GUI)].as().isNull()) settings.createNestedObject(FPSTR(FP_GUI)); changed = guiGetConfig(settings[FPSTR(FP_GUI)]); @@ -561,9 +591,10 @@ void configSetup() configRead(settings, true); } - // #if HASP_USE_SPIFFS > 0 +#if HASP_TARGET_ARDUINO LOG_INFO(TAG_DEBG, F("Loading debug settings")); debugSetConfig(settings[FPSTR(FP_DEBUG)]); +#endif LOG_INFO(TAG_GPIO, F("Loading GUI settings")); guiSetConfig(settings[FPSTR(FP_GUI)]); LOG_INFO(TAG_HASP, F("Loading HASP settings")); @@ -615,15 +646,15 @@ void configLoop(void) void configOutput(const JsonObject& settings, uint8_t tag) { - String output((char*)0); + String output; output.reserve(128); serializeJson(settings, output); - String passmask((char*)0); + String passmask; passmask.reserve(128); passmask = F("\"pass\":\"" D_PASSWORD_MASK "\""); - String password((char*)0); + String password; password.reserve(128); String pass = F("pass"); @@ -631,28 +662,48 @@ void configOutput(const JsonObject& settings, uint8_t tag) password = F("\"pass\":\""); password += settings[pass].as(); password += F("\""); +#if HASP_TARGET_ARDUINO output.replace(password, passmask); +#elif HASP_TARGET_PC + size_t pos = 0; + if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask); +#endif } if(!settings[FPSTR(FP_WIFI)][pass].isNull()) { password = F("\"pass\":\""); password += settings[FPSTR(FP_WIFI)][pass].as(); password += F("\""); +#if HASP_TARGET_ARDUINO output.replace(password, passmask); +#elif HASP_TARGET_PC + size_t pos = 0; + if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask); +#endif } if(!settings[FPSTR(FP_MQTT)][pass].isNull()) { password = F("\"pass\":\""); password += settings[FPSTR(FP_MQTT)][pass].as(); password += F("\""); +#if HASP_TARGET_ARDUINO output.replace(password, passmask); +#elif HASP_TARGET_PC + size_t pos = 0; + if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask); +#endif } if(!settings[FPSTR(FP_HTTP)][pass].isNull()) { password = F("\"pass\":\""); password += settings[FPSTR(FP_HTTP)][pass].as(); password += F("\""); +#if HASP_TARGET_ARDUINO output.replace(password, passmask); +#elif HASP_TARGET_PC + size_t pos = 0; + if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask); +#endif } if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) { @@ -660,7 +711,12 @@ void configOutput(const JsonObject& settings, uint8_t tag) password += settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as(); password += F("\""); passmask = F("\"privkey\":\"" D_PASSWORD_MASK "\""); +#if HASP_TARGET_ARDUINO output.replace(password, passmask); +#elif HASP_TARGET_PC + size_t pos = 0; + if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask); +#endif } LOG_VERBOSE(tag, output.c_str()); @@ -688,4 +744,4 @@ bool configClearEeprom() #endif } -#endif // HAS_USE_CONFIG \ No newline at end of file +#endif // HAS_USE_CONFIG diff --git a/src/hasp_config.h b/src/hasp_config.h index 8a667ed6..04160d30 100644 --- a/src/hasp_config.h +++ b/src/hasp_config.h @@ -25,13 +25,15 @@ void configOutput(const JsonObject& settings, uint8_t tag); bool configClearEeprom(void); /* ===== Getter and Setter Functions ===== */ +#if HASP_TARGET_ARDUINO bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); bool configSet(int8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); bool configSet(uint8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); bool configSet(int32_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name); -bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name); +bool configSet(char* value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name); +#endif bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name); bool configSet(int8_t& value, const JsonVariant& setting, const char* fstr_name); bool configSet(uint8_t& value, const JsonVariant& setting, const char* fstr_name); @@ -41,8 +43,10 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n void configMaskPasswords(JsonDocument& settings); /* ===== Read/Write Configuration ===== */ +#if HASP_TARGET_ARDUINO void configSetConfig(JsonObject& settings); void configGetConfig(JsonDocument& settings); +#endif /* json keys used in the configfile */ const char FP_CONFIG_STARTPAGE[] PROGMEM = "startpage"; @@ -107,4 +111,4 @@ const char FP_OTA[] PROGMEM = "ota"; #endif -#endif // HASP_USE_CONFIG \ No newline at end of file +#endif // HASP_USE_CONFIG diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index fa2f5406..421606cc 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -8,12 +8,12 @@ #include "hasp_debug.h" #include "hasp_macro.h" -#if(!defined(WINDOWS)) && (!defined(POSIX)) +#if HASP_TARGET_ARDUINO #define debug_print(io, ...) io->printf(__VA_ARGS__) #define debug_newline(io) io->println() -#else +#elif HASP_TARGET_PC #include #include #include @@ -21,6 +21,17 @@ #define debug_print(io, ...) fprintf(stdout, __VA_ARGS__) #define debug_newline(io) fprintf(stdout, "\n") +#if defined(WINDOWS) +#include +#include +#define cwd _getcwd +#endif + +#if defined(POSIX) +#include +#define cwd getcwd +#endif + #endif bool debugAnsiCodes = false; @@ -121,6 +132,8 @@ void debugStart(void) debugPrintHaspHeader(NULL); debug_newline(); + char curdir[PATH_MAX]; + LOG_INFO(TAG_DEBG, F("Configuration directory: %s"), cwd(curdir, sizeof(curdir))); LOG_INFO(TAG_DEBG, F("Environment: " PIOENV)); LOG_INFO(TAG_DEBG, F("Console started")); @@ -445,4 +458,4 @@ void debugPrintPrefix(uint8_t tag, int level, Print* _logOutput) #else debug_print(_logOutput, PSTR(" %s: "), buffer); #endif -} \ No newline at end of file +} diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 68a51d1c..d39195e8 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -207,21 +207,7 @@ static inline void gui_init_images() static inline void gui_init_filesystems() { #if LV_USE_FS_IF != 0 - //_lv_fs_init(); // lvgl File System -- not needed, it done in lv_init() when LV_USE_FILESYSTEM is set LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED)); - lv_fs_if_init(); // auxiliary file system drivers - // filesystem_list_path("L:/"); - - lv_fs_file_t f; - lv_fs_res_t res; - res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - LOG_VERBOSE(TAG_HASP, F("TEST Opening config.json OK")); - lv_fs_close(&f); - } else { - LOG_ERROR(TAG_HASP, F("TEST Opening config.json from FS failed %d"), res); - } - #else LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED)); #endif diff --git a/src/main_pc.cpp b/src/main_pc.cpp index c4988771..6b2d0c83 100644 --- a/src/main_pc.cpp +++ b/src/main_pc.cpp @@ -112,15 +112,15 @@ void InitializeConsoleOutput() void setup() { - // Load Settings - - // Init debug log - // debug_init(); - // Initialize lvgl environment lv_init(); lv_log_register_print_cb(debugLvglLogEvent); + // Read & Apply User Configuration +#if HASP_USE_CONFIG > 0 + configSetup(); +#endif + haspDevice.init(); // hardware setup haspDevice.show_info(); // debug info // hal_setup(); diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index 17804f89..323b82fd 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -8,12 +8,14 @@ #if HASP_USE_MQTT > 0 #ifdef HASP_USE_PAHO +#if !HASP_USE_CONFIG const char FP_CONFIG_HOST[] PROGMEM = "host"; const char FP_CONFIG_PORT[] PROGMEM = "port"; const char FP_CONFIG_NAME[] PROGMEM = "name"; const char FP_CONFIG_USER[] PROGMEM = "user"; const char FP_CONFIG_PASS[] PROGMEM = "pass"; const char FP_CONFIG_GROUP[] PROGMEM = "group"; +#endif /******************************************************************************* * Copyright (c) 2012, 2020 IBM Corp. @@ -411,6 +413,32 @@ void mqtt_get_info(JsonDocument& doc) info[F(D_INFO_FAILED)] = mqttFailedCount; } +bool mqttGetConfig(const JsonObject& settings) +{ + bool changed = false; + + if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as().c_str()) != 0) changed = true; + settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname(); + + if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as()) changed = true; + settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName; + + if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as()) changed = true; + settings[FPSTR(FP_CONFIG_HOST)] = mqttServer; + + if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true; + settings[FPSTR(FP_CONFIG_PORT)] = mqttPort; + + if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as()) changed = true; + settings[FPSTR(FP_CONFIG_USER)] = mqttUsername; + + if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as()) changed = true; + settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword; + + if(changed) configOutput(settings, TAG_MQTT); + return changed; +} + /** Set MQTT Configuration. * * Read the settings from json and sets the application variables. diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini index 87a24f4e..4330c02a 100644 --- a/user_setups/win32/windows_gdi_64bits.ini +++ b/user_setups/win32/windows_gdi_64bits.ini @@ -22,7 +22,7 @@ build_flags = -D HASP_USE_LITTLEFS=0 -D HASP_USE_EEPROM=0 -D HASP_USE_GPIO=1 - -D HASP_USE_CONFIG=0 ; Standalone application, as library + -D HASP_USE_CONFIG=1 ; Standalone application, as library -D HASP_USE_DEBUG=1 -D HASP_USE_PNGDECODE=1 -D HASP_USE_BMPDECODE=1 diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini index e7b7b082..30de808f 100644 --- a/user_setups/win32/windows_sdl_64bits.ini +++ b/user_setups/win32/windows_sdl_64bits.ini @@ -26,7 +26,7 @@ build_flags = -D HASP_USE_LITTLEFS=0 -D HASP_USE_EEPROM=0 -D HASP_USE_GPIO=1 - -D HASP_USE_CONFIG=0 ; Standalone application, as library + -D HASP_USE_CONFIG=1 ; Standalone application, as library -D HASP_USE_DEBUG=1 -D HASP_USE_PNGDECODE=1 -D HASP_USE_BMPDECODE=1