Fix FTP not listing on some shared SD (#958)

* Fix Rename not working on GlobalFS

* esp3d_log refactoring
 - Rename Debug to Log
 - Allow now 4 level of log: None, Error, Debug, Verbose
 - Change original verbose log to error log when it is an error

* Update configuration.h to add debug level expected

* Add log for critical steps in FTP module
This commit is contained in:
Luc 2023-10-27 12:40:22 +08:00 committed by GitHub
parent dc84b0bbdb
commit 3ffb7c3b4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 14369 additions and 14452 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
/*
debug_esp3d.cpp - debug esp3d functions class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../include/esp3d_config.h"
#if defined(ESP_DEBUG_FEATURE)
#ifndef DEBUG_BAUDRATE
#define DEBUG_BAUDRATE 115200
#endif //~DEBUG_BAUDRATE
void initDebug()
{
#if (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL0) || (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL1)||(ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2)
#ifdef ARDUINO_ARCH_ESP8266
DEBUG_OUTPUT_SERIAL.begin(DEBUG_BAUDRATE, SERIAL_8N1, SERIAL_FULL, (ESP_DEBUG_TX_PIN == -1)?1:ESP_DEBUG_TX_PIN);
#if ESP_DEBUG_RX_PIN != -1
DEBUG_OUTPUT_SERIAL.pins((ESP_DEBUG_TX_PIN == -1)?1:ESP_DEBUG_TX_PIN, ESP_DEBUG_RX_PIN)
#endif //ESP_DEBUG_RX_PIN != -1
#endif //ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
DEBUG_OUTPUT_SERIAL.begin (DEBUG_BAUDRATE, SERIAL_8N1, ESP_DEBUG_RX_PIN, ESP_DEBUG_TX_PIN);
#endif //ARDUINO_ARCH_ESP32
#endif // (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL0) || (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL1)||(ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2)
}
//Telnet
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_TELNET
Telnet_Server telnet_debug;
#endif // ESP_DEBUG_FEATURE == DEBUG_OUTPUT_TELNET
//Websocket
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_WEBSOCKET
WebSocket_Server websocket_debug("debug");
#endif // ESP_DEBUG_FEATURE == DEBUG_OUTPUT_WEBSOCKET
#endif //ESP_DEBUG_FEATURE

View File

@ -1,93 +0,0 @@
/*
debug_esp3d.h - esp3d debug functions
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _DEBUG_ESP3D_H
#define _DEBUG_ESP3D_H
#include "../include/esp3d_config.h"
#define DEBUG_ESP3D_INIT
#define DEBUG_ESP3D_NETWORK_INIT
#define DEBUG_ESP3D_NETWORK_HANDLE
#define DEBUG_ESP3D_NETWORK_END
#if defined(ESP_DEBUG_FEATURE)
#if defined(ARDUINO_ARCH_ESP8266)
//no need with latest esp8266 core
#define pathToFileName(p) p
#endif //ARDUINO_ARCH_ESP8266
#undef log_esp3d
#undef log_esp3ds
//Serial
#if (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL0) || (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL1) || (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2)
extern void initDebug();
#ifndef ESP3DLIB_ENV
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL0
#define DEBUG_OUTPUT_SERIAL Serial
#endif //DEBUG_OUTPUT_SERIAL0
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL1
#define DEBUG_OUTPUT_SERIAL Serial1
#endif //DEBUG_OUTPUT_SERIAL1
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2
#define DEBUG_OUTPUT_SERIAL Serial2
#endif //DEBUG_OUTPUT_SERIAL2
#undef DEBUG_ESP3D_INIT
#define DEBUG_ESP3D_INIT initDebug();
#else
#define DEBUG_OUTPUT_SERIAL MYSERIAL1
#endif //ESP3DLIB_ENV
#define log_esp3d(format, ...) DEBUG_OUTPUT_SERIAL.printf("[ESP3D][%s:%u] %s(): " format "\r\n", pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define log_esp3ds(format, ...) DEBUG_OUTPUT_SERIAL.printf(format, ##__VA_ARGS__)
#endif //DEBUG_OUTPUT_SERIAL0 || DEBUG_OUTPUT_SERIAL1 || DEBUG_OUTPUT_SERIAL2
//Telnet
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_TELNET
#include "../modules/telnet/telnet_server.h"
extern Telnet_Server telnet_debug;
#undef DEBUG_ESP3D_NETWORK_INIT
#undef DEBUG_ESP3D_NETWORK_END
#undef DEBUG_ESP3D_NETWORK_HANDLE
#define DEBUG_ESP3D_NETWORK_INIT telnet_debug.begin(DEBUG_ESP3D_OUTPUT_PORT, true);
#define DEBUG_ESP3D_NETWORK_HANDLE telnet_debug.handle();
#define DEBUG_ESP3D_NETWORK_END telnet_debug.end();
#define log_esp3d(format, ...) if(telnet_debug.isConnected())telnet_debug.printf("[ESP3D][%s:%u] %s(): " format "\r\n", pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define log_esp3ds(format, ...) if(telnet_debug.isConnected())telnet_debug.printf(format , ##__VA_ARGS__)
#endif // DEBUG_OUTPUT_TELNET
//Telnet
#if ESP_DEBUG_FEATURE == DEBUG_OUTPUT_WEBSOCKET
#include "../modules/websocket/websocket_server.h"
extern WebSocket_Server websocket_debug;
#undef DEBUG_ESP3D_NETWORK_INIT
#undef DEBUG_ESP3D_NETWORK_END
#undef DEBUG_ESP3D_NETWORK_HANDLE
#define DEBUG_ESP3D_NETWORK_INIT websocket_debug.begin(DEBUG_ESP3D_OUTPUT_PORT, true);
#define DEBUG_ESP3D_NETWORK_HANDLE websocket_debug.handle();
#define DEBUG_ESP3D_NETWORK_END websocket_debug.end();
#define log_esp3d(format, ...) websocket_debug.printf("[ESP3D][%s:%u] %s(): " format "\r\n", pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define log_esp3ds(format, ...) websocket_debug.printf(format, ##__VA_ARGS__)
#endif // DEBUG_OUTPUT_WEBSOCKET
#else
#define log_esp3d(format, ...)
#define log_esp3ds(format, ...)
#endif //ESP_DEBUG_FEATURE
#endif //_DEBUG_ESP3D_H

View File

@ -1,21 +1,21 @@
/* /*
This file is part of ESP3D Firmware for 3D printer. This file is part of ESP3D Firmware for 3D printer.
ESP3D Firmware for 3D printer is free software: you can redistribute it and/or modify ESP3D Firmware for 3D printer is free software: you can redistribute it
it under the terms of the GNU General Public License as published by and/or modify it under the terms of the GNU General Public License as
the Free Software Foundation, either version 3 of the License, or published by the Free Software Foundation, either version 3 of the License,
(at your option) any later version. or (at your option) any later version.
ESP3D Firmware for 3D printer is distributed in the hope that it will be useful, ESP3D Firmware for 3D printer is distributed in the hope that it will be
but WITHOUT ANY WARRANTY; without even the implied warranty of useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this Firmware. If not, see <http://www.gnu.org/licenses/>. along with this Firmware. If not, see <http://www.gnu.org/licenses/>.
This firmware is using the standard arduino IDE with module to support ESP8266/ESP32: This firmware is using the standard arduino IDE with module to support
https://github.com/esp8266/Arduino ESP8266/ESP32: https://github.com/esp8266/Arduino
https://github.com/espressif/arduino-esp32 https://github.com/espressif/arduino-esp32
Latest version of the code and documentation can be found here : Latest version of the code and documentation can be found here :
@ -25,243 +25,233 @@
*/ */
#include "esp3d.h" #include "esp3d.h"
#include "../include/esp3d_config.h" #include "../include/esp3d_config.h"
#include "settings_esp3d.h" #include "settings_esp3d.h"
#if COMMUNICATION_PROTOCOL != SOCKET_SERIAL || ESP_SERIAL_BRIDGE_OUTPUT #if COMMUNICATION_PROTOCOL != SOCKET_SERIAL || ESP_SERIAL_BRIDGE_OUTPUT
#include "../modules/serial/serial_service.h" #include "../modules/serial/serial_service.h"
#endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL
#if COMMUNICATION_PROTOCOL ==SOCKET_SERIAL #if COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../modules/serial2socket/serial2socket.h" #include "../modules/serial2socket/serial2socket.h"
#endif // COMMUNICATION_PROTOCOL ==SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL ==SOCKET_SERIAL
#if defined (WIFI_FEATURE) || defined(ETH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
#include "../modules/network/netconfig.h" #include "../modules/network/netconfig.h"
#endif //WIFI_FEATURE || ETH FEATURE #endif // WIFI_FEATURE || ETH FEATURE
#if defined(FILESYSTEM_FEATURE) #if defined(FILESYSTEM_FEATURE)
#include "../modules/filesystem/esp_filesystem.h" #include "../modules/filesystem/esp_filesystem.h"
#endif //FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#ifdef CONNECTED_DEVICES_FEATURE #ifdef CONNECTED_DEVICES_FEATURE
#include "../modules/devices/devices_services.h" #include "../modules/devices/devices_services.h"
#endif //CONNECTED_DEVICES_FEATURE #endif // CONNECTED_DEVICES_FEATURE
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
#include "../modules/display/display.h" #include "../modules/display/display.h"
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#ifdef GCODE_HOST_FEATURE #ifdef GCODE_HOST_FEATURE
#include "../modules/gcode_host/gcode_host.h" #include "../modules/gcode_host/gcode_host.h"
#endif //GCODE_HOST_FEATURE #endif // GCODE_HOST_FEATURE
#ifdef ESP_LUA_INTERPRETER_FEATURE #ifdef ESP_LUA_INTERPRETER_FEATURE
#include "../modules/lua_interpreter/lua_interpreter_service.h" #include "../modules/lua_interpreter/lua_interpreter_service.h"
#endif //#ifdef #endif // #ifdef
#ifdef SD_UPDATE_FEATURE #ifdef SD_UPDATE_FEATURE
#include "../modules/update/update_service.h" #include "../modules/update/update_service.h"
#endif // SD_UPDATE_FEATURE #endif // SD_UPDATE_FEATURE
#include "esp3doutput.h"
#include "../modules/boot_delay/boot_delay.h" #include "../modules/boot_delay/boot_delay.h"
#include "esp3doutput.h"
bool Esp3D::restart = false; bool Esp3D::restart = false;
//Contructor // Contructor
Esp3D::Esp3D() Esp3D::Esp3D() { _started = false; }
{
_started = false;
}
//Destructor // Destructor
Esp3D::~Esp3D() Esp3D::~Esp3D() { end(); }
{
end();
}
//Begin which setup everything // Begin which setup everything
bool Esp3D::begin() bool Esp3D::begin() {
{ BootDelay bd;
BootDelay bd; Hal::begin();
Hal::begin(); LOG_ESP3D_INIT
DEBUG_ESP3D_INIT
#if COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.enable(); Serial2Socket.enable();
#endif // COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//init output // init output
ESP3DOutput::isOutput(ESP_ALL_CLIENTS, true); ESP3DOutput::isOutput(ESP_ALL_CLIENTS, true);
bool res = true; bool res = true;
#if defined(CONNECTED_DEVICES_FEATURE) #if defined(CONNECTED_DEVICES_FEATURE)
if (!DevicesServices::begin()) { if (!DevicesServices::begin()) {
log_esp3d("Error setup connected devices"); log_esp3d_e("Error setup connected devices");
res = false; res = false;
} }
#endif //CONNECTED_DEVICES_FEATURE #endif // CONNECTED_DEVICES_FEATURE
//delay to avoid to disturb printer // delay to avoid to disturb printer
bd.begin(); bd.begin();
#ifdef SD_UPDATE_FEATURE #ifdef SD_UPDATE_FEATURE
if (update_service.begin()) { if (update_service.begin()) {
log_esp3d("Need restart due to update"); log_esp3d("Need restart due to update");
//no need to continue as there was an update // no need to continue as there was an update
restart_now(); restart_now();
} }
#endif // SD_UPDATE_FEATURE #endif // SD_UPDATE_FEATURE
log_esp3d("Mode %d", WiFi.getMode()); log_esp3d("Mode %d", WiFi.getMode());
if (!Settings_ESP3D::begin()) { if (!Settings_ESP3D::begin()) {
log_esp3d("Need reset settings"); log_esp3d("Need reset settings");
reset(); reset();
//Restart ESP3D // Restart ESP3D
restart_now(); restart_now();
} }
//BT do not start automaticaly so should be OK // BT do not start automaticaly so should be OK
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
//Serial service // Serial service
if (!serial_service.begin(ESP_SERIAL_OUTPUT)) { if (!serial_service.begin(ESP_SERIAL_OUTPUT)) {
log_esp3d("Error with serial service"); log_esp3d_e("Error with serial service");
res = false; res = false;
} }
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
//Serial bridge // MKS_SERIAL
// Serial bridge
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
if (!serial_bridge_service.begin(ESP_SERIAL_BRIDGE_OUTPUT)) { if (!serial_bridge_service.begin(ESP_SERIAL_BRIDGE_OUTPUT)) {
log_esp3d("Error with serial bridge service"); log_esp3d_e("Error with serial bridge service");
res = false; res = false;
} }
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
//Setup Filesystem // Setup Filesystem
#if defined(FILESYSTEM_FEATURE) #if defined(FILESYSTEM_FEATURE)
if (!ESP_FileSystem::begin()) { if (!ESP_FileSystem::begin()) {
log_esp3d("Error with filesystem service"); log_esp3d_e("Error with filesystem service");
res = false; res = false;
} }
#endif //FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
esp3d_display.showScreenID(MAIN_SCREEN); esp3d_display.showScreenID(MAIN_SCREEN);
log_esp3d("Main screen"); log_esp3d("Main screen");
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
//Setup Network // Setup Network
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BLUETOOTH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BLUETOOTH_FEATURE)
if (Settings_ESP3D::read_byte(ESP_BOOT_RADIO_STATE) == 1) { if (Settings_ESP3D::read_byte(ESP_BOOT_RADIO_STATE) == 1) {
if (!NetConfig::begin()) { if (!NetConfig::begin()) {
log_esp3d("Error setup network"); log_esp3d_e("Error setup network");
res = false; res = false;
}
} }
}
#endif //WIFI_FEATURE #endif // WIFI_FEATURE
#if defined(GCODE_HOST_FEATURE) #if defined(GCODE_HOST_FEATURE)
#if defined(ESP_AUTOSTART_SCRIPT) #if defined(ESP_AUTOSTART_SCRIPT)
esp3d_gcode_host.processScript(ESP_AUTOSTART_SCRIPT); esp3d_gcode_host.processScript(ESP_AUTOSTART_SCRIPT);
#endif //ESP_AUTOSTART_FEATURE #endif // ESP_AUTOSTART_FEATURE
#if defined(ESP_AUTOSTART_SCRIPT_FILE) #if defined(ESP_AUTOSTART_SCRIPT_FILE)
esp3d_gcode_host.processFile(ESP_AUTOSTART_SCRIPT_FILE); esp3d_gcode_host.processFile(ESP_AUTOSTART_SCRIPT_FILE);
#endif //ESP_AUTOSTART_FEATURE #endif // ESP_AUTOSTART_FEATURE
#endif //GCODE_HOST_FEATURE #endif // GCODE_HOST_FEATURE
_started=true; _started = true;
return res; return res;
} }
//Process which handle all input // Process which handle all input
void Esp3D::handle() void Esp3D::handle() {
{ if (!_started) {
if(!_started) { return;
return; }
} // if need restart
//if need restart if (restart) {
if (restart) { restart_now();
restart_now(); }
}
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
serial_service.handle(); serial_service.handle();
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
// MKS_SERIAL
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
serial_bridge_service.handle(); serial_bridge_service.handle();
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
#if COMMUNICATION_PROTOCOL ==SOCKET_SERIAL #if COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.handle(); Serial2Socket.handle();
#endif //COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
NetConfig::handle(); NetConfig::handle();
#endif //WIFI_FEATURE || ETH_FEATURE #endif // WIFI_FEATURE || ETH_FEATURE
#if defined(CONNECTED_DEVICES_FEATURE) #if defined(CONNECTED_DEVICES_FEATURE)
DevicesServices::handle(); DevicesServices::handle();
#endif //CONNECTED_DEVICES_FEATURE #endif // CONNECTED_DEVICES_FEATURE
#if defined(GCODE_HOST_FEATURE) #if defined(GCODE_HOST_FEATURE)
esp3d_gcode_host.handle(); esp3d_gcode_host.handle();
#endif //GCODE_HOST_FEATURE #endif // GCODE_HOST_FEATURE
} }
bool Esp3D::started() bool Esp3D::started() { return _started; }
{
return _started;
}
//End ESP3D // End ESP3D
bool Esp3D::end() bool Esp3D::end() {
{ _started = false;
_started = false;
#if defined(CONNECTED_DEVICES_FEATURE) #if defined(CONNECTED_DEVICES_FEATURE)
DevicesServices::end(); DevicesServices::end();
#endif //CONNECTED_DEVICES_FEATURE #endif // CONNECTED_DEVICES_FEATURE
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
serial_bridge_service.end(); serial_bridge_service.end();
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
NetConfig::end(); NetConfig::end();
#endif //WIFI_FEATURE || ETH_FEATURE #endif // WIFI_FEATURE || ETH_FEATURE
#if defined(FILESYSTEM_FEATURE) #if defined(FILESYSTEM_FEATURE)
ESP_FileSystem::end(); ESP_FileSystem::end();
#endif //FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
serial_service.end(); serial_service.end();
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
return true; // MKS_SERIAL
return true;
} }
//Reset ESP3D settings // Reset ESP3D settings
bool Esp3D::reset() bool Esp3D::reset() {
{ bool resetOk = true;
bool resetOk = true;
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
if (!serial_service.reset()) { if (!serial_service.reset()) {
resetOk = false; resetOk = false;
log_esp3d("Reset serial error"); log_esp3d_e("Reset serial error");
} }
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
// MKS_SERIAL
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
if (!serial_bridge_service.reset()) { if (!serial_bridge_service.reset()) {
resetOk = false; resetOk = false;
log_esp3d("Reset serial bridge error"); log_esp3d_e("Reset serial bridge error");
} }
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
if (!Settings_ESP3D::reset()) { if (!Settings_ESP3D::reset()) {
log_esp3d("Reset settings error"); log_esp3d_e("Reset settings error");
resetOk = false; resetOk = false;
} }
return resetOk; return resetOk;
} }
//Set Restart flag // Set Restart flag
void Esp3D::restart_esp(bool need_restart) void Esp3D::restart_esp(bool need_restart) { restart = need_restart; }
{
restart = need_restart;
}
void Esp3D::restart_now() void Esp3D::restart_now() {
{ // patch for
//patch for https://github.com/espressif/arduino-esp32/issues/1912#issuecomment-426247971 // https://github.com/espressif/arduino-esp32/issues/1912#issuecomment-426247971
#if defined(ETH_FEATURE) && defined(ESP3D_ETH_PHY_POWER_PIN) #if defined(ETH_FEATURE) && defined(ESP3D_ETH_PHY_POWER_PIN)
digitalWrite(ESP3D_ETH_PHY_POWER_PIN, LOW); digitalWrite(ESP3D_ETH_PHY_POWER_PIN, LOW);
#endif //ESP3D_ETH_PHY_POWER_PIN #endif // ESP3D_ETH_PHY_POWER_PIN
log_esp3d("Restarting"); log_esp3d("Restarting");
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
if (!serial_service.started()) { if (!serial_service.started()) {
serial_service.begin(ESP_SERIAL_OUTPUT); serial_service.begin(ESP_SERIAL_OUTPUT);
} }
serial_service.flush(); serial_service.flush();
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
// MKS_SERIAL
#if defined(FILESYSTEM_FEATURE) #if defined(FILESYSTEM_FEATURE)
ESP_FileSystem::end(); ESP_FileSystem::end();
#endif //FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
serial_service.swap(); serial_service.swap();
#endif //COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
ESP.restart(); // MKS_SERIAL
while (1) { ESP.restart();
delay (1); while (1) {
} delay(1);
}
} }

View File

@ -20,25 +20,25 @@
#ifndef _ESP3D_H #ifndef _ESP3D_H
#define _ESP3D_H #define _ESP3D_H
//be sure correct IDE and settings are used for ESP8266 or ESP32 // be sure correct IDE and settings are used for ESP8266 or ESP32
#if !(defined( ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)) #if !(defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32))
#error Oops! Make sure you have 'ESP8266 or ESP32' compatible board selected from the 'Tools -> Boards' menu. #error Oops! Make sure you have 'ESP8266 or ESP32' compatible board selected from the 'Tools -> Boards' menu.
#endif // ARDUINO_ARCH_ESP8266 + ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP8266 + ARDUINO_ARCH_ESP32
#include <Arduino.h> #include <Arduino.h>
class Esp3D class Esp3D {
{ public:
public: Esp3D();
Esp3D(); ~Esp3D();
~Esp3D(); bool begin();
bool begin(); void handle();
void handle(); bool end();
bool end(); bool started();
bool started(); static bool reset();
static bool reset(); static void restart_esp(bool need_restart = true);
static void restart_esp(bool need_restart = true);
private: private:
static bool restart; static bool restart;
bool _started; bool _started;
void restart_now(); void restart_now();
}; };
#endif //_ESP3D_H #endif //_ESP3D_H

File diff suppressed because it is too large Load Diff

View File

@ -17,49 +17,51 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined( WIFI_FEATURE) || defined (ETH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/network/netconfig.h"
#include "../commands.h" #include "../commands.h"
#include "../esp3doutput.h" #include "../esp3doutput.h"
#include "../settings_esp3d.h" #include "../settings_esp3d.h"
#include "../../modules/network/netconfig.h"
#include "../../modules/authentication/authentication_service.h"
#define COMMANDID 111
//Get current IP
//[ESP111] [json=no]
bool Commands::ESP111(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
{
log_esp3d("Client is %d", output?output->client():0);
(void)auth_type;
bool noError = true;
bool json = has_tag (cmd_params, "json");
String response ;
String parameter = clean_param(get_param (cmd_params, ""));
if (parameter.length() == 0) {
response = format_response(COMMANDID, json, true, NetConfig::localIP().c_str());
} else {
parameter = get_param (cmd_params, "OUTPUT=");
if (parameter != "PRINTER") {
response = format_response(COMMANDID, json, false, "Unknown parameter");
}
}
if (noError) { #define COMMANDID 111
parameter = get_param (cmd_params, "OUTPUT="); // Get current IP
if (json) { //[ESP111] [json=no]
output->printLN (response.c_str() ); bool Commands::ESP111(const char* cmd_params, level_authenticate_type auth_type,
} else { ESP3DOutput* output) {
output->printMSG (response.c_str() ); log_esp3d("Client is %d", output ? output->client() : 0);
if (parameter == "PRINTER") { (void)auth_type;
ESP3DOutput printerOutput(ESP_REMOTE_SCREEN_CLIENT); bool noError = true;
printerOutput.printMSG (NetConfig::localIP().c_str() ); bool json = has_tag(cmd_params, "json");
} String response;
} String parameter = clean_param(get_param(cmd_params, ""));
} else { if (parameter.length() == 0) {
output->printERROR(response.c_str(), 200); response =
format_response(COMMANDID, json, true, NetConfig::localIP().c_str());
} else {
parameter = get_param(cmd_params, "OUTPUT=");
if (parameter != "PRINTER") {
response = format_response(COMMANDID, json, false, "Unknown parameter");
} }
return noError; }
if (noError) {
parameter = get_param(cmd_params, "OUTPUT=");
if (json) {
output->printLN(response.c_str());
} else {
output->printMSG(response.c_str());
if (parameter == "PRINTER") {
ESP3DOutput printerOutput(ESP_REMOTE_SCREEN_CLIENT);
printerOutput.printMSG(NetConfig::localIP().c_str());
}
}
} else {
output->printERROR(response.c_str(), 200);
}
return noError;
} }
#endif //WIFI_FEATURE #endif // WIFI_FEATURE

File diff suppressed because it is too large Load Diff

View File

@ -17,125 +17,139 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined(GCODE_HOST_FEATURE) #if defined(GCODE_HOST_FEATURE)
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/gcode_host/gcode_host.h"
#include "../commands.h" #include "../commands.h"
#include "../esp3doutput.h" #include "../esp3doutput.h"
#include "../settings_esp3d.h" #include "../settings_esp3d.h"
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/gcode_host/gcode_host.h"
#define COMMANDID 701
//Query and Control ESP700 stream #define COMMANDID 701
// Query and Control ESP700 stream
//[ESP701]action=<PAUSE/RESUME/ABORT> //[ESP701]action=<PAUSE/RESUME/ABORT>
bool Commands::ESP701(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output) bool Commands::ESP701(const char* cmd_params, level_authenticate_type auth_type,
{ ESP3DOutput* output) {
bool noError = true; bool noError = true;
bool json = has_tag (cmd_params, "json"); bool json = has_tag(cmd_params, "json");
String response; String response;
String parameter; String parameter;
int errorCode = 200; //unless it is a server error use 200 as default and set error in json instead int errorCode = 200; // unless it is a server error use 200 as default and
// set error in json instead
#ifdef AUTHENTICATION_FEATURE #ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) { if (auth_type != LEVEL_ADMIN) {
response = format_response(COMMANDID, json, false, "Wrong authentication level"); response =
noError = false; format_response(COMMANDID, json, false, "Wrong authentication level");
errorCode = 401; noError = false;
} errorCode = 401;
}
#else #else
(void)auth_type; (void)auth_type;
#endif //AUTHENTICATION_FEATURE #endif // AUTHENTICATION_FEATURE
if (noError) { if (noError) {
parameter = (get_param (cmd_params, "action=")); parameter = (get_param(cmd_params, "action="));
if (parameter.length() != 0) { if (parameter.length() != 0) {
if (parameter.equalsIgnoreCase("PAUSE")) { if (parameter.equalsIgnoreCase("PAUSE")) {
if (esp3d_gcode_host.pause()) { if (esp3d_gcode_host.pause()) {
response = format_response(COMMANDID, json, true, "Stream paused"); response = format_response(COMMANDID, json, true, "Stream paused");
} else { } else {
response = format_response(COMMANDID, json, false, "No stream to pause"); response =
noError = false; format_response(COMMANDID, json, false, "No stream to pause");
} noError = false;
} else if (parameter.equalsIgnoreCase("RESUME")) { }
if (esp3d_gcode_host.resume()) { } else if (parameter.equalsIgnoreCase("RESUME")) {
response = format_response(COMMANDID, json, true, "Stream resumed"); if (esp3d_gcode_host.resume()) {
} else { response = format_response(COMMANDID, json, true, "Stream resumed");
response = format_response(COMMANDID, json, false, "No stream to resume"); } else {
noError = false; response =
} format_response(COMMANDID, json, false, "No stream to resume");
} else if (parameter.equalsIgnoreCase("ABORT")) { noError = false;
if (esp3d_gcode_host.abort()) { }
response = format_response(COMMANDID, json, true, "Stream aborted"); } else if (parameter.equalsIgnoreCase("ABORT")) {
} else { if (esp3d_gcode_host.abort()) {
response = format_response(COMMANDID, json, false, "No stream to abort"); response = format_response(COMMANDID, json, true, "Stream aborted");
noError = false; } else {
} response =
} format_response(COMMANDID, json, false, "No stream to abort");
if (parameter.equalsIgnoreCase("CLEAR_ERROR")) { noError = false;
esp3d_gcode_host.setErrorNum(ERROR_NO_ERROR); }
response = format_response(COMMANDID, json, true, "Error cleared"); }
} else { if (parameter.equalsIgnoreCase("CLEAR_ERROR")) {
response = format_response(COMMANDID, json, false, "Unknown action"); esp3d_gcode_host.setErrorNum(ERROR_NO_ERROR);
noError = false; response = format_response(COMMANDID, json, true, "Error cleared");
} } else {
response = format_response(COMMANDID, json, false, "Unknown action");
noError = false;
}
} else {
String resp;
bool noError = true;
switch (esp3d_gcode_host.getStatus()) {
case HOST_START_STREAM:
case HOST_READ_LINE:
case HOST_PROCESS_LINE:
case HOST_WAIT4_ACK:
//TODO add % of progress and filename if any
//totalSize / processedSize / fileName
if (json) {
resp = "{\"status\":\"processing\",\"total\":\"" + String(esp3d_gcode_host.totalSize()) + "\",\"processed\":\"" + String(esp3d_gcode_host.processedSize()) + "\",\"type\":\"" + String(esp3d_gcode_host.getFSType());
if(esp3d_gcode_host.getFSType() !=TYPE_SCRIPT_STREAM) {
resp+="\",\"name\":\""+String(esp3d_gcode_host.fileName());
}
resp+="\"}";
} else {
resp = "processing";
}
response = format_response(COMMANDID, json, true, resp.c_str());
break;
case HOST_PAUSE_STREAM:
response = format_response(COMMANDID, json, true, "pause");
break;
case HOST_RESUME_STREAM:
response = format_response(COMMANDID, json, true, "resume stream");
break;
case HOST_NO_STREAM:
log_esp3d("No stream %d", esp3d_gcode_host.getErrorNum());
if (esp3d_gcode_host.getErrorNum()!=ERROR_NO_ERROR) {
noError = false;
if(json) {
resp= "{\"status\":\"no stream\",\"code\":\"" + String(esp3d_gcode_host.getErrorNum()) + "\"}";
} else {
resp = "no stream, last error " + String(esp3d_gcode_host.getErrorNum());
}
} else {
resp = "no stream";
}
response = format_response(COMMANDID, json, noError, resp.c_str());
break;
default:
response = format_response(COMMANDID, json, false, String(esp3d_gcode_host.getStatus()).c_str());
noError = false;
break;
}
}
}
if (noError) {
if (json) {
output->printLN (response.c_str() );
} else {
output->printMSG (response.c_str() );
}
} else { } else {
output->printERROR(response.c_str(), errorCode); String resp;
bool noError = true;
switch (esp3d_gcode_host.getStatus()) {
case HOST_START_STREAM:
case HOST_READ_LINE:
case HOST_PROCESS_LINE:
case HOST_WAIT4_ACK:
// TODO add % of progress and filename if any
// totalSize / processedSize / fileName
if (json) {
resp = "{\"status\":\"processing\",\"total\":\"" +
String(esp3d_gcode_host.totalSize()) +
"\",\"processed\":\"" +
String(esp3d_gcode_host.processedSize()) + "\",\"type\":\"" +
String(esp3d_gcode_host.getFSType());
if (esp3d_gcode_host.getFSType() != TYPE_SCRIPT_STREAM) {
resp += "\",\"name\":\"" + String(esp3d_gcode_host.fileName());
}
resp += "\"}";
} else {
resp = "processing";
}
response = format_response(COMMANDID, json, true, resp.c_str());
break;
case HOST_PAUSE_STREAM:
response = format_response(COMMANDID, json, true, "pause");
break;
case HOST_RESUME_STREAM:
response = format_response(COMMANDID, json, true, "resume stream");
break;
case HOST_NO_STREAM:
log_esp3d("No stream %d", esp3d_gcode_host.getErrorNum());
if (esp3d_gcode_host.getErrorNum() != ERROR_NO_ERROR) {
noError = false;
if (json) {
resp = "{\"status\":\"no stream\",\"code\":\"" +
String(esp3d_gcode_host.getErrorNum()) + "\"}";
} else {
resp = "no stream, last error " +
String(esp3d_gcode_host.getErrorNum());
}
} else {
resp = "no stream";
}
response = format_response(COMMANDID, json, noError, resp.c_str());
break;
default:
response =
format_response(COMMANDID, json, false,
String(esp3d_gcode_host.getStatus()).c_str());
noError = false;
break;
}
} }
return noError; }
if (noError) {
if (json) {
output->printLN(response.c_str());
} else {
output->printMSG(response.c_str());
}
} else {
output->printERROR(response.c_str(), errorCode);
}
return noError;
} }
#endif //GCODE_HOST_FEATURE #endif // GCODE_HOST_FEATURE

View File

@ -22,228 +22,215 @@
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <soc/soc.h> #include <soc/soc.h>
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
//FIXME : S3 not support it yet // FIXME : S3 not support it yet
#include <soc/rtc_wdt.h> #include <soc/rtc_wdt.h>
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#include <soc/rtc_cntl_reg.h>
#include <WiFi.h> #include <WiFi.h>
#include <esp_task_wdt.h>
#include <driver/adc.h> #include <driver/adc.h>
#include <esp_task_wdt.h>
#include <soc/rtc_cntl_reg.h>
TaskHandle_t Hal::xHandle = nullptr; TaskHandle_t Hal::xHandle = nullptr;
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#include "esp3doutput.h" #include "esp3doutput.h"
uint32_t Hal::_analogRange = 255; uint32_t Hal::_analogRange = 255;
uint32_t Hal::_analogWriteFreq = 1000; uint32_t Hal::_analogWriteFreq = 1000;
void Hal::pinMode(uint8_t pin, uint8_t mode) void Hal::pinMode(uint8_t pin, uint8_t mode) {
{ #if defined(ARDUINO_ARCH_ESP8266)
#if defined (ARDUINO_ARCH_ESP8266) if ((pin == 16) && (mode == INPUT_PULLUP)) {
if ((pin == 16) && (mode == INPUT_PULLUP)) { ::pinMode(pin, INPUT_PULLDOWN_16);
::pinMode(pin, INPUT_PULLDOWN_16); return;
return; }
}
#endif #endif
::pinMode(pin, mode); ::pinMode(pin, mode);
} }
int Hal::analogRead(uint8_t pin) int Hal::analogRead(uint8_t pin) {
{ #ifdef ARDUINO_ARCH_ESP8266 // only one ADC on ESP8266 A0
#ifdef ARDUINO_ARCH_ESP8266 //only one ADC on ESP8266 A0 (void)pin;
(void)pin; return ::analogRead(A0);
return ::analogRead (A0);
#else #else
return ::analogRead (pin); return ::analogRead(pin);
#endif #endif
} }
bool Hal::analogWrite(uint8_t pin, uint value) bool Hal::analogWrite(uint8_t pin, uint value) {
{ if (value > (_analogRange - 1)) {
if (value > (_analogRange-1)) { return false;
return false; }
}
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::analogWrite(pin, value); ::analogWrite(pin, value);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
::analogWrite(pin, value); ::analogWrite(pin, value);
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
return true; return true;
} }
void Hal::analogWriteFreq(uint32_t freq) void Hal::analogWriteFreq(uint32_t freq) {
{ _analogWriteFreq = freq;
_analogWriteFreq = freq;
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::analogWriteFreq(_analogWriteFreq); ::analogWriteFreq(_analogWriteFreq);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }
void Hal::analogRange(uint32_t range) void Hal::analogRange(uint32_t range) {
{ _analogRange = range;
_analogRange = range; uint8_t resolution = 0;
uint8_t resolution = 0; switch (_analogRange) {
switch(_analogRange) {
case 8191: case 8191:
resolution=13; resolution = 13;
break; break;
case 1024: case 1024:
resolution=10; resolution = 10;
break; break;
case 2047: case 2047:
resolution=11; resolution = 11;
break; break;
case 4095: case 4095:
resolution=12; resolution = 12;
break; break;
default: default:
resolution=8; resolution = 8;
_analogRange = 255; _analogRange = 255;
break; break;
} }
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
analogReadResolution(resolution); analogReadResolution(resolution);
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
(void)resolution; (void)resolution;
::analogWriteRange(_analogRange); ::analogWriteRange(_analogRange);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }
//Setup // Setup
bool Hal::begin() bool Hal::begin() {
{
#if defined(ARDUINO_ARCH_ESP32) && defined(CAMERA_DEVICE) #if defined(ARDUINO_ARCH_ESP32) && defined(CAMERA_DEVICE)
log_esp3d("Disable brown out"); log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
#endif //ARDUINO_ARCH_ESP32 && CAMERA_DEVICE #endif // ARDUINO_ARCH_ESP32 && CAMERA_DEVICE
//Clear all wifi state // Clear all wifi state
WiFi.persistent(false); WiFi.persistent(false);
WiFi.disconnect(true); WiFi.disconnect(true);
WiFi.enableSTA (false); WiFi.enableSTA(false);
WiFi.enableAP (false); WiFi.enableAP(false);
WiFi.mode (WIFI_OFF); WiFi.mode(WIFI_OFF);
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD #if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode (ESP_SD_DETECT_PIN, INPUT); pinMode(ESP_SD_DETECT_PIN, INPUT);
#endif #endif
#if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1 #if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1
pinMode (ESP_FLAG_SHARED_SD_PIN, OUTPUT); pinMode(ESP_FLAG_SHARED_SD_PIN, OUTPUT);
digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE); digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE);
#endif //ESP_FLAG_SHARED_SD_PIN #endif // ESP_FLAG_SHARED_SD_PIN
#endif //SD_DEVICE_CONNECTION == ESP_SHARED_SD #endif // SD_DEVICE_CONNECTION == ESP_SHARED_SD
return true; return true;
} }
//End ESP3D // End ESP3D
void Hal::end() void Hal::end() {}
{
}
//Watchdog feeder // Watchdog feeder
void Hal::wdtFeed() void Hal::wdtFeed() {
{
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
ESP.wdtFeed(); ESP.wdtFeed();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
static uint64_t lastYield = 0; static uint64_t lastYield = 0;
uint64_t now = millis(); uint64_t now = millis();
if((now - lastYield) > 2000) { if ((now - lastYield) > 2000) {
lastYield = now; lastYield = now;
vTaskDelay(5); //delay 1 RTOS tick vTaskDelay(5); // delay 1 RTOS tick
} }
#if !defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0) #if !defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
//FIXME: not implemented // FIXME: not implemented
rtc_wdt_feed(); rtc_wdt_feed();
#endif //CONFIG_IDF_TARGET_ESP32S2 #endif // CONFIG_IDF_TARGET_ESP32S2
#endif//!defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0) #endif //! defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
#ifndef DISABLE_WDT_ESP3DLIB_TASK #ifndef DISABLE_WDT_ESP3DLIB_TASK
if (xHandle && esp_task_wdt_status(xHandle)==ESP_OK) { if (xHandle && esp_task_wdt_status(xHandle) == ESP_OK) {
if (esp_task_wdt_reset()!=ESP_OK) { if (esp_task_wdt_reset() != ESP_OK) {
log_esp3d("WDT Reset failed"); log_esp3d_e("WDT Reset failed");
}
} }
#endif //DISABLE_WDT_ESP3DLIB_TASK }
#endif //ARDUINO_ARCH_ESP32 #endif // DISABLE_WDT_ESP3DLIB_TASK
#endif // ARDUINO_ARCH_ESP32
} }
//wait function // wait function
void Hal::wait (uint32_t milliseconds) void Hal::wait(uint32_t milliseconds) {
{
#if defined(ASYNCWEBSERVER) #if defined(ASYNCWEBSERVER)
uint32_t timeout = millis(); uint32_t timeout = millis();
while ( (millis() - timeout) < milliseconds) { while ((millis() - timeout) < milliseconds) {
wdtFeed();
}
#else // !(ASYNCWEBSERVER
wdtFeed(); wdtFeed();
//before 0 was acceptable, now it seems need to put 5 to have some effect if on esp32 core 0 }
delay(milliseconds<5?5:milliseconds); #else // !(ASYNCWEBSERVER
#endif // !ASYNCWEBSERVER wdtFeed();
// before 0 was acceptable, now it seems need to put 5 to have some effect if
// on esp32 core 0
delay(milliseconds < 5 ? 5 : milliseconds);
#endif // !ASYNCWEBSERVER
} }
uint16_t Hal::getChipID() uint16_t Hal::getChipID() {
{
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
return ESP.getChipId(); return ESP.getChipId();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
return (uint16_t) (ESP.getEfuseMac() >> 32); return (uint16_t)(ESP.getEfuseMac() >> 32);
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
} }
bool Hal::has_temperature_sensor() bool Hal::has_temperature_sensor() {
{
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
return false; return false;
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3
//FIXME: not yet implemented // FIXME: not yet implemented
return false; return false;
#else #else
return true;
#endif // CONFIG_IDF_TARGET_ESP32S3
#endif // ARDUINO_ARCH_ESP32
}
float Hal::temperature() {
#ifdef ARDUINO_ARCH_ESP8266
return 0.0;
#endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
#if CONFIG_IDF_TARGET_ESP32S3
// FIXME: not yet implemented
return 0.0;
#else
return temperatureRead();
#endif // CONFIG_IDF_TARGET_ESP32S3
#endif // ARDUINO_ARCH_ESP32
}
bool Hal::is_pin_usable(uint pin) {
#ifdef ARDUINO_ARCH_ESP8266
if ((pin <= 5) || ((pin >= 12) && (pin <= 16))) {
return true; return true;
#endif //CONFIG_IDF_TARGET_ESP32S3 } else {
#endif //ARDUINO_ARCH_ESP32 return false;
} }
#endif // ARDUINO_ARCH_ESP8266
float Hal::temperature()
{
#ifdef ARDUINO_ARCH_ESP8266
return 0.0;
#endif //ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#if CONFIG_IDF_TARGET_ESP32S3 // TODO: Add support for ESP32 S2 S3 C2 C3
//FIXME: not yet implemented if ((pin <= 5) || ((pin >= 12) && (pin <= 39))) {
return 0.0; return true;
#else } else {
return temperatureRead(); return false;
#endif //CONFIG_IDF_TARGET_ESP32S3 }
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
}
bool Hal::is_pin_usable(uint pin)
{
#ifdef ARDUINO_ARCH_ESP8266
if ((pin <= 5) || ((pin >= 12) && (pin <= 16))) {
return true;
} else {
return false;
}
#endif //ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
//TODO: Add support for ESP32 S2 S3 C2 C3
if ((pin <= 5) || ((pin >= 12) && (pin <= 39))) {
return true;
} else {
return false;
}
#endif //ARDUINO_ARCH_ESP32
} }

View File

@ -0,0 +1,58 @@
/*
log_esp3d.cpp - log esp3d functions class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../include/esp3d_config.h"
#if defined(ESP_LOG_FEATURE)
#ifndef LOG_ESP3D_BAUDRATE
#define LOG_ESP3D_BAUDRATE 115200
#endif //~LOG_ESP3D_BAUDRATE
void initEsp3dLog() {
#if (ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL0) || \
(ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL1) || \
(ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2)
#ifdef ARDUINO_ARCH_ESP8266
LOG_OUTPUT_SERIAL.begin(LOG_ESP3D_BAUDRATE, SERIAL_8N1, SERIAL_FULL,
(ESP_LOG_TX_PIN == -1) ? 1 : ESP_LOG_TX_PIN);
#if ESP_LOG_RX_PIN != -1
LOG_OUTPUT_SERIAL
.pins((ESP_LOG_TX_PIN == -1) ? 1 : ESP_LOG_TX_PIN, ESP_LOG_RX_PIN)
#endif // ESP_LOG_RX_PIN != -1
#endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
LOG_OUTPUT_SERIAL.begin(LOG_ESP3D_BAUDRATE, SERIAL_8N1,
ESP_LOG_RX_PIN, ESP_LOG_TX_PIN);
#endif // ARDUINO_ARCH_ESP32
#endif // (ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL0) || (ESP_LOG_FEATURE ==
// LOG_OUTPUT_SERIAL1)||(ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2)
}
// Telnet
#if ESP_LOG_FEATURE == LOG_OUTPUT_TELNET
Telnet_Server telnet_log;
#endif // ESP_LOG_FEATURE == LOG_OUTPUT_TELNET
// Websocket
#if ESP_LOG_FEATURE == LOG_OUTPUT_WEBSOCKET
WebSocket_Server websocket_log("log");
#endif // ESP_LOG_FEATURE == LOG_OUTPUT_WEBSOCKET
#endif // ESP_LOG_FEATURE

183
esp3d/src/core/log_esp3d.h Normal file
View File

@ -0,0 +1,183 @@
/*
log_esp3d.h - esp3d log functions
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LOG_ESP3D_H
#define _LOG_ESP3D_H
#include "../include/defines.h"
#include "../include/esp3d_config.h"
#ifndef ESP3D_DEBUG_LEVEL
#define ESP3D_DEBUG_LEVEL LOG_LEVEL_NONE
#endif // ESP3D_DEBUG_LEVEL
#define LOG_ESP3D_INIT
#define LOG_ESP3D_NETWORK_INIT
#define LOG_ESP3D_NETWORK_HANDLE
#define LOG_ESP3D_NETWORK_END
#if defined(ESP_LOG_FEATURE)
#if defined(ARDUINO_ARCH_ESP8266)
// no need with latest esp8266 core
#define pathToFileName(p) p
#endif // ARDUINO_ARCH_ESP8266
#undef log_esp3d
#undef log_esp3ds
#undef log_esp3d_e
#undef log_esp3d_d
// Serial
#if (ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL0) || \
(ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL1) || \
(ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2)
extern void initEsp3dLog();
#ifndef ESP3DLIB_ENV
#if ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL0
#define LOG_OUTPUT_SERIAL Serial
#endif // LOG_OUTPUT_SERIAL0
#if ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL1
#define LOG_OUTPUT_SERIAL Serial1
#endif // LOG_OUTPUT_SERIAL1
#if ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2
#define LOG_OUTPUT_SERIAL Serial2
#endif // LOG_OUTPUT_SERIAL2
#undef LOG_ESP3D_INIT
#define LOG_ESP3D_INIT initEsp3dLog();
#else
#define LOG_OUTPUT_SERIAL MYSERIAL1
#endif // ESP3DLIB_ENV
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_VERBOSE
#define log_esp3d(format, ...) \
LOG_OUTPUT_SERIAL.printf("[ESP3D][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#define log_esp3ds(format, ...) LOG_OUTPUT_SERIAL.printf(format, ##__VA_ARGS__)
#else
#define log_esp3d(format, ...)
#define log_esp3ds(format, ...)
#endif // ESP3D_DEBUG_LEVEL>= LOG_LEVEL_VERBOSE
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_DEBUG
#define log_esp3d_d(format, ...) \
LOG_OUTPUT_SERIAL.printf("[ESP3D-DEBUG][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#else
#define log_esp3d_d(format, ...)
#endif // ESP3D_DEBUG_LEVEL>= LOG_LEVEL_DEBUG
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#define log_esp3d_e(format, ...) \
LOG_OUTPUT_SERIAL.printf("[ESP3D-ERROR][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#else
#define log_esp3d_e(format, ...)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#endif // LOG_OUTPUT_SERIAL0 || LOG_OUTPUT_SERIAL1 || LOG_OUTPUT_SERIAL2
// Telnet
#if ESP_LOG_FEATURE == LOG_OUTPUT_TELNET
#include "../modules/telnet/telnet_server.h"
extern Telnet_Server telnet_log;
#undef LOG_ESP3D_NETWORK_INIT
#undef LOG_ESP3D_NETWORK_END
#undef LOG_ESP3D_NETWORK_HANDLE
#define LOG_ESP3D_NETWORK_INIT telnet_log.begin(LOG_ESP3D_OUTPUT_PORT, true);
#define LOG_ESP3D_NETWORK_HANDLE telnet_log.handle();
#define LOG_ESP3D_NETWORK_END telnet_log.end();
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_VERBOSE
#define log_esp3d(format, ...) \
if (telnet_log.isConnected()) \
telnet_log.printf("[ESP3D][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#define log_esp3ds(format, ...) \
if (telnet_log.isConnected()) telnet_log.printf(format, ##__VA_ARGS__)
#else
#define log_esp3d(format, ...)
#define log_esp3ds(format, ...)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_VERBOSE
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_DEBUG
#define log_esp3d_d(format, ...) \
if (telnet_log.isConnected()) \
telnet_log.printf("[ESP3D-DEBUG][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#else
#define log_esp3d_d(format, ...)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_DEBUG
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#define log_esp3d_e(format, ...) \
if (telnet_log.isConnected()) \
telnet_log.printf("[ESP3D-ERROR][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#endif // LOG_OUTPUT_TELNET
// Telnet
#if ESP_LOG_FEATURE == LOG_OUTPUT_WEBSOCKET
#include "../modules/websocket/websocket_server.h"
extern WebSocket_Server websocket_log;
#undef LOG_ESP3D_NETWORK_INIT
#undef LOG_ESP3D_NETWORK_END
#undef LOG_ESP3D_NETWORK_HANDLE
#define LOG_ESP3D_NETWORK_INIT websocket_log.begin(LOG_ESP3D_OUTPUT_PORT, true);
#define LOG_ESP3D_NETWORK_HANDLE websocket_log.handle();
#define LOG_ESP3D_NETWORK_END websocket_log.end();
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_VERBOSE
#define log_esp3d(format, ...) \
websocket_log.printf("[ESP3D][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#define log_esp3ds(format, ...) websocket_log.printf(format, ##__VA_ARGS__)
#else
#define log_esp3d(format, ...)
#define log_esp3ds(format, ...)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_VERBOSE
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_DEBUG
#define log_esp3d_d(format, ...) \
websocket_log.printf("[ESP3D-DEBUG][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#else
#define log_esp3d(format, ...)
#endif // ESP3D_DEBUG_LEVEL >= ESP_LOG_DEBUG
#if ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#define log_esp3d(format, ...) \
websocket_log.printf("[ESP3D-ERROR][%s:%u] %s(): " format "\r\n", \
pathToFileName(__FILE__), __LINE__, __FUNCTION__, \
##__VA_ARGS__)
#endif // ESP3D_DEBUG_LEVEL >= LOG_LEVEL_ERROR
#endif // LOG_OUTPUT_WEBSOCKET
#else
#define log_esp3d(format, ...)
#define log_esp3ds(format, ...)
#define log_esp3d_e(format, ...)
#define log_esp3d_d(format, ...)
#endif // ESP_LOG_FEATURE
#endif //_LOG_ESP3D_H

File diff suppressed because it is too large Load Diff

View File

@ -147,11 +147,16 @@
#define HIDDEN_PASSWORD "********" #define HIDDEN_PASSWORD "********"
// Debug // Debug
#define DEBUG_OUTPUT_SERIAL0 1 #define LOG_OUTPUT_SERIAL0 1
#define DEBUG_OUTPUT_SERIAL1 2 #define LOG_OUTPUT_SERIAL1 2
#define DEBUG_OUTPUT_SERIAL2 3 #define LOG_OUTPUT_SERIAL2 3
#define DEBUG_OUTPUT_TELNET 4 #define LOG_OUTPUT_TELNET 4
#define DEBUG_OUTPUT_WEBSOCKET 5 #define LOG_OUTPUT_WEBSOCKET 5
#define LOG_LEVEL_NONE 0
#define LOG_LEVEL_ERROR 1
#define LOG_LEVEL_DEBUG 2
#define LOG_LEVEL_VERBOSE 3
// Serial // Serial
#define USE_SERIAL_0 1 #define USE_SERIAL_0 1

View File

@ -21,15 +21,17 @@
#ifndef _ESP3D_CONFIG_H #ifndef _ESP3D_CONFIG_H
#define _ESP3D_CONFIG_H #define _ESP3D_CONFIG_H
#include <Arduino.h> #include <Arduino.h>
#include "../include/defines.h" #include "../include/defines.h"
#if defined __has_include #if defined __has_include
# if __has_include ("../../configuration.h") #if __has_include("../../configuration.h")
#include "../../configuration.h" #include "../../configuration.h"
#define ESP3D_CODE_BASE "ESP3D" #define ESP3D_CODE_BASE "ESP3D"
#else #else
#undef DISABLED #undef DISABLED
#undef _BV #undef _BV
# if __has_include ("../esp3dlib_config.h") #if __has_include("../esp3dlib_config.h")
#include "../esp3dlib_config.h" #include "../esp3dlib_config.h"
#define ESP3D_CODE_BASE "ESP3DLib" #define ESP3D_CODE_BASE "ESP3DLib"
#else #else
@ -38,22 +40,23 @@
#endif #endif
#endif #endif
#include "../core/hal.h"
#include "../core/log_esp3d.h"
#include "../include/pins.h" #include "../include/pins.h"
#include "../include/sanity_esp3d.h" #include "../include/sanity_esp3d.h"
#include "../core/hal.h"
#include "../core/debug_esp3d.h"
#include "../include/version.h" #include "../include/version.h"
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
/************************************ /************************************
* *
* SSL Client * SSL Client
* *
* **********************************/ * **********************************/
//Using BearSSL need to decrease size of packet to not be OOM on ESP8266 // Using BearSSL need to decrease size of packet to not be OOM on ESP8266
#define BEARSSL_MFLN_SIZE 512 #define BEARSSL_MFLN_SIZE 512
#define BEARSSL_MFLN_SIZE_FALLBACK 4096 #define BEARSSL_MFLN_SIZE_FALLBACK 4096
#endif // ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
/************************************ /************************************
* *
@ -61,13 +64,17 @@
* *
* **********************************/ * **********************************/
//Make Flag more generic // Make Flag more generic
#if (defined(PIN_RESET_FEATURE) && defined(ESP3D_RESET_PIN) && ESP3D_RESET_PIN!=-1) || defined(SD_RECOVERY_FEATURE) #if (defined(PIN_RESET_FEATURE) && defined(ESP3D_RESET_PIN) && \
ESP3D_RESET_PIN != -1) || \
defined(SD_RECOVERY_FEATURE)
#define RECOVERY_FEATURE #define RECOVERY_FEATURE
#endif //PIN_RESET_FEATURE || SD_RECOVERY_FEATURE #endif // PIN_RESET_FEATURE || SD_RECOVERY_FEATURE
#if defined(DISPLAY_DEVICE) || defined(SENSOR_DEVICE) || defined(RECOVERY_FEATURE) || defined(BUZZER_DEVICE) || defined(CAMERA_DEVICE) || defined(SD_DEVICE) #if defined(DISPLAY_DEVICE) || defined(SENSOR_DEVICE) || \
defined(RECOVERY_FEATURE) || defined(BUZZER_DEVICE) || \
defined(CAMERA_DEVICE) || defined(SD_DEVICE)
#define CONNECTED_DEVICES_FEATURE #define CONNECTED_DEVICES_FEATURE
#endif //DISPLAY_DEVICE || SENSOR_DEVICE , etc... #endif // DISPLAY_DEVICE || SENSOR_DEVICE , etc...
#endif //_ESP3D_CONFIG_H #endif //_ESP3D_CONFIG_H

View File

@ -38,12 +38,12 @@
#endif // ESP_BRIDGE_TX_PIN #endif // ESP_BRIDGE_TX_PIN
#endif // ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
#ifndef ESP_DEBUG_RX_PIN #ifndef ESP_LOG_RX_PIN
#define ESP_DEBUG_RX_PIN -1 #define ESP_LOG_RX_PIN -1
#endif // ESP_DEBUG_RX_PIN #endif // ESP_LOG_RX_PIN
#ifndef ESP_DEBUG_TX_PIN #ifndef ESP_LOG_TX_PIN
#define ESP_DEBUG_TX_PIN -1 #define ESP_LOG_TX_PIN -1
#endif // ESP_DEBUG_TX_PIN #endif // ESP_LOG_TX_PIN
// I2C Pins // I2C Pins
#ifndef ESP_SDA_PIN #ifndef ESP_SDA_PIN

View File

@ -37,14 +37,14 @@
* Debug * Debug
* ***********************/ * ***********************/
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
#if ESP_DEBUG_FEATURE == ESP_SERIAL_OUTPUT #if ESP_LOG_FEATURE == ESP_SERIAL_OUTPUT
#warning You use same serial for output and debug #warning You use same serial for output and log
#endif // ESP_DEBUG_FEATURE == ESP_SERIAL_OUTPUT #endif // ESP_LOG_FEATURE == ESP_SERIAL_OUTPUT
#if (ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2) && defined(ARDUINO_ARCH_ESP8266) #if (ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2) && defined(ARDUINO_ARCH_ESP8266)
#error Serial 2 is not available in ESP8266 for debug #error Serial 2 is not available in ESP8266 for log
#endif // ESP_DEBUG_FEATURE == DEBUG_OUTPUT_SERIAL2 ) && ARDUINO_ARCH_ESP8266 #endif // ESP_LOG_FEATURE == LOG_OUTPUT_SERIAL2 ) && ARDUINO_ARCH_ESP8266
#endif // ESP_DEBUG_FEATURE #endif // ESP_LOG_FEATURE
/************************** /**************************
* Serial * Serial

View File

@ -20,379 +20,364 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
#include "camera.h"
#include "../../core/esp3doutput.h"
#include "../../core/esp3d.h"
#include <esp_camera.h>
#include <soc/soc.h> //not sure this one is needed
#include <soc/rtc_cntl_reg.h>
#include <WebServer.h> #include <WebServer.h>
#if defined (SD_DEVICE) #include <esp_camera.h>
#include "../filesystem/esp_sd.h" #include <soc/rtc_cntl_reg.h>
#endif //SD_DEVICE #include <soc/soc.h> //not sure this one is needed
#include "../../core/esp3d.h"
#include "../../core/esp3doutput.h"
#include "camera.h"
#if defined(SD_DEVICE)
#include "../filesystem/esp_sd.h"
#endif // SD_DEVICE
#define DEFAULT_FRAME_SIZE FRAMESIZE_SVGA #define DEFAULT_FRAME_SIZE FRAMESIZE_SVGA
#define JPEG_COMPRESSION 80 #define JPEG_COMPRESSION 80
Camera esp3d_camera; Camera esp3d_camera;
bool Camera::handle_snap(WebServer * webserver, const char *path, const char* filename) bool Camera::handle_snap(WebServer *webserver, const char *path,
{ const char *filename) {
log_esp3d("Camera stream reached"); log_esp3d("Camera stream reached");
if (!_initialised) { if (!_initialised) {
log_esp3d("Camera not started"); log_esp3d_e("Camera not started");
if (webserver) {
webserver->send (500, "text/plain", "Camera not started");
}
return false;
}
sensor_t * s = esp_camera_sensor_get();
if (webserver) { if (webserver) {
if (webserver->hasArg ("framesize") ) { webserver->send(500, "text/plain", "Camera not started");
if(s->status.framesize != webserver->arg ("framesize").toInt()) { }
command("framesize", webserver->arg ("framesize").c_str()); return false;
} }
} sensor_t *s = esp_camera_sensor_get();
if (webserver->hasArg ("hmirror") ) { if (webserver) {
command("hmirror", webserver->arg ("hmirror").c_str()); if (webserver->hasArg("framesize")) {
} if (s->status.framesize != webserver->arg("framesize").toInt()) {
if (webserver->hasArg ("vflip") ) { command("framesize", webserver->arg("framesize").c_str());
command("vflip", webserver->arg ("vflip").c_str()); }
} }
if (webserver->hasArg ("wb_mode") ) { if (webserver->hasArg("hmirror")) {
command("wb_mode", webserver->arg ("wb_mode").c_str()); command("hmirror", webserver->arg("hmirror").c_str());
} }
if (webserver->hasArg("vflip")) {
command("vflip", webserver->arg("vflip").c_str());
}
if (webserver->hasArg("wb_mode")) {
command("wb_mode", webserver->arg("wb_mode").c_str());
}
#ifdef ESP_ACCESS_CONTROL_ALLOW_ORIGIN #ifdef ESP_ACCESS_CONTROL_ALLOW_ORIGIN
webserver->enableCrossOrigin(true); webserver->enableCrossOrigin(true);
#endif //ESP_ACCESS_CONTROL_ALLOw_ORIGIN #endif // ESP_ACCESS_CONTROL_ALLOw_ORIGIN
} }
camera_fb_t * fb = NULL; camera_fb_t *fb = NULL;
bool res_error = false; bool res_error = false;
size_t _jpg_buf_len = 0; size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL; uint8_t *_jpg_buf = NULL;
if (webserver) {
webserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),
true);
webserver->sendHeader(String(F("Content-Disposition")),
String(F("inline; filename=capture.jpg")), true);
webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
webserver->send(200);
}
log_esp3d("Camera capture ongoing");
fb = esp_camera_fb_get();
if (!fb) {
log_esp3d_e("Camera capture failed");
if (webserver) { if (webserver) {
webserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),true); webserver->send(500, "text/plain", "Capture failed");
webserver->sendHeader(String(F("Content-Disposition")), String(F("inline; filename=capture.jpg")),true);
webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
webserver->send(200);
} }
log_esp3d("Camera capture ongoing"); res_error = true;
fb = esp_camera_fb_get(); } else {
if (!fb) { if (fb->format != PIXFORMAT_JPEG) {
log_esp3d("Camera capture failed"); bool jpeg_converted =
if (webserver) { frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len);
webserver->send (500, "text/plain", "Capture failed"); esp_camera_fb_return(fb);
} fb = NULL;
res_error=true; if (!jpeg_converted) {
log_esp3d_e("JPEG compression failed");
res_error = true;
}
} else { } else {
if(fb->format != PIXFORMAT_JPEG) { _jpg_buf_len = fb->len;
bool jpeg_converted = frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len); _jpg_buf = fb->buf;
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted) {
log_esp3d("JPEG compression failed");
res_error = true;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
} }
if (!res_error) { }
if(webserver) { if (!res_error) {
webserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len); if (webserver) {
} webserver->sendContent_P((const char *)_jpg_buf, _jpg_buf_len);
#if defined (SD_DEVICE) }
if (filename!=nullptr && path!=nullptr) { #if defined(SD_DEVICE)
if (!ESP_SD::accessFS()) { if (filename != nullptr && path != nullptr) {
res_error = true; if (!ESP_SD::accessFS()) {
log_esp3d("SD not available"); res_error = true;
log_esp3d_e("SD not available");
} else {
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
res_error = true;
log_esp3d_e("No SD");
} else {
ESP_SD::setState(ESP_SDCARD_BUSY);
String wpath = path[0] == '/' ? path : String("/") + path;
if (!ESP_SD::exists(wpath.c_str())) {
res_error = !ESP_SD::mkdir(wpath.c_str());
}
if (!res_error) {
if (wpath[wpath.length() - 1] != '/') {
wpath += "/";
}
wpath += filename;
ESP_SDFile f = ESP_SD::open(wpath.c_str(), ESP_FILE_WRITE);
if (f) {
f.write((const uint8_t *)_jpg_buf, _jpg_buf_len);
f.close();
log_esp3d("Camera capture done");
} else { } else {
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) { res_error = true;
res_error = true; log_esp3d_e("Failed to open file for writing");
log_esp3d("No SD");
} else {
ESP_SD::setState(ESP_SDCARD_BUSY );
String wpath = path[0]=='/' ? path : String("/")+path;
if (!ESP_SD::exists(wpath.c_str())) {
res_error = !ESP_SD::mkdir(wpath.c_str());
}
if (!res_error) {
if (wpath[wpath.length()-1]!='/') {
wpath += "/";
}
wpath +=filename ;
ESP_SDFile f = ESP_SD::open(wpath.c_str(), ESP_FILE_WRITE);
if (f) {
f.write((const uint8_t *)_jpg_buf, _jpg_buf_len);
f.close();
log_esp3d("Camera capture done");
} else {
res_error = true;
log_esp3d("Failed to open file for writing");
}
}
}
ESP_SD::releaseFS();
} }
}
}
#endif //SD_DEVICE
if (!webserver && filename==nullptr && path==nullptr) {
log_esp3d("No output defined");
res_error = true;
} }
ESP_SD::releaseFS();
}
} }
#endif // SD_DEVICE
if (!webserver && filename == nullptr && path == nullptr) {
log_esp3d_e("No output defined");
res_error = true;
}
}
if(fb) { if (fb) {
esp_camera_fb_return(fb); esp_camera_fb_return(fb);
fb = NULL; fb = NULL;
_jpg_buf = NULL; _jpg_buf = NULL;
} else if(_jpg_buf) { } else if (_jpg_buf) {
free(_jpg_buf); free(_jpg_buf);
_jpg_buf = NULL; _jpg_buf = NULL;
} }
if(webserver) { if (webserver) {
webserver->sendContent(""); webserver->sendContent("");
} }
return !res_error; return !res_error;
} }
Camera::Camera() Camera::Camera() {
{ _started = false;
_started = false; _initialised = false;
_initialised = false;
} }
Camera::~Camera() Camera::~Camera() { end(); }
{
end();
}
int Camera::command(const char * param, const char * value) int Camera::command(const char *param, const char *value) {
{ log_esp3d("Camera: %s=%s\n", param, value);
log_esp3d("Camera: %s=%s\n",param, value); int res = 0;
int res = 0; int val = atoi(value);
int val = atoi(value); sensor_t *s = esp_camera_sensor_get();
sensor_t * s = esp_camera_sensor_get(); if (s == nullptr) {
if (s == nullptr) { res = -1;
res = -1; }
}
#if CAM_LED_PIN != -1 #if CAM_LED_PIN != -1
if (!strcmp(param, "light")) { if (!strcmp(param, "light")) {
digitalWrite(CAM_LED_PIN, val==1?HIGH:LOW); digitalWrite(CAM_LED_PIN, val == 1 ? HIGH : LOW);
} else } else
#endif //CAM_LED_PIN #endif // CAM_LED_PIN
if(!strcmp(param, "framesize")) { if (!strcmp(param, "framesize")) {
if(s->pixformat == PIXFORMAT_JPEG) { if (s->pixformat == PIXFORMAT_JPEG) {
res = s->set_framesize(s, (framesize_t)val); res = s->set_framesize(s, (framesize_t)val);
} }
} else if(!strcmp(param, "quality")) { } else if (!strcmp(param, "quality")) {
res = s->set_quality(s, val); res = s->set_quality(s, val);
} else if(!strcmp(param, "contrast")) { } else if (!strcmp(param, "contrast")) {
res = s->set_contrast(s, val); res = s->set_contrast(s, val);
} else if(!strcmp(param, "brightness")) { } else if (!strcmp(param, "brightness")) {
res = s->set_brightness(s, val); res = s->set_brightness(s, val);
} else if(!strcmp(param, "saturation")) { } else if (!strcmp(param, "saturation")) {
res = s->set_saturation(s, val); res = s->set_saturation(s, val);
} else if(!strcmp(param, "gainceiling")) { } else if (!strcmp(param, "gainceiling")) {
res = s->set_gainceiling(s, (gainceiling_t)val); res = s->set_gainceiling(s, (gainceiling_t)val);
} else if(!strcmp(param, "colorbar")) { } else if (!strcmp(param, "colorbar")) {
res = s->set_colorbar(s, val); res = s->set_colorbar(s, val);
} else if(!strcmp(param, "awb")) { } else if (!strcmp(param, "awb")) {
res = s->set_whitebal(s, val); res = s->set_whitebal(s, val);
} else if(!strcmp(param, "agc")) { } else if (!strcmp(param, "agc")) {
res = s->set_gain_ctrl(s, val); res = s->set_gain_ctrl(s, val);
} else if(!strcmp(param, "aec")) { } else if (!strcmp(param, "aec")) {
res = s->set_exposure_ctrl(s, val); res = s->set_exposure_ctrl(s, val);
} else if(!strcmp(param, "hmirror")) { } else if (!strcmp(param, "hmirror")) {
res = s->set_hmirror(s, val); res = s->set_hmirror(s, val);
} else if(!strcmp(param, "vflip")) { } else if (!strcmp(param, "vflip")) {
res = s->set_vflip(s, val); res = s->set_vflip(s, val);
} else if(!strcmp(param, "awb_gain")) { } else if (!strcmp(param, "awb_gain")) {
res = s->set_awb_gain(s, val); res = s->set_awb_gain(s, val);
} else if(!strcmp(param, "agc_gain")) { } else if (!strcmp(param, "agc_gain")) {
res = s->set_agc_gain(s, val); res = s->set_agc_gain(s, val);
} else if(!strcmp(param, "aec_value")) { } else if (!strcmp(param, "aec_value")) {
res = s->set_aec_value(s, val); res = s->set_aec_value(s, val);
} else if(!strcmp(param, "aec2")) { } else if (!strcmp(param, "aec2")) {
res = s->set_aec2(s, val); res = s->set_aec2(s, val);
} else if(!strcmp(param, "dcw")) { } else if (!strcmp(param, "dcw")) {
res = s->set_dcw(s, val); res = s->set_dcw(s, val);
} else if(!strcmp(param, "bpc")) { } else if (!strcmp(param, "bpc")) {
res = s->set_bpc(s, val); res = s->set_bpc(s, val);
} else if(!strcmp(param, "wpc")) { } else if (!strcmp(param, "wpc")) {
res = s->set_wpc(s, val); res = s->set_wpc(s, val);
} else if(!strcmp(param, "raw_gma")) { } else if (!strcmp(param, "raw_gma")) {
res = s->set_raw_gma(s, val); res = s->set_raw_gma(s, val);
} else if(!strcmp(param, "lenc")) { } else if (!strcmp(param, "lenc")) {
res = s->set_lenc(s, val); res = s->set_lenc(s, val);
} else if(!strcmp(param, "special_effect")) { } else if (!strcmp(param, "special_effect")) {
res = s->set_special_effect(s, val); res = s->set_special_effect(s, val);
} else if(!strcmp(param, "wb_mode")) { } else if (!strcmp(param, "wb_mode")) {
res = s->set_wb_mode(s, val); res = s->set_wb_mode(s, val);
} else if(!strcmp(param, "ae_level")) { } else if (!strcmp(param, "ae_level")) {
res = s->set_ae_level(s, val); res = s->set_ae_level(s, val);
} else {
res = -1;
}
return res;
}
bool Camera::initHardware()
{
_initialised = false;
log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
stopHardware();
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.jpeg_quality = 5;
config.fb_count = 1;
config.frame_size = DEFAULT_FRAME_SIZE;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.grab_mode = CAMERA_GRAB_LATEST;
if(!psramFound()) {
_initialised = false;
log_esp3d("psram is not enabled");
return false;
}
log_esp3d("Init camera");
#if CAM_PULLUP1 != -1
pinMode(CAM_PULLUP1, INPUT_PULLUP);
#endif //CAM_PULLUP1
#if CAM_PULLUP2 != -1
pinMode(CAM_PULLUP2, INPUT_PULLUP);
#endif //CAM_PULLUP2
#if CAM_LED_PIN != -1
pinMode(CAM_LED_PIN, OUTPUT);
digitalWrite(CAM_LED_PIN, LOW);
#endif //CAM_LED_PIN
//initialize the camera
//https://github.com/espressif/esp32-camera/issues/66#issuecomment-526283681
#if CAMERA_DEVICE == CAMERA_MODEL_AI_THINKER
log_esp3d("Specific config for CAMERA_MODEL_AI_THINKER");
gpio_config_t gpio_pwr_config;
gpio_pwr_config.pin_bit_mask = (1ULL << 32);
gpio_pwr_config.mode = GPIO_MODE_OUTPUT;
gpio_pwr_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_pwr_config.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_pwr_config.intr_type = GPIO_INTR_DISABLE;
gpio_config(&gpio_pwr_config);
gpio_set_level(GPIO_NUM_32,0);
#endif //CAMERA_DEVICE == CAMERA_MODEL_AI_THINKER
delay(500);
log_esp3d("Init camera config");
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
log_esp3d("Camera init failed with error 0x%x", err);
} else { } else {
_initialised = true; res = -1;
} }
return _initialised; return res;
} }
bool Camera::stopHardware() bool Camera::initHardware() {
{ _initialised = false;
return true; log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
stopHardware();
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.jpeg_quality = 5;
config.fb_count = 1;
config.frame_size = DEFAULT_FRAME_SIZE;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.grab_mode = CAMERA_GRAB_LATEST;
if (!psramFound()) {
_initialised = false;
log_esp3d_e("psram is not enabled");
return false;
}
log_esp3d("Init camera");
#if CAM_PULLUP1 != -1
pinMode(CAM_PULLUP1, INPUT_PULLUP);
#endif // CAM_PULLUP1
#if CAM_PULLUP2 != -1
pinMode(CAM_PULLUP2, INPUT_PULLUP);
#endif // CAM_PULLUP2
#if CAM_LED_PIN != -1
pinMode(CAM_LED_PIN, OUTPUT);
digitalWrite(CAM_LED_PIN, LOW);
#endif // CAM_LED_PIN
// initialize the camera
// https://github.com/espressif/esp32-camera/issues/66#issuecomment-526283681
#if CAMERA_DEVICE == CAMERA_MODEL_AI_THINKER
log_esp3d("Specific config for CAMERA_MODEL_AI_THINKER");
gpio_config_t gpio_pwr_config;
gpio_pwr_config.pin_bit_mask = (1ULL << 32);
gpio_pwr_config.mode = GPIO_MODE_OUTPUT;
gpio_pwr_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_pwr_config.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_pwr_config.intr_type = GPIO_INTR_DISABLE;
gpio_config(&gpio_pwr_config);
gpio_set_level(GPIO_NUM_32, 0);
#endif // CAMERA_DEVICE == CAMERA_MODEL_AI_THINKER
delay(500);
log_esp3d("Init camera config");
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
log_esp3d_e("Camera init failed with error 0x%x", err);
} else {
_initialised = true;
}
return _initialised;
} }
//need to be call by device and by network bool Camera::stopHardware() { return true; }
bool Camera::begin()
{
end();
log_esp3d("Begin camera");
if (!_initialised) {
log_esp3d("Init hardware not done");
return false;
}
log_esp3d("Init camera sensor settings");
sensor_t * s = esp_camera_sensor_get();
if (s != nullptr) {
//initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_brightness(s, 1);//up the blightness just a bit
s->set_saturation(s, -2);//lower the saturation
}
s->set_framesize(s, DEFAULT_FRAME_SIZE); // need to be call by device and by network
bool Camera::begin() {
end();
log_esp3d("Begin camera");
if (!_initialised) {
log_esp3d("Init hardware not done");
return false;
}
log_esp3d("Init camera sensor settings");
sensor_t *s = esp_camera_sensor_get();
if (s != nullptr) {
// initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_brightness(s, 1); // up the blightness just a bit
s->set_saturation(s, -2); // lower the saturation
}
s->set_framesize(s, DEFAULT_FRAME_SIZE);
#if defined(CAMERA_DEVICE_FLIP_HORIZONTALY) #if defined(CAMERA_DEVICE_FLIP_HORIZONTALY)
s->set_hmirror(s, 1); s->set_hmirror(s, 1);
#endif //CAMERA_DEVICE_FLIP_HORIZONTALY #endif // CAMERA_DEVICE_FLIP_HORIZONTALY
#if defined(CAMERA_DEVICE_FLIP_VERTICALY) #if defined(CAMERA_DEVICE_FLIP_VERTICALY)
s->set_vflip(s, 1); s->set_vflip(s, 1);
#endif //CAMERA_DEVICE_FLIP_VERTICALY #endif // CAMERA_DEVICE_FLIP_VERTICALY
} else { } else {
log_esp3d("Cannot access camera sensor"); log_esp3d("Cannot access camera sensor");
} }
_started = _initialised; _started = _initialised;
return _started; return _started;
} }
void Camera::end() void Camera::end() { _started = false; }
{
_started = false; void Camera::handle() {
// nothing to do
} }
void Camera::handle() uint8_t Camera::GetModel() { return CAMERA_DEVICE; }
{
//nothing to do
}
uint8_t Camera::GetModel() const char *Camera::GetModelString() {
{
return CAMERA_DEVICE;
}
const char *Camera::GetModelString()
{
#if defined(CUSTOM_CAMERA_NAME) #if defined(CUSTOM_CAMERA_NAME)
return CUSTOM_CAMERA_NAME; return CUSTOM_CAMERA_NAME;
#else #else
switch(CAMERA_DEVICE) { switch (CAMERA_DEVICE) {
case CAMERA_MODEL_WROVER_KIT: case CAMERA_MODEL_WROVER_KIT:
return "WROVER Kit"; return "WROVER Kit";
break; break;
case CAMERA_MODEL_ESP32S3_EYE: case CAMERA_MODEL_ESP32S3_EYE:
case CAMERA_MODEL_ESP_EYE: case CAMERA_MODEL_ESP_EYE:
return "ESP Eye"; return "ESP Eye";
break; break;
case CAMERA_MODEL_M5STACK_WIDE: case CAMERA_MODEL_M5STACK_WIDE:
case CAMERA_MODEL_M5STACK_V2_PSRAM: case CAMERA_MODEL_M5STACK_V2_PSRAM:
case CAMERA_MODEL_M5STACK_PSRAM: case CAMERA_MODEL_M5STACK_PSRAM:
return "M5Stack"; return "M5Stack";
break; break;
case CAMERA_MODEL_ESP32_CAM_BOARD: case CAMERA_MODEL_ESP32_CAM_BOARD:
case CAMERA_MODEL_ESP32S2_CAM_BOARD: case CAMERA_MODEL_ESP32S2_CAM_BOARD:
case CAMERA_MODEL_ESP32S3_CAM_LCD: case CAMERA_MODEL_ESP32S3_CAM_LCD:
case CAMERA_MODEL_AI_THINKER: case CAMERA_MODEL_AI_THINKER:
return "ESP32 Cam"; return "ESP32 Cam";
break; break;
default: default:
return "Unknow Camera"; return "Unknow Camera";
} }
#endif //CUSTOM_CAMERA_NAME #endif // CUSTOM_CAMERA_NAME
} }
#endif //CAMERA_DEVICE #endif // CAMERA_DEVICE

View File

@ -20,125 +20,122 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef CONNECTED_DEVICES_FEATURE #ifdef CONNECTED_DEVICES_FEATURE
#include "devices_services.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h" #include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "devices_services.h"
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
#include "../display/display.h" #include "../display/display.h"
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
#include "../sensor/sensor.h" #include "../sensor/sensor.h"
#endif //SENSOR_DEVICE #endif // SENSOR_DEVICE
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
#include "../buzzer/buzzer.h" #include "../buzzer/buzzer.h"
#endif //BUZZER_DEVICE #endif // BUZZER_DEVICE
#ifdef RECOVERY_FEATURE #ifdef RECOVERY_FEATURE
#include "../recovery/recovery_service.h" #include "../recovery/recovery_service.h"
#endif //RECOVERY_FEATURE #endif // RECOVERY_FEATURE
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
#include "../camera/camera.h" #include "../camera/camera.h"
#endif //CAMERA_DEVICE #endif // CAMERA_DEVICE
#ifdef SD_DEVICE #ifdef SD_DEVICE
#include "../filesystem/esp_sd.h" #include "../filesystem/esp_sd.h"
#endif //SD_DEVICE #endif // SD_DEVICE
bool DevicesServices::_started = false; bool DevicesServices::_started = false;
bool DevicesServices::begin() bool DevicesServices::begin() {
{ bool res = true;
bool res = true; _started = false;
_started = false;
#ifdef SD_DEVICE #ifdef SD_DEVICE
if (!ESP_SD::begin()) { if (!ESP_SD::begin()) {
log_esp3d("Error sd intialization failed"); log_esp3d_e("Error sd intialization failed");
res = false; res = false;
} }
#endif //SD_DEVICE #endif // SD_DEVICE
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
if (!esp3d_display.begin()) { if (!esp3d_display.begin()) {
log_esp3d("Error starting display device"); log_esp3d_e("Error starting display device");
res = false; res = false;
} }
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
if (!esp3d_sensor.begin()) { if (!esp3d_sensor.begin()) {
log_esp3d("Error starting sensor device"); log_esp3d_e("Error starting sensor device");
res = false; res = false;
} }
#endif //SENSOR_DEVICE #endif // SENSOR_DEVICE
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
if (!esp3d_buzzer.begin()) { if (!esp3d_buzzer.begin()) {
log_esp3d("Error starting buzzer device"); log_esp3d_e("Error starting buzzer device");
res = false; res = false;
} }
#endif //BUZZER_DEVICE #endif // BUZZER_DEVICE
#ifdef RECOVERY_FEATURE #ifdef RECOVERY_FEATURE
if (!recovery_service.begin()) { if (!recovery_service.begin()) {
log_esp3d("Error starting recovery service"); log_esp3d_e("Error starting recovery service");
res = false; res = false;
} }
#endif //RECOVERY_FEATURE #endif // RECOVERY_FEATURE
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
if (!esp3d_camera.initHardware()) { if (!esp3d_camera.initHardware()) {
log_esp3d("Error camera intialization failed"); log_esp3d_e("Error camera intialization failed");
res = false; res = false;
} }
#endif //CAMERA_DEVICE #endif // CAMERA_DEVICE
if (!res) { if (!res) {
end(); end();
} }
_started = res; _started = res;
return _started; return _started;
} }
void DevicesServices::end() void DevicesServices::end() {
{ if (!_started) {
if(!_started) { return;
return; }
} _started = false;
_started = false;
#ifdef SD_DEVICE #ifdef SD_DEVICE
ESP_SD::end(); ESP_SD::end();
#endif //SD_DEVICE #endif // SD_DEVICE
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
esp3d_camera.stopHardware(); esp3d_camera.stopHardware();
#endif //CAMERA_DEVICE #endif // CAMERA_DEVICE
#ifdef RECOVERY_FEATURE #ifdef RECOVERY_FEATURE
recovery_service.end(); recovery_service.end();
#endif //RECOVERY_FEATURE #endif // RECOVERY_FEATURE
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
esp3d_buzzer.end(); esp3d_buzzer.end();
#endif //BUZZER_DEVICE #endif // BUZZER_DEVICE
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
esp3d_display.end(); esp3d_display.end();
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
esp3d_sensor.end(); esp3d_sensor.end();
#endif //SENSOR_DEVICE #endif // SENSOR_DEVICE
} }
void DevicesServices::handle() void DevicesServices::handle() {
{ if (_started) {
if (_started) {
#ifdef CAMERA_DEVICE #ifdef CAMERA_DEVICE
esp3d_camera.handle(); esp3d_camera.handle();
#endif //CAMERA_DEVICE #endif // CAMERA_DEVICE
#ifdef DISPLAY_DEVICE #ifdef DISPLAY_DEVICE
esp3d_display.handle(); esp3d_display.handle();
#endif //DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
esp3d_sensor.handle(); esp3d_sensor.handle();
#endif //SENSOR_DEVICE #endif // SENSOR_DEVICE
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
esp3d_buzzer.handle(); esp3d_buzzer.handle();
#endif //BUZZER_DEVICE #endif // BUZZER_DEVICE
#ifdef RECOVERY_FEATURE #ifdef RECOVERY_FEATURE
recovery_service.handle(); recovery_service.handle();
#endif //RECOVERY_FEATURE #endif // RECOVERY_FEATURE
#ifdef SD_DEVICE #ifdef SD_DEVICE
ESP_SD::handle(); ESP_SD::handle();
#endif //SD_DEVICE #endif // SD_DEVICE
} }
} }
#endif //#CONNECTED_DEVICES_FEATURE #endif // #CONNECTED_DEVICES_FEATURE

View File

@ -19,33 +19,33 @@
*/ */
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined (ETH_FEATURE) #if defined(ETH_FEATURE)
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include "esp_eth.h"
#include "dhcpserver/dhcpserver_options.h" #include "dhcpserver/dhcpserver_options.h"
#endif //ARDUINO_ARCH_ESP32 #include "esp_eth.h"
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../../core/esp3doutput.h" #include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h" #include "../../core/settings_esp3d.h"
#include "../network/netconfig.h" #include "../network/netconfig.h"
#include "ethconfig.h" #include "ethconfig.h"
bool EthConfig::_started = false; bool EthConfig::_started = false;
bool EthConfig::_connected = false; bool EthConfig::_connected = false;
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0}; const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
bool EthConfig::StartSTA() bool EthConfig::StartSTA() {
{ bool res = true;
bool res = true; if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) {
if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) { int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_VALUE);
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_VALUE); int32_t GW = Settings_ESP3D::read_IP(ESP_STA_GATEWAY_VALUE);
int32_t GW = Settings_ESP3D::read_IP(ESP_STA_GATEWAY_VALUE); int32_t MK = Settings_ESP3D::read_IP(ESP_STA_MASK_VALUE);
int32_t MK = Settings_ESP3D::read_IP(ESP_STA_MASK_VALUE); int32_t DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
int32_t DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE); IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS); res = ETH.config(ip, gateway, mask, dns);
res = ETH.config(ip, gateway,mask,dns); }
} return res;
return res;
} }
/*bool EthConfig::StartSRV() /*bool EthConfig::StartSRV()
{ {
@ -55,7 +55,7 @@ bool EthConfig::StartSTA()
IPAddress ip(IP), mask(DEFAULT_AP_MASK_VALUE), gateway(IP); IPAddress ip(IP), mask(DEFAULT_AP_MASK_VALUE), gateway(IP);
if (!ETH.config(ip, gateway,mask)) { if (!ETH.config(ip, gateway,mask)) {
res = false; res = false;
log_esp3d("Set static IP error"); log_esp3d_e("Set static IP error");
} }
//start DHCP server //start DHCP server
if(res) { if(res) {
@ -72,97 +72,86 @@ bool EthConfig::StartSTA()
if (tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_ETH) != ESP_OK){ if (tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_ETH) != ESP_OK){
res = false; res = false;
log_esp3d("Start DHCP server failed"); log_esp3d_e("Start DHCP server failed");
} }
} }
return res; return res;
}*/ }*/
bool EthConfig::linkUp() bool EthConfig::linkUp() {
{ #if defined(ESP_IDF_VERSION_MAJOR)
#if defined( ESP_IDF_VERSION_MAJOR ) // patch for https://github.com/espressif/arduino-esp32/issues/6105
//patch for https://github.com/espressif/arduino-esp32/issues/6105 return _connected;
return _connected;
#else #else
return ETH.linkUp(); return ETH.linkUp();
#endif #endif
} }
/** /**
* begin WiFi setup * begin WiFi setup
*/ */
bool EthConfig::begin(int8_t & espMode) bool EthConfig::begin(int8_t& espMode) {
{ bool res = false;
bool res = false; ESP3DOutput output(ESP_ALL_CLIENTS);
ESP3DOutput output(ESP_ALL_CLIENTS); end();
end(); _started = ETH.begin();
_started = ETH.begin(); if (_started) {
if (_started) { if (Settings_ESP3D::isVerboseBoot()) {
if (Settings_ESP3D::isVerboseBoot()) { output.printMSG("Starting Ethernet");
output.printMSG("Starting Ethernet"); }
} res = true;
res=true; } else {
output.printERROR("Failed Starting Ethernet");
}
ETH.setHostname(NetConfig::hostname(true));
// DHCP is only for Client
if (espMode == ESP_ETH_STA) {
if (!StartSTA()) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting fallback mode");
}
espMode = Settings_ESP3D::read_byte(ESP_STA_FALLBACK_MODE);
res = true;
} else { } else {
output.printERROR("Failed Starting Ethernet"); if (Settings_ESP3D::isVerboseBoot()) {
} output.printMSG("Client started");
ETH.setHostname(NetConfig::hostname(true)); }
//DHCP is only for Client
if (espMode == ESP_ETH_STA) {
if(!StartSTA()) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting fallback mode");
}
espMode = Settings_ESP3D::read_byte(ESP_STA_FALLBACK_MODE);
res = true;
} else {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG ("Client started");
}
}
} else {
//if(!StartSRV()){
// res = false;
// output.printMSG ("Failed Starting Server");
//} else {
// output.printMSG ("Server started");
//}
} }
} else {
// if(!StartSRV()){
// res = false;
// output.printMSG ("Failed Starting Server");
// } else {
// output.printMSG ("Server started");
// }
}
//if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) || (espMode == ESP_ETH_SRV)){ // if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) || (espMode
if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) { // == ESP_ETH_SRV)){
//as no event to display static IP if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) {
output.printMSG (ETH.localIP().toString().c_str()); // as no event to display static IP
} output.printMSG(ETH.localIP().toString().c_str());
}
return res; return res;
} }
/** /**
* End WiFi * End WiFi
*/ */
void EthConfig::end() void EthConfig::end() {
{ // esp_eth_disable();
//esp_eth_disable(); _started = false;
_started = false;
} }
bool EthConfig::started() bool EthConfig::started() { return _started; }
{
return _started;
}
/** /**
* Handle not critical actions that must be done in sync environement * Handle not critical actions that must be done in sync environement
*/ */
void EthConfig::handle() void EthConfig::handle() {}
{
}
#endif // ETH_FEATURE
#endif // ETH_FEATURE

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
// #define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SD_DEVICE #ifdef SD_DEVICE
#include <time.h> #include <time.h>
@ -152,7 +152,7 @@ bool ESP_SD::accessFS(uint8_t FS) {
log_esp3d("Access SD ok"); log_esp3d("Access SD ok");
return true; return true;
} else { } else {
log_esp3d("Enable shared SD failed"); log_esp3d_e("Enable shared SD failed");
return false; return false;
} }
#else #else

View File

@ -17,283 +17,262 @@ fat_esp32_filesystem.cpp - ESP3D fat filesystem configuration class
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) #if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM)
#include "../esp_filesystem.h"
#include <stack>
#include <FS.h> #include <FS.h>
#include <stack>
#include "../esp_filesystem.h"
#include "FFat.h" #include "FFat.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE]; extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin() bool ESP_FileSystem::begin() {
{ _started = FFat.begin();
_started = FFat.begin(); return _started;
}
void ESP_FileSystem::end() {
FFat.end();
_started = false;
}
size_t ESP_FileSystem::freeBytes() { return FFat.freeBytes(); }
size_t ESP_FileSystem::totalBytes() { return FFat.totalBytes(); }
size_t ESP_FileSystem::usedBytes() {
return (FFat.totalBytes() - FFat.freeBytes());
}
uint ESP_FileSystem::maxPathLength() { return 32; }
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath) {
return FFat.rename(oldpath, newpath);
}
const char *ESP_FileSystem::FilesystemName() { return "FAT"; }
bool ESP_FileSystem::format() {
bool res = FFat.format();
if (res) {
res = begin();
}
return res;
}
ESP_File ESP_FileSystem::open(const char *path, uint8_t mode) {
log_esp3d("open %s as %s", path, (mode == ESP_FILE_WRITE ? "write" : "read"));
// do some check
if (((strcmp(path, "/") == 0) &&
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) {
log_esp3d_e("reject %s", path);
return ESP_File();
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d_e("%s is invalid path", path);
return ESP_File();
}
File tmp = FFat.open(path, (mode == ESP_FILE_READ) ? FILE_READ
: (mode == ESP_FILE_WRITE) ? FILE_WRITE
: FILE_APPEND);
if (tmp) {
ESP_File esptmp(&tmp, tmp.isDirectory(),
(mode == ESP_FILE_READ) ? false : true, path);
log_esp3d("%s is a %s", path, tmp.isDirectory() ? "Dir" : "File");
log_esp3d("path is %s and filename path is %s", path, tmp.path());
return esptmp;
} else {
log_esp3d_e("open %s failed", path);
return ESP_File();
}
}
bool ESP_FileSystem::exists(const char *path) {
bool res = false;
// root should always be there if started
if (strcmp(path, "/") == 0) {
return _started; return _started;
} }
res = FFat.exists(path);
void ESP_FileSystem::end() if (!res) {
{ ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ);
FFat.end(); if (root) {
_started = false; res = root.isDirectory();
}
size_t ESP_FileSystem::freeBytes()
{
return FFat.freeBytes();
}
size_t ESP_FileSystem::totalBytes()
{
return FFat.totalBytes();
}
size_t ESP_FileSystem::usedBytes()
{
return (FFat.totalBytes() - FFat.freeBytes());
}
uint ESP_FileSystem::maxPathLength()
{
return 32;
}
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath)
{
return FFat.rename(oldpath,newpath);
}
const char * ESP_FileSystem::FilesystemName()
{
return "FAT";
}
bool ESP_FileSystem::format()
{
bool res = FFat.format();
if (res) {
res = begin();
} }
return res; root.close();
}
return res;
} }
ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) bool ESP_FileSystem::remove(const char *path) { return FFat.remove(path); }
{
log_esp3d("open %s as %s", path,(mode == ESP_FILE_WRITE?"write":"read") ); bool ESP_FileSystem::mkdir(const char *path) {
//do some check String p = path;
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { if (p[0] != '/') {
log_esp3d("reject %s", path); p = "/" + p;
return ESP_File(); }
} if (p[p.length() - 1] == '/') {
// path must start by '/' if (p != "/") {
if (path[0] != '/') { p.remove(p.length() - 1);
log_esp3d("%s is invalid path", path);
return ESP_File();
}
File tmp = FFat.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
if(tmp) {
ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
log_esp3d("%s is a %s", path,tmp.isDirectory()?"Dir":"File");
log_esp3d("path is %s and filename path is %s", path, tmp.path());
return esptmp;
} else {
log_esp3d("open %s failed", path);
return ESP_File();
} }
}
return FFat.mkdir(p);
} }
bool ESP_FileSystem::exists(const char* path) bool ESP_FileSystem::rmdir(const char *path) {
{ String p = path;
bool res = false; if (!p.startsWith("/")) {
//root should always be there if started p = '/' + p;
if (strcmp(path, "/") == 0) { }
return _started; if (p != "/") {
if (p.endsWith("/")) {
p.remove(p.length() - 1);
} }
res = FFat.exists(path); }
if (!res) { if (!exists(p.c_str())) {
ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ); return false;
if (root) { }
res = root.isDirectory(); bool res = true;
std::stack<String> pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = FFat.open(pathlist.top().c_str());
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top() + '/';
newdir += f.name();
pathlist.push(newdir);
f.close();
f = File();
} else {
String filepath = pathlist.top() + '/';
filepath += f.name();
f.close();
if (!FFat.remove(filepath.c_str())) {
res = false;
} }
root.close(); f = dir.openNextFile();
}
} }
return res; if (candelete) {
if (pathlist.top() != "/") {
res = FFat.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
} }
bool ESP_FileSystem::remove(const char *path) void ESP_FileSystem::closeAll() {
{ for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
return FFat.remove(path); tFile_handle[i].close();
tFile_handle[i] = File();
}
} }
bool ESP_FileSystem::mkdir(const char *path) ESP_File::ESP_File(void *handle, bool isdir, bool iswritemode,
{ const char *path) {
String p = path; _isdir = isdir;
if(p[0]!='/') { _dirlist = "";
p="/"+p; _isfakedir = false;
} _index = -1;
if (p[p.length()-1] == '/') { _filename = "";
if (p!="/") { _name = "";
p.remove(p.length()-1); _lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File *)handle);
// filename
_filename = tFile_handle[i].path();
// name
if (_filename == "/") {
_name = "/";
} else {
_name = tFile_handle[i].name();
if (_name[0] == '/') {
_name.remove(0, 1);
} }
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
}
// size
_size = tFile_handle[i].size();
// time
_lastwrite = tFile_handle[i].getLastWrite();
_index = i;
log_esp3d("Opening File at index %d", _index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
log_esp3d("path: %s", tFile_handle[i].path());
set = true;
} }
return FFat.mkdir(p); }
if (!set) {
log_esp3d("No handle available");
}
} }
bool ESP_FileSystem::rmdir(const char *path) bool ESP_File::seek(uint32_t pos, uint8_t mode) {
{ return tFile_handle[_index].seek(pos, (SeekMode)mode);
String p = path;
if (!p.startsWith("/")) {
p = '/'+p;
}
if (p!= "/") {
if (p.endsWith("/")) {
p.remove(p.length()-1);
}
}
if (!exists(p.c_str())) {
return false;
}
bool res = true;
std::stack <String > pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = FFat.open(pathlist.top().c_str());
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top()+ '/';
newdir+= f.name();
pathlist.push(newdir);
f.close();
f = File();
} else {
String filepath = pathlist.top()+ '/';
filepath+= f.name();
f.close();
if (!FFat.remove(filepath.c_str())) {
res = false;
}
f = dir.openNextFile();
}
}
if (candelete) {
if (pathlist.top() !="/") {
res = FFat.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
} }
void ESP_FileSystem::closeAll() void ESP_File::close() {
{ if (_index != -1) {
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { log_esp3d("Closing File %s at index %d", _filename.c_str(), _index);
tFile_handle[i].close(); log_esp3d("name: %s", _name.c_str());
tFile_handle[i] = File(); tFile_handle[_index].close();
// reopen if mode = write
// udate size + date
if (_iswritemode && !_isdir) {
log_esp3d("Updating %s size", _filename.c_str());
File ftmp = FFat.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
log_esp3d("Size is %d", _size);
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
} }
} tFile_handle[_index] = File();
ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
_index = -1; _index = -1;
_filename = ""; }
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File*)handle);
//filename
_filename = tFile_handle[i].path();
//name
if (_filename == "/") {
_name = "/";
} else {
_name = tFile_handle[i].name();
if (_name[0] == '/') {
_name.remove( 0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove( 0, pos+1);
}
}
//size
_size = tFile_handle[i].size();
//time
_lastwrite = tFile_handle[i].getLastWrite();
_index = i;
log_esp3d("Opening File at index %d",_index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
log_esp3d("path: %s", tFile_handle[i].path());
set = true;
}
}
if(!set) {
log_esp3d("No handle available");
}
} }
bool ESP_File::seek(uint32_t pos, uint8_t mode) ESP_File ESP_File::openNextFile() {
{ if ((_index == -1) || !_isdir) {
return tFile_handle[_index].seek(pos, (SeekMode)mode); log_esp3d("openNextFile %d failed", _index);
return ESP_File();
}
File tmp = tFile_handle[_index].openNextFile();
while (tmp) {
log_esp3d("tmp name :%s %s", tmp.name(),
(tmp.isDirectory()) ? "isDir" : "isFile");
ESP_File esptmp(&tmp, tmp.isDirectory());
esptmp.close();
return esptmp;
}
return ESP_File();
} }
void ESP_File::close() #endif // ESP_FAT_FILESYSTEM
{
if (_index != -1) {
log_esp3d("Closing File %s at index %d", _filename.c_str(), _index);
log_esp3d("name: %s", _name.c_str());
tFile_handle[_index].close();
//reopen if mode = write
//udate size + date
if (_iswritemode && !_isdir) {
log_esp3d("Updating %s size", _filename.c_str());
File ftmp = FFat.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
log_esp3d("Size is %d",_size);
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
}
tFile_handle[_index] = File();
_index = -1;
}
}
ESP_File ESP_File::openNextFile()
{
if ((_index == -1) || !_isdir) {
log_esp3d("openNextFile %d failed", _index);
return ESP_File();
}
File tmp = tFile_handle[_index].openNextFile();
while (tmp) {
log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile");
ESP_File esptmp(&tmp, tmp.isDirectory());
esptmp.close();
return esptmp;
}
return ESP_File();
}
#endif //ESP_FAT_FILESYSTEM

View File

@ -17,296 +17,279 @@ littlefs_esp32_filesystem.cpp - ESP3D littlefs filesystem configuration class
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if (FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32) #if (FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM) && \
#include "../esp_filesystem.h" defined(ARDUINO_ARCH_ESP32)
#include <stack>
#include <FS.h> #include <FS.h>
#include <LittleFS.h> #include <LittleFS.h>
#include <stack>
#include "../esp_filesystem.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE]; extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin() bool ESP_FileSystem::begin() {
{ _started = LittleFS.begin(true);
_started = LittleFS.begin(true); return _started;
}
void ESP_FileSystem::end() {
LittleFS.end();
_started = false;
}
size_t ESP_FileSystem::freeBytes() {
return (LittleFS.totalBytes() - LittleFS.usedBytes());
}
size_t ESP_FileSystem::totalBytes() { return LittleFS.totalBytes(); }
size_t ESP_FileSystem::usedBytes() { return LittleFS.usedBytes(); }
uint ESP_FileSystem::maxPathLength() { return 32; }
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath) {
log_esp3d("rename %s to %s", oldpath, newpath);
return LittleFS.rename(oldpath, newpath);
}
const char *ESP_FileSystem::FilesystemName() { return "LittleFS"; }
bool ESP_FileSystem::format() {
bool res = LittleFS.format();
if (res) {
res = begin();
}
return res;
}
ESP_File ESP_FileSystem::open(const char *path, uint8_t mode) {
log_esp3d("open %s", path);
// do some check
if (((strcmp(path, "/") == 0) &&
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) {
log_esp3d("reject %s", path);
return ESP_File();
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d("%s is invalid path", path);
return ESP_File();
}
File tmp = LittleFS.open(path, (mode == ESP_FILE_READ) ? FILE_READ
: (mode == ESP_FILE_WRITE) ? FILE_WRITE
: FILE_APPEND);
if (tmp) {
ESP_File esptmp(&tmp, tmp.isDirectory(),
(mode == ESP_FILE_READ) ? false : true, path);
log_esp3d("%s is a %s", path, tmp.isDirectory() ? "Dir" : "File");
return esptmp;
} else {
log_esp3d("open %s failed", path);
return ESP_File();
}
}
bool ESP_FileSystem::exists(const char *path) {
bool res = false;
// root should always be there if started
if (strcmp(path, "/") == 0) {
return _started; return _started;
} }
String p = path;
void ESP_FileSystem::end() if (p[0] != '/') {
{ p = "/" + p;
LittleFS.end(); }
_started = false; res = LittleFS.exists(p);
} if (!res) {
ESP_File root = ESP_FileSystem::open(p.c_str(), ESP_FILE_READ);
size_t ESP_FileSystem::freeBytes() if (root) {
{ res = root.isDirectory();
return (LittleFS.totalBytes() - LittleFS.usedBytes());
}
size_t ESP_FileSystem::totalBytes()
{
return LittleFS.totalBytes();
}
size_t ESP_FileSystem::usedBytes()
{
return LittleFS.usedBytes();
}
uint ESP_FileSystem::maxPathLength()
{
return 32;
}
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath)
{
return LittleFS.rename(oldpath,newpath);
}
const char * ESP_FileSystem::FilesystemName()
{
return "LittleFS";
}
bool ESP_FileSystem::format()
{
bool res = LittleFS.format();
if (res) {
res = begin();
} }
return res; root.close();
}
return res;
} }
ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) bool ESP_FileSystem::remove(const char *path) {
{ String p = path;
log_esp3d("open %s", path); if (p[0] != '/') {
//do some check p = "/" + p;
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { }
log_esp3d("reject %s", path); return LittleFS.remove(p.c_str());
return ESP_File(); }
bool ESP_FileSystem::mkdir(const char *path) {
String p = path;
if (p[0] != '/') {
p = "/" + p;
}
if (p[p.length() - 1] == '/') {
if (p != "/") {
p.remove(p.length() - 1);
} }
// path must start by '/' }
if (path[0] != '/') { return LittleFS.mkdir(p);
log_esp3d("%s is invalid path", path); }
return ESP_File();
bool ESP_FileSystem::rmdir(const char *path) {
String p = path;
if (!p.startsWith("/")) {
p = '/' + p;
}
if (p != "/") {
if (p.endsWith("/")) {
p.remove(p.length() - 1);
} }
File tmp = LittleFS.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); }
if(tmp) { if (!exists(p.c_str())) {
ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path); return false;
log_esp3d("%s is a %s", path,tmp.isDirectory()?"Dir":"File"); }
return esptmp; bool res = true;
std::stack<String> pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = LittleFS.open(pathlist.top().c_str());
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top() + '/';
newdir += f.name();
pathlist.push(newdir);
f.close();
f = File();
} else {
String filepath = pathlist.top() + '/';
filepath += f.name();
f.close();
if (!LittleFS.remove(filepath.c_str())) {
res = false;
}
f = dir.openNextFile();
}
}
if (candelete) {
if (pathlist.top() != "/") {
res = LittleFS.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
}
void ESP_FileSystem::closeAll() {
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
tFile_handle[i].close();
tFile_handle[i] = File();
}
}
ESP_File::ESP_File(void *handle, bool isdir, bool iswritemode,
const char *path) {
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File *)handle);
// filename
_filename = tFile_handle[i].path();
// name
if (_filename == "/") {
_name = "/";
} else {
_name = tFile_handle[i].name();
if (_name[0] == '/') {
_name.remove(0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
}
// size
_size = tFile_handle[i].size();
// time
_lastwrite = tFile_handle[i].getLastWrite();
_index = i;
log_esp3d("Opening File at index %d", _index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
log_esp3d("path: %s", tFile_handle[i].path());
set = true;
} else { } else {
log_esp3d("open %s failed", path); log_esp3d("File %d busy", i);
return ESP_File(); log_esp3d("%s", tFile_handle[i].name());
} }
} }
if (!set) {
bool ESP_FileSystem::exists(const char* path) log_esp3d("No handle available");
{ #if defined(ESP_LOG_FEATURE)
bool res = false; for (uint8_t i = 0; (i < ESP_MAX_OPENHANDLE); i++) {
//root should always be there if started log_esp3d("%s", tFile_handle[i].name());
if (strcmp(path, "/") == 0) {
return _started;
} }
String p = path;
if(p[0]!='/') {
p="/"+p;
}
res = LittleFS.exists(p);
if (!res) {
ESP_File root = ESP_FileSystem::open(p.c_str(), ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
root.close();
}
return res;
}
bool ESP_FileSystem::remove(const char *path)
{
String p = path;
if(p[0]!='/') {
p="/"+p;
}
return LittleFS.remove(p.c_str());
}
bool ESP_FileSystem::mkdir(const char *path)
{
String p = path;
if(p[0]!='/') {
p="/"+p;
}
if (p[p.length()-1] == '/') {
if (p!="/") {
p.remove(p.length()-1);
}
}
return LittleFS.mkdir(p);
}
bool ESP_FileSystem::rmdir(const char *path)
{
String p = path;
if (!p.startsWith("/")) {
p = '/'+p;
}
if (p!= "/") {
if (p.endsWith("/")) {
p.remove(p.length()-1);
}
}
if (!exists(p.c_str())) {
return false;
}
bool res = true;
std::stack <String> pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = LittleFS.open(pathlist.top().c_str());
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top()+ '/';
newdir+= f.name();
pathlist.push(newdir);
f.close();
f = File();
} else {
String filepath = pathlist.top()+ '/';
filepath+= f.name();
f.close();
if (!LittleFS.remove(filepath.c_str())) {
res = false;
}
f = dir.openNextFile();
}
}
if (candelete) {
if (pathlist.top() !="/") {
res = LittleFS.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
}
void ESP_FileSystem::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
tFile_handle[i].close();
tFile_handle[i] = File();
}
}
ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File*)handle);
//filename
_filename = tFile_handle[i].path();
//name
if (_filename == "/") {
_name = "/";
} else {
_name = tFile_handle[i].name();
if (_name[0] == '/') {
_name.remove( 0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove( 0, pos+1);
}
}
//size
_size = tFile_handle[i].size();
//time
_lastwrite = tFile_handle[i].getLastWrite();
_index = i;
log_esp3d("Opening File at index %d",_index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
log_esp3d("path: %s", tFile_handle[i].path());
set = true;
} else {
log_esp3d("File %d busy", i);
log_esp3d("%s", tFile_handle[i].name());
}
}
if(!set) {
log_esp3d("No handle available");
#if defined(ESP_DEBUG_FEATURE)
for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) ; i++) {
log_esp3d("%s", tFile_handle[i].name());
}
#endif #endif
} }
} }
void ESP_File::close() void ESP_File::close() {
{ if (_index != -1) {
if (_index != -1) { log_esp3d("Closing File at index %d", _index);
log_esp3d("Closing File at index %d", _index); tFile_handle[_index].close();
tFile_handle[_index].close(); // reopen if mode = write
//reopen if mode = write // udate size + date
//udate size + date if (_iswritemode && !_isdir) {
if (_iswritemode && !_isdir) { File ftmp = LittleFS.open(_filename.c_str());
File ftmp = LittleFS.open(_filename.c_str()); if (ftmp) {
if (ftmp) { _size = ftmp.size();
_size = ftmp.size(); _lastwrite = ftmp.getLastWrite();
_lastwrite = ftmp.getLastWrite(); ftmp.close();
ftmp.close(); } else {
} else { log_esp3d("Error opening %s", _filename.c_str());
log_esp3d("Error opening %s", _filename.c_str()); }
}
}
tFile_handle[_index] = File();
_index = -1;
} }
tFile_handle[_index] = File();
_index = -1;
}
} }
bool ESP_File::seek(uint32_t pos, uint8_t mode) bool ESP_File::seek(uint32_t pos, uint8_t mode) {
{ return tFile_handle[_index].seek(pos, (SeekMode)mode);
return tFile_handle[_index].seek(pos, (SeekMode)mode);
} }
ESP_File ESP_File::openNextFile() ESP_File ESP_File::openNextFile() {
{ if ((_index == -1) || !_isdir) {
if ((_index == -1) || !_isdir) { log_esp3d("openNextFile %d failed", _index);
log_esp3d("openNextFile %d failed", _index); return ESP_File();
return ESP_File(); }
} File tmp = tFile_handle[_index].openNextFile();
File tmp = tFile_handle[_index].openNextFile(); while (tmp) {
while (tmp) { log_esp3d("tmp name :%s %s", tmp.name(),
log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile"); (tmp.isDirectory()) ? "isDir" : "isFile");
ESP_File esptmp(&tmp, tmp.isDirectory()); ESP_File esptmp(&tmp, tmp.isDirectory());
esptmp.close(); esptmp.close();
return esptmp; return esptmp;
} }
return ESP_File(); return ESP_File();
} }
#endif // ESP_LITTLEFS_FILESYSTEM
#endif //ESP_LITTLEFS_FILESYSTEM

View File

@ -17,331 +17,319 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32) #if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32)
#include "../esp_filesystem.h"
#include <stack>
#include <FS.h> #include <FS.h>
#include <SPIFFS.h> #include <SPIFFS.h>
#include <stack>
#include "../esp_filesystem.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE]; extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin() bool ESP_FileSystem::begin() {
{ _started = SPIFFS.begin(true);
_started = SPIFFS.begin(true); return _started;
}
void ESP_FileSystem::end() {
_started = false;
SPIFFS.end();
}
size_t ESP_FileSystem::freeBytes() { return totalBytes() - usedBytes(); }
size_t ESP_FileSystem::totalBytes() { return SPIFFS.totalBytes(); }
size_t ESP_FileSystem::usedBytes() { return SPIFFS.usedBytes(); }
uint ESP_FileSystem::maxPathLength() { return 32; }
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath) {
return SPIFFS.rename(oldpath, newpath);
}
const char *ESP_FileSystem::FilesystemName() { return "SPIFFS"; }
bool ESP_FileSystem::format() {
bool res = SPIFFS.format();
if (res) {
res = begin();
}
return res;
}
ESP_File ESP_FileSystem::open(const char *path, uint8_t mode) {
// do some check
if (((strcmp(path, "/") == 0) &&
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) {
return ESP_File();
}
// path must start by '/'
if (path[0] != '/') {
return ESP_File();
}
// TODO add support if path = /DIR1/ <- with last /
File tmp = SPIFFS.open(path, (mode == ESP_FILE_READ) ? FILE_READ
: (mode == ESP_FILE_WRITE) ? FILE_WRITE
: FILE_APPEND);
if (tmp) {
ESP_File esptmp(&tmp, tmp.isDirectory(),
(mode == ESP_FILE_READ) ? false : true, path);
log_esp3d("%s is a %s", path, tmp.isDirectory() ? "Dir" : "File");
return esptmp;
} else {
log_esp3d("open %s failed", path);
return ESP_File();
}
}
bool ESP_FileSystem::exists(const char *path) {
bool res = false;
// root should always be there if started
if (strcmp(path, "/") == 0) {
return _started; return _started;
} }
void ESP_FileSystem::end() String spath = path;
{ spath.trim();
_started = false; if (spath[spath.length() - 1] == '/') {
SPIFFS.end(); if (spath != "/") {
} spath.remove(spath.length() - 1);
size_t ESP_FileSystem::freeBytes()
{
return totalBytes() - usedBytes();
}
size_t ESP_FileSystem::totalBytes()
{
return SPIFFS.totalBytes();
}
size_t ESP_FileSystem::usedBytes()
{
return SPIFFS.usedBytes();
}
uint ESP_FileSystem::maxPathLength()
{
return 32;
}
bool ESP_FileSystem::rename(const char *oldpath, const char *newpath)
{
return SPIFFS.rename(oldpath,newpath);
}
const char * ESP_FileSystem::FilesystemName()
{
return "SPIFFS";
}
bool ESP_FileSystem::format()
{
bool res = SPIFFS.format();
if (res) {
res = begin();
} }
return res; }
} res = SPIFFS.exists(spath.c_str());
if (!res) {
ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) String newpath = spath;
{ if (newpath[newpath.length() - 1] != '/') {
//do some check newpath += "/";
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
return ESP_File();
} }
// path must start by '/' newpath += ".";
if (path[0] != '/') { log_esp3d("Check %s", newpath.c_str());
return ESP_File(); res = SPIFFS.exists(newpath);
}
//TODO add support if path = /DIR1/ <- with last /
File tmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
if(tmp) {
ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
log_esp3d("%s is a %s", path,tmp.isDirectory()?"Dir":"File");
return esptmp;
} else {
log_esp3d("open %s failed", path);
return ESP_File();
}
}
bool ESP_FileSystem::exists(const char* path)
{
bool res = false;
//root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
}
String spath = path;
spath.trim();
if (spath[spath.length()-1] == '/') {
if (spath!="/") {
spath.remove(spath.length()-1);
}
}
res = SPIFFS.exists(spath.c_str());
if (!res) { if (!res) {
String newpath = spath; ESP_File f = ESP_FileSystem::open(path, ESP_FILE_READ);
if (newpath[newpath.length()-1] != '/') { if (f) {
newpath+="/"; // Check directories
ESP_File sub = f.openNextFile();
if (sub) {
sub.close();
res = true;
} }
newpath+=".";
log_esp3d("Check %s", newpath.c_str());
res = SPIFFS.exists(newpath);
if (!res) {
ESP_File f = ESP_FileSystem::open(path, ESP_FILE_READ);
if (f) {
//Check directories
ESP_File sub = f.openNextFile();
if (sub) {
sub.close();
res = true;
}
f.close();
}
}
}
return res;
}
bool ESP_FileSystem::remove(const char *path)
{
String p = path;
if(p[0]!='/') {
p="/"+p;
}
return SPIFFS.remove(p);
}
bool ESP_FileSystem::mkdir(const char *path)
{
//Use file named . to simulate directory
String p = path;
if (p[p.length()-1] != '/') {
p+="/";
}
p+=".";
log_esp3d("Dir create : %s", p.c_str());
ESP_File f = open(p.c_str(), ESP_FILE_WRITE);
if (f) {
f.close(); f.close();
return true; }
} else {
return false;
} }
}
return res;
} }
bool ESP_FileSystem::rmdir(const char *path) bool ESP_FileSystem::remove(const char *path) {
{ String p = path;
String spath = path; if (p[0] != '/') {
spath.trim(); p = "/" + p;
if (!spath.startsWith("/")) { }
spath = '/'+spath; return SPIFFS.remove(p);
}
bool ESP_FileSystem::mkdir(const char *path) {
// Use file named . to simulate directory
String p = path;
if (p[p.length() - 1] != '/') {
p += "/";
}
p += ".";
log_esp3d("Dir create : %s", p.c_str());
ESP_File f = open(p.c_str(), ESP_FILE_WRITE);
if (f) {
f.close();
return true;
} else {
return false;
}
}
bool ESP_FileSystem::rmdir(const char *path) {
String spath = path;
spath.trim();
if (!spath.startsWith("/")) {
spath = '/' + spath;
}
if (spath != "/") {
if (spath.endsWith("/")) {
spath.remove(spath.length() - 1);
} }
if (spath!= "/") { }
if (spath.endsWith("/")) { log_esp3d("Deleting : %s", spath.c_str());
spath.remove(spath.length()-1); File ftmp = SPIFFS.open(spath.c_str());
} if (ftmp) {
File pfile = ftmp.openNextFile();
while (pfile) {
log_esp3d("File: %s", pfile.path());
if (!SPIFFS.remove(pfile.path())) {
pfile.close();
return false;
}
pfile.close();
pfile = ftmp.openNextFile();
} }
log_esp3d("Deleting : %s",spath.c_str()); ftmp.close();
File ftmp = SPIFFS.open(spath.c_str()); return true;
if (ftmp) { } else {
File pfile = ftmp.openNextFile(); return false;
while (pfile) { }
log_esp3d("File: %s",pfile.path()); }
if (!SPIFFS.remove(pfile.path())) {
pfile.close(); void ESP_FileSystem::closeAll() {
return false; for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
} tFile_handle[i].close();
pfile.close(); tFile_handle[i] = File();
pfile = ftmp.openNextFile(); }
}
ESP_File::ESP_File(void *handle, bool isdir, bool iswritemode,
const char *path) {
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File *)handle);
// filename
_filename = tFile_handle[i].path();
// if root
if (_filename == "/") {
_filename = "/.";
}
if (_isdir) {
if (_filename[_filename.length() - 1] != '.') {
if (_filename[_filename.length() - 2] != '/') {
_filename += "/";
}
_filename += ".";
} }
}
// name
if (_filename == "/.") {
_name = "/";
} else {
_name = tFile_handle[i].name();
if (_name.endsWith("/.")) {
_name.remove(_name.length() - 2, 2);
_isfakedir = true;
_isdir = true;
}
if (_name[0] == '/') {
_name.remove(0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
}
// size
_size = tFile_handle[i].size();
// time
_lastwrite = tFile_handle[i].getLastWrite();
_index = i;
log_esp3d("Opening File at index %d", _index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
set = true;
}
}
}
bool ESP_File::seek(uint32_t pos, uint8_t mode) {
return tFile_handle[_index].seek(pos, (SeekMode)mode);
}
void ESP_File::close() {
if (_index != -1) {
log_esp3d("Closing File at index %d", _index);
tFile_handle[_index].close();
// reopen if mode = write
// udate size + date
if (_iswritemode && !_isdir) {
File ftmp = SPIFFS.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close(); ftmp.close();
return true; }
} else {
return false;
} }
} tFile_handle[_index] = File();
void ESP_FileSystem::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
tFile_handle[i].close();
tFile_handle[i] = File();
}
}
ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
_index = -1; _index = -1;
_filename = ""; }
_name = ""; }
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
log_esp3d("No handle");
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
if (!tFile_handle[i]) {
tFile_handle[i] = *((File*)handle);
//filename
_filename = tFile_handle[i].path();
//if root ESP_File ESP_File::openNextFile() {
if (_filename == "/") { if ((_index == -1) || !_isdir) {
_filename = "/."; log_esp3d("openNextFile failed");
} return ESP_File();
if (_isdir) { }
if (_filename[_filename.length()-1] != '.') { File tmp = tFile_handle[_index].openNextFile();
if (_filename[_filename.length()-2] != '/') { while (tmp) {
_filename+="/"; log_esp3d("tmp name :%s %s", tmp.name(),
} (tmp.isDirectory()) ? "isDir" : "isFile");
_filename+="."; ESP_File esptmp(&tmp, tmp.isDirectory());
} esptmp.close();
} String sub = esptmp.filename();
//name sub.remove(0, _filename.length() - 1);
if (_filename == "/.") { int pos = sub.indexOf("/");
_name = "/"; if (pos != -1) {
} else { // is subdir
_name = tFile_handle[i].name(); sub = sub.substring(0, pos);
if (_name.endsWith("/.")) { log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(),
_name.remove( _name.length() - 2,2); esptmp.name(), (esptmp.isDirectory()) ? "isDir" : "isFile",
_isfakedir = true; sub.c_str(), _filename.c_str());
_isdir = true; String tag = "*" + sub + "*";
} // test if already in directory list
if (_name[0] == '/') { if (_dirlist.indexOf(tag) ==
_name.remove( 0, 1); -1) { // not in list so add it and return the info
} _dirlist += tag;
int pos = _name.lastIndexOf('/'); String fname =
if (pos != -1) { _filename.substring(0, _filename.length() - 1) + sub + "/.";
_name.remove( 0, pos+1); log_esp3d("Found dir # name: %s filename:%s", sub.c_str(),
} fname.c_str());
} if (sub == ".") {
//size log_esp3d("Dir tag, ignore it");
_size = tFile_handle[i].size(); tmp = tFile_handle[_index].openNextFile();
//time } else {
_lastwrite = tFile_handle[i].getLastWrite(); esptmp = ESP_File(sub.c_str(), fname.c_str());
_index = i; return esptmp;
log_esp3d("Opening File at index %d",_index);
log_esp3d("name: %s", _name.c_str());
log_esp3d("filename: %s", _filename.c_str());
set = true;
} }
} else { // already in list so ignore it
log_esp3d("Dir name: %s already in list", sub.c_str());
tmp = tFile_handle[_index].openNextFile();
}
} else { // is file
log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(),
esptmp.name(), (esptmp.isDirectory()) ? "isDir" : "isFile",
sub.c_str(), _filename.c_str());
if (sub == ".") {
log_esp3d("Dir tag, ignore it");
tmp = tFile_handle[_index].openNextFile();
} else {
log_esp3d("Found file # name: %s filename:%s", esptmp.filename(),
esptmp.name());
return esptmp;
}
} }
}
return ESP_File();
} }
bool ESP_File::seek(uint32_t pos, uint8_t mode) #endif // ESP_SPIFFS_FILESYSTEM
{
return tFile_handle[_index].seek(pos, (SeekMode)mode);
}
void ESP_File::close()
{
if (_index != -1) {
log_esp3d("Closing File at index %d", _index);
tFile_handle[_index].close();
//reopen if mode = write
//udate size + date
if (_iswritemode && !_isdir) {
File ftmp = SPIFFS.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
}
tFile_handle[_index] = File();
_index = -1;
}
}
ESP_File ESP_File::openNextFile()
{
if ((_index == -1) || !_isdir) {
log_esp3d("openNextFile failed");
return ESP_File();
}
File tmp = tFile_handle[_index].openNextFile();
while (tmp) {
log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile");
ESP_File esptmp(&tmp, tmp.isDirectory());
esptmp.close();
String sub = esptmp.filename();
sub.remove(0,_filename.length()-1);
int pos = sub.indexOf("/");
if (pos!=-1) {
//is subdir
sub = sub.substring(0,pos);
log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
String tag = "*" + sub + "*";
//test if already in directory list
if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info
_dirlist+= tag;
String fname = _filename.substring(0,_filename.length()-1) + sub + "/.";
log_esp3d("Found dir # name: %s filename:%s", sub.c_str(), fname.c_str());
if (sub == ".") {
log_esp3d("Dir tag, ignore it");
tmp = tFile_handle[_index].openNextFile();
} else {
esptmp = ESP_File(sub.c_str(), fname.c_str());
return esptmp;
}
} else { //already in list so ignore it
log_esp3d("Dir name: %s already in list", sub.c_str());
tmp = tFile_handle[_index].openNextFile();
}
} else { //is file
log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
if (sub == ".") {
log_esp3d("Dir tag, ignore it");
tmp = tFile_handle[_index].openNextFile();
} else {
log_esp3d("Found file # name: %s filename:%s", esptmp.filename(), esptmp.name());
return esptmp;
}
}
}
return ESP_File();
}
#endif //ESP_SPIFFS_FILESYSTEM

View File

@ -150,6 +150,7 @@ uint64_t ESP_SD::freeBytes(bool refresh) {
uint ESP_SD::maxPathLength() { return 255; } uint ESP_SD::maxPathLength() { return 255; }
bool ESP_SD::rename(const char *oldpath, const char *newpath) { bool ESP_SD::rename(const char *oldpath, const char *newpath) {
log_esp3d("rename %s to %s", oldpath, newpath);
return SD.rename(oldpath, newpath); return SD.rename(oldpath, newpath);
} }
@ -177,7 +178,7 @@ ESP_SDFile ESP_SD::open(const char *path, uint8_t mode) {
String p = path; String p = path;
p.remove(p.lastIndexOf('/') + 1); p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) { if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path); log_esp3d_e("Error opening: %s", path);
return ESP_SDFile(); return ESP_SDFile();
} }
} }

View File

@ -18,408 +18,391 @@ sd_native_esp8266.cpp - ESP3D sd support class
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE) #if defined(ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE)
#if (SD_DEVICE == ESP_SD_NATIVE) #if (SD_DEVICE == ESP_SD_NATIVE)
#define FS_NO_GLOBALS #define FS_NO_GLOBALS
#include "../esp_sd.h"
#include <stack>
#include "../../../core/settings_esp3d.h"
#include <SD.h> #include <SD.h>
#include <SDFS.h> #include <SDFS.h>
#include <stack>
#include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE]; extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
void dateTime (uint16_t* date, uint16_t* dtime) void dateTime(uint16_t* date, uint16_t* dtime) {
{ struct tm tmstruct;
struct tm tmstruct; time_t now;
time_t now; time(&now);
time (&now); localtime_r(&now, &tmstruct);
localtime_r (&now, &tmstruct); *date = FAT_DATE((tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1,
*date = FAT_DATE ( (tmstruct.tm_year) + 1900, ( tmstruct.tm_mon) + 1, tmstruct.tm_mday); tmstruct.tm_mday);
*dtime = FAT_TIME (tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec); *dtime = FAT_TIME(tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
} }
time_t getDateTimeFile(File & filehandle) time_t getDateTimeFile(File& filehandle) {
{ static time_t dt = 0;
static time_t dt = 0;
#ifdef SD_TIMESTAMP_FEATURE #ifdef SD_TIMESTAMP_FEATURE
struct tm timefile; struct tm timefile;
dir_t d; dir_t d;
if(filehandle) { if (filehandle) {
if (filehandle.dirEntry(&d)) { if (filehandle.dirEntry(&d)) {
timefile.tm_year = FAT_YEAR(d.lastWriteDate) - 1900; timefile.tm_year = FAT_YEAR(d.lastWriteDate) - 1900;
timefile.tm_mon = FAT_MONTH(d.lastWriteDate) - 1; timefile.tm_mon = FAT_MONTH(d.lastWriteDate) - 1;
timefile.tm_mday = FAT_DAY(d.lastWriteDate); timefile.tm_mday = FAT_DAY(d.lastWriteDate);
timefile.tm_hour = FAT_HOUR(d.lastWriteTime); timefile.tm_hour = FAT_HOUR(d.lastWriteTime);
timefile.tm_min = FAT_MINUTE(d.lastWriteTime); timefile.tm_min = FAT_MINUTE(d.lastWriteTime);
timefile.tm_sec = FAT_SECOND(d.lastWriteTime); timefile.tm_sec = FAT_SECOND(d.lastWriteTime);
timefile.tm_isdst = -1; timefile.tm_isdst = -1;
dt = mktime(&timefile); dt = mktime(&timefile);
if (dt == -1) { if (dt == -1) {
log_esp3d("mktime failed"); log_esp3d_e("mktime failed");
} }
} else {
log_esp3d("stat file failed");
}
} else { } else {
log_esp3d("check file for stat failed"); log_esp3d_e("stat file failed");
} }
#endif //SD_TIMESTAMP_FEATURE } else {
return dt; log_esp3d("check file for stat failed");
}
#endif // SD_TIMESTAMP_FEATURE
return dt;
} }
uint8_t ESP_SD::getState(bool refresh) uint8_t ESP_SD::getState(bool refresh) {
{
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
//no need to go further if SD detect is not correct // no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) { if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
log_esp3d("No SD State %d vs %d", digitalRead (ESP_SD_DETECT_PIN), ESP_SD_DETECT_VALUE); : false)) {
_state = ESP_SDCARD_NOT_PRESENT; log_esp3d("No SD State %d vs %d", digitalRead(ESP_SD_DETECT_PIN),
return _state; ESP_SD_DETECT_VALUE);
} else {
log_esp3d("SD Detect Pin ok");
}
#endif //ESP_SD_DETECT_PIN
//if busy doing something return state
if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
log_esp3d("Busy SD State");
return _state;
}
if (!refresh) {
log_esp3d("SD State cache is %d", _state);
return _state; //to avoid refresh=true + busy to reset SD and waste time
} else {
_sizechanged = true;
}
//SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT; _state = ESP_SDCARD_NOT_PRESENT;
//refresh content if card was removed
if (SD.begin((ESP_SD_CS_PIN == -1)?SS:ESP_SD_CS_PIN, SD_SCK_HZ(F_CPU/_spi_speed_divider))) {
log_esp3d("Init SD State ok");
if (SD.size64() > 0 ) {
log_esp3d("SD available");
_state = ESP_SDCARD_IDLE;
} else {
log_esp3d("Cannot get card size");
}
} else {
log_esp3d("Init SD State failed");
}
log_esp3d("SD State is %d", _state);
return _state; return _state;
} } else {
log_esp3d("SD Detect Pin ok");
bool ESP_SD::begin() }
{ #endif // ESP_SD_DETECT_PIN
_started = true; // if busy doing something return state
_state = ESP_SDCARD_NOT_PRESENT; if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
_spi_speed_divider = Settings_ESP3D::read_byte(ESP_SD_SPEED_DIV); log_esp3d("Busy SD State");
//sanity check return _state;
if (_spi_speed_divider <= 0) { }
_spi_speed_divider = 1; if (!refresh) {
} log_esp3d("SD State cache is %d", _state);
#ifdef SD_TIMESTAMP_FEATURE return _state; // to avoid refresh=true + busy to reset SD and waste time
//set callback to get time on files on SD } else {
SdFile::dateTimeCallback (dateTime);
#endif //SD_TIMESTAMP_FEATURE
//Setup pins
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode (ESP_SD_DETECT_PIN, INPUT);
#endif //ESP_SD_DETECT_PIN
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1
pinMode (ESP_FLAG_SHARED_SD_PIN, OUTPUT);
digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE);
#endif //ESP_FLAG_SHARED_SD_PIN
#endif //SD_DEVICE_CONNECTION == ESP_SHARED_SD
return _started;
}
void ESP_SD::end()
{
_state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force)
{
if (force || _sizechanged) {
freeBytes(true);
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh)
{
static uint64_t _totalBytes = 0;
if (refresh || _totalBytes==0) {
_totalBytes = SD.size64();;
}
return _totalBytes;
}
uint64_t ESP_SD::usedBytes(bool refresh)
{
FSInfo64 info;
static uint64_t _usedBytes = 0;
if (refresh) {
if (!SDFS.info64(info)) {
return 0;
}
_usedBytes = info.usedBytes;
}
return _usedBytes;
}
uint64_t ESP_SD::freeBytes(bool refresh)
{
return (totalBytes(refresh) - usedBytes(refresh));
}
uint ESP_SD::maxPathLength()
{
return 255;
}
bool ESP_SD::rename(const char *oldpath, const char *newpath)
{
return (bool)SDFS.rename(oldpath,newpath);
}
bool ESP_SD::format(ESP3DOutput * output)
{
if (output) {
output->printERROR ("Not implemented!");
}
return false;
}
ESP_SDFile ESP_SD::open(const char* path, uint8_t mode)
{
//do some check
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
_sizechanged = true;
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
//check container exists
String p = path;
p.remove(p.lastIndexOf('/') +1);
if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path);
return ESP_SDFile();
}
}
File tmp = SD.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_WRITE);
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
return esptmp;
}
bool ESP_SD::exists(const char* path)
{
bool res = false;
//root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
}
log_esp3d("%s exists ?", path);
res = SD.exists(path);
if (!res) {
log_esp3d("Seems not - trying open it");
ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
}
log_esp3d("Seems %s", res?"yes":"no");
return res;
}
bool ESP_SD::remove(const char *path)
{
_sizechanged = true; _sizechanged = true;
return SD.remove(path); }
// SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT;
// refresh content if card was removed
if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
SD_SCK_HZ(F_CPU / _spi_speed_divider))) {
log_esp3d("Init SD State ok");
if (SD.size64() > 0) {
log_esp3d("SD available");
_state = ESP_SDCARD_IDLE;
} else {
log_esp3d_e("Cannot get card size");
}
} else {
log_esp3d_e("Init SD State failed");
}
log_esp3d("SD State is %d", _state);
return _state;
} }
bool ESP_SD::mkdir(const char *path) bool ESP_SD::begin() {
{ _started = true;
return SD.mkdir(path); _state = ESP_SDCARD_NOT_PRESENT;
_spi_speed_divider = Settings_ESP3D::read_byte(ESP_SD_SPEED_DIV);
// sanity check
if (_spi_speed_divider <= 0) {
_spi_speed_divider = 1;
}
#ifdef SD_TIMESTAMP_FEATURE
// set callback to get time on files on SD
SdFile::dateTimeCallback(dateTime);
#endif // SD_TIMESTAMP_FEATURE
// Setup pins
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode(ESP_SD_DETECT_PIN, INPUT);
#endif // ESP_SD_DETECT_PIN
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1
pinMode(ESP_FLAG_SHARED_SD_PIN, OUTPUT);
digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE);
#endif // ESP_FLAG_SHARED_SD_PIN
#endif // SD_DEVICE_CONNECTION == ESP_SHARED_SD
return _started;
} }
bool ESP_SD::rmdir(const char *path) void ESP_SD::end() {
{ _state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force) {
if (force || _sizechanged) {
freeBytes(true);
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh) {
static uint64_t _totalBytes = 0;
if (refresh || _totalBytes == 0) {
_totalBytes = SD.size64();
;
}
return _totalBytes;
}
uint64_t ESP_SD::usedBytes(bool refresh) {
FSInfo64 info;
static uint64_t _usedBytes = 0;
if (refresh) {
if (!SDFS.info64(info)) {
return 0;
}
_usedBytes = info.usedBytes;
}
return _usedBytes;
}
uint64_t ESP_SD::freeBytes(bool refresh) {
return (totalBytes(refresh) - usedBytes(refresh));
}
uint ESP_SD::maxPathLength() { return 255; }
bool ESP_SD::rename(const char* oldpath, const char* newpath) {
return (bool)SDFS.rename(oldpath, newpath);
}
bool ESP_SD::format(ESP3DOutput* output) {
if (output) {
output->printERROR("Not implemented!");
}
return false;
}
ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
// do some check
if (((strcmp(path, "/") == 0) &&
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) {
_sizechanged = true;
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
// check container exists
String p = path; String p = path;
if (!p.endsWith("/")) { p.remove(p.lastIndexOf('/') + 1);
p+= '/';
}
if (!p.startsWith("/")) {
p = '/'+p;
}
if (!exists(p.c_str())) { if (!exists(p.c_str())) {
return false; log_esp3d("Error opening: %s", path);
return ESP_SDFile();
} }
bool res = true; }
std::stack <String > pathlist; File tmp = SD.open(path, (mode == ESP_FILE_READ) ? FILE_READ
pathlist.push(p); : (mode == ESP_FILE_WRITE) ? FILE_WRITE
while (pathlist.size() > 0 && res) { : FILE_WRITE);
File dir = SD.open(pathlist.top().c_str()); ESP_SDFile esptmp(&tmp, tmp.isDirectory(),
dir.rewindDirectory(); (mode == ESP_FILE_READ) ? false : true, path);
File f = dir.openNextFile(); return esptmp;
bool candelete = true; }
while (f && res) {
if (f.isDirectory()) { bool ESP_SD::exists(const char* path) {
candelete = false; bool res = false;
String newdir = pathlist.top() + f.name(); // root should always be there if started
newdir+="/"; if (strcmp(path, "/") == 0) {
pathlist.push(newdir); return _started;
f.close(); }
f = File(); log_esp3d("%s exists ?", path);
} else { res = SD.exists(path);
_sizechanged = true; if (!res) {
String filepath = pathlist.top() + f.name(); log_esp3d("Seems not - trying open it");
f.close(); ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
if (!SD.remove(filepath.c_str())) { if (root) {
res= false; res = root.isDirectory();
} }
f = dir.openNextFile(); }
} log_esp3d("Seems %s", res ? "yes" : "no");
return res;
}
bool ESP_SD::remove(const char* path) {
_sizechanged = true;
return SD.remove(path);
}
bool ESP_SD::mkdir(const char* path) { return SD.mkdir(path); }
bool ESP_SD::rmdir(const char* path) {
String p = path;
if (!p.endsWith("/")) {
p += '/';
}
if (!p.startsWith("/")) {
p = '/' + p;
}
if (!exists(p.c_str())) {
return false;
}
bool res = true;
std::stack<String> pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = SD.open(pathlist.top().c_str());
dir.rewindDirectory();
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top() + f.name();
newdir += "/";
pathlist.push(newdir);
f.close();
f = File();
} else {
_sizechanged = true;
String filepath = pathlist.top() + f.name();
f.close();
if (!SD.remove(filepath.c_str())) {
res = false;
} }
if (candelete) { f = dir.openNextFile();
if (pathlist.top() !="/") { }
res = SD.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
} }
p = String(); if (candelete) {
log_esp3d("count %d", pathlist.size()); if (pathlist.top() != "/") {
return res; res = SD.rmdir(pathlist.top().c_str());
} }
pathlist.pop();
bool ESP_SDFile::seek(uint32_t pos, uint8_t mode)
{
return tSDFile_handle[_index].seek(pos, (SeekMode)mode);
}
void ESP_SD::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = File();
} }
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
} }
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path) bool ESP_SDFile::seek(uint32_t pos, uint8_t mode) {
{ return tSDFile_handle[_index].seek(pos, (SeekMode)mode);
_isdir = isdir; }
_dirlist = "";
void ESP_SD::closeAll() {
for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = File();
}
}
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode,
const char* path) {
_isdir = isdir;
_dirlist = "";
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((File*)handle);
// filename
_filename = path;
// name
_name = tSDFile_handle[i].name();
if (_name.endsWith("/")) {
_name.remove(_name.length() - 1, 1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove(0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
if (_name.length() == 0) {
_name = "/";
}
// size
_size = tSDFile_handle[i].size();
// time
if (!_isdir) {
_lastwrite = getDateTimeFile(tSDFile_handle[i]);
} else {
// no need date time for directory
_lastwrite = 0;
}
_index = i;
// log_esp3d("Opening File at index %d",_index);
set = true;
}
}
}
// todo need also to add short filename
const char* ESP_SDFile::shortname() const {
// not supported in native so return name
return _name.c_str();
}
void ESP_SDFile::close() {
if (_index != -1) {
// log_esp3d("Closing File at index %d", _index);
tSDFile_handle[_index].close();
// reopen if mode = write
// udate size + date
if (_iswritemode && !_isdir) {
File ftmp = SD.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = getDateTimeFile(ftmp);
ftmp.close();
}
}
tSDFile_handle[_index] = File();
// log_esp3d("Closing File at index %d",_index);
_index = -1; _index = -1;
_filename = ""; }
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((File*)handle);
//filename
_filename = path;
//name
_name = tSDFile_handle[i].name();
if (_name.endsWith("/")) {
_name.remove( _name.length() - 1,1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove( 0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove( 0, pos+1);
}
if (_name.length() == 0) {
_name = "/";
}
//size
_size = tSDFile_handle[i].size();
//time
if (!_isdir) {
_lastwrite = getDateTimeFile(tSDFile_handle[i]);
} else {
//no need date time for directory
_lastwrite = 0;
}
_index = i;
//log_esp3d("Opening File at index %d",_index);
set = true;
}
}
}
//todo need also to add short filename
const char* ESP_SDFile::shortname() const
{
//not supported in native so return name
return _name.c_str();
} }
void ESP_SDFile::close() ESP_SDFile ESP_SDFile::openNextFile() {
{ if ((_index == -1) || !_isdir) {
if (_index != -1) { log_esp3d_e("openNextFile failed");
//log_esp3d("Closing File at index %d", _index); return ESP_SDFile();
tSDFile_handle[_index].close(); }
//reopen if mode = write File tmp = tSDFile_handle[_index].openNextFile();
//udate size + date if (tmp) {
if (_iswritemode && !_isdir) { String name = tmp.name();
File ftmp = SD.open(_filename.c_str()); log_esp3d("tmp name :%s %s", name.c_str(),
if (ftmp) { (tmp.isDirectory()) ? "isDir" : "isFile");
_size = ftmp.size(); String s = _filename;
_lastwrite = getDateTimeFile(ftmp); if (s != "/") {
ftmp.close(); s += "/";
}
}
tSDFile_handle[_index] = File();
//log_esp3d("Closing File at index %d",_index);
_index = -1;
} }
s += name;
ESP_SDFile esptmp(&tmp, tmp.isDirectory(), false, s.c_str());
esptmp.close();
return esptmp;
}
return ESP_SDFile();
} }
ESP_SDFile ESP_SDFile::openNextFile() const char* ESP_SD::FilesystemName() { return "SD native"; }
{
if ((_index == -1) || !_isdir) {
log_esp3d("openNextFile failed");
return ESP_SDFile();
}
File tmp = tSDFile_handle[_index].openNextFile();
if (tmp) {
String name = tmp.name();
log_esp3d("tmp name :%s %s", name.c_str(), (tmp.isDirectory())?"isDir":"isFile");
String s = _filename ;
if (s!="/") {
s+="/";
}
s += name;
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),false, s.c_str());
esptmp.close();
return esptmp;
}
return ESP_SDFile();
}
const char * ESP_SD::FilesystemName() #endif // SD_DEVICE == ESP_SD_NATIVE
{ #endif // ARCH_ESP8266 && SD_DEVICE
return "SD native";
}
#endif //SD_DEVICE == ESP_SD_NATIVE
#endif //ARCH_ESP8266 && SD_DEVICE

View File

@ -89,13 +89,13 @@ time_t getDateTimeFile(File& filehandle) {
timefile.tm_isdst = -1; timefile.tm_isdst = -1;
dt = mktime(&timefile); dt = mktime(&timefile);
if (dt == -1) { if (dt == -1) {
log_esp3d("mktime failed"); log_esp3d_e("mktime failed");
} }
} else { } else {
log_esp3d("stat file failed"); log_esp3d_e("stat file failed");
} }
} else { } else {
log_esp3d("check file for stat failed"); log_esp3d_e("check file for stat failed");
} }
#endif // SD_TIMESTAMP_FEATURE #endif // SD_TIMESTAMP_FEATURE
return dt; return dt;
@ -319,12 +319,12 @@ ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) { (strlen(path) == 0)) {
_sizechanged = true; _sizechanged = true;
log_esp3d("reject %s", path); log_esp3d_e("reject %s", path);
return ESP_SDFile(); return ESP_SDFile();
} }
// path must start by '/' // path must start by '/'
if (path[0] != '/') { if (path[0] != '/') {
log_esp3d("%s is invalid path", path); log_esp3d_e("%s is invalid path", path);
return ESP_SDFile(); return ESP_SDFile();
} }
if (mode != ESP_FILE_READ) { if (mode != ESP_FILE_READ) {
@ -332,7 +332,7 @@ ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
String p = path; String p = path;
p.remove(p.lastIndexOf('/') + 1); p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) { if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path); log_esp3d_e("Error opening: %s", path);
return ESP_SDFile(); return ESP_SDFile();
} }
} }
@ -345,7 +345,7 @@ ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
log_esp3d("%s is a %s", path, tmp.isDir() ? "Dir" : "File"); log_esp3d("%s is a %s", path, tmp.isDir() ? "Dir" : "File");
return esptmp; return esptmp;
} else { } else {
log_esp3d("open %s failed", path); log_esp3d_e("open %s failed", path);
return ESP_SDFile(); return ESP_SDFile();
} }
} }

View File

@ -17,14 +17,16 @@ sd_sdfat2_esp8266.cpp - ESP3D sd support class
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE) #if defined(ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE)
#if (SD_DEVICE == ESP_SDFAT2) #if (SD_DEVICE == ESP_SDFAT2)
#define FS_NO_GLOBALS #define FS_NO_GLOBALS
#include "../esp_sd.h"
#include <stack> #include <stack>
#include "../../../core/settings_esp3d.h" #include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
#define NO_GLOBAL_SD #define NO_GLOBAL_SD
#include <SdFat.h> #include <SdFat.h>
#include <sdios.h> #include <sdios.h>
@ -33,509 +35,491 @@ sd_sdfat2_esp8266.cpp - ESP3D sd support class
#if HAS_SDIO_CLASS #if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO) #define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI #elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig((ESP_SD_CS_PIN == -1)?SS:ESP_SD_CS_PIN, DEDICATED_SPI) #define SD_CONFIG \
SdSpiConfig((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN, DEDICATED_SPI)
#else // HAS_SDIO_CLASS #else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig((ESP_SD_CS_PIN == -1)?SS:ESP_SD_CS_PIN, SHARED_SPI) #define SD_CONFIG \
SdSpiConfig((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN, SHARED_SPI)
#endif // HAS_SDIO_CLASS #endif // HAS_SDIO_CLASS
extern sdfat::File tSDFile_handle[ESP_MAX_SD_OPENHANDLE]; extern sdfat::File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
using namespace sdfat; using namespace sdfat;
SdFat SD; SdFat SD;
void dateTime (uint16_t* date, uint16_t* dtime) void dateTime(uint16_t* date, uint16_t* dtime) {
{ struct tm tmstruct;
struct tm tmstruct; time_t now;
time_t now; time(&now);
time (&now); localtime_r(&now, &tmstruct);
localtime_r (&now, &tmstruct); *date = FAT_DATE((tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1,
*date = FAT_DATE ( (tmstruct.tm_year) + 1900, ( tmstruct.tm_mon) + 1, tmstruct.tm_mday); tmstruct.tm_mday);
*dtime = FAT_TIME (tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec); *dtime = FAT_TIME(tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
} }
time_t getDateTimeFile(sdfat::File & filehandle) time_t getDateTimeFile(sdfat::File& filehandle) {
{ static time_t dt = 0;
static time_t dt = 0;
#ifdef SD_TIMESTAMP_FEATURE #ifdef SD_TIMESTAMP_FEATURE
struct tm timefile; struct tm timefile;
uint16_t date; uint16_t date;
uint16_t time; uint16_t time;
if(filehandle) { if (filehandle) {
if (filehandle.getModifyDateTime(&date, &time)) { if (filehandle.getModifyDateTime(&date, &time)) {
timefile.tm_year = FS_YEAR(date) - 1900; timefile.tm_year = FS_YEAR(date) - 1900;
timefile.tm_mon = FS_MONTH(date) - 1; timefile.tm_mon = FS_MONTH(date) - 1;
timefile.tm_mday = FS_DAY(date); timefile.tm_mday = FS_DAY(date);
timefile.tm_hour = FS_HOUR(time); timefile.tm_hour = FS_HOUR(time);
timefile.tm_min = FS_MINUTE(time); timefile.tm_min = FS_MINUTE(time);
timefile.tm_sec = FS_SECOND(time); timefile.tm_sec = FS_SECOND(time);
timefile.tm_isdst = -1; timefile.tm_isdst = -1;
dt = mktime(&timefile); dt = mktime(&timefile);
if (dt == -1) { if (dt == -1) {
log_esp3d("mktime failed"); log_esp3d_e("mktime failed");
} }
} else {
log_esp3d("stat file failed");
}
} else { } else {
log_esp3d("check file for stat failed"); log_esp3d_e("stat file failed");
} }
#endif //SD_TIMESTAMP_FEATURE } else {
return dt; log_esp3d_e("check file for stat failed");
}
#endif // SD_TIMESTAMP_FEATURE
return dt;
} }
uint8_t ESP_SD::getState(bool refresh) uint8_t ESP_SD::getState(bool refresh) {
{
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
//no need to go further if SD detect is not correct // no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) { if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
log_esp3d("No SD State %d vs %d", digitalRead (ESP_SD_DETECT_PIN), ESP_SD_DETECT_VALUE); : false)) {
_state = ESP_SDCARD_NOT_PRESENT; log_esp3d("No SD State %d vs %d", digitalRead(ESP_SD_DETECT_PIN),
return _state; ESP_SD_DETECT_VALUE);
} else {
log_esp3d("SD Detect Pin ok");
}
#endif //ESP_SD_DETECT_PIN
//if busy doing something return state
if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
log_esp3d("Busy SD State");
return _state;
}
if (!refresh) {
log_esp3d("SD State cache is %d", _state);
return _state; //to avoid refresh=true + busy to reset SD and waste time
} else {
_sizechanged = true;
}
//SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT; _state = ESP_SDCARD_NOT_PRESENT;
//refresh content if card was removed
if (SD.begin((ESP_SD_CS_PIN == -1)?SS:ESP_SD_CS_PIN, SD_SCK_HZ(F_CPU/_spi_speed_divider))) {
log_esp3d("Init SD State ok");
csd_t m_csd;
if (SD.card()->readCSD(&m_csd) && sdCardCapacity(&m_csd) > 0 ) {
_state = ESP_SDCARD_IDLE;
} else {
log_esp3d("Cannot get card size");
}
} else {
log_esp3d("Init SD State failed");
}
log_esp3d("SD State is %d", _state);
return _state; return _state;
} } else {
log_esp3d("SD Detect Pin ok");
bool ESP_SD::begin() }
{ #endif // ESP_SD_DETECT_PIN
_started = true; // if busy doing something return state
_state = ESP_SDCARD_NOT_PRESENT; if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
_spi_speed_divider = Settings_ESP3D::read_byte(ESP_SD_SPEED_DIV); log_esp3d("Busy SD State");
//sanity check return _state;
if (_spi_speed_divider <= 0) { }
_spi_speed_divider = 1; if (!refresh) {
} log_esp3d("SD State cache is %d", _state);
#ifdef SD_TIMESTAMP_FEATURE return _state; // to avoid refresh=true + busy to reset SD and waste time
//set callback to get time on files on SD } else {
SdFile::dateTimeCallback (dateTime);
#endif //SD_TIMESTAMP_FEATURE
//Setup pins
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode (ESP_SD_DETECT_PIN, INPUT);
#endif //ESP_SD_DETECT_PIN
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1
pinMode (ESP_FLAG_SHARED_SD_PIN, OUTPUT);
digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE);
#endif //ESP_FLAG_SHARED_SD_PIN
#endif //SD_DEVICE_CONNECTION == ESP_SHARED_SD
return _started;
}
void ESP_SD::end()
{
_state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force)
{
if (force || _sizechanged) {
usedBytes(true);
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh)
{
static uint64_t _totalBytes = 0;
if (!SD.volumeBegin()) {
return 0;
}
if (refresh || _totalBytes==0) {
_totalBytes = SD.clusterCount();
uint8_t sectors = SD.sectorsPerCluster();
_totalBytes = _totalBytes * sectors * 512;
}
return _totalBytes;
}
uint64_t ESP_SD::usedBytes(bool refresh)
{
return totalBytes(refresh) - freeBytes(refresh);
}
uint64_t ESP_SD::freeBytes(bool refresh)
{
static uint64_t _freeBytes = 0;
if (!SD.volumeBegin()) {
return 0;
}
if (refresh || _freeBytes==0) {
_freeBytes = SD.freeClusterCount();
uint8_t sectors = SD.sectorsPerCluster();
_freeBytes = _freeBytes * sectors * 512;
}
return _freeBytes;
}
uint ESP_SD::maxPathLength()
{
return 255;
}
bool ESP_SD::rename(const char *oldpath, const char *newpath)
{
return SD.rename(oldpath,newpath);
}
bool ESP_SD::format(ESP3DOutput * output)
{
if (ESP_SD::getState(true) == ESP_SDCARD_IDLE) {
uint32_t const ERASE_SIZE = 262144L;
uint32_t cardSectorCount = 0;
uint8_t sectorBuffer[512];
// SdCardFactory constructs and initializes the appropriate card.
SdCardFactory cardFactory;
// Pointer to generic SD card.
SdCard* m_card = nullptr;
//prepare
m_card = cardFactory.newCard(SD_CONFIG);
if (!m_card || m_card->errorCode()) {
if (output) {
output->printMSG("card init failed.");
}
return false;
}
cardSectorCount = m_card->sectorCount();
if (!cardSectorCount) {
if (output) {
output->printMSG("Get sector count failed.");
}
return false;
}
if (output) {
String s = "Capacity detected :" + String(cardSectorCount*5.12e-7) + "GB";
output->printMSG(s.c_str());
}
uint32_t firstBlock = 0;
uint32_t lastBlock;
uint16_t n = 0;
do {
lastBlock = firstBlock + ERASE_SIZE - 1;
if (lastBlock >= cardSectorCount) {
lastBlock = cardSectorCount - 1;
}
if (!m_card->erase(firstBlock, lastBlock)) {
if (output) {
output->printMSG("erase failed");
}
return false;
}
firstBlock += ERASE_SIZE;
if ((n++)%64 == 63) {
Hal::wait(0);
}
} while (firstBlock < cardSectorCount);
if (!m_card->readSector(0, sectorBuffer)) {
if (output) {
output->printMSG("readBlock");
}
}
ExFatFormatter exFatFormatter;
FatFormatter fatFormatter;
// Format exFAT if larger than 32GB.
bool rtn = cardSectorCount > 67108864 ?
exFatFormatter.format(m_card, sectorBuffer, nullptr) :
fatFormatter.format(m_card, sectorBuffer, nullptr);
if (!rtn) {
if (output) {
output->printMSG("erase failed");
}
return false;
}
return true;
}
if (output) {
output->printMSG("cannot erase");
}
return false;
}
ESP_SDFile ESP_SD::open(const char* path, uint8_t mode)
{
//do some check
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
_sizechanged = true;
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
//check container exists
String p = path;
p.remove(p.lastIndexOf('/') +1);
if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path);
return ESP_SDFile();
}
}
sdfat::File tmp = SD.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_WRITE);
ESP_SDFile esptmp(&tmp, tmp.isDir(),(mode == ESP_FILE_READ)?false:true, path);
return esptmp;
}
bool ESP_SD::exists(const char* path)
{
bool res = false;
//root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
}
log_esp3d("%s exists ?", path);
res = SD.exists(path);
if (!res) {
log_esp3d("Seems not - trying open it");
ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
}
log_esp3d("Seems %s", res?"yes":"no");
return res;
}
bool ESP_SD::remove(const char *path)
{
_sizechanged = true; _sizechanged = true;
return SD.remove(path); }
} // SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT;
bool ESP_SD::mkdir(const char *path) // refresh content if card was removed
{ if (SD.begin((ESP_SD_CS_PIN == -1) ? SS : ESP_SD_CS_PIN,
return SD.mkdir(path); SD_SCK_HZ(F_CPU / _spi_speed_divider))) {
} log_esp3d("Init SD State ok");
csd_t m_csd;
bool ESP_SD::rmdir(const char *path) if (SD.card()->readCSD(&m_csd) && sdCardCapacity(&m_csd) > 0) {
{ _state = ESP_SDCARD_IDLE;
String p = path;
if (!p.endsWith("/")) {
p+= '/';
}
if (!p.startsWith("/")) {
p = '/'+p;
}
if (!exists(p.c_str())) {
return false;
}
bool res = true;
std::stack <String > pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
sdfat::File dir = SD.open(pathlist.top().c_str());
dir.rewindDirectory();
sdfat::File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDir()) {
candelete = false;
String newdir;
char tmp[255];
f.getName(tmp,254);
newdir = pathlist.top() + tmp;
newdir+="/";
pathlist.push(newdir);
f.close();
f = sdfat::File();
} else {
char tmp[255];
f.getName(tmp,254);
_sizechanged = true;
String filepath = pathlist.top() + tmp;
f.close();
if (!SD.remove(filepath.c_str())) {
res= false;
}
f = dir.openNextFile();
}
}
if (candelete) {
if (pathlist.top() !="/") {
res = SD.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
}
bool ESP_SDFile::seek(uint32_t pos, uint8_t mode)
{
if (mode == SeekCur) {
return tSDFile_handle[_index].seekCur(pos);
}
if (mode == SeekEnd) {
return tSDFile_handle[_index].seekEnd(pos);
}
// if (mode == SeekSet)
return tSDFile_handle[_index].seekSet(pos);
}
void ESP_SD::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = sdfat::File();
}
}
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((sdfat::File*)handle);
//filename
char tmp[255];
tSDFile_handle[i].getName(tmp,254);
_filename = path;
//name
_name = tmp;
if (_name.endsWith("/")) {
_name.remove( _name.length() - 1,1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove( 0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove( 0, pos+1);
}
if (_name.length() == 0) {
_name = "/";
}
//size
_size = tSDFile_handle[i].size();
//time
if (!_isdir) {
_lastwrite = getDateTimeFile(tSDFile_handle[i]);
} else {
//no need date time for directory
_lastwrite = 0;
}
_index = i;
//log_esp3d("Opening File at index %d",_index);
set = true;
}
}
}
//todo need also to add short filename
const char* ESP_SDFile::shortname() const
{
static char sname[13];
sdfat::File ftmp = SD.open(_filename.c_str());
if (ftmp) {
ftmp.getSFN(sname);
ftmp.close();
return sname;
} else { } else {
return _name.c_str(); log_esp3d_e("Cannot get card size");
} }
} else {
log_esp3d_e("Init SD State failed");
}
log_esp3d("SD State is %d", _state);
return _state;
} }
void ESP_SDFile::close() bool ESP_SD::begin() {
{ _started = true;
if (_index != -1) { _state = ESP_SDCARD_NOT_PRESENT;
//log_esp3d("Closing File at index %d", _index); _spi_speed_divider = Settings_ESP3D::read_byte(ESP_SD_SPEED_DIV);
tSDFile_handle[_index].close(); // sanity check
//reopen if mode = write if (_spi_speed_divider <= 0) {
//udate size + date _spi_speed_divider = 1;
if (_iswritemode && !_isdir) { }
sdfat::File ftmp = SD.open(_filename.c_str()); #ifdef SD_TIMESTAMP_FEATURE
if (ftmp) { // set callback to get time on files on SD
_size = ftmp.size(); SdFile::dateTimeCallback(dateTime);
_lastwrite = getDateTimeFile(ftmp); #endif // SD_TIMESTAMP_FEATURE
ftmp.close(); // Setup pins
} #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode(ESP_SD_DETECT_PIN, INPUT);
#endif // ESP_SD_DETECT_PIN
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_FLAG_SHARED_SD_PIN) && ESP_FLAG_SHARED_SD_PIN != -1
pinMode(ESP_FLAG_SHARED_SD_PIN, OUTPUT);
digitalWrite(ESP_FLAG_SHARED_SD_PIN, !ESP_FLAG_SHARED_SD_VALUE);
#endif // ESP_FLAG_SHARED_SD_PIN
#endif // SD_DEVICE_CONNECTION == ESP_SHARED_SD
return _started;
}
void ESP_SD::end() {
_state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force) {
if (force || _sizechanged) {
usedBytes(true);
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh) {
static uint64_t _totalBytes = 0;
if (!SD.volumeBegin()) {
return 0;
}
if (refresh || _totalBytes == 0) {
_totalBytes = SD.clusterCount();
uint8_t sectors = SD.sectorsPerCluster();
_totalBytes = _totalBytes * sectors * 512;
}
return _totalBytes;
}
uint64_t ESP_SD::usedBytes(bool refresh) {
return totalBytes(refresh) - freeBytes(refresh);
}
uint64_t ESP_SD::freeBytes(bool refresh) {
static uint64_t _freeBytes = 0;
if (!SD.volumeBegin()) {
return 0;
}
if (refresh || _freeBytes == 0) {
_freeBytes = SD.freeClusterCount();
uint8_t sectors = SD.sectorsPerCluster();
_freeBytes = _freeBytes * sectors * 512;
}
return _freeBytes;
}
uint ESP_SD::maxPathLength() { return 255; }
bool ESP_SD::rename(const char* oldpath, const char* newpath) {
return SD.rename(oldpath, newpath);
}
bool ESP_SD::format(ESP3DOutput* output) {
if (ESP_SD::getState(true) == ESP_SDCARD_IDLE) {
uint32_t const ERASE_SIZE = 262144L;
uint32_t cardSectorCount = 0;
uint8_t sectorBuffer[512];
// SdCardFactory constructs and initializes the appropriate card.
SdCardFactory cardFactory;
// Pointer to generic SD card.
SdCard* m_card = nullptr;
// prepare
m_card = cardFactory.newCard(SD_CONFIG);
if (!m_card || m_card->errorCode()) {
if (output) {
output->printMSG("card init failed.");
}
return false;
}
cardSectorCount = m_card->sectorCount();
if (!cardSectorCount) {
if (output) {
output->printMSG("Get sector count failed.");
}
return false;
}
if (output) {
String s =
"Capacity detected :" + String(cardSectorCount * 5.12e-7) + "GB";
output->printMSG(s.c_str());
}
uint32_t firstBlock = 0;
uint32_t lastBlock;
uint16_t n = 0;
do {
lastBlock = firstBlock + ERASE_SIZE - 1;
if (lastBlock >= cardSectorCount) {
lastBlock = cardSectorCount - 1;
}
if (!m_card->erase(firstBlock, lastBlock)) {
if (output) {
output->printMSG("erase failed");
} }
tSDFile_handle[_index] = sdfat::File(); return false;
//log_esp3d("Closing File at index %d",_index); }
_index = -1;
firstBlock += ERASE_SIZE;
if ((n++) % 64 == 63) {
Hal::wait(0);
}
} while (firstBlock < cardSectorCount);
if (!m_card->readSector(0, sectorBuffer)) {
if (output) {
output->printMSG("readBlock");
}
} }
ExFatFormatter exFatFormatter;
FatFormatter fatFormatter;
// Format exFAT if larger than 32GB.
bool rtn = cardSectorCount > 67108864
? exFatFormatter.format(m_card, sectorBuffer, nullptr)
: fatFormatter.format(m_card, sectorBuffer, nullptr);
if (!rtn) {
if (output) {
output->printMSG("erase failed");
}
return false;
}
return true;
}
if (output) {
output->printMSG("cannot erase");
}
return false;
} }
ESP_SDFile ESP_SDFile::openNextFile() ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
{ // do some check
if ((_index == -1) || !_isdir) { if (((strcmp(path, "/") == 0) &&
log_esp3d("openNextFile failed"); ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
return ESP_SDFile(); (strlen(path) == 0)) {
_sizechanged = true;
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
// check container exists
String p = path;
p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path);
return ESP_SDFile();
} }
sdfat::File tmp = tSDFile_handle[_index].openNextFile(); }
if (tmp) { sdfat::File tmp = SD.open(path, (mode == ESP_FILE_READ) ? FILE_READ
char tmps[255]; : (mode == ESP_FILE_WRITE) ? FILE_WRITE
tmp.getName(tmps,254); : FILE_WRITE);
log_esp3d("tmp name :%s %s", tmps, (tmp.isDir())?"isDir":"isFile"); ESP_SDFile esptmp(&tmp, tmp.isDir(), (mode == ESP_FILE_READ) ? false : true,
String s = _filename ; path);
if (s!="/") { return esptmp;
s+="/"; }
bool ESP_SD::exists(const char* path) {
bool res = false;
// root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
}
log_esp3d("%s exists ?", path);
res = SD.exists(path);
if (!res) {
log_esp3d("Seems not - trying open it");
ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
}
log_esp3d("Seems %s", res ? "yes" : "no");
return res;
}
bool ESP_SD::remove(const char* path) {
_sizechanged = true;
return SD.remove(path);
}
bool ESP_SD::mkdir(const char* path) { return SD.mkdir(path); }
bool ESP_SD::rmdir(const char* path) {
String p = path;
if (!p.endsWith("/")) {
p += '/';
}
if (!p.startsWith("/")) {
p = '/' + p;
}
if (!exists(p.c_str())) {
return false;
}
bool res = true;
std::stack<String> pathlist;
pathlist.push(p);
while (pathlist.size() > 0 && res) {
sdfat::File dir = SD.open(pathlist.top().c_str());
dir.rewindDirectory();
sdfat::File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDir()) {
candelete = false;
String newdir;
char tmp[255];
f.getName(tmp, 254);
newdir = pathlist.top() + tmp;
newdir += "/";
pathlist.push(newdir);
f.close();
f = sdfat::File();
} else {
char tmp[255];
f.getName(tmp, 254);
_sizechanged = true;
String filepath = pathlist.top() + tmp;
f.close();
if (!SD.remove(filepath.c_str())) {
res = false;
} }
s += tmps; f = dir.openNextFile();
ESP_SDFile esptmp(&tmp, tmp.isDir(),false, s.c_str()); }
esptmp.close();
return esptmp;
} }
return ESP_SDFile(); if (candelete) {
if (pathlist.top() != "/") {
res = SD.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
} }
const char * ESP_SD::FilesystemName() bool ESP_SDFile::seek(uint32_t pos, uint8_t mode) {
{ if (mode == SeekCur) {
return "SDFat - " SD_FAT_VERSION_STR ; return tSDFile_handle[_index].seekCur(pos);
}
if (mode == SeekEnd) {
return tSDFile_handle[_index].seekEnd(pos);
}
// if (mode == SeekSet)
return tSDFile_handle[_index].seekSet(pos);
} }
#endif //SD_DEVICE == ESP_SDFAT2 void ESP_SD::closeAll() {
#endif //ARCH_ESP8266 && SD_DEVICE for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = sdfat::File();
}
}
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode,
const char* path) {
_isdir = isdir;
_dirlist = "";
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((sdfat::File*)handle);
// filename
char tmp[255];
tSDFile_handle[i].getName(tmp, 254);
_filename = path;
// name
_name = tmp;
if (_name.endsWith("/")) {
_name.remove(_name.length() - 1, 1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove(0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
if (_name.length() == 0) {
_name = "/";
}
// size
_size = tSDFile_handle[i].size();
// time
if (!_isdir) {
_lastwrite = getDateTimeFile(tSDFile_handle[i]);
} else {
// no need date time for directory
_lastwrite = 0;
}
_index = i;
// log_esp3d("Opening File at index %d",_index);
set = true;
}
}
}
// todo need also to add short filename
const char* ESP_SDFile::shortname() const {
static char sname[13];
sdfat::File ftmp = SD.open(_filename.c_str());
if (ftmp) {
ftmp.getSFN(sname);
ftmp.close();
return sname;
} else {
return _name.c_str();
}
}
void ESP_SDFile::close() {
if (_index != -1) {
// log_esp3d("Closing File at index %d", _index);
tSDFile_handle[_index].close();
// reopen if mode = write
// udate size + date
if (_iswritemode && !_isdir) {
sdfat::File ftmp = SD.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = getDateTimeFile(ftmp);
ftmp.close();
}
}
tSDFile_handle[_index] = sdfat::File();
// log_esp3d("Closing File at index %d",_index);
_index = -1;
}
}
ESP_SDFile ESP_SDFile::openNextFile() {
if ((_index == -1) || !_isdir) {
log_esp3d("openNextFile failed");
return ESP_SDFile();
}
sdfat::File tmp = tSDFile_handle[_index].openNextFile();
if (tmp) {
char tmps[255];
tmp.getName(tmps, 254);
log_esp3d("tmp name :%s %s", tmps, (tmp.isDir()) ? "isDir" : "isFile");
String s = _filename;
if (s != "/") {
s += "/";
}
s += tmps;
ESP_SDFile esptmp(&tmp, tmp.isDir(), false, s.c_str());
esptmp.close();
return esptmp;
}
return ESP_SDFile();
}
const char* ESP_SD::FilesystemName() { return "SDFat - " SD_FAT_VERSION_STR; }
#endif // SD_DEVICE == ESP_SDFAT2
#endif // ARCH_ESP8266 && SD_DEVICE

View File

@ -18,376 +18,358 @@ sdio_esp32.cpp - ESP3D sd support class
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (ARDUINO_ARCH_ESP32) && defined(SD_DEVICE) #if defined(ARDUINO_ARCH_ESP32) && defined(SD_DEVICE)
#if (SD_DEVICE == ESP_SDIO) #if (SD_DEVICE == ESP_SDIO)
#include "../esp_sd.h"
#include <stack> #include <stack>
#include "../../../core/settings_esp3d.h" #include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
#include "FS.h" #include "FS.h"
#include "SD_MMC.h" #include "SD_MMC.h"
extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE]; extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
#define SDMMC_FORCE_BEGIN #define SDMMC_FORCE_BEGIN
#ifndef SDIO_BIT_MODE #ifndef SDIO_BIT_MODE
#define SDIO_BIT_MODE SD_FOUR_BIT_MODE #define SDIO_BIT_MODE SD_FOUR_BIT_MODE
#endif //SDIO_BIT_MODE #endif // SDIO_BIT_MODE
uint8_t ESP_SD::getState(bool refresh) uint8_t ESP_SD::getState(bool refresh) {
{ static bool lastinitok = false;
static bool lastinitok = false;
#ifdef SDMMC_FORCE_BEGIN #ifdef SDMMC_FORCE_BEGIN
lastinitok = false; lastinitok = false;
#endif //SDMMC_LIGHT_CHECK #endif // SDMMC_LIGHT_CHECK
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
//no need to go further if SD detect is not correct // no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) { if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
_state = ESP_SDCARD_NOT_PRESENT; : false)) {
return _state;
}
#endif //ESP_SD_DETECT_PIN
//if busy doing something return state
if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
return _state;
}
if (!refresh) {
return _state; //to avoid refresh=true + busy to reset SD and waste time
}
//SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT; _state = ESP_SDCARD_NOT_PRESENT;
//refresh content if card was removed
if (!lastinitok) {
log_esp3d("last init was failed try sd_mmc begin");
SD_MMC.end();
if (SD_MMC.begin("/sdcard", SDIO_BIT_MODE)) {
log_esp3d("sd_mmc begin succeed");
if (SD_MMC.cardType() != CARD_NONE ) {
_state = ESP_SDCARD_IDLE;
lastinitok = true;
log_esp3d("sd_mmc card type succeed");
} else {
log_esp3d("sd_mmc card type failed");
}
} else {
log_esp3d("sd_mmc begin failed");
}
} else {
log_esp3d("last init was ok try card type");
if(SD_MMC.cardType() != CARD_NONE) {
log_esp3d("checking sd_mmc card type succeed");
_state = ESP_SDCARD_IDLE;
} else {
lastinitok = false;
log_esp3d("Soft sd check failed");
SD_MMC.end();
if (SD_MMC.begin("/sdcard", SDIO_BIT_MODE)) {
log_esp3d("new sd_mmc begin succeed");
if ( SD_MMC.cardType() != CARD_NONE ) {
_state = ESP_SDCARD_IDLE;
lastinitok = true;
log_esp3d("new sd_mmc card type succeed");
} else {
log_esp3d("new sd_mmc card type failed");
}
} else {
log_esp3d("new sd_mmc begin failed");
}
}
}
return _state; return _state;
} }
#endif // ESP_SD_DETECT_PIN
bool ESP_SD::begin() // if busy doing something return state
{ if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
#if (ESP_SDIO_CLK_PIN != -1) || (ESP_SDIO_CMD_PIN != -1) || (ESP_SDIO_D0_PIN != -1) || (ESP_SDIO_D1_PIN != -1) || (ESP_SDIO_D2_PIN != -1) || (ESP_SDIO_D3_PIN != -1) return _state;
SD_MMC.setPins(ESP_SDIO_CLK_PIN, ESP_SDIO_CMD_PIN, ESP_SDIO_D0_PIN, ESP_SDIO_D1_PIN, ESP_SDIO_D2_PIN, ESP_SDIO_D3_PIN) }
#endif //(ESP_SDIO_CLK_PIN != -1) if (!refresh) {
log_esp3d("Begin SDIO"); return _state; // to avoid refresh=true + busy to reset SD and waste time
_started = true; }
#ifdef SDMMC_FORCE_BEGIN // SD is idle or not detected, let see if still the case
_state = ESP_SDCARD_NOT_PRESENT; _state = ESP_SDCARD_NOT_PRESENT;
#else // refresh content if card was removed
_state = getState(true); if (!lastinitok) {
#endif //SDMMC_FORCE_BEGIN log_esp3d("last init was failed try sd_mmc begin");
return _started;
}
void ESP_SD::end()
{
SD_MMC.end(); SD_MMC.end();
_state = ESP_SDCARD_NOT_PRESENT; if (SD_MMC.begin("/sdcard", SDIO_BIT_MODE)) {
_started = false; log_esp3d("sd_mmc begin succeed");
} if (SD_MMC.cardType() != CARD_NONE) {
_state = ESP_SDCARD_IDLE;
void ESP_SD::refreshStats(bool force) lastinitok = true;
{ log_esp3d("sd_mmc card type succeed");
if (force || _sizechanged) { } else {
freeBytes(true); log_esp3d_e("sd_mmc card type failed");
}
} else {
log_esp3d_e("sd_mmc begin failed");
} }
_sizechanged = false; } else {
} log_esp3d("last init was ok try card type");
if (SD_MMC.cardType() != CARD_NONE) {
uint64_t ESP_SD::totalBytes(bool refresh) log_esp3d("checking sd_mmc card type succeed");
{ _state = ESP_SDCARD_IDLE;
static uint64_t _totalBytes = 0; } else {
if (refresh || _totalBytes==0) { lastinitok = false;
_totalBytes = SD_MMC.totalBytes();; log_esp3d_e("Soft sd check failed");
SD_MMC.end();
if (SD_MMC.begin("/sdcard", SDIO_BIT_MODE)) {
log_esp3d("new sd_mmc begin succeed");
if (SD_MMC.cardType() != CARD_NONE) {
_state = ESP_SDCARD_IDLE;
lastinitok = true;
log_esp3d("new sd_mmc card type succeed");
} else {
log_esp3d_e("new sd_mmc card type failed");
}
} else {
log_esp3d("new sd_mmc begin failed");
}
} }
return _totalBytes; }
return _state;
} }
uint64_t ESP_SD::usedBytes(bool refresh) bool ESP_SD::begin() {
{ #if (ESP_SDIO_CLK_PIN != -1) || (ESP_SDIO_CMD_PIN != -1) || \
static uint64_t _usedBytes = 0; (ESP_SDIO_D0_PIN != -1) || (ESP_SDIO_D1_PIN != -1) || \
if (refresh || _usedBytes==0) { (ESP_SDIO_D2_PIN != -1) || (ESP_SDIO_D3_PIN != -1)
_usedBytes = SD_MMC.usedBytes(); SD_MMC.setPins(ESP_SDIO_CLK_PIN, ESP_SDIO_CMD_PIN, ESP_SDIO_D0_PIN,
ESP_SDIO_D1_PIN, ESP_SDIO_D2_PIN, ESP_SDIO_D3_PIN)
#endif //(ESP_SDIO_CLK_PIN != -1)
log_esp3d("Begin SDIO");
_started = true;
#ifdef SDMMC_FORCE_BEGIN
_state = ESP_SDCARD_NOT_PRESENT;
#else
_state = getState(true);
#endif // SDMMC_FORCE_BEGIN
return _started;
}
void ESP_SD::end() {
SD_MMC.end();
_state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force) {
if (force || _sizechanged) {
freeBytes(true);
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh) {
static uint64_t _totalBytes = 0;
if (refresh || _totalBytes == 0) {
_totalBytes = SD_MMC.totalBytes();
;
}
return _totalBytes;
}
uint64_t ESP_SD::usedBytes(bool refresh) {
static uint64_t _usedBytes = 0;
if (refresh || _usedBytes == 0) {
_usedBytes = SD_MMC.usedBytes();
}
return _usedBytes;
}
uint64_t ESP_SD::freeBytes(bool refresh) {
return (totalBytes(refresh) - usedBytes(refresh));
}
uint ESP_SD::maxPathLength() { return 255; }
bool ESP_SD::rename(const char *oldpath, const char *newpath) {
return SD_MMC.rename(oldpath, newpath);
}
bool ESP_SD::format(ESP3DOutput *output) {
// not available yet
if (output) {
output->printERROR("Not implemented!");
}
return false;
}
ESP_SDFile ESP_SD::open(const char *path, uint8_t mode) {
// do some check
if (((strcmp(path, "/") == 0) &&
((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) ||
(strlen(path) == 0)) {
log_esp3d_e("File open check : failed");
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d_e("File open path is invalid");
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
// check container exists
String p = path;
p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) {
log_esp3d_e("Error opening: %s, %s does not exists", path, p.c_str());
return ESP_SDFile();
} }
return _usedBytes; }
File tmp = SD_MMC.open(path, (mode == ESP_FILE_READ) ? FILE_READ
: (mode == ESP_FILE_WRITE) ? FILE_WRITE
: FILE_APPEND);
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),
(mode == ESP_FILE_READ) ? false : true, path);
return esptmp;
} }
uint64_t ESP_SD::freeBytes(bool refresh) bool ESP_SD::exists(const char *path) {
{ bool res = false;
return (totalBytes(refresh) - usedBytes(refresh)); String p = path;
} // root should always be there if started
if (p == "/") {
return _started;
}
uint ESP_SD::maxPathLength() if (p.endsWith("/")) {
{ p.remove(p.length() - 1, 1);
return 255; }
} res = SD_MMC.exists(p);
if (!res) {
bool ESP_SD::rename(const char *oldpath, const char *newpath) ESP_SDFile root = ESP_SD::open(p.c_str(), ESP_FILE_READ);
{ if (root) {
return SD_MMC.rename(oldpath,newpath); res = root.isDirectory();
}
bool ESP_SD::format(ESP3DOutput * output)
{
//not available yet
if (output) {
output->printERROR ("Not implemented!");
} }
}
return res;
}
bool ESP_SD::remove(const char *path) { return SD_MMC.remove(path); }
bool ESP_SD::mkdir(const char *path) {
String p = path;
if (p.endsWith("/")) {
p.remove(p.length() - 1, 1);
}
return SD_MMC.mkdir(p.c_str());
}
bool ESP_SD::rmdir(const char *path) {
if (!exists(path)) {
return false; return false;
} }
bool res = true;
ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) std::stack<String> pathlist;
{ String p = path;
//do some check if (p.endsWith("/")) {
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { p.remove(p.length() - 1, 1);
log_esp3d("File open check : failed"); }
return ESP_SDFile(); pathlist.push(p);
} while (pathlist.size() > 0 && res) {
// path must start by '/' File dir = SD_MMC.open(pathlist.top().c_str());
if (path[0] != '/') { File f = dir.openNextFile();
log_esp3d("File open path is invalid"); bool candelete = true;
return ESP_SDFile(); while (f && res) {
} if (f.isDirectory()) {
if (mode != ESP_FILE_READ) { candelete = false;
//check container exists String newdir = pathlist.top() + '/';
String p = path; newdir += f.name();
p.remove(p.lastIndexOf('/') +1); pathlist.push(newdir);
if (!exists(p.c_str())) { f.close();
log_esp3d("Error opening: %s, %s does not exists", path,p.c_str()); f = File();
return ESP_SDFile(); } else {
String filepath = pathlist.top() + '/';
filepath += f.name();
f.close();
if (!SD_MMC.remove(filepath.c_str())) {
res = false;
} }
f = dir.openNextFile();
}
} }
File tmp = SD_MMC.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); if (candelete) {
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path); if (pathlist.top() != "/") {
return esptmp; res = SD_MMC.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
} }
bool ESP_SD::exists(const char* path) void ESP_SD::closeAll() {
{ for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
bool res = false; tSDFile_handle[i].close();
String p = path; tSDFile_handle[i] = File();
//root should always be there if started }
if (p == "/") {
return _started;
}
if (p.endsWith("/")) {
p.remove( p.length() - 1,1);
}
res = SD_MMC.exists(p);
if (!res) {
ESP_SDFile root = ESP_SD::open(p.c_str(), ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
}
return res;
} }
bool ESP_SD::remove(const char *path) ESP_SDFile::ESP_SDFile(void *handle, bool isdir, bool iswritemode,
{ const char *path) {
return SD_MMC.remove(path); _isdir = isdir;
_dirlist = "";
_index = -1;
_filename = "";
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return;
}
bool set = false;
for (uint8_t i = 0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((File *)handle);
// filename
_name = tSDFile_handle[i].name();
_filename = path;
if (_name.endsWith("/")) {
_name.remove(_name.length() - 1, 1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove(0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove(0, pos + 1);
}
if (_name.length() == 0) {
_name = "/";
}
// size
_size = tSDFile_handle[i].size();
// time
_lastwrite = tSDFile_handle[i].getLastWrite();
_index = i;
// log_esp3d("Opening File at index %d",_index);
set = true;
}
}
} }
bool ESP_SD::mkdir(const char *path) bool ESP_SDFile::seek(uint32_t pos, uint8_t mode) {
{ return tSDFile_handle[_index].seek(pos, (SeekMode)mode);
String p = path;
if (p.endsWith("/")) {
p.remove( p.length() - 1,1);
}
return SD_MMC.mkdir(p.c_str());
} }
bool ESP_SD::rmdir(const char *path) void ESP_SDFile::close() {
{ if (_index != -1) {
if (!exists(path)) { // log_esp3d("Closing File at index %d", _index);
return false; tSDFile_handle[_index].close();
// reopen if mode = write
// udate size + date
if (_iswritemode && !_isdir) {
File ftmp = SD_MMC.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
} }
bool res = true; tSDFile_handle[_index] = File();
std::stack <String > pathlist; // log_esp3d("Closing File at index %d",_index);
String p = path;
if (p.endsWith("/")) {
p.remove( p.length() - 1,1);
}
pathlist.push(p);
while (pathlist.size() > 0 && res) {
File dir = SD_MMC.open(pathlist.top().c_str());
File f = dir.openNextFile();
bool candelete = true;
while (f && res) {
if (f.isDirectory()) {
candelete = false;
String newdir = pathlist.top()+ '/';
newdir+= f.name();
pathlist.push(newdir);
f.close();
f = File();
} else {
String filepath = pathlist.top()+ '/';
filepath+= f.name();
f.close();
if (!SD_MMC.remove(filepath.c_str())) {
res = false;
}
f = dir.openNextFile();
}
}
if (candelete) {
if (pathlist.top() !="/") {
res = SD_MMC.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
}
void ESP_SD::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = File();
}
}
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_index = -1; _index = -1;
_filename = ""; }
_name = "";
_lastwrite = 0;
_iswritemode = iswritemode;
_size = 0;
if (!handle) {
return ;
}
bool set =false;
for (uint8_t i=0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
if (!tSDFile_handle[i]) {
tSDFile_handle[i] = *((File*)handle);
//filename
_name = tSDFile_handle[i].name();
_filename = path;
if (_name.endsWith("/")) {
_name.remove( _name.length() - 1,1);
_isdir = true;
}
if (_name[0] == '/') {
_name.remove( 0, 1);
}
int pos = _name.lastIndexOf('/');
if (pos != -1) {
_name.remove( 0, pos+1);
}
if (_name.length() == 0) {
_name = "/";
}
//size
_size = tSDFile_handle[i].size();
//time
_lastwrite = tSDFile_handle[i].getLastWrite();
_index = i;
//log_esp3d("Opening File at index %d",_index);
set = true;
}
}
} }
bool ESP_SDFile::seek(uint32_t pos, uint8_t mode) ESP_SDFile ESP_SDFile::openNextFile() {
{ if ((_index == -1) || !_isdir) {
return tSDFile_handle[_index].seek(pos, (SeekMode)mode); log_esp3d("openNextFile failed");
return ESP_SDFile();
}
File tmp = tSDFile_handle[_index].openNextFile();
if (tmp) {
log_esp3d("tmp name :%s %s %s", tmp.name(),
(tmp.isDirectory()) ? "isDir" : "isFile", _filename.c_str());
String s = tmp.name();
// if (s!="/")s+="/";
// s += tmp.name();
ESP_SDFile esptmp(&tmp, tmp.isDirectory(), false, s.c_str());
esptmp.close();
return esptmp;
}
return ESP_SDFile();
} }
void ESP_SDFile::close() // TODO need to find reliable way
{ const char *ESP_SDFile::shortname() const { return _name.c_str(); }
if (_index != -1) {
//log_esp3d("Closing File at index %d", _index);
tSDFile_handle[_index].close();
//reopen if mode = write
//udate size + date
if (_iswritemode && !_isdir) {
File ftmp = SD_MMC.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
}
tSDFile_handle[_index] = File();
//log_esp3d("Closing File at index %d",_index);
_index = -1;
}
}
ESP_SDFile ESP_SDFile::openNextFile() const char *ESP_SD::FilesystemName() { return "SDIO"; }
{ #endif // SD_DEVICE == ESP_SDIO
if ((_index == -1) || !_isdir) { #endif // ARCH_ESP32 && SD_DEVICE
log_esp3d("openNextFile failed");
return ESP_SDFile();
}
File tmp = tSDFile_handle[_index].openNextFile();
if (tmp) {
log_esp3d("tmp name :%s %s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile", _filename.c_str());
String s = tmp.name() ;
//if (s!="/")s+="/";
//s += tmp.name();
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),false, s.c_str());
esptmp.close();
return esptmp;
}
return ESP_SDFile();
}
//TODO need to find reliable way
const char* ESP_SDFile::shortname() const
{
return _name.c_str();
}
const char * ESP_SD::FilesystemName()
{
return "SDIO";
}
#endif //SD_DEVICE == ESP_SDIO
#endif //ARCH_ESP32 && SD_DEVICE

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
// #define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined(HTTP_FEATURE) && defined(SD_DEVICE) #if defined(HTTP_FEATURE) && defined(SD_DEVICE)
#include "../http_server.h" #include "../http_server.h"

View File

@ -18,104 +18,107 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) #if defined(HTTP_FEATURE)
#include "../http_server.h" #include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> #include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h"
#include "../../authentication/authentication_service.h" #include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_filesystem.h"
#if defined(SD_DEVICE) #if defined(SD_DEVICE)
#include "../../filesystem/esp_sd.h" #include "../../filesystem/esp_sd.h"
#endif //SD_DEVICE #endif // SD_DEVICE
#include "../favicon.h" #include "../favicon.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../serial2socket/serial2socket.h" #include "../../serial2socket/serial2socket.h"
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Handle not registred path on FS neither SD /////////////////////// // Handle not registred path on FS neither SD ///////////////////////
void HTTP_Server:: handle_not_found() void HTTP_Server::handle_not_found() {
{ if (AuthenticationService::authenticated_level() == LEVEL_GUEST) {
if (AuthenticationService::authenticated_level() == LEVEL_GUEST) { _webserver->send(401, "text/plain", "Wrong authentication!");
_webserver->send (401, "text/plain", "Wrong authentication!"); return;
return; }
String path = _webserver->urlDecode(_webserver->uri());
String contentType = getContentType(path.c_str());
String pathWithGz = path + ".gz";
log_esp3d("URI: %s", path.c_str());
#if defined(FILESYSTEM_FEATURE)
if (ESP_FileSystem::exists(pathWithGz.c_str()) ||
ESP_FileSystem::exists(path.c_str())) {
log_esp3d("Path found `%s`", path.c_str());
if (ESP_FileSystem::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
log_esp3d("Path is gz `%s`", path.c_str());
} }
String path = _webserver->urlDecode(_webserver->uri()); if (!StreamFSFile(path.c_str(), contentType.c_str())) {
String contentType = getContentType(path.c_str()); log_esp3d_e("Stream `%s` failed", path.c_str());
String pathWithGz = path + ".gz"; }
log_esp3d("URI: %s", path.c_str()); return;
#if defined (FILESYSTEM_FEATURE) }
if(ESP_FileSystem::exists(pathWithGz.c_str()) || ESP_FileSystem::exists(path.c_str())) { if (path == "favicon.ico" || path == "/favicon.ico") {
log_esp3d("Path found `%s`", path.c_str()); _webserver->sendHeader("Content-Encoding", "gzip");
if(ESP_FileSystem::exists(pathWithGz.c_str())) { _webserver->send_P(200, "image/x-icon", (const char *)favicon,
favicon_size);
return;
}
#endif // #if defined (FILESYSTEM_FEATURE)
#if defined(SD_DEVICE)
if (path.startsWith("/sd/")) {
path = path.substring(3);
pathWithGz = path + ".gz";
if (ESP_SD::accessFS()) {
if (ESP_SD::getState(true) != ESP_SDCARD_NOT_PRESENT) {
ESP_SD::setState(ESP_SDCARD_BUSY);
if (ESP_SD::exists(pathWithGz.c_str()) ||
ESP_SD::exists(path.c_str())) {
if (ESP_SD::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip"); _webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz; path = pathWithGz;
log_esp3d("Path is gz `%s`", path.c_str()); }
}
if(!StreamFSFile(path.c_str(),contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str());
}
return;
}
if (path=="favicon.ico" || path=="/favicon.ico") {
_webserver->sendHeader("Content-Encoding", "gzip");
_webserver->send_P(200,"image/x-icon",(const char *)favicon,favicon_size);
return;
}
#endif //#if defined (FILESYSTEM_FEATURE)
#if defined (SD_DEVICE)
if (path.startsWith("/sd/")) {
path = path.substring(3);
pathWithGz = path + ".gz";
if (ESP_SD::accessFS()) {
if (ESP_SD::getState(true) != ESP_SDCARD_NOT_PRESENT) {
ESP_SD::setState(ESP_SDCARD_BUSY );
if(ESP_SD::exists(pathWithGz.c_str()) || ESP_SD::exists(path.c_str())) {
if(ESP_SD::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
}
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(); Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
if(!StreamSDFile(path.c_str(),contentType.c_str())) { if (!StreamSDFile(path.c_str(), contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str()); log_esp3d_e("Stream `%s` failed", path.c_str());
} }
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false); Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
ESP_SD::releaseFS(); ESP_SD::releaseFS();
return; return;
}
}
ESP_SD::releaseFS();
} }
}
ESP_SD::releaseFS();
} }
#endif //#if defined (SD_DEVICE) }
#endif // #if defined (SD_DEVICE)
#ifdef FILESYSTEM_FEATURE #ifdef FILESYSTEM_FEATURE
//check local page // check local page
path = "/404.htm"; path = "/404.htm";
contentType = getContentType(path.c_str()); contentType = getContentType(path.c_str());
pathWithGz = path + ".gz"; pathWithGz = path + ".gz";
if(ESP_FileSystem::exists(pathWithGz.c_str()) || ESP_FileSystem::exists(path.c_str())) { if (ESP_FileSystem::exists(pathWithGz.c_str()) ||
if(ESP_FileSystem::exists(pathWithGz.c_str())) { ESP_FileSystem::exists(path.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip"); if (ESP_FileSystem::exists(pathWithGz.c_str())) {
path = pathWithGz; _webserver->sendHeader("Content-Encoding", "gzip");
} path = pathWithGz;
if(!StreamFSFile(path.c_str(),contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str());
}
return;
} }
#endif //FILESYSTEM_FEATURE if (!StreamFSFile(path.c_str(), contentType.c_str())) {
//let's keep simple just send minimum log_esp3d_e("Stream `%s` failed", path.c_str());
_webserver->send(404); }
return;
}
#endif // FILESYSTEM_FEATURE
// let's keep simple just send minimum
_webserver->send(404);
} }
#endif //HTTP_FEATURE #endif // HTTP_FEATURE

View File

@ -18,46 +18,49 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) #if defined(HTTP_FEATURE)
#include "../http_server.h" #include "../http_server.h"
//embedded response file if no files on ESP Filesystem // embedded response file if no files on ESP Filesystem
#include "../embedded.h" #include "../embedded.h"
#if defined (ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> #include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h" #include "../../filesystem/esp_filesystem.h"
//Root of Webserver///////////////////////////////////////////////////// // Root of Webserver/////////////////////////////////////////////////////
void HTTP_Server::handle_root() void HTTP_Server::handle_root() {
{ String path = ESP3D_HOST_PATH;
String path = ESP3D_HOST_PATH; // Some sanity check
//Some sanity check if (path[0] != '/') {
if (path[0]!='/') { path = "/" + path;
path ="/" + path; }
if (path[path.length() - 1] != '/') {
path = path + "/";
}
path += "index.html";
String contentType = getContentType(path.c_str());
String pathWithGz = path + ".gz";
// if have a index.html or gzip version this is default root page
if ((ESP_FileSystem::exists(pathWithGz.c_str()) ||
ESP_FileSystem::exists(path.c_str())) &&
!_webserver->hasArg("forcefallback") &&
_webserver->arg("forcefallback") != "yes") {
log_esp3d("Path found `%s`", path.c_str());
if (ESP_FileSystem::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
log_esp3d("Path is gz `%s`", path.c_str());
} }
if (path[path.length()-1]!='/') { if (!StreamFSFile(path.c_str(), contentType.c_str())) {
path = path + "/"; log_esp3d_e("Stream `%s` failed", path.c_str());
} }
path += "index.html"; return;
String contentType = getContentType(path.c_str()); }
String pathWithGz = path + ".gz"; // if no lets launch the default content
//if have a index.html or gzip version this is default root page _webserver->sendHeader("Content-Encoding", "gzip");
if((ESP_FileSystem::exists(pathWithGz.c_str()) || ESP_FileSystem::exists(path.c_str())) && !_webserver->hasArg("forcefallback") && _webserver->arg("forcefallback")!="yes") { _webserver->send_P(200, "text/html", (const char *)tool_html_gz,
log_esp3d("Path found `%s`", path.c_str()); tool_html_gz_size);
if(ESP_FileSystem::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
log_esp3d("Path is gz `%s`", path.c_str());
}
if(!StreamFSFile(path.c_str(),contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str());
}
return;
}
//if no lets launch the default content
_webserver->sendHeader("Content-Encoding", "gzip");
_webserver->send_P(200,"text/html",(const char *)tool_html_gz,tool_html_gz_size);
} }
#endif //HTTP_FEATURE #endif // HTTP_FEATURE

View File

@ -17,242 +17,244 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) && defined(SD_DEVICE) #if defined(HTTP_FEATURE) && defined(SD_DEVICE)
#include "../http_server.h" #include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> #include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_sd.h"
#include "../../authentication/authentication_service.h" #include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_sd.h"
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
#include "../../../core/benchmark.h" #include "../../../core/benchmark.h"
#endif //ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../serial2socket/serial2socket.h" #include "../../serial2socket/serial2socket.h"
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../websocket/websocket_server.h" #include "../../websocket/websocket_server.h"
//SD files uploader handle // SD files uploader handle
void HTTP_Server::SDFileupload () void HTTP_Server::SDFileupload() {
{
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
static uint64_t bench_start; static uint64_t bench_start;
static size_t bench_transfered; static size_t bench_transfered;
#endif//ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
static uint64_t last_WS_update; static uint64_t last_WS_update;
//get authentication status // get authentication status
level_authenticate_type auth_level= AuthenticationService::authenticated_level(); level_authenticate_type auth_level =
static String filename; AuthenticationService::authenticated_level();
static ESP_SDFile fsUploadFile; static String filename;
//Guest cannot upload - only admin static ESP_SDFile fsUploadFile;
if (auth_level == LEVEL_GUEST) { // Guest cannot upload - only admin
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401); if (auth_level == LEVEL_GUEST) {
_upload_status=UPLOAD_STATUS_FAILED; pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
} else { _upload_status = UPLOAD_STATUS_FAILED;
HTTPUpload& upload = _webserver->upload(); } else {
String upload_filename = upload.filename; HTTPUpload& upload = _webserver->upload();
if ((_upload_status != UPLOAD_STATUS_FAILED) || (upload.status == UPLOAD_FILE_START)) { String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) ||
(upload.status == UPLOAD_FILE_START)) {
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(true); Serial2Socket.pause(true);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload start // Upload start
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
last_WS_update = millis(); last_WS_update = millis();
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
bench_start = millis(); bench_start = millis();
bench_transfered = 0; bench_transfered = 0;
#endif//ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING; _upload_status = UPLOAD_STATUS_ONGOING;
if (!ESP_SD::accessFS()) { if (!ESP_SD::accessFS()) {
_upload_status=UPLOAD_STATUS_FAILED; _upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NO_SD, "Upload rejected"); pushError(ESP_ERROR_NO_SD, "Upload rejected");
return; return;
}
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
log_esp3d("Release Sd called");
ESP_SD::releaseFS();
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NO_SD, "Upload rejected");
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
return;
}
ESP_SD::setState(ESP_SDCARD_BUSY );
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload.filename;
}
if (_webserver->hasArg ("rpath") ) {
upload_filename = _webserver->arg ("rpath") + filename;
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload_filename;
}
}
//Sanity check
if (ESP_SD::exists (filename.c_str()) ) {
ESP_SD::remove (filename.c_str());
}
String path = _webserver->arg ("path");
if (path[0] != '/') {
path = "/" + path;
}
if (path[path.length()-1] != '/') {
path = path + "/";
}
if (_webserver->hasArg("createPath") && path.length() > 1) {
if (_webserver->arg("createPath")== "true") {
int pos = path.indexOf('/',1);
while (pos != -1) {
String currentPath = path.substring(0, pos);
if (!ESP_SD::exists (currentPath.c_str()) ) {
if ( !ESP_SD::mkdir (currentPath.c_str()) ) {
pushError(ESP_ERROR_FILE_CREATION, "Failed to create path", 500);
_upload_status=UPLOAD_STATUS_FAILED;
break;
}
}
if ((size_t)(pos+1) >= path.length()-1) {
pos=-1;
break;
} else {
pos = path.indexOf('/',pos+1);
}
}
}
}
if (fsUploadFile.isOpen() ) {
fsUploadFile.close();
}
String sizeargname = upload.filename + "S";
log_esp3d("Uploading file %s", filename.c_str());
if (_upload_status!=UPLOAD_STATUS_FAILED) {
if (_webserver->hasArg (sizeargname.c_str()) ) {
size_t freespace = ESP_SD::totalBytes() - ESP_SD::usedBytes();
size_t filesize = _webserver->arg (sizeargname.c_str()).toInt();
if (freespace < filesize ) {
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NOT_ENOUGH_SPACE, "Upload rejected");
}
}
}
if (_upload_status!=UPLOAD_STATUS_FAILED) {
log_esp3d("Try file creation");
//create file
fsUploadFile = ESP_SD::open(filename.c_str(), ESP_FILE_WRITE);
//check If creation succeed
if (fsUploadFile) {
//if yes upload is started
_upload_status= UPLOAD_STATUS_ONGOING;
log_esp3d("Try file creation");
} else {
//if no set cancel flag
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CREATION, "File creation failed");
log_esp3d("File creation failed");
}
}
//Upload write
} else if(upload.status == UPLOAD_FILE_WRITE) {
//check if file is available and no error
if(fsUploadFile && _upload_status == UPLOAD_STATUS_ONGOING) {
#ifdef ESP_BENCHMARK_FEATURE
bench_transfered += upload.currentSize;
#endif//ESP_BENCHMARK_FEATURE
//update websocket every 2000 ms
if (millis()-last_WS_update > 2000) {
websocket_terminal_server.handle();
last_WS_update = millis();
}
//no error so write post date
int writeddatanb=fsUploadFile.write(upload.buf, upload.currentSize);
if(upload.currentSize != (size_t)writeddatanb) {
//we have a problem set flag UPLOAD_STATUS_FAILED
log_esp3d("File write failed du to mismatch size %d vs %d", writeddatanb, upload.currentSize);
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
} else {
//we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status=UPLOAD_STATUS_FAILED;
log_esp3d("Error detected");
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
//Upload end
} else if(upload.status == UPLOAD_FILE_END) {
uint32_t filesize = 0;
//check if file is still open
if(fsUploadFile) {
//close it
fsUploadFile.close();
#ifdef ESP_BENCHMARK_FEATURE
benchMark("SD upload", bench_start, millis(), bench_transfered);
#endif//ESP_BENCHMARK_FEATURE
//check size
String sizeargname = upload.filename + "S";
//fsUploadFile = ESP_SD::open (filename, ESP_FILE_READ);
filesize = fsUploadFile.size();
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
if (_webserver->hasArg (sizeargname.c_str()) ) {
if (_webserver->arg (sizeargname.c_str()) != String(filesize)) {
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_SIZE, "File upload failed");
}
}
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
}
} else {
//we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CLOSE, "File close failed");
}
log_esp3d("Release Sd called");
ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload cancelled
} else {
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_FAILED;
log_esp3d("Release Sd called");
ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
}
}
} }
} if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
log_esp3d("Release Sd called");
if(_upload_status == UPLOAD_STATUS_FAILED) { ESP_SD::releaseFS();
cancelUpload(); _upload_status = UPLOAD_STATUS_FAILED;
if(fsUploadFile) { pushError(ESP_ERROR_NO_SD, "Upload rejected");
fsUploadFile.close(); #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
return;
} }
if (auth_level != LEVEL_GUEST) { ESP_SD::setState(ESP_SDCARD_BUSY);
if (ESP_SD::exists (filename.c_str())) {
ESP_SD::remove (filename.c_str()); if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload.filename;
}
if (_webserver->hasArg("rpath")) {
upload_filename = _webserver->arg("rpath") + filename;
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload_filename;
}
}
// Sanity check
if (ESP_SD::exists(filename.c_str())) {
ESP_SD::remove(filename.c_str());
}
String path = _webserver->arg("path");
if (path[0] != '/') {
path = "/" + path;
}
if (path[path.length() - 1] != '/') {
path = path + "/";
}
if (_webserver->hasArg("createPath") && path.length() > 1) {
if (_webserver->arg("createPath") == "true") {
int pos = path.indexOf('/', 1);
while (pos != -1) {
String currentPath = path.substring(0, pos);
if (!ESP_SD::exists(currentPath.c_str())) {
if (!ESP_SD::mkdir(currentPath.c_str())) {
pushError(ESP_ERROR_FILE_CREATION, "Failed to create path",
500);
_upload_status = UPLOAD_STATUS_FAILED;
break;
}
}
if ((size_t)(pos + 1) >= path.length() - 1) {
pos = -1;
break;
} else {
pos = path.indexOf('/', pos + 1);
}
} }
}
}
if (fsUploadFile.isOpen()) {
fsUploadFile.close();
}
String sizeargname = upload.filename + "S";
log_esp3d("Uploading file %s", filename.c_str());
if (_upload_status != UPLOAD_STATUS_FAILED) {
if (_webserver->hasArg(sizeargname.c_str())) {
size_t freespace = ESP_SD::totalBytes() - ESP_SD::usedBytes();
size_t filesize = _webserver->arg(sizeargname.c_str()).toInt();
if (freespace < filesize) {
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NOT_ENOUGH_SPACE, "Upload rejected");
}
}
}
if (_upload_status != UPLOAD_STATUS_FAILED) {
log_esp3d("Try file creation");
// create file
fsUploadFile = ESP_SD::open(filename.c_str(), ESP_FILE_WRITE);
// check If creation succeed
if (fsUploadFile) {
// if yes upload is started
_upload_status = UPLOAD_STATUS_ONGOING;
log_esp3d("Try file creation");
} else {
// if no set cancel flag
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CREATION, "File creation failed");
log_esp3d_e("File creation failed");
}
}
// Upload write
} else if (upload.status == UPLOAD_FILE_WRITE) {
// check if file is available and no error
if (fsUploadFile && _upload_status == UPLOAD_STATUS_ONGOING) {
#ifdef ESP_BENCHMARK_FEATURE
bench_transfered += upload.currentSize;
#endif // ESP_BENCHMARK_FEATURE
// update websocket every 2000 ms
if (millis() - last_WS_update > 2000) {
websocket_terminal_server.handle();
last_WS_update = millis();
}
// no error so write post date
int writeddatanb = fsUploadFile.write(upload.buf, upload.currentSize);
if (upload.currentSize != (size_t)writeddatanb) {
// we have a problem set flag UPLOAD_STATUS_FAILED
log_esp3d_e("File write failed du to mismatch size %d vs %d",
writeddatanb, upload.currentSize);
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
} else {
// we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status = UPLOAD_STATUS_FAILED;
log_esp3d_e("Error detected");
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
// Upload end
} else if (upload.status == UPLOAD_FILE_END) {
uint32_t filesize = 0;
// check if file is still open
if (fsUploadFile) {
// close it
fsUploadFile.close();
#ifdef ESP_BENCHMARK_FEATURE
benchMark("SD upload", bench_start, millis(), bench_transfered);
#endif // ESP_BENCHMARK_FEATURE
// check size
String sizeargname = upload.filename + "S";
// fsUploadFile = ESP_SD::open (filename, ESP_FILE_READ);
filesize = fsUploadFile.size();
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
if (_webserver->hasArg(sizeargname.c_str())) {
if (_webserver->arg(sizeargname.c_str()) != String(filesize)) {
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_SIZE, "File upload failed");
}
}
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
}
} else {
// we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CLOSE, "File close failed");
} }
log_esp3d("Release Sd called"); log_esp3d("Release Sd called");
ESP_SD::releaseFS(); ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false); Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
// Upload cancelled
} else {
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_FAILED;
log_esp3d("Release Sd called");
ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
}
}
} }
Hal::wait(5); }
if (_upload_status == UPLOAD_STATUS_FAILED) {
cancelUpload();
if (fsUploadFile) {
fsUploadFile.close();
}
if (auth_level != LEVEL_GUEST) {
if (ESP_SD::exists(filename.c_str())) {
ESP_SD::remove(filename.c_str());
}
}
log_esp3d("Release Sd called");
ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
}
Hal::wait(5);
} }
#endif //HTTP_FEATURE && SD_DEVICE #endif // HTTP_FEATURE && SD_DEVICE

View File

@ -17,205 +17,207 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../../include/esp3d_config.h" #include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) && defined(FILESYSTEM_FEATURE) #if defined(HTTP_FEATURE) && defined(FILESYSTEM_FEATURE)
#include "../http_server.h" #include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> #include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h"
#include "../../authentication/authentication_service.h" #include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_filesystem.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../serial2socket/serial2socket.h" #include "../../serial2socket/serial2socket.h"
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
#include "../../../core/benchmark.h" #include "../../../core/benchmark.h"
#endif //ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
//FS files uploader handle // FS files uploader handle
void HTTP_Server::FSFileupload () void HTTP_Server::FSFileupload() {
{
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
static uint64_t bench_start; static uint64_t bench_start;
static size_t bench_transfered; static size_t bench_transfered;
#endif//ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
//get authentication status // get authentication status
level_authenticate_type auth_level= AuthenticationService::authenticated_level(); level_authenticate_type auth_level =
static String filename; AuthenticationService::authenticated_level();
static ESP_File fsUploadFile; static String filename;
//Guest cannot upload - only admin static ESP_File fsUploadFile;
if (auth_level == LEVEL_GUEST) { // Guest cannot upload - only admin
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401); if (auth_level == LEVEL_GUEST) {
_upload_status=UPLOAD_STATUS_FAILED; pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
} else { _upload_status = UPLOAD_STATUS_FAILED;
HTTPUpload& upload = _webserver->upload(); } else {
String upload_filename = upload.filename; HTTPUpload& upload = _webserver->upload();
if ((_upload_status != UPLOAD_STATUS_FAILED) || (upload.status == UPLOAD_FILE_START)) { String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) ||
(upload.status == UPLOAD_FILE_START)) {
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(); Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload start // Upload start
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
#ifdef ESP_BENCHMARK_FEATURE #ifdef ESP_BENCHMARK_FEATURE
bench_start = millis(); bench_start = millis();
bench_transfered = 0; bench_transfered = 0;
#endif//ESP_BENCHMARK_FEATURE #endif // ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING; _upload_status = UPLOAD_STATUS_ONGOING;
if (upload_filename[0] != '/') { if (upload_filename[0] != '/') {
filename = "/" + upload_filename; filename = "/" + upload_filename;
} else { } else {
filename = upload.filename; filename = upload.filename;
}
if (_webserver->hasArg ("rpath") ) {
upload_filename = _webserver->arg ("rpath") + filename;
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload_filename;
}
}
//Sanity check
if (ESP_FileSystem::exists (filename.c_str()) ) {
ESP_FileSystem::remove (filename.c_str());
}
String path = _webserver->arg ("path");
if (path[0] != '/') {
path = "/" + path;
}
if (path[path.length()-1] != '/') {
path = path + "/";
}
if (_webserver->hasArg("createPath") && path.length() > 1) {
if (_webserver->arg("createPath")== "true") {
int pos = path.indexOf('/',1);
while (pos != -1) {
String currentPath = path.substring(0, pos);
if (!ESP_FileSystem::exists (currentPath.c_str()) ) {
if ( !ESP_FileSystem::mkdir (currentPath.c_str()) ) {
pushError(ESP_ERROR_FILE_CREATION, "Failed to create path", 500);
_upload_status=UPLOAD_STATUS_FAILED;
break;
}
}
if ((uint)(pos+1) >= path.length()-1) {
pos=-1;
break;
} else {
pos = path.indexOf('/',pos+1);
}
}
}
}
if (fsUploadFile.isOpen() ) {
fsUploadFile.close();
}
String sizeargname = upload.filename + "S";
if (_webserver->hasArg (sizeargname.c_str()) ) {
size_t freespace = ESP_FileSystem::totalBytes() - ESP_FileSystem::usedBytes();
size_t filesize = _webserver->arg (sizeargname.c_str()).toInt();
if (freespace < filesize ) {
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NOT_ENOUGH_SPACE, "Upload rejected");
}
}
if (_upload_status!=UPLOAD_STATUS_FAILED) {
//create file
fsUploadFile = ESP_FileSystem::open(filename.c_str(), ESP_FILE_WRITE);
//check If creation succeed
if (fsUploadFile) {
//if yes upload is started
_upload_status= UPLOAD_STATUS_ONGOING;
} else {
//if no set cancel flag
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CREATION, "File creation failed");
}
}
//Upload write
} else if(upload.status == UPLOAD_FILE_WRITE) {
//check if file is available and no error
if(fsUploadFile && _upload_status == UPLOAD_STATUS_ONGOING) {
//no error so write post date
#ifdef ESP_BENCHMARK_FEATURE
bench_transfered += upload.currentSize;
#endif//ESP_BENCHMARK_FEATURE
if(upload.currentSize != fsUploadFile.write(upload.buf, upload.currentSize)) {
//we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
} else {
//we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
//Upload end
} else if(upload.status == UPLOAD_FILE_END) {
log_esp3d("upload end");
//check if file is still open
if(fsUploadFile) {
//close it
fsUploadFile.close();
#ifdef ESP_BENCHMARK_FEATURE
benchMark("FS upload", bench_start, millis(), bench_transfered);
#endif//ESP_BENCHMARK_FEATURE
//check size
String sizeargname = upload.filename + "S";
//fsUploadFile = ESP_FileSystem::open (filename, ESP_FILE_READ);
uint32_t filesize = fsUploadFile.size();
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
if (_webserver->hasArg (sizeargname.c_str()) ) {
log_esp3d("Size check: %s vs %s", _webserver->arg (sizeargname.c_str()).c_str(), String(filesize).c_str());
if (_webserver->arg (sizeargname.c_str()) != String(filesize)) {
log_esp3d("Size Error");
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_SIZE, "File upload failed");
}
}
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
}
} else {
//we have a problem set flag UPLOAD_STATUS_FAILED
log_esp3d("Close Error");
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CLOSE, "File close failed");
}
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload cancelled
} else {
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_FAILED;
}
}
} }
} if (_webserver->hasArg("rpath")) {
upload_filename = _webserver->arg("rpath") + filename;
if(_upload_status == UPLOAD_STATUS_FAILED) { if (upload_filename[0] != '/') {
cancelUpload(); filename = "/" + upload_filename;
if(fsUploadFile) { } else {
fsUploadFile.close(); filename = upload_filename;
}
} }
if (auth_level != LEVEL_GUEST) { // Sanity check
if (ESP_FileSystem::exists (filename.c_str())) { if (ESP_FileSystem::exists(filename.c_str())) {
ESP_FileSystem::remove (filename.c_str()); ESP_FileSystem::remove(filename.c_str());
}
String path = _webserver->arg("path");
if (path[0] != '/') {
path = "/" + path;
}
if (path[path.length() - 1] != '/') {
path = path + "/";
}
if (_webserver->hasArg("createPath") && path.length() > 1) {
if (_webserver->arg("createPath") == "true") {
int pos = path.indexOf('/', 1);
while (pos != -1) {
String currentPath = path.substring(0, pos);
if (!ESP_FileSystem::exists(currentPath.c_str())) {
if (!ESP_FileSystem::mkdir(currentPath.c_str())) {
pushError(ESP_ERROR_FILE_CREATION, "Failed to create path",
500);
_upload_status = UPLOAD_STATUS_FAILED;
break;
}
}
if ((uint)(pos + 1) >= path.length() - 1) {
pos = -1;
break;
} else {
pos = path.indexOf('/', pos + 1);
}
} }
}
}
if (fsUploadFile.isOpen()) {
fsUploadFile.close();
}
String sizeargname = upload.filename + "S";
if (_webserver->hasArg(sizeargname.c_str())) {
size_t freespace =
ESP_FileSystem::totalBytes() - ESP_FileSystem::usedBytes();
size_t filesize = _webserver->arg(sizeargname.c_str()).toInt();
if (freespace < filesize) {
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NOT_ENOUGH_SPACE, "Upload rejected");
}
}
if (_upload_status != UPLOAD_STATUS_FAILED) {
// create file
fsUploadFile = ESP_FileSystem::open(filename.c_str(), ESP_FILE_WRITE);
// check If creation succeed
if (fsUploadFile) {
// if yes upload is started
_upload_status = UPLOAD_STATUS_ONGOING;
} else {
// if no set cancel flag
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CREATION, "File creation failed");
}
}
// Upload write
} else if (upload.status == UPLOAD_FILE_WRITE) {
// check if file is available and no error
if (fsUploadFile && _upload_status == UPLOAD_STATUS_ONGOING) {
// no error so write post date
#ifdef ESP_BENCHMARK_FEATURE
bench_transfered += upload.currentSize;
#endif // ESP_BENCHMARK_FEATURE
if (upload.currentSize !=
fsUploadFile.write(upload.buf, upload.currentSize)) {
// we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
} else {
// we have a problem set flag UPLOAD_STATUS_FAILED
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_WRITE, "File write failed");
}
// Upload end
} else if (upload.status == UPLOAD_FILE_END) {
log_esp3d("upload end");
// check if file is still open
if (fsUploadFile) {
// close it
fsUploadFile.close();
#ifdef ESP_BENCHMARK_FEATURE
benchMark("FS upload", bench_start, millis(), bench_transfered);
#endif // ESP_BENCHMARK_FEATURE
// check size
String sizeargname = upload.filename + "S";
// fsUploadFile = ESP_FileSystem::open (filename, ESP_FILE_READ);
uint32_t filesize = fsUploadFile.size();
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
if (_webserver->hasArg(sizeargname.c_str())) {
log_esp3d("Size check: %s vs %s",
_webserver->arg(sizeargname.c_str()).c_str(),
String(filesize).c_str());
if (_webserver->arg(sizeargname.c_str()) != String(filesize)) {
log_esp3d_e("Size Error");
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_SIZE, "File upload failed");
}
}
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_SUCCESSFUL;
}
} else {
// we have a problem set flag UPLOAD_STATUS_FAILED
log_esp3d_e("Close Error");
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_FILE_CLOSE, "File close failed");
} }
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false); Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
// Upload cancelled
} else {
if (_upload_status == UPLOAD_STATUS_ONGOING) {
_upload_status = UPLOAD_STATUS_FAILED;
}
}
} }
}
if (_upload_status == UPLOAD_STATUS_FAILED) {
cancelUpload();
if (fsUploadFile) {
fsUploadFile.close();
}
if (auth_level != LEVEL_GUEST) {
if (ESP_FileSystem::exists(filename.c_str())) {
ESP_FileSystem::remove(filename.c_str());
}
}
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
}
} }
#endif //HTTP_FEATURE && FILESYSTEM_FEATURE #endif // HTTP_FEATURE && FILESYSTEM_FEATURE

View File

@ -17,7 +17,7 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
// #define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef MDNS_FEATURE #ifdef MDNS_FEATURE
@ -97,38 +97,38 @@ void mDNS_Service::end() {
if (_hMDNSServiceQuery) { if (_hMDNSServiceQuery) {
log_esp3d("Remove mdns service for %s", _hostname.c_str()); log_esp3d("Remove mdns service for %s", _hostname.c_str());
if (!MDNS.removeServiceQuery(_hMDNSServiceQuery)) { if (!MDNS.removeServiceQuery(_hMDNSServiceQuery)) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
} }
_hMDNSServiceQuery = 0; _hMDNSServiceQuery = 0;
log_esp3d("Remove mdns for %s", _hostname.c_str()); log_esp3d("Remove mdns for %s", _hostname.c_str());
if (!MDNS.removeService(_hostname.c_str(), MDNS_SERVICE_NAME, if (!MDNS.removeService(_hostname.c_str(), MDNS_SERVICE_NAME,
MDNS_SERVICE_TYPE)) { MDNS_SERVICE_TYPE)) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#if defined(HTTP_FEATURE) #if defined(HTTP_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "http", "tcp")) { if (!MDNS.removeService(_hostname.c_str(), "http", "tcp")) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#endif // HTTP_FEATURE #endif // HTTP_FEATURE
#if defined(FTP_FEATURE) #if defined(FTP_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "ftp", "tcp")) { if (!MDNS.removeService(_hostname.c_str(), "ftp", "tcp")) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#endif // FTP_FEATURE #endif // FTP_FEATURE
#if defined(TELNET_FEATURE) #if defined(TELNET_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "telnet", "tcp")) { if (!MDNS.removeService(_hostname.c_str(), "telnet", "tcp")) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#endif // TELNET_FEATURE #endif // TELNET_FEATURE
#if defined(WEBDAV_FEATURE) #if defined(WEBDAV_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "webdav", "tcp")) { if (!MDNS.removeService(_hostname.c_str(), "webdav", "tcp")) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#endif // WEBDAV_FEATURE #endif // WEBDAV_FEATURE
#if defined(WS_DATA_FEATURE) #if defined(WS_DATA_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "websocket", "tcp")) { if (!MDNS.removeService(_hostname.c_str(), "websocket", "tcp")) {
log_esp3d("failed"); log_esp3d_e("failed");
} }
#endif // WS_DATA_FEATURE #endif // WS_DATA_FEATURE
#endif // ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
@ -194,7 +194,7 @@ void mDNS_Service::addESP3DServices(uint16_t port) {
if (_hMDNSServiceQuery) { if (_hMDNSServiceQuery) {
log_esp3d("MDNS Service query services installed."); log_esp3d("MDNS Service query services installed.");
} else { } else {
log_esp3d("MDNS Service query services installation failed."); log_esp3d_e("MDNS Service query services installation failed.");
} }
#endif // ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }

File diff suppressed because it is too large Load Diff

View File

@ -19,30 +19,30 @@
*/ */
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined (WIFI_FEATURE) || defined (ETH_FEATURE) || defined (BLUETOOTH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BLUETOOTH_FEATURE)
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#define WIFI_EVENT_STAMODE_CONNECTED ARDUINO_EVENT_WIFI_STA_CONNECTED #define WIFI_EVENT_STAMODE_CONNECTED ARDUINO_EVENT_WIFI_STA_CONNECTED
#define WIFI_EVENT_STAMODE_DISCONNECTED ARDUINO_EVENT_WIFI_STA_DISCONNECTED #define WIFI_EVENT_STAMODE_DISCONNECTED ARDUINO_EVENT_WIFI_STA_DISCONNECTED
#define WIFI_EVENT_STAMODE_GOT_IP ARDUINO_EVENT_WIFI_STA_GOT_IP #define WIFI_EVENT_STAMODE_GOT_IP ARDUINO_EVENT_WIFI_STA_GOT_IP
#define WIFI_EVENT_SOFTAPMODE_STACONNECTED ARDUINO_EVENT_WIFI_AP_STACONNECTED #define WIFI_EVENT_SOFTAPMODE_STACONNECTED ARDUINO_EVENT_WIFI_AP_STACONNECTED
#define RADIO_OFF_MSG "Radio Off" #define RADIO_OFF_MSG "Radio Off"
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#define RADIO_OFF_MSG "WiFi Off" #define RADIO_OFF_MSG "WiFi Off"
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "netconfig.h" #include "netconfig.h"
#if defined (WIFI_FEATURE) #if defined(WIFI_FEATURE)
#include "../wifi/wificonfig.h" #include "../wifi/wificonfig.h"
#endif //WIFI_FEATURE #endif // WIFI_FEATURE
#if defined (ETH_FEATURE) #if defined(ETH_FEATURE)
#include "../ethernet/ethconfig.h" #include "../ethernet/ethconfig.h"
#endif //ETH_FEATURE #endif // ETH_FEATURE
#if defined (BLUETOOTH_FEATURE) #if defined(BLUETOOTH_FEATURE)
#include "../bluetooth/BT_service.h" #include "../bluetooth/BT_service.h"
#endif //BLUETOOTH_FEATURE #endif // BLUETOOTH_FEATURE
#include "netservices.h"
#include "../../core/esp3doutput.h" #include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h" #include "../../core/settings_esp3d.h"
#include "netservices.h"
String NetConfig::_hostname = ""; String NetConfig::_hostname = "";
bool NetConfig::_needReconnect2AP = false; bool NetConfig::_needReconnect2AP = false;
@ -50,428 +50,407 @@ bool NetConfig::_events_registered = false;
bool NetConfig::_started = false; bool NetConfig::_started = false;
uint8_t NetConfig::_mode = ESP_NO_NETWORK; uint8_t NetConfig::_mode = ESP_NO_NETWORK;
//just simple helper to convert mac address to string // just simple helper to convert mac address to string
char * NetConfig::mac2str (uint8_t mac [8]) char* NetConfig::mac2str(uint8_t mac[8]) {
{ static char macstr[18];
static char macstr [18]; if (0 > sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1],
if (0 > sprintf (macstr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ) { mac[2], mac[3], mac[4], mac[5])) {
strcpy (macstr, "00:00:00:00:00:00"); strcpy(macstr, "00:00:00:00:00:00");
} }
return macstr; return macstr;
} }
/** /**
* Helper to convert IP string to int * Helper to convert IP string to int
*/ */
uint32_t NetConfig::IP_int_from_string(const char * s) uint32_t NetConfig::IP_int_from_string(const char* s) {
{ uint32_t ip_int = 0;
uint32_t ip_int = 0; IPAddress ipaddr;
IPAddress ipaddr; if (ipaddr.fromString(s)) {
if (ipaddr.fromString(s)) { ip_int = ipaddr;
ip_int = ipaddr; }
} return ip_int;
return ip_int;
} }
/** /**
* Helper to convert int to IP string * Helper to convert int to IP string
*/ */
String NetConfig::IP_string_from_int(uint32_t ip_int) String NetConfig::IP_string_from_int(uint32_t ip_int) {
{ IPAddress ipaddr(ip_int);
IPAddress ipaddr(ip_int); return ipaddr.toString();
return ipaddr.toString();
} }
/** /**
* Check if Hostname string is valid * Check if Hostname string is valid
*/ */
bool NetConfig::isHostnameValid (const char * hostname) bool NetConfig::isHostnameValid(const char* hostname) {
{ // limited size
//limited size char c;
char c; if (strlen(hostname) > MAX_HOSTNAME_LENGTH ||
if (strlen (hostname) > MAX_HOSTNAME_LENGTH || strlen (hostname) < MIN_HOSTNAME_LENGTH) { strlen(hostname) < MIN_HOSTNAME_LENGTH) {
return false; return false;
}
// only letter and digit
for (uint i = 0; i < strlen(hostname); i++) {
c = hostname[i];
if (!(isdigit(c) || isalpha(c) || c == '-')) {
return false;
} }
//only letter and digit if (c == ' ') {
for (uint i = 0; i < strlen (hostname); i++) { return false;
c = hostname[i];
if (! (isdigit (c) || isalpha (c) || c == '-') ) {
return false;
}
if (c == ' ') {
return false;
}
} }
return true; }
return true;
} }
/** /**
* Get IP Integer what ever is enabled * Get IP Integer what ever is enabled
*/ */
IPAddress NetConfig::localIPAddress() IPAddress NetConfig::localIPAddress() {
{ IPAddress current_ip = IPAddress(0, 0, 0, 0);
IPAddress current_ip = IPAddress(0,0,0,0); #if defined(WIFI_FEATURE)
#if defined( WIFI_FEATURE) if (WiFi.getMode() == WIFI_STA) {
if (WiFi.getMode() == WIFI_STA) { current_ip = WiFi.localIP();
current_ip = WiFi.localIP(); } else if (WiFi.getMode() == WIFI_AP) {
} else if (WiFi.getMode() == WIFI_AP) { current_ip = WiFi.softAPIP();
current_ip = WiFi.softAPIP(); }
} #endif // WIFI_FEATURE
#endif //WIFI_FEATURE #if defined(ETH_FEATURE)
#if defined (ETH_FEATURE) if (EthConfig::started()) {
if (EthConfig::started()) { current_ip = ETH.localIP();
current_ip = ETH.localIP(); }
} #endif // ETH_FEATURE
#endif //ETH_FEATURE
return current_ip; return current_ip;
} }
/** /**
* Get IP string what ever is enabled * Get IP string what ever is enabled
*/ */
String NetConfig::localIP() String NetConfig::localIP() {
{ static String currentIP = "";
static String currentIP = ""; #if defined(WIFI_FEATURE)
#if defined( WIFI_FEATURE) if (WiFi.getMode() == WIFI_STA) {
if (WiFi.getMode() == WIFI_STA) { currentIP = WiFi.localIP().toString();
currentIP = WiFi.localIP().toString(); } else if (WiFi.getMode() == WIFI_AP) {
} else if (WiFi.getMode() == WIFI_AP) { currentIP = WiFi.softAPIP().toString();
currentIP = WiFi.softAPIP().toString(); }
} #endif // WIFI_FEATURE
#endif //WIFI_FEATURE #if defined(ETH_FEATURE)
#if defined (ETH_FEATURE) if (EthConfig::started()) {
if (EthConfig::started()) { currentIP = ETH.localIP().toString();
currentIP = ETH.localIP().toString(); }
} #endif // ETH_FEATURE
#endif //ETH_FEATURE if (currentIP.length() == 0) {
if (currentIP.length() == 0) { currentIP = "0.0.0.0";
currentIP = "0.0.0.0"; }
} return currentIP;
return currentIP;
} }
/** /**
* Check if IP string is valid * Check if IP string is valid
*/ */
bool NetConfig::isValidIP(const char * string) bool NetConfig::isValidIP(const char* string) {
{ IPAddress ip;
IPAddress ip; return ip.fromString(string);
return ip.fromString(string);
} }
// wifi event
//wifi event void NetConfig::onWiFiEvent(WiFiEvent_t event) {
void NetConfig::onWiFiEvent(WiFiEvent_t event) ESP3DOutput output(ESP_ALL_CLIENTS);
{ switch (event) {
ESP3DOutput output(ESP_ALL_CLIENTS);
switch (event) {
case WIFI_EVENT_STAMODE_CONNECTED: case WIFI_EVENT_STAMODE_CONNECTED:
_needReconnect2AP = false; _needReconnect2AP = false;
break; break;
case WIFI_EVENT_STAMODE_DISCONNECTED: { case WIFI_EVENT_STAMODE_DISCONNECTED: {
if(_started) { if (_started) {
output.printMSG ("Disconnected"); output.printMSG("Disconnected");
//_needReconnect2AP = true; //_needReconnect2AP = true;
} }
} } break;
break;
case WIFI_EVENT_STAMODE_GOT_IP: { case WIFI_EVENT_STAMODE_GOT_IP: {
#if COMMUNICATION_PROTOCOL != MKS_SERIAL #if COMMUNICATION_PROTOCOL != MKS_SERIAL
output.printMSG (WiFi.localIP().toString().c_str()); output.printMSG(WiFi.localIP().toString().c_str());
#endif //#if COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
} } break;
break;
case WIFI_EVENT_SOFTAPMODE_STACONNECTED: { case WIFI_EVENT_SOFTAPMODE_STACONNECTED: {
output.printMSG ("New client"); output.printMSG("New client");
} } break;
break;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
case ARDUINO_EVENT_WIFI_STA_LOST_IP: case ARDUINO_EVENT_WIFI_STA_LOST_IP:
if(_started) { if (_started) {
_needReconnect2AP = true; _needReconnect2AP = true;
} }
break; break;
#ifdef ETH_FEATURE #ifdef ETH_FEATURE
case ARDUINO_EVENT_ETH_START: { case ARDUINO_EVENT_ETH_START: {
EthConfig::setConnected(false); EthConfig::setConnected(false);
if (Settings_ESP3D::isVerboseBoot()) { if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG ("Checking connection"); output.printMSG("Checking connection");
} }
} } break;
break;
case ARDUINO_EVENT_ETH_CONNECTED: { case ARDUINO_EVENT_ETH_CONNECTED: {
output.printMSG ("Cable connected"); output.printMSG("Cable connected");
EthConfig::setConnected(true); EthConfig::setConnected(true);
} } break;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED: { case ARDUINO_EVENT_ETH_DISCONNECTED: {
output.printMSG ("Cable disconnected"); output.printMSG("Cable disconnected");
EthConfig::setConnected(false); EthConfig::setConnected(false);
} } break;
break;
case ARDUINO_EVENT_ETH_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP:
output.printMSG (ETH.localIP().toString().c_str()); output.printMSG(ETH.localIP().toString().c_str());
EthConfig::setConnected(true); EthConfig::setConnected(true);
break; break;
case ARDUINO_EVENT_ETH_STOP: case ARDUINO_EVENT_ETH_STOP:
EthConfig::setConnected(false); EthConfig::setConnected(false);
break; break;
#endif //ETH_FEATURE #endif // ETH_FEATURE
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
default: default:
break; break;
} }
} }
void NetConfig::setMode(uint8_t mode) void NetConfig::setMode(uint8_t mode) { _mode = mode; }
{
_mode=mode;
}
uint8_t NetConfig::getMode() uint8_t NetConfig::getMode() { return _mode; }
{
return _mode;
}
/** /**
* begin WiFi setup * begin WiFi setup
*/ */
bool NetConfig::begin() bool NetConfig::begin() {
{ bool res = false;
bool res = false; // clear everything
//clear everything end();
end(); int8_t espMode = Settings_ESP3D::read_byte(ESP_RADIO_MODE);
int8_t espMode =Settings_ESP3D::read_byte(ESP_RADIO_MODE); ESP3DOutput output(ESP_ALL_CLIENTS);
ESP3DOutput output(ESP_ALL_CLIENTS); log_esp3d("Starting Network");
log_esp3d("Starting Network"); if (espMode != ESP_NO_NETWORK) {
if (espMode != ESP_NO_NETWORK) { if (Settings_ESP3D::isVerboseBoot()) {
if (Settings_ESP3D::isVerboseBoot()) { output.printMSG("Starting Network");
output.printMSG("Starting Network");
}
} }
//setup events }
if(!_events_registered) { // setup events
if (!_events_registered) {
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
WiFi.onEvent(NetConfig::onWiFiEvent, WIFI_EVENT_ANY); WiFi.onEvent(NetConfig::onWiFiEvent, WIFI_EVENT_ANY);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
WiFi.onEvent(NetConfig::onWiFiEvent); WiFi.onEvent(NetConfig::onWiFiEvent);
#endif #endif
_events_registered = true; _events_registered = true;
} }
//Get hostname // Get hostname
_hostname = Settings_ESP3D::read_string(ESP_HOSTNAME); _hostname = Settings_ESP3D::read_string(ESP_HOSTNAME);
_mode = espMode; _mode = espMode;
if (espMode == ESP_NO_NETWORK) { if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network"); output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr); ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
if (Settings_ESP3D::isVerboseBoot()) { if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS); ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG); output.printMSG(RADIO_OFF_MSG);
output.flush(); output.flush();
}
return true;
}
#if defined (WIFI_FEATURE)
if ((espMode == ESP_AP_SETUP) || (espMode == ESP_WIFI_AP) || (espMode == ESP_WIFI_STA)) {
output.printMSG("Setup wifi");
res = WiFiConfig::begin(espMode);
}
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
//if ((espMode == ESP_ETH_STA) || (espMode == ESP_ETH_SRV)) {
if ((espMode == ESP_ETH_STA)) {
WiFi.mode(WIFI_OFF);
res = EthConfig::begin(espMode);
} }
return true;
}
#if defined(WIFI_FEATURE)
if ((espMode == ESP_AP_SETUP) || (espMode == ESP_WIFI_AP) ||
(espMode == ESP_WIFI_STA)) {
output.printMSG("Setup wifi");
res = WiFiConfig::begin(espMode);
}
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
// if ((espMode == ESP_ETH_STA) || (espMode == ESP_ETH_SRV)) {
if ((espMode == ESP_ETH_STA)) {
WiFi.mode(WIFI_OFF);
res = EthConfig::begin(espMode);
}
#else #else
//if Eth and no Eth enabled let's go to no network // if Eth and no Eth enabled let's go to no network
if (espMode == ESP_ETH_STA) { if (espMode == ESP_ETH_STA) {
espMode = ESP_NO_NETWORK; espMode = ESP_NO_NETWORK;
} }
#endif //ETH_FEATURE #endif // ETH_FEATURE
#if defined (BLUETOOTH_FEATURE) #if defined(BLUETOOTH_FEATURE)
if (espMode == ESP_BT) { if (espMode == ESP_BT) {
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
String msg = "BT On"; String msg = "BT On";
ESP3DOutput::toScreen(ESP_OUTPUT_STATUS, msg.c_str()); ESP3DOutput::toScreen(ESP_OUTPUT_STATUS, msg.c_str());
res = bt_service.begin(); res = bt_service.begin();
} }
#else #else
//if BT and no BT enabled let's go to no network // if BT and no BT enabled let's go to no network
if (espMode == ESP_BT) { if (espMode == ESP_BT) {
espMode = ESP_NO_NETWORK; espMode = ESP_NO_NETWORK;
} }
#endif //BLUETOOTH_FEATURE #endif // BLUETOOTH_FEATURE
if (espMode == ESP_NO_NETWORK) { if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network"); output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr); ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
if (Settings_ESP3D::isVerboseBoot()) { if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS); ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG); output.printMSG(RADIO_OFF_MSG);
output.flush(); output.flush();
}
return true;
} }
//if network is up, let's start services return true;
if (res) { }
_started = true; // if network is up, let's start services
bool start_services = false; if (res) {
#if defined (ETH_FEATURE) _started = true;
if (EthConfig::started()) { bool start_services = false;
start_services = true; #if defined(ETH_FEATURE)
} if (EthConfig::started()) {
#endif //ETH_FEATURE start_services = true;
#if defined (WIFI_FEATURE)
if (WiFiConfig::started()) {
start_services = true;
}
#endif //WIFI_FEATURE
if (start_services) {
log_esp3d("Starting service");
res = NetServices::begin();
}
} }
//work around as every services seems reset the AP name #endif // ETH_FEATURE
#if defined(WIFI_FEATURE)
if (WiFiConfig::started()) {
start_services = true;
}
#endif // WIFI_FEATURE
if (start_services) {
log_esp3d("Starting service");
res = NetServices::begin();
}
}
// work around as every services seems reset the AP name
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#if defined (WIFI_FEATURE) #if defined(WIFI_FEATURE)
if (WiFi.getMode() == WIFI_AP) { if (WiFi.getMode() == WIFI_AP) {
WiFi.softAPsetHostname(_hostname.c_str()); WiFi.softAPsetHostname(_hostname.c_str());
} }
#endif //WIFI_FEATURE #endif // WIFI_FEATURE
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
DEBUG_ESP3D_NETWORK_INIT LOG_ESP3D_NETWORK_INIT
if (res) { if (res) {
log_esp3d("Network config started"); log_esp3d("Network config started");
} else {
end(); } else {
log_esp3d("Network config failed"); end();
} log_esp3d_e("Network config failed");
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr); }
return res; ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
return res;
} }
/** /**
* End WiFi * End WiFi
*/ */
void NetConfig::end() void NetConfig::end() {
{ NetServices::end();
NetServices::end(); LOG_ESP3D_NETWORK_END
DEBUG_ESP3D_NETWORK_END _mode = ESP_NO_NETWORK;
_mode = ESP_NO_NETWORK; #if defined(WIFI_FEATURE)
#if defined (WIFI_FEATURE) WiFiConfig::end();
WiFiConfig::end(); _needReconnect2AP = false;
_needReconnect2AP=false;
#else #else
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
#endif //WIFI_FEATURE #endif // WIFI_FEATURE
#if defined (ETH_FEATURE) #if defined(ETH_FEATURE)
EthConfig::end(); EthConfig::end();
#endif //ETH_FEATURE #endif // ETH_FEATURE
#if defined (BLUETOOTH_FEATURE) #if defined(BLUETOOTH_FEATURE)
bt_service.end(); bt_service.end();
#endif //BLUETOOTH_FEATURE #endif // BLUETOOTH_FEATURE
_started = false; _started = false;
} }
const char* NetConfig::hostname(bool fromsettings) const char* NetConfig::hostname(bool fromsettings) {
{ if (fromsettings) {
if (fromsettings) { _hostname = Settings_ESP3D::read_string(ESP_HOSTNAME);
_hostname = Settings_ESP3D::read_string(ESP_HOSTNAME);
return _hostname.c_str();
}
#if defined (WIFI_FEATURE)
if(WiFi.getMode()!= WIFI_OFF) {
_hostname = WiFiConfig::hostname();
return _hostname.c_str();
}
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
if(EthConfig::started()) {
return ETH.getHostname();
}
#endif //ETH_FEATURE
#if defined (BLUETOOTH_FEATURE)
if(bt_service.started()) {
return bt_service.hostname();
}
#endif //BLUETOOTH_FEATURE
return _hostname.c_str(); return _hostname.c_str();
}
#if defined(WIFI_FEATURE)
if (WiFi.getMode() != WIFI_OFF) {
_hostname = WiFiConfig::hostname();
return _hostname.c_str();
}
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
if (EthConfig::started()) {
return ETH.getHostname();
}
#endif // ETH_FEATURE
#if defined(BLUETOOTH_FEATURE)
if (bt_service.started()) {
return bt_service.hostname();
}
#endif // BLUETOOTH_FEATURE
return _hostname.c_str();
} }
/** /**
* Handle not critical actions that must be done in sync environement * Handle not critical actions that must be done in sync environement
*/ */
void NetConfig::handle() void NetConfig::handle() {
{ if (_started) {
if (_started) { #if defined(WIFI_FEATURE)
#if defined (WIFI_FEATURE) if (_needReconnect2AP) {
if(_needReconnect2AP) { if (WiFi.getMode() != WIFI_OFF) {
begin();
if(WiFi.getMode()!= WIFI_OFF) { }
begin();
}
}
WiFiConfig::handle();
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
EthConfig::handle();
#endif //ETH_FEATURE
#if defined (BLUETOOTH_FEATURE)
bt_service.handle();
#endif //BLUETOOTH_FEATURE
NetServices::handle();
//Debug
DEBUG_ESP3D_NETWORK_HANDLE
} }
WiFiConfig::handle();
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
EthConfig::handle();
#endif // ETH_FEATURE
#if defined(BLUETOOTH_FEATURE)
bt_service.handle();
#endif // BLUETOOTH_FEATURE
NetServices::handle();
// Debug
LOG_ESP3D_NETWORK_HANDLE
}
} }
bool NetConfig::isIPModeDHCP (uint8_t mode) bool NetConfig::isIPModeDHCP(uint8_t mode) {
{ bool started = false;
bool started = false;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_dhcp_status_t dhcp_status; tcpip_adapter_dhcp_status_t dhcp_status;
tcpip_adapter_dhcpc_get_status ((mode == ESP_WIFI_STA)?TCPIP_ADAPTER_IF_STA:(mode == ESP_WIFI_AP)?TCPIP_ADAPTER_IF_AP:TCPIP_ADAPTER_IF_ETH, &dhcp_status); tcpip_adapter_dhcpc_get_status((mode == ESP_WIFI_STA) ? TCPIP_ADAPTER_IF_STA
started = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED); : (mode == ESP_WIFI_AP) ? TCPIP_ADAPTER_IF_AP
#endif //ARDUINO_ARCH_ESP32 : TCPIP_ADAPTER_IF_ETH,
&dhcp_status);
started = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
(void)mode; (void)mode;
started = (wifi_station_dhcpc_status() == DHCP_STARTED); started = (wifi_station_dhcpc_status() == DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
return started; return started;
} }
bool NetConfig::isDHCPServer (uint8_t mode) bool NetConfig::isDHCPServer(uint8_t mode) {
{ bool itis = false;
bool itis = false;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_dhcp_status_t dhcp_status; tcpip_adapter_dhcp_status_t dhcp_status;
tcpip_adapter_dhcps_get_status ((mode == ESP_WIFI_STA)?TCPIP_ADAPTER_IF_STA:(mode == ESP_WIFI_AP)?TCPIP_ADAPTER_IF_AP:TCPIP_ADAPTER_IF_ETH, &dhcp_status); tcpip_adapter_dhcps_get_status((mode == ESP_WIFI_STA) ? TCPIP_ADAPTER_IF_STA
itis = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED); : (mode == ESP_WIFI_AP) ? TCPIP_ADAPTER_IF_AP
#endif //ARDUINO_ARCH_ESP32 : TCPIP_ADAPTER_IF_ETH,
&dhcp_status);
itis = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
(void)mode; (void)mode;
itis = (wifi_softap_dhcps_status() == DHCP_STARTED); itis = (wifi_softap_dhcps_status() == DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
return itis; return itis;
} }
#endif // WIFI_FEATURE || ETH_FEATURE #endif // WIFI_FEATURE || ETH_FEATURE

File diff suppressed because it is too large Load Diff

View File

@ -20,187 +20,169 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
#if SENSOR_DEVICE==BMP280_DEVICE || SENSOR_DEVICE==BME280_DEVICE #if SENSOR_DEVICE == BMP280_DEVICE || SENSOR_DEVICE == BME280_DEVICE
#include "bmx280.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include <BMx280I2C.h> #include <BMx280I2C.h>
#include <Wire.h> #include <Wire.h>
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "bmx280.h"
#define NB_TYPE_SENSOR 2 #define NB_TYPE_SENSOR 2
const char * SENSOR_NAME[NB_TYPE_SENSOR] = {"BMP280", "BME280"}; const char *SENSOR_NAME[NB_TYPE_SENSOR] = {"BMP280", "BME280"};
const uint8_t SENSOR_ID[NB_TYPE_SENSOR] = {BMP280_DEVICE, BME280_DEVICE}; const uint8_t SENSOR_ID[NB_TYPE_SENSOR] = {BMP280_DEVICE, BME280_DEVICE};
BMx280I2C * bmx280_device; BMx280I2C *bmx280_device;
BMX280SensorDevice::BMX280SensorDevice() BMX280SensorDevice::BMX280SensorDevice() { bmx280_device = nullptr; }
{
bmx280_device = nullptr;
}
BMX280SensorDevice::~BMX280SensorDevice() BMX280SensorDevice::~BMX280SensorDevice() { end(); }
{
end();
}
bool BMX280SensorDevice::begin() bool BMX280SensorDevice::begin() {
{ end();
end(); uint8_t sensortype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
uint8_t sensortype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE); if (sensortype == 0) {
if (sensortype == 0) { log_esp3d("No Sensor active");
log_esp3d("No Sensor active");
return true;
}
if (!isModelValid(sensortype)) {
log_esp3d("No valid id ");
return false;
}
//Setup Wire pins first as lib does setup wire
Wire.begin(ESP_SDA_PIN,ESP_SCL_PIN);
log_esp3d("Starting wire SDA:%d SCL:%d", ESP_SDA_PIN,ESP_SCL_PIN);
bmx280_device = new BMx280I2C(SENSOR_ADDR);
if (!bmx280_device) {
log_esp3d("Cannot instanciate sensor");
return false;
}
if (!bmx280_device->begin()) {
log_esp3d("No valid sensor status");
return false;
}
//reset sensor to default parameters.
bmx280_device->resetToDefaults();
//by default sensing is disabled and must be enabled by setting a non-zero
//oversampling setting.
//set an oversampling setting for pressure and temperature measurements.
bmx280_device->writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280_device->writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//if sensor is a BME280, set an oversampling setting for humidity measurements.
if (bmx280_device->isBME280()) {
bmx280_device->writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
return true; return true;
} }
if (!isModelValid(sensortype)) {
void BMX280SensorDevice::end() log_esp3d_e("No valid id ");
{
if (bmx280_device) {
delete bmx280_device;
}
bmx280_device = nullptr;
}
bool BMX280SensorDevice::isModelValid(uint8_t model)
{
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if (model == SENSOR_ID[i]) {
return true;
}
}
return false; return false;
}
// Setup Wire pins first as lib does setup wire
Wire.begin(ESP_SDA_PIN, ESP_SCL_PIN);
log_esp3d("Starting wire SDA:%d SCL:%d", ESP_SDA_PIN, ESP_SCL_PIN);
bmx280_device = new BMx280I2C(SENSOR_ADDR);
if (!bmx280_device) {
log_esp3d_e("Cannot instanciate sensor");
return false;
}
if (!bmx280_device->begin()) {
log_esp3d("No valid sensor status");
return false;
}
// reset sensor to default parameters.
bmx280_device->resetToDefaults();
// by default sensing is disabled and must be enabled by setting a non-zero
// oversampling setting.
// set an oversampling setting for pressure and temperature measurements.
bmx280_device->writeOversamplingPressure(BMx280MI::OSRS_P_x16);
bmx280_device->writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
// if sensor is a BME280, set an oversampling setting for humidity
// measurements.
if (bmx280_device->isBME280()) {
bmx280_device->writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}
return true;
} }
uint8_t BMX280SensorDevice::getIDFromString(const char *s) void BMX280SensorDevice::end() {
{ if (bmx280_device) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) { delete bmx280_device;
log_esp3d("checking %s with %s",s, SENSOR_NAME[i]); }
if (strcmp(s, SENSOR_NAME[i])==0) { bmx280_device = nullptr;
log_esp3d("found %d",SENSOR_ID[i]); }
return SENSOR_ID[i];
} bool BMX280SensorDevice::isModelValid(uint8_t model) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if (model == SENSOR_ID[i]) {
return true;
} }
}
return 0; return false;
} }
uint8_t BMX280SensorDevice::nbType() uint8_t BMX280SensorDevice::getIDFromString(const char *s) {
{ for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
return NB_TYPE_SENSOR; log_esp3d("checking %s with %s", s, SENSOR_NAME[i]);
} if (strcmp(s, SENSOR_NAME[i]) == 0) {
log_esp3d("found %d", SENSOR_ID[i]);
uint8_t BMX280SensorDevice::GetModel(uint8_t i) return SENSOR_ID[i];
{
if (i <NB_TYPE_SENSOR) {
return SENSOR_ID[i];
} }
return 0; }
return 0;
} }
const char *BMX280SensorDevice::GetCurrentModelString() uint8_t BMX280SensorDevice::nbType() { return NB_TYPE_SENSOR; }
{
uint8_t sensortype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE); uint8_t BMX280SensorDevice::GetModel(uint8_t i) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) { if (i < NB_TYPE_SENSOR) {
return SENSOR_ID[i];
}
return 0;
}
const char *BMX280SensorDevice::GetCurrentModelString() {
uint8_t sensortype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if ((sensortype == SENSOR_TYPE[i]) { if ((sensortype == SENSOR_TYPE[i]) {
return SENSOR_NAME[i]; return SENSOR_NAME[i];
} }
} }
return "NONE"; return "NONE";
} }
const char * BMX280SensorDevice::GetModelString(uint8_t i) const char *BMX280SensorDevice::GetModelString(uint8_t i) {
{ if (i < NB_TYPE_SENSOR) {
if (i <NB_TYPE_SENSOR) {
return SENSOR_NAME[i]; return SENSOR_NAME[i];
} }
return "NONE"; return "NONE";
} }
//helper function // helper function
float toFahrenheit(float fromCelcius) float toFahrenheit(float fromCelcius) { return 1.8 * fromCelcius + 32.0; };
{
return 1.8 * fromCelcius + 32.0;
};
const char * BMX280SensorDevice::GetData() const char *BMX280SensorDevice::GetData() {
{ static String s;
static String s; if (bmx280_device) {
if (bmx280_device) {
if (!bmx280_device->measure()) { if (!bmx280_device->measure()) {
s="BUSY"; s = "BUSY";
log_esp3d("sensor is busy"); log_esp3d("sensor is busy");
} else { } else {
uint8_t nbtry = 0; uint8_t nbtry = 0;
do { do {
log_esp3d("try sensor %d",nbtry); log_esp3d("try sensor %d", nbtry);
Hal::wait(100); Hal::wait(100);
nbtry ++; nbtry++;
} while (!bmx280_device->hasValue() && nbtry < 3); } while (!bmx280_device->hasValue() && nbtry < 3);
if (bmx280_device->hasValue()) { if (bmx280_device->hasValue()) {
float temperature = bmx280_device->getTemperature(); float temperature = bmx280_device->getTemperature();
float pressure = bmx280_device->getPressure(); float pressure = bmx280_device->getPressure();
float humidity=0; float humidity = 0;
if (bmx280_device->isBME280()) { if (bmx280_device->isBME280()) {
humidity = bmx280_device->getHumidity(); humidity = bmx280_device->getHumidity();
}
log_esp3d("T %f P %f H %f",temperature, pressure, humidity);
if ( String(temperature,1)!="nan") {
if (strcmp(SENSOR__UNIT,"F")==0) {
temperature = toFahrenheit(temperature);
}
s= String(temperature,1);
s+= "[";
s+= SENSOR__UNIT;
s+= "] " +String(pressure,1);
s+= "[Pa]";
if (bmx280_device->isBME280()) {
s+=" " + String(humidity,1) + "[%]";
}
} else {
s="DISCONNECTED";
log_esp3d("No valid data");
}
} else {
s="DISCONNECTED";
log_esp3d("No valid data");
} }
log_esp3d("T %f P %f H %f", temperature, pressure, humidity);
if (String(temperature, 1) != "nan") {
if (strcmp(SENSOR__UNIT, "F") == 0) {
temperature = toFahrenheit(temperature);
}
s = String(temperature, 1);
s += "[";
s += SENSOR__UNIT;
s += "] " + String(pressure, 1);
s += "[Pa]";
if (bmx280_device->isBME280()) {
s += " " + String(humidity, 1) + "[%]";
}
} else {
s = "DISCONNECTED";
log_esp3d_e("No valid data");
}
} else {
s = "DISCONNECTED";
log_esp3_ed("No valid data");
}
} }
} else { } else {
s="DISCONNECTED"; s = "DISCONNECTED";
log_esp3d("No device"); log_esp3d_e("No device");
} }
return s.c_str(); return s.c_str();
} }
#endif // BMP280_DEVICE || BME280_DEVICE
#endif //BMP280_DEVICE || BME280_DEVICE #endif // SENSOR_DEVICE
#endif //SENSOR_DEVICE

View File

@ -20,146 +20,134 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
#if SENSOR_DEVICE==DHT11_DEVICE || SENSOR_DEVICE==DHT22_DEVICE #if SENSOR_DEVICE == DHT11_DEVICE || SENSOR_DEVICE == DHT22_DEVICE
#include "dht.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include <DHTesp.h> #include <DHTesp.h>
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "dht.h"
#define NB_TYPE_SENSOR 2 #define NB_TYPE_SENSOR 2
const char * SENSOR_NAME[NB_TYPE_SENSOR] = {"DHT11", "DHT22"}; const char *SENSOR_NAME[NB_TYPE_SENSOR] = {"DHT11", "DHT22"};
const uint8_t SENSOR_ID[NB_TYPE_SENSOR] = {DHT11_DEVICE, DHT22_DEVICE}; const uint8_t SENSOR_ID[NB_TYPE_SENSOR] = {DHT11_DEVICE, DHT22_DEVICE};
const DHTesp::DHT_MODEL_t SENSOR_TYPE[NB_TYPE_SENSOR] = {DHTesp::DHT11, DHTesp::DHT22}; const DHTesp::DHT_MODEL_t SENSOR_TYPE[NB_TYPE_SENSOR] = {DHTesp::DHT11,
DHTesp * dht_device; DHTesp::DHT22};
DHTesp *dht_device;
DHTSensorDevice::DHTSensorDevice() DHTSensorDevice::DHTSensorDevice() { dht_device = nullptr; }
{
dht_device = nullptr;
}
DHTSensorDevice::~DHTSensorDevice() DHTSensorDevice::~DHTSensorDevice() { end(); }
{
end();
}
bool DHTSensorDevice::begin() bool DHTSensorDevice::begin() {
{ end();
end(); uint8_t dhttype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
uint8_t dhttype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE); log_esp3d("Read %d, %s", dhttype,
log_esp3d("Read %d, %s", dhttype, dhttype==1?"DHT11":dhttype==2?"DHT22":dhttype==0?"NONE":"Unknow type"); dhttype == 1 ? "DHT11"
if (dhttype == 0) { : dhttype == 2 ? "DHT22"
log_esp3d("No Sensor active"); : dhttype == 0 ? "NONE"
return true; : "Unknow type");
} if (dhttype == 0) {
if (!isModelValid(dhttype)) { log_esp3d("No Sensor active");
log_esp3d("No valid id ");
return false;
}
dht_device = new DHTesp;
if (!dht_device) {
log_esp3d("Cannot instanciate dht");
return false;
}
log_esp3d("DHT PIN %d",ESP3D_SENSOR_PIN);
dht_device->setup(ESP3D_SENSOR_PIN, (DHTesp::DHT_MODEL_t)dhttype );
if (strcmp(dht_device->getStatusString(), "OK")!=0) {
log_esp3d("No valid dht status: %d, %s",dht_device->getStatus(), dht_device->getStatusString());
return false;
}
log_esp3d("DHT ok");
return true; return true;
} }
if (!isModelValid(dhttype)) {
void DHTSensorDevice::end() log_esp3d_e("No valid id ");
{
if (dht_device) {
delete dht_device;
}
dht_device = nullptr;
}
bool DHTSensorDevice::isModelValid(uint8_t model)
{
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if (model == SENSOR_ID[i]) {
return true;
}
}
return false; return false;
}
dht_device = new DHTesp;
if (!dht_device) {
log_esp3d_e("Cannot instanciate dht");
return false;
}
log_esp3d("DHT PIN %d", ESP3D_SENSOR_PIN);
dht_device->setup(ESP3D_SENSOR_PIN, (DHTesp::DHT_MODEL_t)dhttype);
if (strcmp(dht_device->getStatusString(), "OK") != 0) {
log_esp3d_e("No valid dht status: %d, %s", dht_device->getStatus(),
dht_device->getStatusString());
return false;
}
log_esp3d("DHT ok");
return true;
} }
uint8_t DHTSensorDevice::getIDFromString(const char *s) void DHTSensorDevice::end() {
{ if (dht_device) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) { delete dht_device;
log_esp3d("checking %s with %s",s, SENSOR_NAME[i]); }
if (strcmp(s, SENSOR_NAME[i])==0) { dht_device = nullptr;
log_esp3d("found %d",SENSOR_ID[i]); }
return SENSOR_ID[i];
} bool DHTSensorDevice::isModelValid(uint8_t model) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if (model == SENSOR_ID[i]) {
return true;
} }
}
return 0; return false;
} }
uint8_t DHTSensorDevice::nbType() uint8_t DHTSensorDevice::getIDFromString(const char *s) {
{ for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
return NB_TYPE_SENSOR; log_esp3d("checking %s with %s", s, SENSOR_NAME[i]);
} if (strcmp(s, SENSOR_NAME[i]) == 0) {
log_esp3d("found %d", SENSOR_ID[i]);
uint8_t DHTSensorDevice::GetModel(uint8_t i) return SENSOR_ID[i];
{
if (i <NB_TYPE_SENSOR) {
return SENSOR_ID[i];
} }
return 0; }
return 0;
} }
const char *DHTSensorDevice::GetCurrentModelString() uint8_t DHTSensorDevice::nbType() { return NB_TYPE_SENSOR; }
{
uint8_t dhttype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE); uint8_t DHTSensorDevice::GetModel(uint8_t i) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) { if (i < NB_TYPE_SENSOR) {
if ((DHTesp::DHT_MODEL_t)dhttype == SENSOR_TYPE[i]) { return SENSOR_ID[i];
return SENSOR_NAME[i]; }
} return 0;
}
const char *DHTSensorDevice::GetCurrentModelString() {
uint8_t dhttype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
if ((DHTesp::DHT_MODEL_t)dhttype == SENSOR_TYPE[i]) {
return SENSOR_NAME[i];
} }
return "NONE"; }
return "NONE";
} }
const char * DHTSensorDevice::GetModelString(uint8_t i) const char *DHTSensorDevice::GetModelString(uint8_t i) {
{ if (i < NB_TYPE_SENSOR) {
if (i <NB_TYPE_SENSOR) { return SENSOR_NAME[i];
return SENSOR_NAME[i]; }
return "NONE";
}
const char *DHTSensorDevice::GetData() {
static String s;
if (dht_device) {
float temperature = dht_device->getTemperature();
float humidity = dht_device->getHumidity();
log_esp3d("T %f H %f", temperature, humidity);
if (strcmp(SENSOR__UNIT, "F") == 0) {
temperature = dht_device->toFahrenheit(temperature);
} }
return "NONE"; if (String(humidity, 1) != "nan") {
} s = String(temperature, 1);
s += "[";
const char * DHTSensorDevice::GetData() s += SENSOR__UNIT;
{ s += "] " + String(humidity, 1) + "[%]";
static String s;
if (dht_device) {
float temperature = dht_device->getTemperature();
float humidity= dht_device->getHumidity();
log_esp3d("T %f H %f",temperature, humidity);
if (strcmp(SENSOR__UNIT,"F")==0) {
temperature = dht_device->toFahrenheit(temperature);
}
if ( String(humidity,1)!="nan") {
s= String(temperature,1);
s+= "[";
s+= SENSOR__UNIT;
s+="] " + String(humidity,1) + "[%]";
} else {
s="DISCONNECTED";
log_esp3d("No valid data");
}
} else { } else {
s="DISCONNECTED"; s = "DISCONNECTED";
log_esp3d("No device"); log_esp3d_e("No valid data");
} }
return s.c_str(); } else {
s = "DISCONNECTED";
log_esp3d_e("No device");
}
return s.c_str();
} }
#endif // DHT11_DEVICE || DHT22_DEVICE
#endif //DHT11_DEVICE || DHT22_DEVICE #endif // SENSOR_DEVICE
#endif //SENSOR_DEVICE

View File

@ -20,166 +20,148 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
#include "sensor.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h" #include "../../core/esp3doutput.h"
//Include file according sensor #include "../../core/settings_esp3d.h"
#if SENSOR_DEVICE==DHT11_DEVICE || SENSOR_DEVICE==DHT22_DEVICE #include "sensor.h"
#include "dht.h"
#endif //DHT11_DEVICE || DHT22_DEVICE
#if SENSOR_DEVICE==ANALOG_DEVICE
#include "analogsensor.h"
#endif //ANALOG_DEVICE
#if SENSOR_DEVICE==BMP280_DEVICE || SENSOR_DEVICE==BME280_DEVICE
#include "bmx280.h"
#endif //BMP280_DEVICE || BME280_DEVICE
#if defined (WIFI_FEATURE) || defined(ETH_FEATURE) // Include file according sensor
#if SENSOR_DEVICE == DHT11_DEVICE || SENSOR_DEVICE == DHT22_DEVICE
#include "dht.h"
#endif // DHT11_DEVICE || DHT22_DEVICE
#if SENSOR_DEVICE == ANALOG_DEVICE
#include "analogsensor.h"
#endif // ANALOG_DEVICE
#if SENSOR_DEVICE == BMP280_DEVICE || SENSOR_DEVICE == BME280_DEVICE
#include "bmx280.h"
#endif // BMP280_DEVICE || BME280_DEVICE
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
#include "../websocket/websocket_server.h" #include "../websocket/websocket_server.h"
#endif // WIFI_FEATURE || ETH_FEATURE #endif // WIFI_FEATURE || ETH_FEATURE
ESP3DSensor esp3d_sensor; ESP3DSensor esp3d_sensor;
ESP3DSensor::ESP3DSensor() ESP3DSensor::ESP3DSensor() {
{ _started = false;
_started = false; _interval = 0;
_interval = 0; _device = nullptr;
_device = nullptr;
} }
ESP3DSensor::~ESP3DSensor() ESP3DSensor::~ESP3DSensor() { end(); }
{
end();
}
bool ESP3DSensor::begin() bool ESP3DSensor::begin() {
{ log_esp3d("Sensor Begin");
log_esp3d("Sensor Begin"); bool res = true;
bool res = true; end();
end(); // new _device
//new _device #if SENSOR_DEVICE == ANALOG_DEVICE
#if SENSOR_DEVICE==ANALOG_DEVICE _device = (ESP3DSensorDevice*)new AnalogSensorDevice();
_device = (ESP3DSensorDevice * )new AnalogSensorDevice(); #endif // ANALOG_DEVICE
#endif //ANALOG_DEVICE #if SENSOR_DEVICE == DHT11_DEVICE || SENSOR_DEVICE == DHT22_DEVICE
#if SENSOR_DEVICE==DHT11_DEVICE || SENSOR_DEVICE==DHT22_DEVICE _device = (ESP3DSensorDevice*)new DHTSensorDevice();
_device = (ESP3DSensorDevice * )new DHTSensorDevice(); #endif // DHT11_DEVICE || DHT22_DEVICE
#endif //DHT11_DEVICE || DHT22_DEVICE #if SENSOR_DEVICE == BMP280_DEVICE || SENSOR_DEVICE == BME280_DEVICE
#if SENSOR_DEVICE==BMP280_DEVICE || SENSOR_DEVICE==BME280_DEVICE _device = (ESP3DSensorDevice*)new BMX280SensorDevice();
_device = (ESP3DSensorDevice * )new BMX280SensorDevice(); #endif // DHT11_DEVICE || DHT22_DEVICE
#endif //DHT11_DEVICE || DHT22_DEVICE if (!_device) {
if (!_device) { log_esp3d_e("No device created");
log_esp3d("No device created");
return false;
}
log_esp3d("Sensor Device created");
uint8_t sensortype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
log_esp3d("Sensor %d", sensortype);
//No Sensor defined - exit is not an error
if (sensortype == 0) {
log_esp3d("Sensor Device is not active at start");
return true;
}
_interval = Settings_ESP3D::read_uint32(ESP_SENSOR_INTERVAL);
if (!_device->begin()) {
res = false;
}
_lastReadTime = millis();
_started = res;
return _started;
}
void ESP3DSensor::end()
{
if (_device) {
delete _device;
_device = nullptr;
}
_started = false;
_interval = 0;
}
uint8_t ESP3DSensor::GetModel(uint8_t i)
{
if (_device) {
return _device->GetModel(i);
} else {
return 0;
}
}
uint8_t ESP3DSensor::nbType()
{
if (_device) {
return _device->nbType();
}
return 0;
}
bool ESP3DSensor::isModelValid(uint8_t model)
{
if (_device) {
return _device->isModelValid(model);
}
return false; return false;
} }
log_esp3d("Sensor Device created");
const char * ESP3DSensor::GetCurrentModelString() uint8_t sensortype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
{ log_esp3d("Sensor %d", sensortype);
if (_device) { // No Sensor defined - exit is not an error
if (sensortype == 0) {
return _device->GetCurrentModelString(); log_esp3d("Sensor Device is not active at start");
}
return "NONE";
}
const char * ESP3DSensor::GetModelString(uint8_t i)
{
if (_device) {
return _device->GetModelString(i);
}
return "NONE";
}
uint8_t ESP3DSensor::getIDFromString(const char * s)
{
if (_device) {
return _device->getIDFromString(s);
}
return 0;
}
bool ESP3DSensor::setInterval(uint interval)
{
_interval = interval;
return true; return true;
}
_interval = Settings_ESP3D::read_uint32(ESP_SENSOR_INTERVAL);
if (!_device->begin()) {
res = false;
}
_lastReadTime = millis();
_started = res;
return _started;
} }
const char * ESP3DSensor::GetData() void ESP3DSensor::end() {
{ if (_device) {
if (_started && _device) { delete _device;
return _device->GetData(); _device = nullptr;
} }
return ""; _started = false;
_interval = 0;
} }
void ESP3DSensor::handle() uint8_t ESP3DSensor::GetModel(uint8_t i) {
{ if (_device) {
if (_interval == 0) { return _device->GetModel(i);
return; } else {
} return 0;
if (_started && _device) { }
if ((millis() - _lastReadTime) > _interval) {
String data = _device->GetData();
_lastReadTime = millis();
#if defined (WIFI_FEATURE) || defined(ETH_FEATURE)
String s = "SENSOR:" + data ;
websocket_terminal_server.pushMSG(s.c_str());
#endif // WIFI_FEATURE || ETH_FEATURE
}
}
} }
#endif //SENSOR_DEVICE uint8_t ESP3DSensor::nbType() {
if (_device) {
return _device->nbType();
}
return 0;
}
bool ESP3DSensor::isModelValid(uint8_t model) {
if (_device) {
return _device->isModelValid(model);
}
return false;
}
const char* ESP3DSensor::GetCurrentModelString() {
if (_device) {
return _device->GetCurrentModelString();
}
return "NONE";
}
const char* ESP3DSensor::GetModelString(uint8_t i) {
if (_device) {
return _device->GetModelString(i);
}
return "NONE";
}
uint8_t ESP3DSensor::getIDFromString(const char* s) {
if (_device) {
return _device->getIDFromString(s);
}
return 0;
}
bool ESP3DSensor::setInterval(uint interval) {
_interval = interval;
return true;
}
const char* ESP3DSensor::GetData() {
if (_started && _device) {
return _device->GetData();
}
return "";
}
void ESP3DSensor::handle() {
if (_interval == 0) {
return;
}
if (_started && _device) {
if ((millis() - _lastReadTime) > _interval) {
String data = _device->GetData();
_lastReadTime = millis();
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE)
String s = "SENSOR:" + data;
websocket_terminal_server.pushMSG(s.c_str());
#endif // WIFI_FEATURE || ETH_FEATURE
}
}
}
#endif // SENSOR_DEVICE

View File

@ -19,34 +19,35 @@
*/ */
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if COMMUNICATION_PROTOCOL == MKS_SERIAL || COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT) #if COMMUNICATION_PROTOCOL == MKS_SERIAL || \
#include "serial_service.h" COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT)
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h" #include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "serial_service.h"
#if COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == MKS_SERIAL
#include "../mks/mks_service.h" #include "../mks/mks_service.h"
#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == MKS_SERIAL
#include "../authentication/authentication_service.h" #include "../authentication/authentication_service.h"
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#define MAX_SERIAL 2 #define MAX_SERIAL 2
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1}; HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#if defined (ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#if defined (CONFIG_IDF_TARGET_ESP32C3) #if defined(CONFIG_IDF_TARGET_ESP32C3)
#define MAX_SERIAL 2 #define MAX_SERIAL 2
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1}; HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
#else #else
#define MAX_SERIAL 3 #define MAX_SERIAL 3
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1, &Serial2}; HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1, &Serial2};
#endif #endif
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
// Serial Parameters
//Serial Parameters
#define ESP_SERIAL_PARAM SERIAL_8N1 #define ESP_SERIAL_PARAM SERIAL_8N1
#define ESP3DSERIAL_RUNNING_PRIORITY 1 #define ESP3DSERIAL_RUNNING_PRIORITY 1
@ -56,492 +57,486 @@ HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1};
SerialService serial_service = SerialService(MAIN_SERIAL); SerialService serial_service = SerialService(MAIN_SERIAL);
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
SerialService serial_bridge_service = SerialService(BRIDGE_SERIAL); SerialService serial_bridge_service = SerialService(BRIDGE_SERIAL);
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
#if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK) #if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK)
TaskHandle_t _hserialtask= nullptr; TaskHandle_t _hserialtask = nullptr;
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
const long SupportedBaudList[] = {9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 921600, 1958400}; const long SupportedBaudList[] = {9600, 19200, 38400, 57600,
74880, 115200, 230400, 250000,
500000, 921600, 1958400};
#define TIMEOUT_SERIAL_FLUSH 1500 #define TIMEOUT_SERIAL_FLUSH 1500
//Constructor // Constructor
SerialService::SerialService(uint8_t id) SerialService::SerialService(uint8_t id) {
{ _buffer_size = 0;
_buffer_size = 0; _started = false;
_started = false; _needauthentication = true;
_needauthentication = true; _id = id;
_id = id; switch (_id) {
switch (_id) {
case MAIN_SERIAL: case MAIN_SERIAL:
_rxPin = ESP_RX_PIN; _rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN; _txPin = ESP_TX_PIN;
_client=ESP_SERIAL_CLIENT; _client = ESP_SERIAL_CLIENT;
break; break;
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
case BRIDGE_SERIAL: case BRIDGE_SERIAL:
_rxPin = ESP_BRIDGE_RX_PIN; _rxPin = ESP_BRIDGE_RX_PIN;
_txPin = ESP_BRIDGE_TX_PIN; _txPin = ESP_BRIDGE_TX_PIN;
_client=ESP_SERIAL_BRIDGE_CLIENT; _client = ESP_SERIAL_BRIDGE_CLIENT;
break; break;
#endif //ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
default: default:
_rxPin = ESP_RX_PIN; _rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN; _txPin = ESP_TX_PIN;
_client=ESP_SERIAL_CLIENT; _client = ESP_SERIAL_CLIENT;
break; break;
} }
} }
//Destructor // Destructor
SerialService::~SerialService() SerialService::~SerialService() { end(); }
{
end();
}
//dedicated serial task // dedicated serial task
#if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK) #if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK)
void ESP3DSerialTaskfn( void * parameter ) void ESP3DSerialTaskfn(void *parameter) {
{ for (;;) {
for(;;) { serial_service.process();
serial_service.process(); Hal::wait(SERIAL_YIELD); // Yield to other tasks
Hal::wait(SERIAL_YIELD); // Yield to other tasks }
} vTaskDelete(NULL);
vTaskDelete( NULL );
} }
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
//extra parameters that do not need a begin // extra parameters that do not need a begin
void SerialService::setParameters() void SerialService::setParameters() {
{ #if defined(AUTHENTICATION_FEATURE)
#if defined (AUTHENTICATION_FEATURE) _needauthentication =
_needauthentication = (Settings_ESP3D::read_byte (ESP_SECURE_SERIAL)==0)?false:true; (Settings_ESP3D::read_byte(ESP_SECURE_SERIAL) == 0) ? false : true;
#else #else
_needauthentication = false; _needauthentication = false;
#endif //AUTHENTICATION_FEATURE #endif // AUTHENTICATION_FEATURE
} }
//Setup Serial // Setup Serial
bool SerialService::begin(uint8_t serialIndex) bool SerialService::begin(uint8_t serialIndex) {
{ _serialIndex = serialIndex - 1;
_serialIndex = serialIndex-1; log_esp3d("Serial %d begin for %d", _serialIndex, _id);
log_esp3d("Serial %d begin for %d", _serialIndex, _id); if (_id == BRIDGE_SERIAL &&
if (_id== BRIDGE_SERIAL && Settings_ESP3D::read_byte(ESP_SERIAL_BRIDGE_ON)==0) { Settings_ESP3D::read_byte(ESP_SERIAL_BRIDGE_ON) == 0) {
log_esp3d("Serial %d for %d is disabled", _serialIndex, _id); log_esp3d("Serial %d for %d is disabled", _serialIndex, _id);
return true;
}
if(_serialIndex >= MAX_SERIAL) {
log_esp3d("Serial %d begin for %d failed, index out of range", _serialIndex, _id);
return false;
}
_lastflush = millis();
//read from settings
long br = 0;
long defaultBr = 0;
switch (_id) {
case MAIN_SERIAL:
br = Settings_ESP3D::read_uint32(ESP_BAUD_RATE);
defaultBr = Settings_ESP3D::get_default_int32_value(ESP_BAUD_RATE);
break;
#if defined(ESP_SERIAL_BRIDGE_OUTPUT)
case BRIDGE_SERIAL:
br = Settings_ESP3D::read_uint32(ESP_SERIAL_BRIDGE_BAUD);
defaultBr = Settings_ESP3D::get_default_int32_value(ESP_SERIAL_BRIDGE_BAUD);
break;
#endif //ESP_SERIAL_BRIDGE_OUTPUT
default:
log_esp3d("Serial %d begin for %d failed, unknown id", _serialIndex, _id);
return false;
}
setParameters();
log_esp3d("Baud rate is %d , default is %d",br, defaultBr);
_buffer_size = 0;
//change only if different from current
if (br != baudRate() || (_rxPin != -1) || (_txPin != -1)) {
if ( !is_valid_baudrate(br)) {
br = defaultBr;
}
Serials[_serialIndex]->setRxBufferSize (SERIAL_RX_BUFFER_SIZE);
#ifdef ARDUINO_ARCH_ESP8266
Serials[_serialIndex]->begin(br, ESP_SERIAL_PARAM, SERIAL_FULL, (_txPin == -1)?1:_txPin);
if (_rxPin != -1) {
Serials[_serialIndex]->pins((_txPin == -1)?1:_txPin, _rxPin);
}
#endif //ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
Serials[_serialIndex]->begin (br, ESP_SERIAL_PARAM, ESP_RX_PIN, ESP_TX_PIN);
#if defined(SERIAL_INDEPENDANT_TASK)
//create serial task once
log_esp3d("Serial %d for %d Task creation", _serialIndex,_id);
if (_hserialtask == nullptr && _id==MAIN_SERIAL) {
xTaskCreatePinnedToCore(
ESP3DSerialTaskfn, /* Task function. */
"ESP3D Serial Task", /* name of task. */
8192, /* Stack size of task */
NULL, /* parameter of the task */
ESP3DSERIAL_RUNNING_PRIORITY, /* priority of the task */
&_hserialtask, /* Task handle to keep track of created task */
ESP3DSERIAL_RUNNING_CORE /* Core to run the task */
);
}
if (_hserialtask == nullptr) {
log_esp3d("Serial %d for %d Task creation failed",_serialIndex, _id);
return false;
}
#endif //SERIAL_INDEPENDANT_TASK
#endif //ARDUINO_ARCH_ESP32
}
_started = true;
log_esp3d("Serial %d for %d is started", _serialIndex, _id);
return true; return true;
} }
//End serial if (_serialIndex >= MAX_SERIAL) {
bool SerialService::end() log_esp3d_e("Serial %d begin for %d failed, index out of range",
{ _serialIndex, _id);
flush();
delay (100);
swap();
Serials[_serialIndex]->end();
_buffer_size = 0;
_started = false;
return true;
}
//return the array of long and array size
const long * SerialService::get_baudratelist(uint8_t * count)
{
if (count) {
*count = sizeof(SupportedBaudList)/sizeof(long);
}
return SupportedBaudList;
}
//check if value is in baudrate list
bool SerialService::is_valid_baudrate(long br)
{
uint8_t listesize = sizeof(SupportedBaudList)/sizeof(long);
for (uint8_t i = 0; i < listesize ; i++) {
if (SupportedBaudList[i] == br) {
return true;
}
}
return false; return false;
}
_lastflush = millis();
// read from settings
long br = 0;
long defaultBr = 0;
switch (_id) {
case MAIN_SERIAL:
br = Settings_ESP3D::read_uint32(ESP_BAUD_RATE);
defaultBr = Settings_ESP3D::get_default_int32_value(ESP_BAUD_RATE);
break;
#if defined(ESP_SERIAL_BRIDGE_OUTPUT)
case BRIDGE_SERIAL:
br = Settings_ESP3D::read_uint32(ESP_SERIAL_BRIDGE_BAUD);
defaultBr =
Settings_ESP3D::get_default_int32_value(ESP_SERIAL_BRIDGE_BAUD);
break;
#endif // ESP_SERIAL_BRIDGE_OUTPUT
default:
log_esp3d_e("Serial %d begin for %d failed, unknown id", _serialIndex,
_id);
return false;
}
setParameters();
log_esp3d("Baud rate is %d , default is %d", br, defaultBr);
_buffer_size = 0;
// change only if different from current
if (br != baudRate() || (_rxPin != -1) || (_txPin != -1)) {
if (!is_valid_baudrate(br)) {
br = defaultBr;
}
Serials[_serialIndex]->setRxBufferSize(SERIAL_RX_BUFFER_SIZE);
#ifdef ARDUINO_ARCH_ESP8266
Serials[_serialIndex]->begin(br, ESP_SERIAL_PARAM, SERIAL_FULL,
(_txPin == -1) ? 1 : _txPin);
if (_rxPin != -1) {
Serials[_serialIndex]->pins((_txPin == -1) ? 1 : _txPin, _rxPin);
}
#endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
Serials[_serialIndex]->begin(br, ESP_SERIAL_PARAM, ESP_RX_PIN, ESP_TX_PIN);
#if defined(SERIAL_INDEPENDANT_TASK)
// create serial task once
log_esp3d("Serial %d for %d Task creation", _serialIndex, _id);
if (_hserialtask == nullptr && _id == MAIN_SERIAL) {
xTaskCreatePinnedToCore(
ESP3DSerialTaskfn, /* Task function. */
"ESP3D Serial Task", /* name of task. */
8192, /* Stack size of task */
NULL, /* parameter of the task */
ESP3DSERIAL_RUNNING_PRIORITY, /* priority of the task */
&_hserialtask, /* Task handle to keep track of created task */
ESP3DSERIAL_RUNNING_CORE /* Core to run the task */
);
}
if (_hserialtask == nullptr) {
log_esp3d_e("Serial %d for %d Task creation failed", _serialIndex, _id);
return false;
}
#endif // SERIAL_INDEPENDANT_TASK
#endif // ARDUINO_ARCH_ESP32
}
_started = true;
log_esp3d("Serial %d for %d is started", _serialIndex, _id);
return true;
}
// End serial
bool SerialService::end() {
flush();
delay(100);
swap();
Serials[_serialIndex]->end();
_buffer_size = 0;
_started = false;
return true;
} }
//Function which could be called in other loop // return the array of long and array size
void SerialService::process() const long *SerialService::get_baudratelist(uint8_t *count) {
{ if (count) {
if (!_started) { *count = sizeof(SupportedBaudList) / sizeof(long);
return; }
} return SupportedBaudList;
//Do we have some data waiting
size_t len = available();
if (len > 0) {
//if yes read them
log_esp3d("Got %d chars in serial", len);
uint8_t * sbuf = (uint8_t *)malloc(len);
if(sbuf) {
size_t count = readBytes(sbuf, len);
//push to buffer
if (count > 0) {
push2buffer(sbuf, count);
}
//freen buffer
free(sbuf);
}
}
//we cannot left data in buffer too long
//in case some commands "forget" to add \n
if (((millis() - _lastflush) > TIMEOUT_SERIAL_FLUSH) && (_buffer_size > 0)) {
flushbuffer();
}
} }
//Function which could be called in other loop // check if value is in baudrate list
void SerialService::handle() bool SerialService::is_valid_baudrate(long br) {
{ uint8_t listesize = sizeof(SupportedBaudList) / sizeof(long);
//the serial bridge do not use independant task for (uint8_t i = 0; i < listesize; i++) {
//not sure if it is sill necessary to do it for the main serial if (SupportedBaudList[i] == br) {
//TBC.. return true;
}
}
return false;
}
// Function which could be called in other loop
void SerialService::process() {
if (!_started) {
return;
}
// Do we have some data waiting
size_t len = available();
if (len > 0) {
// if yes read them
log_esp3d("Got %d chars in serial", len);
uint8_t *sbuf = (uint8_t *)malloc(len);
if (sbuf) {
size_t count = readBytes(sbuf, len);
// push to buffer
if (count > 0) {
push2buffer(sbuf, count);
}
// freen buffer
free(sbuf);
}
}
// we cannot left data in buffer too long
// in case some commands "forget" to add \n
if (((millis() - _lastflush) > TIMEOUT_SERIAL_FLUSH) && (_buffer_size > 0)) {
flushbuffer();
}
}
// Function which could be called in other loop
void SerialService::handle() {
// the serial bridge do not use independant task
// not sure if it is sill necessary to do it for the main serial
// TBC..
#if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK) #if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK)
if (_id==MAIN_SERIAL) { if (_id == MAIN_SERIAL) {
return; return;
} }
#endif //ARDUINO_ARCH_ESP32 && SERIAL_INDEPENDANT_TASK0 #endif // ARDUINO_ARCH_ESP32 && SERIAL_INDEPENDANT_TASK0
process(); process();
} }
void SerialService::flushbuffer() void SerialService::flushbuffer() {
{ ESP3DOutput output(_client);
ESP3DOutput output(_client); _buffer[_buffer_size] = 0x0;
_buffer[_buffer_size] = 0x0; // dispatch command
//dispatch command if (_started) {
if (_started) { esp3d_commands.process(_buffer, _buffer_size, &output,
esp3d_commands.process(_buffer, _buffer_size, &output,_needauthentication?LEVEL_GUEST:LEVEL_ADMIN); _needauthentication ? LEVEL_GUEST : LEVEL_ADMIN);
} }
_lastflush = millis(); _lastflush = millis();
_buffer_size = 0; _buffer_size = 0;
} }
//push collected data to buffer and proceed accordingly // push collected data to buffer and proceed accordingly
void SerialService::push2buffer(uint8_t * sbuf, size_t len) void SerialService::push2buffer(uint8_t *sbuf, size_t len) {
{ if (!_started) {
if (!_started) { return;
return; }
} log_esp3d("buffer get %d data ", len);
log_esp3d("buffer get %d data ", len);
#if COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == MKS_SERIAL
static bool isFrameStarted = false; static bool isFrameStarted = false;
static bool isCommandFrame = false; static bool isCommandFrame = false;
static uint8_t type; static uint8_t type;
//expected size // expected size
static int16_t framePos = -1; static int16_t framePos = -1;
//currently received // currently received
static uint datalen = 0; static uint datalen = 0;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
log_esp3d("Data : %c %x", sbuf[i],sbuf[i]); log_esp3d("Data : %c %x", sbuf[i], sbuf[i]);
framePos++; framePos++;
_lastflush = millis(); _lastflush = millis();
//so frame head was detected // so frame head was detected
if (isFrameStarted) { if (isFrameStarted) {
//checking it is a valid Frame header // checking it is a valid Frame header
if (framePos==1) { if (framePos == 1) {
log_esp3d("type = %x",sbuf[i]); log_esp3d("type = %x", sbuf[i]);
if(MKSService::isFrame(char(sbuf[i]))) { if (MKSService::isFrame(char(sbuf[i]))) {
if (MKSService::isCommand(char(sbuf[i]))) { if (MKSService::isCommand(char(sbuf[i]))) {
isCommandFrame =true; isCommandFrame = true;
log_esp3d("type: Command"); log_esp3d("type: Command");
} else { } else {
log_esp3d("type: other"); log_esp3d("type: other");
type = sbuf[i]; type = sbuf[i];
isCommandFrame =false; isCommandFrame = false;
} }
} else {
log_esp3d("wrong frame type");
isFrameStarted = false;
_buffer_size = 0;
}
} else if ((framePos==2) || (framePos==3)) {
//add size to int
if (framePos==2) {
datalen = sbuf[i];
} else {
datalen += (sbuf[i]<<8);
log_esp3d("Data len: %d", datalen);
if (datalen > (ESP3D_SERIAL_BUFFER_SIZE -5)) {
log_esp3d("Overflow in data len");
isFrameStarted = false;
_buffer_size = 0;
}
}
} else if (MKSService::isTail(char(sbuf[i]))) {
log_esp3d("got tail");
_buffer[_buffer_size]='\0';
log_esp3d("size is %d", _buffer_size);
//let check integrity
if (_buffer_size == datalen) {
log_esp3d("Flushing buffer");
if (isCommandFrame) {
flushbuffer();
} else {
MKSService::handleFrame(type,(const uint8_t*)_buffer, _buffer_size);
}
} else {
log_esp3d("Error in data len");
}
//clear frame infos
_buffer_size = 0;
isFrameStarted = false;
} else {
//it is data
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE -5) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
} else {
log_esp3d("Overflow in data len");
isFrameStarted = false;
_buffer_size = 0;
}
}
} else { } else {
//frame is not started let see if it is a head log_esp3d_e("wrong frame type");
if (MKSService::isHead(char(sbuf[i]))) { isFrameStarted = false;
log_esp3d("got head"); _buffer_size = 0;
//yes it is
isFrameStarted = true;
framePos =0;
_buffer_size = 0;
} else {
//no so let reset all and just ignore it
//TODO should we handle these data ?
log_esp3d("Unidentified data : %c %x", sbuf[i],sbuf[i]);
isCommandFrame = false;
framePos = -1;
datalen = 0;
}
} }
} else if ((framePos == 2) || (framePos == 3)) {
// add size to int
if (framePos == 2) {
datalen = sbuf[i];
} else {
datalen += (sbuf[i] << 8);
log_esp3d("Data len: %d", datalen);
if (datalen > (ESP3D_SERIAL_BUFFER_SIZE - 5)) {
log_esp3d_e("Overflow in data len");
isFrameStarted = false;
_buffer_size = 0;
}
}
} else if (MKSService::isTail(char(sbuf[i]))) {
log_esp3d("got tail");
_buffer[_buffer_size] = '\0';
log_esp3d("size is %d", _buffer_size);
// let check integrity
if (_buffer_size == datalen) {
log_esp3d("Flushing buffer");
if (isCommandFrame) {
flushbuffer();
} else {
MKSService::handleFrame(type, (const uint8_t *)_buffer,
_buffer_size);
}
} else {
log_esp3d_e("Error in data len");
}
// clear frame infos
_buffer_size = 0;
isFrameStarted = false;
} else {
// it is data
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE - 5) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
} else {
log_esp3d_e("Overflow in data len");
isFrameStarted = false;
_buffer_size = 0;
}
}
} else {
// frame is not started let see if it is a head
if (MKSService::isHead(char(sbuf[i]))) {
log_esp3d("got head");
// yes it is
isFrameStarted = true;
framePos = 0;
_buffer_size = 0;
} else {
// no so let reset all and just ignore it
// TODO should we handle these data ?
log_esp3d_e("Unidentified data : %c %x", sbuf[i], sbuf[i]);
isCommandFrame = false;
framePos = -1;
datalen = 0;
}
} }
}
#else #else
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
_lastflush = millis(); _lastflush = millis();
//command is defined // command is defined
if ((char(sbuf[i]) == '\n')|| (char(sbuf[i]) == '\r')) { if ((char(sbuf[i]) == '\n') || (char(sbuf[i]) == '\r')) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) { if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i]; _buffer[_buffer_size] = sbuf[i];
_buffer_size++; _buffer_size++;
} }
flushbuffer(); flushbuffer();
} else if (isPrintable (char(sbuf[i]) )) { } else if (isPrintable(char(sbuf[i]))) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) { if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i]; _buffer[_buffer_size] = sbuf[i];
_buffer_size++; _buffer_size++;
} else { } else {
flushbuffer(); flushbuffer();
_buffer[_buffer_size] = sbuf[i]; _buffer[_buffer_size] = sbuf[i];
_buffer_size++; _buffer_size++;
} }
} else { //it is not printable char } else { // it is not printable char
//clean buffer first // clean buffer first
if (_buffer_size > 0) { if (_buffer_size > 0) {
flushbuffer(); flushbuffer();
} }
//process char // process char
_buffer[_buffer_size] = sbuf[i]; _buffer[_buffer_size] = sbuf[i];
_buffer_size++; _buffer_size++;
flushbuffer(); flushbuffer();
}
} }
}
#endif #endif
} }
//Reset Serial Setting (baud rate) // Reset Serial Setting (baud rate)
bool SerialService::reset() bool SerialService::reset() {
{ log_esp3d("Reset serial");
log_esp3d("Reset serial"); bool res = false;
bool res = false; switch (_id) {
switch (_id) {
case MAIN_SERIAL: case MAIN_SERIAL:
return Settings_ESP3D::write_uint32 (ESP_BAUD_RATE, Settings_ESP3D::get_default_int32_value(ESP_BAUD_RATE)); return Settings_ESP3D::write_uint32(
ESP_BAUD_RATE,
Settings_ESP3D::get_default_int32_value(ESP_BAUD_RATE));
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
case BRIDGE_SERIAL: case BRIDGE_SERIAL:
res = Settings_ESP3D::write_byte (ESP_SERIAL_BRIDGE_ON, Settings_ESP3D::get_default_byte_value(ESP_SERIAL_BRIDGE_ON)); res = Settings_ESP3D::write_byte(
return res && Settings_ESP3D::write_uint32 (ESP_SERIAL_BRIDGE_BAUD, Settings_ESP3D::get_default_int32_value(ESP_SERIAL_BRIDGE_BAUD)); ESP_SERIAL_BRIDGE_ON,
#endif //ESP_SERIAL_BRIDGE_OUTPUT Settings_ESP3D::get_default_byte_value(ESP_SERIAL_BRIDGE_ON));
return res && Settings_ESP3D::write_uint32(
ESP_SERIAL_BRIDGE_BAUD,
Settings_ESP3D::get_default_int32_value(
ESP_SERIAL_BRIDGE_BAUD));
#endif // ESP_SERIAL_BRIDGE_OUTPUT
default: default:
return res; return res;
} }
} }
void SerialService::updateBaudRate(long br) void SerialService::updateBaudRate(long br) {
{ if (br != baudRate()) {
if (br!=baudRate()) {
Serials[_serialIndex]->flush();
Serials[_serialIndex]->updateBaudRate(br);
}
}
//Get current baud rate
long SerialService::baudRate()
{
long br = 0;
br = Serials[_serialIndex]->baudRate();
#ifdef ARDUINO_ARCH_ESP32
//workaround for ESP32
if (br == 115201) {
br = 115200;
}
if (br == 230423) {
br = 230400;
}
#endif //ARDUINO_ARCH_ESP32
return br;
}
size_t SerialService::write(uint8_t c)
{
if (!_started) {
return 0;
}
return Serials[_serialIndex]->write(c);
}
size_t SerialService::write(const uint8_t *buffer, size_t size)
{
if (!_started) {
return 0;
}
if ((uint)Serials[_serialIndex]->availableForWrite() >= size) {
return Serials[_serialIndex]->write(buffer, size);
} else {
size_t sizetosend = size;
size_t sizesent = 0;
uint8_t *buffertmp=(uint8_t *)buffer;
uint32_t starttime = millis();
//loop until all is sent or timeout
while (sizetosend>0 && ((millis() - starttime) < 100)) {
size_t available = Serials[_serialIndex]->availableForWrite();
if(available>0) {
//in case less is sent
available = Serials[_serialIndex]->write(&buffertmp[sizesent], (available >= sizetosend)?sizetosend:available);
sizetosend-=available;
sizesent+=available;
starttime=millis();
} else {
Hal::wait(5);
}
}
return sizesent;
}
}
int SerialService::availableForWrite()
{
if (!_started) {
return 0;
}
return Serials[_serialIndex]->availableForWrite();
}
int SerialService::available()
{
if (!_started) {
return 0;
}
return Serials[_serialIndex]->available();
}
int SerialService::read()
{
if (!_started) {
return -1;
}
return Serials[_serialIndex]->read();
}
size_t SerialService::readBytes(uint8_t * sbuf, size_t len)
{
if (!_started) {
return -1;
}
return Serials[_serialIndex]->readBytes(sbuf, len);
}
void SerialService::flush()
{
if (!_started) {
return ;
}
Serials[_serialIndex]->flush(); Serials[_serialIndex]->flush();
Serials[_serialIndex]->updateBaudRate(br);
}
} }
void SerialService::swap() // Get current baud rate
{ long SerialService::baudRate() {
long br = 0;
br = Serials[_serialIndex]->baudRate();
#ifdef ARDUINO_ARCH_ESP32
// workaround for ESP32
if (br == 115201) {
br = 115200;
}
if (br == 230423) {
br = 230400;
}
#endif // ARDUINO_ARCH_ESP32
return br;
}
size_t SerialService::write(uint8_t c) {
if (!_started) {
return 0;
}
return Serials[_serialIndex]->write(c);
}
size_t SerialService::write(const uint8_t *buffer, size_t size) {
if (!_started) {
return 0;
}
if ((uint)Serials[_serialIndex]->availableForWrite() >= size) {
return Serials[_serialIndex]->write(buffer, size);
} else {
size_t sizetosend = size;
size_t sizesent = 0;
uint8_t *buffertmp = (uint8_t *)buffer;
uint32_t starttime = millis();
// loop until all is sent or timeout
while (sizetosend > 0 && ((millis() - starttime) < 100)) {
size_t available = Serials[_serialIndex]->availableForWrite();
if (available > 0) {
// in case less is sent
available = Serials[_serialIndex]->write(
&buffertmp[sizesent],
(available >= sizetosend) ? sizetosend : available);
sizetosend -= available;
sizesent += available;
starttime = millis();
} else {
Hal::wait(5);
}
}
return sizesent;
}
}
int SerialService::availableForWrite() {
if (!_started) {
return 0;
}
return Serials[_serialIndex]->availableForWrite();
}
int SerialService::available() {
if (!_started) {
return 0;
}
return Serials[_serialIndex]->available();
}
int SerialService::read() {
if (!_started) {
return -1;
}
return Serials[_serialIndex]->read();
}
size_t SerialService::readBytes(uint8_t *sbuf, size_t len) {
if (!_started) {
return -1;
}
return Serials[_serialIndex]->readBytes(sbuf, len);
}
void SerialService::flush() {
if (!_started) {
return;
}
Serials[_serialIndex]->flush();
}
void SerialService::swap() {
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
Serials[_serialIndex]->swap(); Serials[_serialIndex]->swap();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }
#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL || COMMUNICATION_PROTOCOL == RAW_SERIAL #endif // COMMUNICATION_PROTOCOL == MKS_SERIAL || COMMUNICATION_PROTOCOL ==
// RAW_SERIAL

View File

@ -18,196 +18,158 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include <Arduino.h> #include <Arduino.h>
#include "serial2socket.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h" #include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "serial2socket.h"
Serial_2_Socket Serial2Socket; Serial_2_Socket Serial2Socket;
Serial_2_Socket::Serial_2_Socket() { end(); }
Serial_2_Socket::~Serial_2_Socket() { end(); }
void Serial_2_Socket::begin(long speed) { end(); }
Serial_2_Socket::Serial_2_Socket() void Serial_2_Socket::enable(bool enable) { _started = enable; }
{
end();
}
Serial_2_Socket::~Serial_2_Socket()
{
end();
}
void Serial_2_Socket::begin(long speed)
{
end();
}
void Serial_2_Socket::enable(bool enable) void Serial_2_Socket::pause(bool state) {
{ _paused = state;
_started = enable; if (_paused) {
}
void Serial_2_Socket::pause(bool state)
{
_paused = state;
if (_paused) {
_TXbufferSize = 0;
_RXbufferSize = 0;
_RXbufferpos = 0;
} else {
_lastflush = millis();
}
}
bool Serial_2_Socket::isPaused()
{
return _paused;
}
void Serial_2_Socket::end()
{
_TXbufferSize = 0; _TXbufferSize = 0;
_RXbufferSize = 0; _RXbufferSize = 0;
_RXbufferpos = 0; _RXbufferpos = 0;
_started = false; } else {
_paused = false;
_lastflush = millis(); _lastflush = millis();
}
} }
long Serial_2_Socket::baudRate() bool Serial_2_Socket::isPaused() { return _paused; }
{
void Serial_2_Socket::end() {
_TXbufferSize = 0;
_RXbufferSize = 0;
_RXbufferpos = 0;
_started = false;
_paused = false;
_lastflush = millis();
}
long Serial_2_Socket::baudRate() { return 0; }
bool Serial_2_Socket::started() { return _started; }
Serial_2_Socket::operator bool() const { return true; }
int Serial_2_Socket::available() {
if (_paused) {
return 0; return 0;
}
return _RXbufferSize;
} }
bool Serial_2_Socket::started() size_t Serial_2_Socket::write(uint8_t c) {
{ if (!_started || _paused) {
return _started; return 1;
}
return write(&c, 1);
} }
Serial_2_Socket::operator bool() const size_t Serial_2_Socket::write(const uint8_t *buffer, size_t size) {
{ if (buffer == NULL || size == 0 || !_started || _paused) {
return true; log_esp3d("Serial2Socket: no data, not started or paused");
}
int Serial_2_Socket::available()
{
if (_paused) {
return 0;
}
return _RXbufferSize;
}
size_t Serial_2_Socket::write(uint8_t c)
{
if (!_started || _paused) {
return 1;
}
return write(&c,1);
}
size_t Serial_2_Socket::write(const uint8_t *buffer, size_t size)
{
if(buffer == NULL || size == 0 || !_started || _paused) {
log_esp3d("Serial2Socket: no data, not started or paused");
return size;
}
if (_TXbufferSize==0) {
_lastflush = millis();
}
//send full line
if (_TXbufferSize + size > S2S_TXBUFFERSIZE) {
flush();
}
//need periodic check to force to flush in case of no end
for (int i = 0; i < size; i++) {
_TXbuffer[_TXbufferSize] = buffer[i];
_TXbufferSize++;
if (buffer[i] == (const uint8_t)'\n'|| buffer[i] == (const uint8_t)'\r') {
log_esp3d("S2S: %s TXSize: %d", (const char *)_TXbuffer, _TXbufferSize);
flush();
}
}
handle_flush();
return size; return size;
}
if (_TXbufferSize == 0) {
_lastflush = millis();
}
// send full line
if (_TXbufferSize + size > S2S_TXBUFFERSIZE) {
flush();
}
// need periodic check to force to flush in case of no end
for (int i = 0; i < size; i++) {
_TXbuffer[_TXbufferSize] = buffer[i];
_TXbufferSize++;
if (buffer[i] == (const uint8_t)'\n' || buffer[i] == (const uint8_t)'\r') {
log_esp3d("S2S: %s TXSize: %d", (const char *)_TXbuffer, _TXbufferSize);
flush();
}
}
handle_flush();
return size;
} }
int Serial_2_Socket::peek(void) int Serial_2_Socket::peek(void) {
{ if (_RXbufferSize > 0 && _started) {
if (_RXbufferSize > 0 && _started) { return _RXbuffer[_RXbufferpos];
return _RXbuffer[_RXbufferpos]; } else {
} else { return -1;
return -1; }
}
} }
bool Serial_2_Socket::push (const uint8_t *buffer, size_t size) bool Serial_2_Socket::push(const uint8_t *buffer, size_t size) {
{ if (buffer == NULL || size == 0 || !_started || _paused) {
if (buffer == NULL || size == 0 || !_started || _paused) {
return false;
}
int data_size = size;
if ((data_size + _RXbufferSize) <= S2S_RXBUFFERSIZE) {
int current = _RXbufferpos + _RXbufferSize;
if (current > S2S_RXBUFFERSIZE) {
current = current - S2S_RXBUFFERSIZE;
}
for (int i = 0; i < data_size; i++) {
if (current > (S2S_RXBUFFERSIZE-1)) {
current = 0;
}
_RXbuffer[current] = buffer[i];
current ++;
}
_RXbufferSize+=size;
_RXbuffer[current] = 0;
return true;
}
return false; return false;
} }
int data_size = size;
int Serial_2_Socket::read(void) if ((data_size + _RXbufferSize) <= S2S_RXBUFFERSIZE) {
{ int current = _RXbufferpos + _RXbufferSize;
if (_RXbufferSize > 0 && _started && !_paused) { if (current > S2S_RXBUFFERSIZE) {
int v = _RXbuffer[_RXbufferpos]; current = current - S2S_RXBUFFERSIZE;
_RXbufferpos++;
if (_RXbufferpos > (S2S_RXBUFFERSIZE-1)) {
_RXbufferpos = 0;
}
_RXbufferSize--;
return v;
} else {
return -1;
} }
for (int i = 0; i < data_size; i++) {
} if (current > (S2S_RXBUFFERSIZE - 1)) {
current = 0;
void Serial_2_Socket::handle() }
{ _RXbuffer[current] = buffer[i];
handle_flush(); current++;
}
void Serial_2_Socket::handle_flush()
{
if (_TXbufferSize > 0 && _started && !_paused) {
if ((_TXbufferSize>=S2S_TXBUFFERSIZE) || ((millis()- _lastflush) > S2S_FLUSHTIMEOUT)) {
log_esp3d("force socket flush");
flush();
}
}
}
void Serial_2_Socket::flush(void)
{
if (_TXbufferSize > 0 && _started && !_paused) {
ESP3DOutput output(ESP_SOCKET_SERIAL_CLIENT);
//dispatch command
esp3d_commands.process(_TXbuffer,_TXbufferSize, &output);
//refresh timout
_lastflush = millis();
//reset buffer
_TXbufferSize = 0;
} }
_RXbufferSize += size;
_RXbuffer[current] = 0;
return true;
}
return false;
} }
#endif // ESP3DLIB_ENV int Serial_2_Socket::read(void) {
if (_RXbufferSize > 0 && _started && !_paused) {
int v = _RXbuffer[_RXbufferpos];
_RXbufferpos++;
if (_RXbufferpos > (S2S_RXBUFFERSIZE - 1)) {
_RXbufferpos = 0;
}
_RXbufferSize--;
return v;
} else {
return -1;
}
}
void Serial_2_Socket::handle() { handle_flush(); }
void Serial_2_Socket::handle_flush() {
if (_TXbufferSize > 0 && _started && !_paused) {
if ((_TXbufferSize >= S2S_TXBUFFERSIZE) ||
((millis() - _lastflush) > S2S_FLUSHTIMEOUT)) {
log_esp3d("force socket flush");
flush();
}
}
}
void Serial_2_Socket::flush(void) {
if (_TXbufferSize > 0 && _started && !_paused) {
ESP3DOutput output(ESP_SOCKET_SERIAL_CLIENT);
// dispatch command
esp3d_commands.process(_TXbuffer, _TXbufferSize, &output);
// refresh timout
_lastflush = millis();
// reset buffer
_TXbufferSize = 0;
}
}
#endif // ESP3DLIB_ENV

View File

@ -164,7 +164,7 @@ bool TimeServer::setTime(const char* stime) {
log_esp3d("Invalid time format, try without seconds"); log_esp3d("Invalid time format, try without seconds");
// allow not to set seconds for lazy guys typing command line // allow not to set seconds for lazy guys typing command line
if (strptime(stime, "%Y-%m-%dT%H:%M", &tmstruct) == nullptr) { if (strptime(stime, "%Y-%m-%dT%H:%M", &tmstruct) == nullptr) {
log_esp3d("Invalid time format"); log_esp3d_e("Invalid time format");
return false; return false;
} }
} }

View File

@ -21,255 +21,245 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SD_UPDATE_FEATURE #ifdef SD_UPDATE_FEATURE
#include "esp_config_file.h"
#include "../filesystem/esp_sd.h" #include "../filesystem/esp_sd.h"
#include "esp_config_file.h"
#define LINE_MAX_SIZE 255 #define LINE_MAX_SIZE 255
#define SECTION_MAX_SIZE 10 #define SECTION_MAX_SIZE 10
#define KEY_MAX_SIZE 30 #define KEY_MAX_SIZE 30
#define VALUE_MAX_SIZE 128 #define VALUE_MAX_SIZE 128
const char * protectedkeys[] = {"NOTIF_TOKEN1","NOTIF_TOKEN2","AP_Password","STA_Password","ADMIN_PASSWORD","USER_PASSWORD"} ; const char *protectedkeys[] = {"NOTIF_TOKEN1", "NOTIF_TOKEN2",
"AP_Password", "STA_Password",
"ADMIN_PASSWORD", "USER_PASSWORD"};
ESP_ConfigFile::ESP_ConfigFile(const char * path, TProcessingFunction fn) ESP_ConfigFile::ESP_ConfigFile(const char *path, TProcessingFunction fn) {
{ _filename = (char *)malloc(strlen(path) + 1);
_filename = (char *)malloc(strlen(path)+1); strcpy(_filename, path);
strcpy(_filename, path); _pfunction = fn;
_pfunction = fn;
} }
bool ESP_ConfigFile::processFile() bool ESP_ConfigFile::processFile() {
{ bool res = true;
bool res = true; if (!ESP_SD::exists(_filename)) {
if (!ESP_SD::exists(_filename)) { log_esp3d_e("No ini file");
log_esp3d("No ini file");
return false;
}
ESP_SDFile rFile = ESP_SD::open(_filename);
if (rFile) {
bool processing = true;
char line[LINE_MAX_SIZE+1];
char section[SECTION_MAX_SIZE+1]; //system / network / services
char key[KEY_MAX_SIZE+1];
uint8_t pos = 0;
line[0] = '\0';
section[0]='\0';
while (processing) {
//to handle file without endline
processing = rFile.available();
char c = '\0';
if (processing) {
c = (char)rFile.read();
if (!((c =='\n') || (c =='\r')) && (pos<(LINE_MAX_SIZE-1))) {
line[pos] = c;
pos++;
}
}
if ((c =='\n') || (c =='\r') || !processing || (pos==(LINE_MAX_SIZE-1))) {
line[pos] = '\0';
char * stmp = trimSpaces(line);
if(strlen(stmp)>0) {
//is comment ?
if (!isComment(stmp)) {
//is section ?
if(isSection(stmp)) {
strcpy(section,getSectionName(stmp));
} else {
//is key + value?
if (isValue(stmp) && strlen(section)>0) {
strcpy(key,getKeyName(stmp));
if(_pfunction) {
if(!_pfunction(section, key, getValue(stmp))) {
res=false;
}
}
}
}
}
}
pos = 0;
line[pos] = '\0';
}
}
rFile.close();
return res;
}
log_esp3d("Cannot open ini file");
return false; return false;
} }
ESP_SDFile rFile = ESP_SD::open(_filename);
bool ESP_ConfigFile::isComment(char * line) if (rFile) {
{ bool processing = true;
if (strlen(line) > 0) { char line[LINE_MAX_SIZE + 1];
if((line[0]==';') || (line[0]=='#')) { char section[SECTION_MAX_SIZE + 1]; // system / network / services
return true; char key[KEY_MAX_SIZE + 1];
uint8_t pos = 0;
line[0] = '\0';
section[0] = '\0';
while (processing) {
// to handle file without endline
processing = rFile.available();
char c = '\0';
if (processing) {
c = (char)rFile.read();
if (!((c == '\n') || (c == '\r')) && (pos < (LINE_MAX_SIZE - 1))) {
line[pos] = c;
pos++;
} }
} }
return false; if ((c == '\n') || (c == '\r') || !processing ||
} (pos == (LINE_MAX_SIZE - 1))) {
line[pos] = '\0';
bool ESP_ConfigFile::isSection(char * line) char *stmp = trimSpaces(line);
{ if (strlen(stmp) > 0) {
if (strlen(line) > 0) { // is comment ?
if((line[0]=='[') && (line[strlen(line)-1]==']')) { if (!isComment(stmp)) {
return true; // is section ?
} if (isSection(stmp)) {
} strcpy(section, getSectionName(stmp));
return false; } else {
} // is key + value?
if (isValue(stmp) && strlen(section) > 0) {
bool ESP_ConfigFile::isValue(char * line) strcpy(key, getKeyName(stmp));
{ if (_pfunction) {
if (strlen(line) > 3) { if (!_pfunction(section, key, getValue(stmp))) {
for(uint8_t i = 1; i < strlen(line)-2; i++) { res = false;
if(line[i]=='=') { }
return true;
}
}
}
return false;
}
char * ESP_ConfigFile::getSectionName(char * line)
{
line[strlen(line)-1]='\0';
return trimSpaces(&line[1],SECTION_MAX_SIZE);
}
char * ESP_ConfigFile::getKeyName(char * line)
{
for(uint8_t i = 0; i < strlen(line); i++) {
if (line[i]=='=') {
line[i]='\0';
return trimSpaces(line,KEY_MAX_SIZE);
}
}
return NULL;
}
char * ESP_ConfigFile::getValue(char * line)
{
char * startptr = line + strlen(line)+1;
while ( * startptr == '\0') {
startptr++;
}
return trimSpaces(startptr,VALUE_MAX_SIZE);
}
char * ESP_ConfigFile::trimSpaces(char * line, uint8_t maxsize)
{
char *endptr = line + strlen(line) - 1;
char * startptr = line;
while (endptr >= line && isspace(*endptr)) {
*endptr-- = '\0';
}
endptr = line + strlen(line) - 1;
while (endptr != startptr && isspace(*startptr)) {
startptr++;
}
if((maxsize>0) && (strlen(startptr)> maxsize)) {
startptr[maxsize]='\0';
}
return startptr;
}
ESP_ConfigFile::~ESP_ConfigFile()
{
free(_filename);
}
bool ESP_ConfigFile::isScrambleKey(const char *key, const char * str)
{
if (strlen(key)>strlen(str)) {
return false;
}
for(uint8_t p = 0; p< strlen(str) ; p++) {
if (p <strlen(key)) {
if(key[p]!=str[p]) {
return false;
}
} else {
if (str[p]!=' ') {
if (str[p]=='=') {
return true;
} else {
return false;
} }
}
} }
}
} }
pos = 0;
line[pos] = '\0';
}
} }
rFile.close();
return false; return res;
}
log_esp3d_e("Cannot open ini file");
return false;
} }
bool ESP_ConfigFile::revokeFile() bool ESP_ConfigFile::isComment(char *line) {
{ if (strlen(line) > 0) {
char * filename; if ((line[0] == ';') || (line[0] == '#')) {
if (!ESP_SD::exists(_filename)) { return true;
log_esp3d("No ini file to revoke");
return false;
} }
filename = (char *)malloc(strlen(_filename)+1); }
strcpy(filename, _filename); return false;
filename[strlen(filename)-3]='o'; }
filename[strlen(filename)-2]='k';
filename[strlen(filename)-1]='\0'; bool ESP_ConfigFile::isSection(char *line) {
ESP_SD::remove(filename); if (strlen(line) > 0) {
ESP_SDFile wFile = ESP_SD::open(filename, ESP_FILE_WRITE); if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) {
ESP_SDFile rFile = ESP_SD::open(_filename); return true;
free(filename); }
if (wFile && rFile) { }
bool processing = true; return false;
char line[LINE_MAX_SIZE+1]; }
uint8_t pos = 0;
line[0] = '\0'; bool ESP_ConfigFile::isValue(char *line) {
while (processing) { if (strlen(line) > 3) {
processing = rFile.available(); for (uint8_t i = 1; i < strlen(line) - 2; i++) {
char c = '\0'; if (line[i] == '=') {
if (processing) {
c = (char)rFile.read();
if (!((c =='\n') || (c =='\r')) && (pos<(LINE_MAX_SIZE-1))) {
line[pos] = c;
pos++;
}
}
if ((c =='\n') || (c =='\r') || !processing || (pos==(LINE_MAX_SIZE-1))) {
line[pos] = '\0';
char * stmp = trimSpaces(line);
if (strlen(stmp) > 0 ) {
if(sizeof(protectedkeys) > 0) {
bool foundscramble = false;
uint8_t size = sizeof(protectedkeys)/sizeof(char*);
for(uint8_t i = 0; (i < size) && !foundscramble; i++) {
if (isScrambleKey(protectedkeys[i],stmp)) {
strcpy(line, protectedkeys[i]);
strcat(line, "=********");
stmp = line;
foundscramble = true;
}
}
}
wFile.write((const uint8_t *)stmp, strlen(stmp));
wFile.write('\r');
wFile.write('\n');
}
pos = 0;
line[pos] = '\0';
}
}
wFile.close();
rFile.close();
ESP_SD::remove(_filename);
return true; return true;
}
} }
log_esp3d("Cannot open / create revoked file"); }
if (wFile ) { return false;
wFile.close();
}
if (rFile ) {
rFile.close();
}
return false;
} }
#endif //SD_UPDATE_FEATURE char *ESP_ConfigFile::getSectionName(char *line) {
line[strlen(line) - 1] = '\0';
return trimSpaces(&line[1], SECTION_MAX_SIZE);
}
char *ESP_ConfigFile::getKeyName(char *line) {
for (uint8_t i = 0; i < strlen(line); i++) {
if (line[i] == '=') {
line[i] = '\0';
return trimSpaces(line, KEY_MAX_SIZE);
}
}
return NULL;
}
char *ESP_ConfigFile::getValue(char *line) {
char *startptr = line + strlen(line) + 1;
while (*startptr == '\0') {
startptr++;
}
return trimSpaces(startptr, VALUE_MAX_SIZE);
}
char *ESP_ConfigFile::trimSpaces(char *line, uint8_t maxsize) {
char *endptr = line + strlen(line) - 1;
char *startptr = line;
while (endptr >= line && isspace(*endptr)) {
*endptr-- = '\0';
}
endptr = line + strlen(line) - 1;
while (endptr != startptr && isspace(*startptr)) {
startptr++;
}
if ((maxsize > 0) && (strlen(startptr) > maxsize)) {
startptr[maxsize] = '\0';
}
return startptr;
}
ESP_ConfigFile::~ESP_ConfigFile() { free(_filename); }
bool ESP_ConfigFile::isScrambleKey(const char *key, const char *str) {
if (strlen(key) > strlen(str)) {
return false;
}
for (uint8_t p = 0; p < strlen(str); p++) {
if (p < strlen(key)) {
if (key[p] != str[p]) {
return false;
}
} else {
if (str[p] != ' ') {
if (str[p] == '=') {
return true;
} else {
return false;
}
}
}
}
return false;
}
bool ESP_ConfigFile::revokeFile() {
char *filename;
if (!ESP_SD::exists(_filename)) {
log_esp3d("No ini file to revoke");
return false;
}
filename = (char *)malloc(strlen(_filename) + 1);
strcpy(filename, _filename);
filename[strlen(filename) - 3] = 'o';
filename[strlen(filename) - 2] = 'k';
filename[strlen(filename) - 1] = '\0';
ESP_SD::remove(filename);
ESP_SDFile wFile = ESP_SD::open(filename, ESP_FILE_WRITE);
ESP_SDFile rFile = ESP_SD::open(_filename);
free(filename);
if (wFile && rFile) {
bool processing = true;
char line[LINE_MAX_SIZE + 1];
uint8_t pos = 0;
line[0] = '\0';
while (processing) {
processing = rFile.available();
char c = '\0';
if (processing) {
c = (char)rFile.read();
if (!((c == '\n') || (c == '\r')) && (pos < (LINE_MAX_SIZE - 1))) {
line[pos] = c;
pos++;
}
}
if ((c == '\n') || (c == '\r') || !processing ||
(pos == (LINE_MAX_SIZE - 1))) {
line[pos] = '\0';
char *stmp = trimSpaces(line);
if (strlen(stmp) > 0) {
if (sizeof(protectedkeys) > 0) {
bool foundscramble = false;
uint8_t size = sizeof(protectedkeys) / sizeof(char *);
for (uint8_t i = 0; (i < size) && !foundscramble; i++) {
if (isScrambleKey(protectedkeys[i], stmp)) {
strcpy(line, protectedkeys[i]);
strcat(line, "=********");
stmp = line;
foundscramble = true;
}
}
}
wFile.write((const uint8_t *)stmp, strlen(stmp));
wFile.write('\r');
wFile.write('\n');
}
pos = 0;
line[pos] = '\0';
}
}
wFile.close();
rFile.close();
ESP_SD::remove(_filename);
return true;
}
log_esp3d_e("Cannot open / create revoked file");
if (wFile) {
wFile.close();
}
if (rFile) {
rFile.close();
}
return false;
}
#endif // SD_UPDATE_FEATURE

View File

@ -20,21 +20,21 @@
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#ifdef SD_UPDATE_FEATURE #ifdef SD_UPDATE_FEATURE
#include "update_service.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h" #include "../../core/commands.h"
#include "esp_config_file.h" #include "../../core/esp3doutput.h"
#include "../filesystem/esp_sd.h" #include "../../core/settings_esp3d.h"
#include "../filesystem/esp_filesystem.h" #include "../filesystem/esp_filesystem.h"
#if defined (ARDUINO_ARCH_ESP32) #include "../filesystem/esp_sd.h"
#include "esp_config_file.h"
#include "update_service.h"
#if defined(ARDUINO_ARCH_ESP32)
#include <Update.h> #include <Update.h>
#define U_FS U_SPIFFS #define U_FS U_SPIFFS
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP8266
UpdateService update_service; UpdateService update_service;
@ -42,57 +42,32 @@ UpdateService update_service;
#define FW_FILE "/esp3dfw.bin" #define FW_FILE "/esp3dfw.bin"
#define FS_FILE "/esp3dfs.bin" #define FS_FILE "/esp3dfs.bin"
const char * NetstringKeysVal[] = {"hostname", const char* NetstringKeysVal[] = {"hostname", "STA_SSID", "STA_Password",
"STA_SSID", "AP_SSID", "AP_Password"};
"STA_Password",
"AP_SSID",
"AP_Password"
} ;
const uint16_t NetstringKeysPos[] = {ESP_HOSTNAME, const uint16_t NetstringKeysPos[] = {
ESP_STA_SSID, ESP_HOSTNAME, ESP_STA_SSID, ESP_STA_PASSWORD, ESP_AP_SSID, ESP_AP_PASSWORD};
ESP_STA_PASSWORD,
ESP_AP_SSID,
ESP_AP_PASSWORD
} ;
const char * ServstringKeysVal[] = { const char* ServstringKeysVal[] = {
"Time_server1", "Time_server1", "Time_server2", "Time_server3", "ADMIN_PASSWORD",
"Time_server2", "USER_PASSWORD", "NOTIF_TOKEN1", "NOTIF_TOKEN2", "NOTIF_TOKEN_Settings"};
"Time_server3",
"ADMIN_PASSWORD",
"USER_PASSWORD",
"NOTIF_TOKEN1",
"NOTIF_TOKEN2",
"NOTIF_TOKEN_Settings"
} ;
const uint16_t ServstringKeysPos[] = { const uint16_t ServstringKeysPos[] = {ESP_TIME_SERVER1,
ESP_TIME_SERVER1, ESP_TIME_SERVER2,
ESP_TIME_SERVER2, ESP_TIME_SERVER3,
ESP_TIME_SERVER3, ESP_ADMIN_PWD,
ESP_ADMIN_PWD, ESP_USER_PWD,
ESP_USER_PWD, ESP_NOTIFICATION_TOKEN1,
ESP_NOTIFICATION_TOKEN1, ESP_NOTIFICATION_TOKEN2,
ESP_NOTIFICATION_TOKEN2, ESP_NOTIFICATION_SETTINGS};
ESP_NOTIFICATION_SETTINGS
} ;
const char * IPKeysVal[] = {"STA_IP", const char* IPKeysVal[] = {"STA_IP", "STA_GW", "STA_MSK", "STA_DNS", "AP_IP"};
"STA_GW",
"STA_MSK",
"STA_DNS",
"AP_IP"
} ;
const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE, const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE, ESP_STA_GATEWAY_VALUE,
ESP_STA_GATEWAY_VALUE, ESP_STA_MASK_VALUE, ESP_STA_DNS_VALUE,
ESP_STA_MASK_VALUE, ESP_AP_IP_VALUE};
ESP_STA_DNS_VALUE,
ESP_AP_IP_VALUE
} ;
const char * ServintKeysVal[] = { const char* ServintKeysVal[] = {
"Serial_Bridge_Baud" "Serial_Bridge_Baud"
"HTTP_Port", "HTTP_Port",
"TELNET_Port", "TELNET_Port",
@ -101,65 +76,48 @@ const char * ServintKeysVal[] = {
"WebDav_Port", "WebDav_Port",
"FTP_Control_Port", "FTP_Control_Port",
"FTP_Active_Port ", "FTP_Active_Port ",
"FTP_Passive_Port" "FTP_Passive_Port"};
} ;
const uint16_t ServintKeysPos[] = { const uint16_t ServintKeysPos[] = {
ESP_SERIAL_BRIDGE_BAUD, ESP_SERIAL_BRIDGE_BAUD, ESP_HTTP_PORT,
ESP_HTTP_PORT, ESP_TELNET_PORT, ESP_SENSOR_INTERVAL,
ESP_TELNET_PORT, ESP_WEBSOCKET_PORT, ESP_WEBDAV_PORT,
ESP_SENSOR_INTERVAL, ESP_FTP_CTRL_PORT, ESP_FTP_DATA_ACTIVE_PORT,
ESP_WEBSOCKET_PORT, ESP_FTP_DATA_PASSIVE_PORT};
ESP_WEBDAV_PORT,
ESP_FTP_CTRL_PORT,
ESP_FTP_DATA_ACTIVE_PORT,
ESP_FTP_DATA_PASSIVE_PORT
} ;
const char * SysintKeysVal[] = {"Baud_rate", const char* SysintKeysVal[] = {"Baud_rate", "Boot_delay"};
"Boot_delay"
} ;
const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE, const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE, ESP_BOOT_DELAY};
ESP_BOOT_DELAY
} ;
const char * ServboolKeysVal[] = {"Serial_Bridge_active", const char* ServboolKeysVal[] = {"Serial_Bridge_active",
"AUTONOTIFICATION", "AUTONOTIFICATION",
"HTTP_active", "HTTP_active",
"TELNET_active", "TELNET_active",
"WebSocket_active", "WebSocket_active",
"WebDav_active", "WebDav_active",
"Time_DST", "Time_DST",
"CHECK_FOR_UPDATE", "CHECK_FOR_UPDATE",
"Active_buzzer", "Active_buzzer",
"Active_Internet_time", "Active_Internet_time",
"Radio_enabled" "Radio_enabled"};
} ;
const uint16_t ServboolKeysPos[] = {ESP_SERIAL_BRIDGE_ON, const uint16_t ServboolKeysPos[] = {
ESP_AUTO_NOTIFICATION, ESP_SERIAL_BRIDGE_ON, ESP_AUTO_NOTIFICATION,
ESP_HTTP_ON, ESP_HTTP_ON, ESP_TELNET_ON,
ESP_TELNET_ON, ESP_WEBSOCKET_ON, ESP_WEBDAV_ON,
ESP_WEBSOCKET_ON, ESP_TIME_IS_DST, ESP_SD_CHECK_UPDATE_AT_BOOT,
ESP_WEBDAV_ON, ESP_BUZZER, ESP_INTERNET_TIME,
ESP_TIME_IS_DST, ESP_BOOT_RADIO_STATE};
ESP_SD_CHECK_UPDATE_AT_BOOT,
ESP_BUZZER,
ESP_INTERNET_TIME,
ESP_BOOT_RADIO_STATE
} ;
const char * SysboolKeysVal[] = {"Active_Serial_Bridge", const char* SysboolKeysVal[] = {"Active_Serial_Bridge",
"Active_Remote_Screen", "Active_Remote_Screen",
"Active_ESP3D_Screen", "Active_ESP3D_Screen",
"Active_Serial ", "Active_Serial ",
"Active_WebSocket", "Active_WebSocket",
"Active_Telnet", "Active_Telnet",
"Active_BT", "Active_BT",
"Boot_verbose", "Boot_verbose",
"Secure_serial" "Secure_serial"};
} ;
const uint16_t SysboolKeysPos[] = {ESP_SERIAL_BRIDGE_FLAG, const uint16_t SysboolKeysPos[] = {ESP_SERIAL_BRIDGE_FLAG,
ESP_REMOTE_SCREEN_FLAG, ESP_REMOTE_SCREEN_FLAG,
@ -169,381 +127,389 @@ const uint16_t SysboolKeysPos[] = {ESP_SERIAL_BRIDGE_FLAG,
ESP_TELNET_FLAG, ESP_TELNET_FLAG,
ESP_BT_FLAG, ESP_BT_FLAG,
ESP_VERBOSE_BOOT, ESP_VERBOSE_BOOT,
ESP_SECURE_SERIAL ESP_SECURE_SERIAL};
} ;
const char * NetbyteKeysVal[] = { const char* NetbyteKeysVal[] = {"AP_channel"};
"AP_channel"
} ;
const uint16_t NetbyteKeysPos[] = { const uint16_t NetbyteKeysPos[] = {ESP_AP_CHANNEL};
ESP_AP_CHANNEL const char* ServbyteKeysVal[] = {"Time_zone", "Sesion_timeout", "SD_SPEED"};
} ;
const char * ServbyteKeysVal[] = {"Time_zone",
"Sesion_timeout",
"SD_SPEED"
} ;
const uint16_t ServbyteKeysPos[] = {ESP_TIMEZONE, const uint16_t ServbyteKeysPos[] = {ESP_TIMEZONE, ESP_SESSION_TIMEOUT,
ESP_SESSION_TIMEOUT, ESP_SD_SPEED_DIV};
ESP_SD_SPEED_DIV
} ;
bool processString(const char** keysval, const uint16_t* keypos,
bool processString(const char** keysval, const uint16_t * keypos, const size_t size, const char * key, const char * value, char & T, int & P ) const size_t size, const char* key, const char* value,
{ char& T, int& P) {
for (uint i = 0; i < size; i++) {
for(uint i=0; i< size ; i++) { if (strcasecmp(keysval[i], key) == 0) {
if (strcasecmp(keysval[i],key)==0) { // if it is a previouly saved scrambled password ignore it
//if it is a previouly saved scrambled password ignore it if (strcasecmp(value, "********") != 0) {
if (strcasecmp(value,"********")!=0) { T = 'S';
T='S'; P = keypos[i];
P=keypos[i]; return true;
return true; }
}
}
} }
return false; }
return false;
} }
bool processInt(const char** keysval, const uint16_t * keypos, const size_t size, const char * key, const char * value, char & T, int & P, uint32_t & v) bool processInt(const char** keysval, const uint16_t* keypos, const size_t size,
{ const char* key, const char* value, char& T, int& P,
for(uint i=0; i< size ; i++) { uint32_t& v) {
if (strcasecmp(keysval[i],key)==0) { for (uint i = 0; i < size; i++) {
T='I'; if (strcasecmp(keysval[i], key) == 0) {
P=keypos[i]; T = 'I';
v=String(value).toInt(); P = keypos[i];
return true; v = String(value).toInt();
} return true;
} }
return false; }
return false;
} }
bool processBool(const char** keysval, const uint16_t * keypos, const size_t size, const char * key, const char * value, char & T, int & P, byte & b) bool processBool(const char** keysval, const uint16_t* keypos,
{ const size_t size, const char* key, const char* value, char& T,
for(uint i=0; i< size ; i++) { int& P, byte& b) {
if (strcasecmp(keysval[i],key)==0) { for (uint i = 0; i < size; i++) {
T='B'; if (strcasecmp(keysval[i], key) == 0) {
P=keypos[i]; T = 'B';
if ((strcasecmp("yes",value)==0)||(strcasecmp("on", value)==0)||(strcasecmp("true", value)==0)||(strcasecmp("1", value)==0) ) { P = keypos[i];
b = 1; if ((strcasecmp("yes", value) == 0) || (strcasecmp("on", value) == 0) ||
} else if ((strcasecmp("no", value)==0)||(strcasecmp("off", value)==0)||(strcasecmp("false", value)==0)||(strcasecmp("0", value)==0) ) { (strcasecmp("true", value) == 0) || (strcasecmp("1", value) == 0)) {
b = 0; b = 1;
} else { } else if ((strcasecmp("no", value) == 0) ||
P=-1; (strcasecmp("off", value) == 0) ||
} (strcasecmp("false", value) == 0) ||
return true; (strcasecmp("0", value) == 0)) {
} b = 0;
} else {
P = -1;
}
return true;
} }
return false; }
return false;
} }
// Parsing all entries of file once is faster that checking all possible
// parameters for each line of file
//Parsing all entries of file once is faster that checking all possible parameters for each line of file bool processingFileFunction(const char* section, const char* key,
bool processingFileFunction (const char * section, const char * key, const char * value) const char* value) {
{ bool res = true;
bool res = true; char T = '\0';
char T = '\0'; int P = -1;
int P = -1; uint32_t v = 0;
uint32_t v = 0; byte b = 0;
byte b = 0; bool done = false;
bool done=false; log_esp3d("[%s]%s=%s", section, key, value);
log_esp3d("[%s]%s=%s",section, key,value); // network / services / system sections
//network / services / system sections if (strcasecmp("network", section) == 0) {
if (strcasecmp("network",section)==0) { if (!done) {
if (!done) { done = processString(NetstringKeysVal, NetstringKeysPos,
done = processString(NetstringKeysVal,NetstringKeysPos,sizeof(NetstringKeysVal)/sizeof(char*), key, value, T, P ); sizeof(NetstringKeysVal) / sizeof(char*), key, value,
T, P);
}
if (!done) {
done = processString(IPKeysVal, IPKeysPos,
sizeof(IPKeysVal) / sizeof(char*), key, value, T, P);
if (done) {
T = 'A';
}
}
if (!done) {
done = processInt(NetbyteKeysVal, NetbyteKeysPos,
sizeof(NetbyteKeysVal) / sizeof(char*), key, value, T,
P, v);
if (done) {
T = 'B';
b = v;
}
}
// Radio mode BT, WIFI-STA, WIFI-AP, ETH-STA, OFF
if (!done) {
if (strcasecmp("radio_mode", key) == 0) {
T = 'B';
P = ESP_RADIO_MODE;
done = true;
if (strcasecmp("BT", value) == 0) {
b = ESP_BT;
} else if (strcasecmp("WIFI-STA", value) == 0) {
b = ESP_WIFI_STA;
} else if (strcasecmp("WIFI-AP", value) == 0) {
b = ESP_WIFI_AP;
} else if (strcasecmp("WIFI-SETUP", value) == 0) {
b = ESP_AP_SETUP;
} else if (strcasecmp("ETH-STA", value) == 0) {
b = ESP_ETH_STA;
} else if (strcasecmp("OFF", value) == 0) {
b = ESP_NO_NETWORK;
} else {
P = -1; // invalide value
} }
if (!done) { }
done = processString(IPKeysVal,IPKeysPos,sizeof(IPKeysVal)/sizeof(char*), key, value, T, P ); }
if(done) { // STA fallback mode BT, WIFI-AP, OFF
T='A'; if (!done) {
} if (strcasecmp("sta_fallback", key) == 0) {
} T = 'B';
if (!done) { P = ESP_STA_FALLBACK_MODE;
done = processInt(NetbyteKeysVal,NetbyteKeysPos,sizeof(NetbyteKeysVal)/sizeof(char*), key, value, T, P, v); done = true;
if(done) { if (strcasecmp("BT", value) == 0) {
T='B'; b = ESP_BT;
b=v; } else if (strcasecmp("WIFI-SETUP", value) == 0) {
} b = ESP_AP_SETUP;
} } else if (strcasecmp("OFF", value) == 0) {
//Radio mode BT, WIFI-STA, WIFI-AP, ETH-STA, OFF b = ESP_NO_NETWORK;
if (!done) { } else {
if (strcasecmp("radio_mode",key)==0) { P = -1; // invalide value
T='B';
P=ESP_RADIO_MODE;
done = true;
if (strcasecmp("BT",value)==0) {
b=ESP_BT;
} else if (strcasecmp("WIFI-STA",value)==0) {
b=ESP_WIFI_STA;
} else if (strcasecmp("WIFI-AP",value)==0) {
b=ESP_WIFI_AP;
} else if (strcasecmp("WIFI-SETUP",value)==0) {
b=ESP_AP_SETUP;
} else if (strcasecmp("ETH-STA",value)==0) {
b=ESP_ETH_STA;
} else if (strcasecmp("OFF",value)==0) {
b=ESP_NO_NETWORK;
} else {
P=-1; //invalide value
}
}
}
//STA fallback mode BT, WIFI-AP, OFF
if (!done) {
if (strcasecmp("sta_fallback",key)==0) {
T='B';
P = ESP_STA_FALLBACK_MODE;
done = true;
if (strcasecmp("BT",value)==0) {
b=ESP_BT;
} else if (strcasecmp("WIFI-SETUP",value)==0) {
b=ESP_AP_SETUP;
} else if (strcasecmp("OFF",value)==0) {
b=ESP_NO_NETWORK;
} else {
P=-1; //invalide value
}
}
}
//STA IP Mode DHCP / STATIC
if (!done) {
if (strcasecmp("STA_IP_mode",key)==0) {
T='B';
P=ESP_STA_IP_MODE;
done = true;
if (strcasecmp("DHCP",value)==0) {
b=DHCP_MODE;
} else if (strcasecmp("STATIC",key)==0) {
b=STATIC_IP_MODE;
} else {
P=-1; //invalide value
}
}
}
} else if (strcasecmp("services",section)==0) {
if (!done) {
done = processString(ServstringKeysVal,ServstringKeysPos,sizeof(ServstringKeysVal)/sizeof(char*), key, value, T, P );
}
if (!done) {
done = processInt(ServintKeysVal,ServintKeysPos,sizeof(ServintKeysVal)/sizeof(char*), key, value, T, P, v);
}
if (!done) {
done = processBool(ServboolKeysVal,ServboolKeysPos,sizeof(ServboolKeysVal)/sizeof(char*), key, value, T, P, b);
}
if (!done) {
done = processInt(ServbyteKeysVal,ServbyteKeysPos,sizeof(ServbyteKeysVal)/sizeof(char*), key, value, T, P, v);
if(done) {
T='B';
b=v;
}
}
//Notification type None / PushOver / Line / Email / Telegram / IFTTT
if (!done) {
if (strcasecmp("NOTIF_TYPE",key)==0) {
T='B';
P=ESP_NOTIFICATION_TYPE;
done = true;
if (strcasecmp("None",value)==0) {
b=ESP_NO_NOTIFICATION;
} else if (strcasecmp("PushOver",value)==0) {
b=ESP_PUSHOVER_NOTIFICATION;
} else if (strcasecmp("Line",value)==0) {
b=ESP_LINE_NOTIFICATION;
} else if (strcasecmp("Email",value)==0) {
b=ESP_EMAIL_NOTIFICATION;
} else if (strcasecmp("Telegram",value)==0) {
b=ESP_TELEGRAM_NOTIFICATION;
} else if (strcasecmp("IFTTT",value)==0) {
b=ESP_IFTTT_NOTIFICATION;
} else {
P=-1; //invalide value
}
}
}
//Sensor type if enabled None / DHT11 / DHT22 / ANALOG / BMP280 / BME280
if (!done) {
if (strcasecmp("SENSOR_TYPE",key)==0) {
T='B';
P=ESP_SENSOR_TYPE;
done = true;
if (strcasecmp("None",value)==0) {
b=NO_SENSOR_DEVICE;
} else if (strcasecmp("DHT11",key)==0) {
b=DHT11_DEVICE;
} else if (strcasecmp("DHT22",key)==0) {
b=DHT22_DEVICE;
} else if (strcasecmp("ANALOG",key)==0) {
b=ANALOG_DEVICE;
} else if (strcasecmp("BMP280",key)==0) {
b=BMP280_DEVICE;
} else if (strcasecmp("BME280",key)==0) {
b=BME280_DEVICE;
} else {
P=-1; //invalide value
}
}
}
} else if (strcasecmp("system",section)==0) {
if (!done) {
done = processInt(SysintKeysVal,SysintKeysPos,sizeof(SysintKeysVal)/sizeof(char*), key, value, T, P, v);
}
if (!done) {
done = processBool(SysboolKeysVal,SysboolKeysPos,sizeof(SysboolKeysVal)/sizeof(char*), key, value, T, P, b);
}
//Target Firmware None / Marlin / Repetier / MarlinKimbra / Smoothieware / GRBL
if (!done) {
if (strcasecmp("TargetFW",key)==0) {
T='B';
P=ESP_TARGET_FW;
done = true;
if (strcasecmp("None",value)==0) {
b=UNKNOWN_FW;
} else if (strcasecmp("MARLIN",value)==0) {
b=MARLIN;
} else if (strcasecmp("GRBL",value)==0) {
b=GRBL;
} else if (strcasecmp("REPETIER",value)==0) {
b=REPETIER;
} else if (strcasecmp("SMOOTHIEWARE",value)==0) {
b=SMOOTHIEWARE;
} else {
P=-1; //invalide value
}
}
} }
}
} }
//now we save -handle saving status // STA IP Mode DHCP / STATIC
//if setting is not recognized it is not a problem if (!done) {
//but if save is fail - that is a problem - so report it if (strcasecmp("STA_IP_mode", key) == 0) {
if(P!=-1) { T = 'B';
switch(T) { P = ESP_STA_IP_MODE;
case 'S': done = true;
log_esp3d("Saving setting to ESP3D"); if (strcasecmp("DHCP", value) == 0) {
res = Settings_ESP3D::write_string (P, value); b = DHCP_MODE;
break; } else if (strcasecmp("STATIC", key) == 0) {
case 'B': b = STATIC_IP_MODE;
case 'F': } else {
res = Settings_ESP3D::write_byte (P, b); P = -1; // invalide value
break;
case 'I':
res = Settings_ESP3D::write_uint32 (P, v);
break;
case 'A':
res = Settings_ESP3D::write_IP_String (P, value);
break;
default:
log_esp3d("Unknown flag");
} }
}
} }
return res; } else if (strcasecmp("services", section) == 0) {
if (!done) {
done = processString(ServstringKeysVal, ServstringKeysPos,
sizeof(ServstringKeysVal) / sizeof(char*), key,
value, T, P);
}
if (!done) {
done = processInt(ServintKeysVal, ServintKeysPos,
sizeof(ServintKeysVal) / sizeof(char*), key, value, T,
P, v);
}
if (!done) {
done = processBool(ServboolKeysVal, ServboolKeysPos,
sizeof(ServboolKeysVal) / sizeof(char*), key, value, T,
P, b);
}
if (!done) {
done = processInt(ServbyteKeysVal, ServbyteKeysPos,
sizeof(ServbyteKeysVal) / sizeof(char*), key, value, T,
P, v);
if (done) {
T = 'B';
b = v;
}
}
// Notification type None / PushOver / Line / Email / Telegram / IFTTT
if (!done) {
if (strcasecmp("NOTIF_TYPE", key) == 0) {
T = 'B';
P = ESP_NOTIFICATION_TYPE;
done = true;
if (strcasecmp("None", value) == 0) {
b = ESP_NO_NOTIFICATION;
} else if (strcasecmp("PushOver", value) == 0) {
b = ESP_PUSHOVER_NOTIFICATION;
} else if (strcasecmp("Line", value) == 0) {
b = ESP_LINE_NOTIFICATION;
} else if (strcasecmp("Email", value) == 0) {
b = ESP_EMAIL_NOTIFICATION;
} else if (strcasecmp("Telegram", value) == 0) {
b = ESP_TELEGRAM_NOTIFICATION;
} else if (strcasecmp("IFTTT", value) == 0) {
b = ESP_IFTTT_NOTIFICATION;
} else {
P = -1; // invalide value
}
}
}
// Sensor type if enabled None / DHT11 / DHT22 / ANALOG / BMP280 / BME280
if (!done) {
if (strcasecmp("SENSOR_TYPE", key) == 0) {
T = 'B';
P = ESP_SENSOR_TYPE;
done = true;
if (strcasecmp("None", value) == 0) {
b = NO_SENSOR_DEVICE;
} else if (strcasecmp("DHT11", key) == 0) {
b = DHT11_DEVICE;
} else if (strcasecmp("DHT22", key) == 0) {
b = DHT22_DEVICE;
} else if (strcasecmp("ANALOG", key) == 0) {
b = ANALOG_DEVICE;
} else if (strcasecmp("BMP280", key) == 0) {
b = BMP280_DEVICE;
} else if (strcasecmp("BME280", key) == 0) {
b = BME280_DEVICE;
} else {
P = -1; // invalide value
}
}
}
} else if (strcasecmp("system", section) == 0) {
if (!done) {
done = processInt(SysintKeysVal, SysintKeysPos,
sizeof(SysintKeysVal) / sizeof(char*), key, value, T, P,
v);
}
if (!done) {
done = processBool(SysboolKeysVal, SysboolKeysPos,
sizeof(SysboolKeysVal) / sizeof(char*), key, value, T,
P, b);
}
// Target Firmware None / Marlin / Repetier / MarlinKimbra / Smoothieware /
// GRBL
if (!done) {
if (strcasecmp("TargetFW", key) == 0) {
T = 'B';
P = ESP_TARGET_FW;
done = true;
if (strcasecmp("None", value) == 0) {
b = UNKNOWN_FW;
} else if (strcasecmp("MARLIN", value) == 0) {
b = MARLIN;
} else if (strcasecmp("GRBL", value) == 0) {
b = GRBL;
} else if (strcasecmp("REPETIER", value) == 0) {
b = REPETIER;
} else if (strcasecmp("SMOOTHIEWARE", value) == 0) {
b = SMOOTHIEWARE;
} else {
P = -1; // invalide value
}
}
}
}
// now we save -handle saving status
// if setting is not recognized it is not a problem
// but if save is fail - that is a problem - so report it
if (P != -1) {
switch (T) {
case 'S':
log_esp3d("Saving setting to ESP3D");
res = Settings_ESP3D::write_string(P, value);
break;
case 'B':
case 'F':
res = Settings_ESP3D::write_byte(P, b);
break;
case 'I':
res = Settings_ESP3D::write_uint32(P, v);
break;
case 'A':
res = Settings_ESP3D::write_IP_String(P, value);
break;
default:
log_esp3d("Unknown flag");
}
}
return res;
} }
UpdateService::UpdateService() {} UpdateService::UpdateService() {}
UpdateService::~UpdateService() {} UpdateService::~UpdateService() {}
bool UpdateService::flash(const char * filename, int type) bool UpdateService::flash(const char* filename, int type) {
{ bool res = false;
bool res = false; if (ESP_SD::exists(filename)) {
if (ESP_SD::exists (filename)) { log_esp3d("Update found");
log_esp3d("Update found"); bool issucess = false;
bool issucess = false; ESP_SDFile sdfile;
ESP_SDFile sdfile; String finalName = filename;
String finalName = filename; sdfile = ESP_SD::open(filename);
sdfile = ESP_SD::open(filename); if (sdfile) {
if(sdfile) { size_t s = sdfile.size();
size_t s = sdfile.size(); size_t rs = 0;
size_t rs = 0; uint8_t v[1];
uint8_t v[1] ; if (Update.begin(s, type)) {
if(Update.begin(s, type)) { log_esp3d("Update started");
log_esp3d("Update started"); while (sdfile.available() && (rs <= (s + 1))) {
while (sdfile.available() && (rs <= (s+1))) { rs++;
rs++; v[0] = sdfile.read();
v[0]=sdfile.read(); Update.write(v, 1);
Update.write(v,1); Hal::wait(0);
Hal::wait(0); }
} if (rs == s) {
if (rs==s) { log_esp3d("Update done");
log_esp3d("Update done"); if (Update.end(true)) {
if(Update.end(true)) { log_esp3d("Update success");
log_esp3d("Update success"); issucess = true;
issucess = true; }
}
} else {
Update.end();
log_esp3d("Wrong size");
}
}
sdfile.close();
} else { } else {
log_esp3d("Cannot open file"); Update.end();
} log_esp3d_e("Wrong size");
if(issucess) {
res = true;
finalName.replace(".bin", ".ok");
} else {
finalName.replace(".bin", ".bad");
}
if (ESP_SD::exists (finalName.c_str())) {
String name = filename;
uint8_t n = 1;
log_esp3d("Final name already exists, backup existing");
name.replace("bin", String(n).c_str());
while(ESP_SD::exists (name.c_str())) {
n++;
name.replace("bin", String(n).c_str());
}
ESP_SD::rename(finalName.c_str(),name.c_str());
}
ESP_SD::rename(filename, finalName.c_str());
}
return res;
}
bool UpdateService::begin()
{
bool res = false;
if(Settings_ESP3D::read_byte(ESP_SD_CHECK_UPDATE_AT_BOOT)!=0) {
if (ESP_SD::accessFS()) {
log_esp3d("Update SD for update requestest");
if(ESP_SD::getState(true) != ESP_SDCARD_NOT_PRESENT) {
ESP_SD::setState(ESP_SDCARD_BUSY );
ESP_ConfigFile updateConfig(CONFIG_FILE, processingFileFunction);
if (updateConfig.processFile()) {
log_esp3d("Processing ini file done");
if(updateConfig.revokeFile()) {
log_esp3d("Revoking ini file done");
res = true;
} else {
log_esp3d("Revoking ini file failed");
}
} else {
log_esp3d("Processing ini file failed");
}
if (flash(FW_FILE,U_FLASH)) {
res = true;
} else {
if (flash(FS_FILE,U_FS)) {
res = true;
}
}
}
ESP_SD::releaseFS();
} }
}
sdfile.close();
} else { } else {
log_esp3d("No need to check for update"); log_esp3d_e("Cannot open file");
} }
if (issucess) {
res = true;
finalName.replace(".bin", ".ok");
} else {
finalName.replace(".bin", ".bad");
}
if (ESP_SD::exists(finalName.c_str())) {
String name = filename;
uint8_t n = 1;
log_esp3d("Final name already exists, backup existing");
name.replace("bin", String(n).c_str());
while (ESP_SD::exists(name.c_str())) {
n++;
name.replace("bin", String(n).c_str());
}
ESP_SD::rename(finalName.c_str(), name.c_str());
}
ESP_SD::rename(filename, finalName.c_str());
}
return res;
}
return res; bool UpdateService::begin() {
} bool res = false;
void UpdateService::end() if (Settings_ESP3D::read_byte(ESP_SD_CHECK_UPDATE_AT_BOOT) != 0) {
{ if (ESP_SD::accessFS()) {
log_esp3d("Update SD for update requestest");
if (ESP_SD::getState(true) != ESP_SDCARD_NOT_PRESENT) {
ESP_SD::setState(ESP_SDCARD_BUSY);
ESP_ConfigFile updateConfig(CONFIG_FILE, processingFileFunction);
if (updateConfig.processFile()) {
log_esp3d("Processing ini file done");
if (updateConfig.revokeFile()) {
log_esp3d("Revoking ini file done");
res = true;
} else {
log_esp3d_e("Revoking ini file failed");
}
} else {
log_esp3d_e("Processing ini file failed");
}
if (flash(FW_FILE, U_FLASH)) {
res = true;
} else {
if (flash(FS_FILE, U_FS)) {
res = true;
}
}
}
ESP_SD::releaseFS();
}
} else {
log_esp3d("No need to check for update");
}
return res;
} }
void UpdateService::end() {}
void UpdateService::handle() {} void UpdateService::handle() {}
#endif //SD_UPDATE_FEATURE #endif // SD_UPDATE_FEATURE

View File

@ -27,7 +27,7 @@
Lebosse (ESP3D Integration) Lebosse (ESP3D Integration)
*/ */
// #define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined(WEBDAV_FEATURE) #if defined(WEBDAV_FEATURE)
@ -35,7 +35,6 @@
#include "ESPWebDAV.h" #include "ESPWebDAV.h"
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <PolledTimeout.h> #include <PolledTimeout.h>
@ -821,7 +820,7 @@ void ESPWebDAVCore::handleGet(ResourceType resource, WebDavFile& file,
// no lock on GET // no lock on GET
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
long tStart = millis(); long tStart = millis();
#endif #endif
@ -899,7 +898,7 @@ void ESPWebDAVCore::handleGet(ResourceType resource, WebDavFile& file,
break; break;
} }
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
for (size_t i = 0; i < 80 && i < numRead; i++) { for (size_t i = 0; i < 80 && i < numRead; i++) {
log_esp3ds("%c", buf[i] < 32 || buf[i] > 127 ? '.' : buf[i]); log_esp3ds("%c", buf[i] < 32 || buf[i] > 127 ? '.' : buf[i]);
} }
@ -953,7 +952,7 @@ void ESPWebDAVCore::handlePut(ResourceType resource) {
if (contentLengthHeader != 0) { if (contentLengthHeader != 0) {
uint8_t buf[BUFFER_SIZE]; uint8_t buf[BUFFER_SIZE];
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
long tStart = millis(); long tStart = millis();
#endif #endif
size_t numRemaining = contentLengthHeader; size_t numRemaining = contentLengthHeader;
@ -1542,7 +1541,7 @@ void ESPWebDAVCore::send(const String& code, const char* content_type,
if (content.length()) { if (content.length()) {
sendContent(content); sendContent(content);
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
log_esp3d("send content (%d bytes):", (int)content.length()); log_esp3d("send content (%d bytes):", (int)content.length());
for (size_t i = 0; i < DEBUG_LEN && i < content.length(); i++) { for (size_t i = 0; i < DEBUG_LEN && i < content.length(); i++) {
log_esp3ds("%c", content[i] < 32 || content[i] > 127 ? '.' : content[i]); log_esp3ds("%c", content[i] < 32 || content[i] > 127 ? '.' : content[i]);
@ -1571,7 +1570,7 @@ bool ESPWebDAVCore::sendContent(const char* data, size_t size) {
log_esp3d("---- chunk %s", chunkSize); log_esp3d("---- chunk %s", chunkSize);
} }
#if defined(ESP_DEBUG_FEATURE) #if defined(ESP_LOG_FEATURE)
log_esp3d("---- %scontent (%d bytes):", _chunked ? "chunked " : "", log_esp3d("---- %scontent (%d bytes):", _chunked ? "chunked " : "",
(int)size); (int)size);
for (size_t i = 0; i < DEBUG_LEN && i < size; i++) { for (size_t i = 0; i < DEBUG_LEN && i < size; i++) {

View File

@ -23,146 +23,141 @@
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
Modified 22 Jan 2021 by Luc Lebosse (ESP3D Integration) Modified 22 Jan 2021 by Luc Lebosse (ESP3D Integration)
*/ */
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined (WEBDAV_FEATURE) #if defined(WEBDAV_FEATURE)
#include "ESPWebDAV.h" #include "ESPWebDAV.h"
// Sections are copied from ESP8266Webserver // Sections are copied from ESP8266Webserver
String ESPWebDAV::getMimeType(const String& path) String ESPWebDAV::getMimeType(const String& path) {
{ if (path.endsWith(".html")) {
if (path.endsWith(".html")) { return "text/html";
return "text/html"; } else if (path.endsWith(".htm")) {
} else if (path.endsWith(".htm")) { return "text/html";
return "text/html"; } else if (path.endsWith(".css")) {
} else if (path.endsWith(".css")) { return "text/css";
return "text/css"; } else if (path.endsWith(".txt")) {
} else if (path.endsWith(".txt")) { return "text/plain";
return "text/plain"; } else if (path.endsWith(".js")) {
} else if (path.endsWith(".js")) { return "application/javascript";
return "application/javascript"; } else if (path.endsWith(".json")) {
} else if (path.endsWith(".json")) { return "application/json";
return "application/json"; } else if (path.endsWith(".png")) {
} else if (path.endsWith(".png")) { return "image/png";
return "image/png"; } else if (path.endsWith(".gif")) {
} else if (path.endsWith(".gif")) { return "image/gif";
return "image/gif"; } else if (path.endsWith(".jpg")) {
} else if (path.endsWith(".jpg")) { return "image/jpeg";
return "image/jpeg"; } else if (path.endsWith(".ico")) {
} else if (path.endsWith(".ico")) { return "image/x-icon";
return "image/x-icon"; } else if (path.endsWith(".svg")) {
} else if (path.endsWith(".svg")) { return "image/svg+xml";
return "image/svg+xml"; } else if (path.endsWith(".ttf")) {
} else if (path.endsWith(".ttf")) { return "application/x-font-ttf";
return "application/x-font-ttf"; } else if (path.endsWith(".otf")) {
} else if (path.endsWith(".otf")) { return "application/x-font-opentype";
return "application/x-font-opentype"; } else if (path.endsWith(".woff")) {
} else if (path.endsWith(".woff")) { return "application/font-woff";
return "application/font-woff"; } else if (path.endsWith(".woff2")) {
} else if (path.endsWith(".woff2")) { return "application/font-woff2";
return "application/font-woff2"; } else if (path.endsWith(".eot")) {
} else if (path.endsWith(".eot")) { return "application/vnd.ms-fontobject";
return "application/vnd.ms-fontobject"; } else if (path.endsWith(".sfnt")) {
} else if (path.endsWith(".sfnt")) { return "application/font-sfnt";
return "application/font-sfnt"; } else if (path.endsWith(".xml")) {
} else if (path.endsWith(".xml")) { return "text/xml";
return "text/xml"; } else if (path.endsWith(".pdf")) {
} else if (path.endsWith(".pdf")) { return "application/pdf";
return "application/pdf"; } else if (path.endsWith(".zip")) {
} else if (path.endsWith(".zip")) { return "application/zip";
return "application/zip"; } else if (path.endsWith(".gz")) {
} else if (path.endsWith(".gz")) { return "application/x-gzip";
return "application/x-gzip"; } else if (path.endsWith(".appcache")) {
} else if (path.endsWith(".appcache")) { return "text/cache-manifest";
return "text/cache-manifest"; }
}
return "application/octet-stream"; return "application/octet-stream";
} }
String ESPWebDAV::urlDecode(const String& text) {
String decoded = "";
char temp[] = "0x00";
String ESPWebDAV::urlDecode(const String& text) unsigned int len = text.length();
{ unsigned int i = 0;
String decoded = ""; while (i < len) {
char temp[] = "0x00"; char decodedChar;
unsigned int len = text.length(); char encodedChar = text.charAt(i++);
unsigned int i = 0; if ((encodedChar == '%') && (i + 1 < len)) {
while (i < len) { temp[2] = text.charAt(i++);
char decodedChar; temp[3] = text.charAt(i++);
char encodedChar = text.charAt(i++); decodedChar = strtol(temp, NULL, 16);
if ((encodedChar == '%') && (i + 1 < len)) { } else {
temp[2] = text.charAt(i++); if (encodedChar == '+') {
temp[3] = text.charAt(i++); decodedChar = ' ';
decodedChar = strtol(temp, NULL, 16); } else {
} else { decodedChar = encodedChar; // normal ascii char
if (encodedChar == '+') { }
decodedChar = ' ';
} else {
decodedChar = encodedChar; // normal ascii char
}
}
decoded += decodedChar;
} }
return decoded; decoded += decodedChar;
}
return decoded;
} }
void ESPWebDAV::handleClient() void ESPWebDAV::handleClient() {
{ if (!server) {
if (!server) { log_esp3d_e("handleClient: server is null");
log_esp3d("handleClient: server is null"); return;
return; }
}
if (server->hasClient()) {
if (!locClient || !locClient.available()) {
// no or sleeping current client
// take it over
locClient = server->available();
m_persistent_timer_ms = millis();
log_esp3d("NEW CLIENT-------------------------------------------------------");
}
}
if (server->hasClient()) {
if (!locClient || !locClient.available()) { if (!locClient || !locClient.available()) {
// no current client // no or sleeping current client
//do not put debug here or it will flood the serial // take it over
return; locClient = server->available();
m_persistent_timer_ms = millis();
log_esp3d(
"NEW CLIENT-------------------------------------------------------");
} }
}
// extract uri, headers etc if (!locClient || !locClient.available()) {
parseRequest(); // no current client
// do not put debug here or it will flood the serial
return;
}
if (!m_persistent) // extract uri, headers etc
// close the connection parseRequest();
{
log_esp3d("CLOSE CONNECTION-------------------------------------------------------"); if (!m_persistent)
locClient.stop(); // close the connection
} {
log_esp3d(
"CLOSE "
"CONNECTION-------------------------------------------------------");
locClient.stop();
}
} }
bool ESPWebDAV::parseRequest() {
// Read the first line of HTTP request
String req = locClient.readStringUntil('\r');
locClient.readStringUntil('\n');
bool ESPWebDAV::parseRequest() // First line of HTTP request looks like "GET /path HTTP/1.1"
{ // Retrieve the "/path" part by finding the spaces
// Read the first line of HTTP request int addr_start = req.indexOf(' ');
String req = locClient.readStringUntil('\r'); int addr_end = req.indexOf(' ', addr_start + 1);
locClient.readStringUntil('\n'); if (addr_start == -1 || addr_end == -1) {
log_esp3d("Invalid request %s", req.c_str());
return false;
}
// First line of HTTP request looks like "GET /path HTTP/1.1" method = req.substring(0, addr_start);
// Retrieve the "/path" part by finding the spaces uri = urlDecode(req.substring(addr_start + 1, addr_end));
int addr_start = req.indexOf(' '); return ESPWebDAVCore::parseRequest(method, uri, &locClient, getMimeType);
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
log_esp3d("Invalid request %s", req.c_str());
return false;
}
method = req.substring(0, addr_start);
uri = urlDecode(req.substring(addr_start + 1, addr_end));
return ESPWebDAVCore::parseRequest(method, uri, &locClient, getMimeType);
} }
#endif //WEBDAV_FEATURE #endif // WEBDAV_FEATURE

View File

@ -18,350 +18,320 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) || defined(WS_DATA_FEATURE) #if defined(HTTP_FEATURE) || defined(WS_DATA_FEATURE)
#include "websocket_server.h"
#include <WebSocketsServer.h> #include <WebSocketsServer.h>
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h" #include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "../authentication/authentication_service.h" #include "../authentication/authentication_service.h"
#include "websocket_server.h"
WebSocket_Server websocket_terminal_server("webui-v3"); WebSocket_Server websocket_terminal_server("webui-v3");
#if defined(WS_DATA_FEATURE) #if defined(WS_DATA_FEATURE)
WebSocket_Server websocket_data_server("arduino"); WebSocket_Server websocket_data_server("arduino");
#endif //WS_DATA_FEATURE #endif // WS_DATA_FEATURE
void WebSocket_Server::pushMSG (const char * data) void WebSocket_Server::pushMSG(const char *data) {
{ if (_websocket_server) {
if (_websocket_server) { _websocket_server->broadcastTXT(data);
_websocket_server->broadcastTXT(data); log_esp3d("[%u]Broadcast %s", _current_id, data);
log_esp3d("[%u]Broadcast %s", _current_id,data); }
}
} }
void WebSocket_Server::enableOnly (uint num) void WebSocket_Server::enableOnly(uint num) {
{ // some sanity check
//some sanity check if (_websocket_server) {
if (_websocket_server) { for (uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++)
for (uint8_t i=0; i<WEBSOCKETS_SERVER_CLIENT_MAX; i++) if (i != num && _websocket_server->clientIsConnected(i)) {
if(i!=num && _websocket_server->clientIsConnected(i)) { _websocket_server->disconnect(i);
_websocket_server->disconnect(i); }
} }
}
} }
void WebSocket_Server::pushMSG(uint num, const char *data) {
void WebSocket_Server::pushMSG (uint num, const char * data) if (_websocket_server) {
{ _websocket_server->sendTXT(num, data);
if (_websocket_server) { log_esp3d("[%u]Send %s", num, data);
_websocket_server->sendTXT(num, data); }
log_esp3d("[%u]Send %s", num,data);
}
} }
void WebSocket_Server::closeClients() void WebSocket_Server::closeClients() {
{ if (_websocket_server) {
if (_websocket_server) { _websocket_server->disconnect();
_websocket_server->disconnect(); }
}
} }
#if defined(WS_DATA_FEATURE) #if defined(WS_DATA_FEATURE)
//Events for Websocket bridge // Events for Websocket bridge
void handle_Websocket_Server_Event(uint8_t num, uint8_t type, uint8_t * payload, size_t length) void handle_Websocket_Server_Event(uint8_t num, uint8_t type, uint8_t *payload,
{ size_t length) {
(void)num; (void)num;
switch(type) { switch (type) {
case WStype_DISCONNECTED: case WStype_DISCONNECTED:
log_esp3d("[%u] Disconnected! port %d", num,websocket_data_server.port()); log_esp3d("[%u] Disconnected! port %d", num,
break; websocket_data_server.port());
break;
case WStype_CONNECTED: { case WStype_CONNECTED: {
log_esp3d("[%u] Connected! port %d, %s", num,websocket_data_server.port(), payload); log_esp3d("[%u] Connected! port %d, %s", num,
} websocket_data_server.port(), payload);
break; } break;
case WStype_TEXT: case WStype_TEXT:
log_esp3d("[%u] get Text: %s port %d", num, payload,websocket_data_server.port()); log_esp3d("[%u] get Text: %s port %d", num, payload,
websocket_data_server.push2RXbuffer(payload, length); websocket_data_server.port());
break; websocket_data_server.push2RXbuffer(payload, length);
break;
case WStype_BIN: case WStype_BIN:
log_esp3d("[%u] get binary length: %u port %d", num, length,websocket_data_server.port()); log_esp3d("[%u] get binary length: %u port %d", num, length,
websocket_data_server.push2RXbuffer(payload, length); websocket_data_server.port());
break; websocket_data_server.push2RXbuffer(payload, length);
break;
default: default:
break; break;
} }
} }
#endif //WS_DATA_FEATURE #endif // WS_DATA_FEATURE
#if defined (HTTP_FEATURE) #if defined(HTTP_FEATURE)
//Events for Websocket used in WebUI for events and serial bridge // Events for Websocket used in WebUI for events and serial bridge
void handle_Websocket_Terminal_Event(uint8_t num, uint8_t type, uint8_t * payload, size_t length) void handle_Websocket_Terminal_Event(uint8_t num, uint8_t type,
{ uint8_t *payload, size_t length) {
(void)payload; (void)payload;
(void)length; (void)length;
String msg; String msg;
switch(type) { switch (type) {
case WStype_DISCONNECTED: case WStype_DISCONNECTED:
log_esp3d("[%u] Socket Disconnected port %d!", num,websocket_terminal_server.port()); log_esp3d("[%u] Socket Disconnected port %d!", num,
break; websocket_terminal_server.port());
break;
case WStype_CONNECTED: { case WStype_CONNECTED: {
log_esp3d("[%u] Connected! port %d, %s", num,websocket_terminal_server.port(), (const char *)payload); log_esp3d("[%u] Connected! port %d, %s", num,
msg = "currentID:" + String(num); websocket_terminal_server.port(), (const char *)payload);
// send message to client msg = "currentID:" + String(num);
websocket_terminal_server.set_currentID(num); // send message to client
websocket_terminal_server.pushMSG(num, msg.c_str()); websocket_terminal_server.set_currentID(num);
msg = "activeID:" + String(num); websocket_terminal_server.pushMSG(num, msg.c_str());
websocket_terminal_server.pushMSG(msg.c_str()); msg = "activeID:" + String(num);
websocket_terminal_server.enableOnly(num); websocket_terminal_server.pushMSG(msg.c_str());
log_esp3d("[%u] Socket connected port %d", num,websocket_terminal_server.port()); websocket_terminal_server.enableOnly(num);
} log_esp3d("[%u] Socket connected port %d", num,
break; websocket_terminal_server.port());
} break;
case WStype_TEXT: case WStype_TEXT:
#if defined (AUTHENTICATION_FEATURE) #if defined(AUTHENTICATION_FEATURE)
//we do not expect any input but ping to get session timeout if any // we do not expect any input but ping to get session timeout if any
if (AuthenticationService::getSessionTimeout() != 0) { if (AuthenticationService::getSessionTimeout() != 0) {
msg = (const char*)payload; msg = (const char *)payload;
if (msg.startsWith("PING:")) { if (msg.startsWith("PING:")) {
String session = msg.substring(5); String session = msg.substring(5);
String response = "PING:"+String(AuthenticationService::getSessionRemaining(session.c_str())); String response =
response += ":"+String(AuthenticationService::getSessionTimeout()); "PING:" + String(AuthenticationService::getSessionRemaining(
websocket_terminal_server.pushMSG(num, response.c_str()); session.c_str()));
} response += ":" + String(AuthenticationService::getSessionTimeout());
websocket_terminal_server.pushMSG(num, response.c_str());
} }
#endif //AUTHENTICATION_FEATURE }
//log_esp3d("[IGNORED][%u] get Text: %s port %d", num, payload, websocket_terminal_server.port()); #endif // AUTHENTICATION_FEATURE
break; // log_esp3d("[IGNORED][%u] get Text: %s port %d", num, payload,
// websocket_terminal_server.port());
break;
case WStype_BIN: case WStype_BIN:
//we do not expect any input // we do not expect any input
//log_esp3d("[IGNORED][%u] get binary length: %u port %d", num, length, websocket_terminal_server.port()); // log_esp3d("[IGNORED][%u] get binary length: %u port %d", num, length,
break; // websocket_terminal_server.port());
break;
default: default:
break; break;
}
}
#endif // HTTP_FEATURE
int WebSocket_Server::available() { return _RXbufferSize; }
int WebSocket_Server::availableForWrite() {
return TXBUFFERSIZE - _TXbufferSize;
}
WebSocket_Server::WebSocket_Server(const char *protocol) {
_websocket_server = nullptr;
_started = false;
_port = 0;
_current_id = 0;
_RXbuffer = nullptr;
_RXbufferSize = 0;
_protocol = protocol;
}
WebSocket_Server::~WebSocket_Server() { end(); }
bool WebSocket_Server::begin(uint16_t port) {
end();
if (port == 0) {
_port = Settings_ESP3D::read_uint32(ESP_HTTP_PORT) + 1;
} else {
_port = port;
if (Settings_ESP3D::read_byte(ESP_WEBSOCKET_ON) == 0) {
return true;
} }
}
_websocket_server = new WebSocketsServer(_port, "", _protocol.c_str());
if (_websocket_server) {
_websocket_server->begin();
#if defined(HTTP_FEATURE) // terminal websocket for HTTP
if (port == 0) {
_websocket_server->onEvent(handle_Websocket_Terminal_Event);
}
#endif // HTTP_FEATURE
#if defined(WS_DATA_FEATURE) // terminal websocket for HTTP
if ((port != 0) && _protocol != "log") {
_websocket_server->onEvent(handle_Websocket_Server_Event);
_RXbuffer = (uint8_t *)malloc(RXBUFFERSIZE + 1);
if (!_RXbuffer) {
return false;
}
}
#endif // WS_DATA_FEATURE
_started = true;
} else {
end();
}
return _started;
}
} void WebSocket_Server::end() {
#endif //HTTP_FEATURE _current_id = 0;
_TXbufferSize = 0;
int WebSocket_Server::available() if (_RXbuffer) {
{ free(_RXbuffer);
return _RXbufferSize;
}
int WebSocket_Server::availableForWrite()
{
return TXBUFFERSIZE -_TXbufferSize;
}
WebSocket_Server::WebSocket_Server(const char * protocol )
{
_websocket_server = nullptr;
_started = false;
_port = 0;
_current_id = 0;
_RXbuffer = nullptr; _RXbuffer = nullptr;
_RXbufferSize = 0; }
_protocol = protocol; _RXbufferSize = 0;
if (_websocket_server) {
_websocket_server->close();
delete _websocket_server;
_websocket_server = nullptr;
_port = 0;
}
_started = false;
}
WebSocket_Server::operator bool() const { return _started; }
void WebSocket_Server::set_currentID(uint8_t current_id) {
_current_id = current_id;
} }
WebSocket_Server::~WebSocket_Server() uint8_t WebSocket_Server::get_currentID() { return _current_id; }
{
end(); size_t WebSocket_Server::write(uint8_t c) { return write(&c, 1); }
}
bool WebSocket_Server::begin(uint16_t port) size_t WebSocket_Server::write(const uint8_t *buffer, size_t size) {
{ if (_started) {
end(); if ((buffer == nullptr) || (!_websocket_server) || (size == 0)) {
if(port == 0) { return 0;
_port = Settings_ESP3D::read_uint32(ESP_HTTP_PORT) +1;
} else {
_port = port;
if (Settings_ESP3D::read_byte(ESP_WEBSOCKET_ON) == 0) {
return true;
}
} }
_websocket_server = new WebSocketsServer(_port,"",_protocol.c_str()); if (_TXbufferSize == 0) {
if (_websocket_server) { _lastTXflush = millis();
_websocket_server->begin();
#if defined (HTTP_FEATURE) //terminal websocket for HTTP
if(port == 0) {
_websocket_server->onEvent(handle_Websocket_Terminal_Event);
}
#endif //HTTP_FEATURE
#if defined (WS_DATA_FEATURE) //terminal websocket for HTTP
if((port != 0) && _protocol!="debug") {
_websocket_server->onEvent(handle_Websocket_Server_Event);
_RXbuffer= (uint8_t *)malloc(RXBUFFERSIZE +1);
if (!_RXbuffer) {
return false;
}
}
#endif //WS_DATA_FEATURE
_started = true;
} else {
end();
} }
return _started; // send full line
} if (_TXbufferSize + size > TXBUFFERSIZE) {
flushTXbuffer();
void WebSocket_Server::end()
{
_current_id = 0;
_TXbufferSize = 0;
if(_RXbuffer) {
free(_RXbuffer);
_RXbuffer = nullptr;
} }
_RXbufferSize = 0; if (_websocket_server->connectedClients() == 0) {
if (_websocket_server) { return 0;
_websocket_server->close();
delete _websocket_server;
_websocket_server = nullptr;
_port = 0;
} }
_started = false; // need periodic check to force to flush in case of no end
} for (uint i = 0; i < size; i++) {
_TXbuffer[_TXbufferSize] = buffer[i];
_TXbufferSize++;
WebSocket_Server::operator bool() const
{
return _started;
}
void WebSocket_Server::set_currentID(uint8_t current_id)
{
_current_id = current_id;
}
uint8_t WebSocket_Server::get_currentID()
{
return _current_id;
}
size_t WebSocket_Server::write(uint8_t c)
{
return write(&c,1);
}
size_t WebSocket_Server::write(const uint8_t *buffer, size_t size)
{
if (_started) {
if((buffer == nullptr) ||(!_websocket_server) || (size == 0)) {
return 0;
}
if (_TXbufferSize==0) {
_lastTXflush = millis();
}
//send full line
if (_TXbufferSize + size > TXBUFFERSIZE) {
flushTXbuffer();
}
if(_websocket_server->connectedClients() == 0) {
return 0;
}
//need periodic check to force to flush in case of no end
for (uint i = 0; i < size; i++) {
_TXbuffer[_TXbufferSize] = buffer[i];
_TXbufferSize++;
}
return size;
} }
return 0; return size;
}
return 0;
} }
void WebSocket_Server::push2RXbuffer(uint8_t * sbuf, size_t len) void WebSocket_Server::push2RXbuffer(uint8_t *sbuf, size_t len) {
{ if (!_RXbuffer || !_started) {
if (!_RXbuffer || !_started) { return;
return; }
} for (size_t i = 0; i < len; i++) {
for (size_t i = 0; i < len; i++) {
_lastRXflush = millis();
//command is defined
if ((char(sbuf[i]) == '\n')|| (char(sbuf[i]) == '\r')) {
if (_RXbufferSize < RXBUFFERSIZE) {
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
}
flushRXbuffer();
} else if (isPrintable (char(sbuf[i]) ) ) {
if (_RXbufferSize < RXBUFFERSIZE) {
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
} else {
flushRXbuffer();
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
}
} else { //it is not printable char
//clean buffer first
if (_RXbufferSize > 0) {
flushRXbuffer();
}
//process char
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
flushRXbuffer();
}
}
}
void WebSocket_Server::flushRXbuffer()
{
if (!_RXbuffer || !_started) {
_RXbufferSize = 0;
return;
}
ESP3DOutput output(ESP_WEBSOCKET_CLIENT);
_RXbuffer[_RXbufferSize] = 0x0;
//dispatch command
esp3d_commands.process(_RXbuffer, _RXbufferSize, &output);
_lastRXflush = millis(); _lastRXflush = millis();
// command is defined
if ((char(sbuf[i]) == '\n') || (char(sbuf[i]) == '\r')) {
if (_RXbufferSize < RXBUFFERSIZE) {
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
}
flushRXbuffer();
} else if (isPrintable(char(sbuf[i]))) {
if (_RXbufferSize < RXBUFFERSIZE) {
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
} else {
flushRXbuffer();
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
}
} else { // it is not printable char
// clean buffer first
if (_RXbufferSize > 0) {
flushRXbuffer();
}
// process char
_RXbuffer[_RXbufferSize] = sbuf[i];
_RXbufferSize++;
flushRXbuffer();
}
}
}
void WebSocket_Server::flushRXbuffer() {
if (!_RXbuffer || !_started) {
_RXbufferSize = 0; _RXbufferSize = 0;
return;
}
ESP3DOutput output(ESP_WEBSOCKET_CLIENT);
_RXbuffer[_RXbufferSize] = 0x0;
// dispatch command
esp3d_commands.process(_RXbuffer, _RXbufferSize, &output);
_lastRXflush = millis();
_RXbufferSize = 0;
} }
void WebSocket_Server::handle() {
void WebSocket_Server::handle() Hal::wait(0);
{ if (_started) {
Hal::wait(0); if (_TXbufferSize > 0) {
if (_started) { if ((_TXbufferSize >= TXBUFFERSIZE) ||
if (_TXbufferSize > 0) { ((millis() - _lastTXflush) > FLUSHTIMEOUT)) {
if ((_TXbufferSize>=TXBUFFERSIZE) || ((millis()- _lastTXflush) > FLUSHTIMEOUT)) { flushTXbuffer();
flushTXbuffer(); }
}
}
if (_RXbufferSize > 0) {
if ((_RXbufferSize>=RXBUFFERSIZE) || ((millis()- _lastRXflush) > FLUSHTIMEOUT)) {
flushRXbuffer();
}
}
if (_websocket_server) {
_websocket_server->loop();
}
} }
} if (_RXbufferSize > 0) {
if ((_RXbufferSize >= RXBUFFERSIZE) ||
void WebSocket_Server::flush(void) ((millis() - _lastRXflush) > FLUSHTIMEOUT)) {
{ flushRXbuffer();
flushTXbuffer(); }
flushRXbuffer();
}
void WebSocket_Server::flushTXbuffer(void)
{
if (_started) {
if ((_TXbufferSize > 0) && (_websocket_server->connectedClients() > 0 )) {
if (_websocket_server) {
_websocket_server->broadcastBIN(_TXbuffer,_TXbufferSize);
log_esp3d("WS Broadcast bin port %d: %d bytes", port(), _TXbufferSize);
}
//refresh timout
_lastTXflush = millis();
}
} }
//reset buffer if (_websocket_server) {
_TXbufferSize = 0; _websocket_server->loop();
}
}
} }
void WebSocket_Server::flush(void) {
flushTXbuffer();
flushRXbuffer();
}
void WebSocket_Server::flushTXbuffer(void) {
if (_started) {
if ((_TXbufferSize > 0) && (_websocket_server->connectedClients() > 0)) {
if (_websocket_server) {
_websocket_server->broadcastBIN(_TXbuffer, _TXbufferSize);
log_esp3d("WS Broadcast bin port %d: %d bytes", port(), _TXbufferSize);
}
// refresh timout
_lastTXflush = millis();
}
}
// reset buffer
_TXbufferSize = 0;
}
#endif // HTTP_FEATURE || WS_DATA_FEATURE #endif // HTTP_FEATURE || WS_DATA_FEATURE

View File

@ -19,562 +19,546 @@
*/ */
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if defined (WIFI_FEATURE) #if defined(WIFI_FEATURE)
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include <esp_wifi.h> #include <esp_wifi.h>
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
#include "../wifi/wificonfig.h"
#include "../network/netconfig.h"
#include "../../core/esp3doutput.h" #include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h" #include "../../core/settings_esp3d.h"
#include "../network/netconfig.h"
#include "../wifi/wificonfig.h"
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
const uint8_t DEFAULT_AP_MASK_VALUE[] = {255, 255, 255, 0};
/** /**
* Check if SSID string is valid * Check if SSID string is valid
*/ */
bool WiFiConfig::isSSIDValid (const char * ssid) bool WiFiConfig::isSSIDValid(const char* ssid) {
{ // limited size
//limited size // char c;
//char c; if (strlen(ssid) > MAX_SSID_LENGTH || strlen(ssid) < MIN_SSID_LENGTH) {
if (strlen (ssid) > MAX_SSID_LENGTH || strlen (ssid) < MIN_SSID_LENGTH) { return false;
return false; }
// only printable
for (uint i = 0; i < strlen(ssid); i++) {
if (!isPrintable(ssid[i])) {
return false;
} }
//only printable }
for (uint i = 0; i < strlen (ssid); i++) { return true;
if (!isPrintable (ssid[i]) ) {
return false;
}
}
return true;
} }
const char * WiFiConfig::hostname() const char* WiFiConfig::hostname() {
{ static String tmp;
static String tmp; #if defined(ARDUINO_ARCH_ESP8266)
#if defined (ARDUINO_ARCH_ESP8266) if (WiFi.getMode() == WIFI_AP) {
if (WiFi.getMode() == WIFI_AP) { // No API for AP
//No API for AP tmp = NetConfig::hostname(true);
tmp = NetConfig::hostname(true); } else {
} else { tmp = WiFi.hostname();
tmp = WiFi.hostname(); }
#endif // ARDUINO_ARCH_ESP8266
} #if defined(ARDUINO_ARCH_ESP32)
#endif //ARDUINO_ARCH_ESP8266 if (WiFi.getMode() == WIFI_AP) {
#if defined (ARDUINO_ARCH_ESP32) // tmp = NetConfig::hostname(true);
if (WiFi.getMode() == WIFI_AP) { // Set API is not working so far
//tmp = NetConfig::hostname(true); tmp = WiFi.softAPgetHostname();
//Set API is not working so far } else {
tmp = WiFi.softAPgetHostname(); tmp = WiFi.getHostname();
} else { }
tmp = WiFi.getHostname(); #endif // ARDUINO_ARCH_ESP8266
} return tmp.c_str();
#endif //ARDUINO_ARCH_ESP8266
return tmp.c_str();
} }
/** /**
* Check if password string is valid * Check if password string is valid
*/ */
bool WiFiConfig::isPasswordValid (const char * password) bool WiFiConfig::isPasswordValid(const char* password) {
{ if (strlen(password) == 0) {
if (strlen (password) == 0) { return true; // open network
return true; //open network }
} // limited size
//limited size if ((strlen(password) > MAX_PASSWORD_LENGTH) ||
if ((strlen (password) > MAX_PASSWORD_LENGTH) || (strlen (password) < MIN_PASSWORD_LENGTH)) { (strlen(password) < MIN_PASSWORD_LENGTH)) {
return false; return false;
} }
return true; return true;
} }
/* /*
* Get WiFi signal strength * Get WiFi signal strength
*/ */
int32_t WiFiConfig::getSignal (int32_t RSSI, bool filter) int32_t WiFiConfig::getSignal(int32_t RSSI, bool filter) {
{ if (RSSI < MIN_RSSI && filter) {
if (RSSI < MIN_RSSI && filter) { return 0;
return 0; }
} if (RSSI <= -100 && !filter) {
if (RSSI <= -100 && !filter) { return 0;
return 0; }
} if (RSSI >= -50) {
if (RSSI >= -50) { return 100;
return 100; }
} return (2 * (RSSI + 100));
return (2 * (RSSI + 100) );
} }
/* /*
* Connect client to AP * Connect client to AP
*/ */
bool WiFiConfig::ConnectSTA2AP() bool WiFiConfig::ConnectSTA2AP() {
{ String msg, msg_out;
String msg, msg_out; uint8_t count = 0;
uint8_t count = 0; uint8_t dot = 0;
uint8_t dot = 0; wl_status_t status = WiFi.status();
wl_status_t status = WiFi.status(); ESP3DOutput output(ESP_ALL_CLIENTS);
ESP3DOutput output(ESP_ALL_CLIENTS); log_esp3d("Connecting");
log_esp3d("Connecting");
#if COMMUNICATION_PROTOCOL != MKS_SERIAL #if COMMUNICATION_PROTOCOL != MKS_SERIAL
if (!Settings_ESP3D::isVerboseBoot()) { if (!Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Connecting"); output.printMSG("Connecting");
output.flush(); output.flush();
} }
#endif //#if COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
while (status != WL_CONNECTED && count < 40) { while (status != WL_CONNECTED && count < 40) {
switch (status) {
switch (status) { case WL_NO_SSID_AVAIL:
case WL_NO_SSID_AVAIL: msg = "No SSID";
msg="No SSID"; break;
break; case WL_CONNECT_FAILED:
case WL_CONNECT_FAILED: msg = "Connection failed";
msg="Connection failed"; break;
break; case WL_CONNECTED:
case WL_CONNECTED: break;
break; default:
default: if ((dot > 3) || (dot == 0)) {
if ((dot>3) || (dot==0) ) { dot = 0;
dot=0; msg_out = "Connecting";
msg_out = "Connecting";
}
msg_out+=".";
msg= msg_out;
log_esp3d("...");
dot++;
break;
} }
if (Settings_ESP3D::isVerboseBoot()) { msg_out += ".";
output.printMSG(msg.c_str()); msg = msg_out;
output.flush(); log_esp3d("...");
} dot++;
Hal::wait (500); break;
count++;
status = WiFi.status();
} }
return (status == WL_CONNECTED); if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG(msg.c_str());
output.flush();
}
Hal::wait(500);
count++;
status = WiFi.status();
}
return (status == WL_CONNECTED);
} }
/* /*
* Start client mode (Station) * Start client mode (Station)
*/ */
bool WiFiConfig::StartSTA() bool WiFiConfig::StartSTA() {
{ log_esp3d("StartSTA");
log_esp3d("StartSTA"); if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) { WiFi.softAPdisconnect();
WiFi.softAPdisconnect(); }
} WiFi.enableAP(false);
WiFi.enableAP (false); WiFi.enableSTA(true);
WiFi.enableSTA (true); WiFi.mode(WIFI_STA);
WiFi.mode(WIFI_STA); #if defined(ARDUINO_ARCH_ESP32)
#if defined (ARDUINO_ARCH_ESP32) esp_wifi_start();
esp_wifi_start(); WiFi.setMinSecurity(WIFI_AUTH_WEP);
WiFi.setMinSecurity(WIFI_AUTH_WEP); WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); #endif // ARDUINO_ARCH_ESP32
#endif //ARDUINO_ARCH_ESP32 // Get parameters for STA
//Get parameters for STA String SSID = Settings_ESP3D::read_string(ESP_STA_SSID);
String SSID = Settings_ESP3D::read_string(ESP_STA_SSID); String password = Settings_ESP3D::read_string(ESP_STA_PASSWORD);
String password = Settings_ESP3D::read_string(ESP_STA_PASSWORD);
if (Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) { if (Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) {
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_VALUE); int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_VALUE);
int32_t GW = Settings_ESP3D::read_IP(ESP_STA_GATEWAY_VALUE); int32_t GW = Settings_ESP3D::read_IP(ESP_STA_GATEWAY_VALUE);
int32_t MK = Settings_ESP3D::read_IP(ESP_STA_MASK_VALUE); int32_t MK = Settings_ESP3D::read_IP(ESP_STA_MASK_VALUE);
int32_t DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE); int32_t DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS); IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
WiFi.config(ip, gateway,mask,dns); WiFi.config(ip, gateway, mask, dns);
} }
ESP3DOutput output(ESP_ALL_CLIENTS); ESP3DOutput output(ESP_ALL_CLIENTS);
if (Settings_ESP3D::isVerboseBoot()) { if (Settings_ESP3D::isVerboseBoot()) {
String stmp; String stmp;
stmp = "Connecting to '" + SSID + "'";; stmp = "Connecting to '" + SSID + "'";
output.printMSG(stmp.c_str()); ;
} output.printMSG(stmp.c_str());
if (WiFi.begin(SSID.c_str(), (password.length() > 0)?password.c_str():nullptr)) { }
#if defined (ARDUINO_ARCH_ESP8266) if (WiFi.begin(SSID.c_str(),
WiFi.setSleepMode(WIFI_NONE_SLEEP); (password.length() > 0) ? password.c_str() : nullptr)) {
WiFi.hostname(NetConfig::hostname(true)); #if defined(ARDUINO_ARCH_ESP8266)
#endif //ARDUINO_ARCH_ESP8266 WiFi.setSleepMode(WIFI_NONE_SLEEP);
#if defined (ARDUINO_ARCH_ESP32) WiFi.hostname(NetConfig::hostname(true));
WiFi.setSleep(false); #endif // ARDUINO_ARCH_ESP8266
WiFi.setHostname(NetConfig::hostname(true)); #if defined(ARDUINO_ARCH_ESP32)
#endif //ARDUINO_ARCH_ESP32 WiFi.setSleep(false);
return ConnectSTA2AP(); WiFi.setHostname(NetConfig::hostname(true));
} else { #endif // ARDUINO_ARCH_ESP32
output.printERROR("Starting client failed"); return ConnectSTA2AP();
return false; } else {
} output.printERROR("Starting client failed");
return false;
}
} }
/** /**
* Setup and start Access point * Setup and start Access point
*/ */
bool WiFiConfig::StartAP(bool setupMode) bool WiFiConfig::StartAP(bool setupMode) {
{ ESP3DOutput output(ESP_ALL_CLIENTS);
ESP3DOutput output(ESP_ALL_CLIENTS); // Sanity check
//Sanity check if ((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) { if (WiFi.isConnected()) {
if(WiFi.isConnected()) { WiFi.disconnect();
WiFi.disconnect();
}
} }
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) { }
WiFi.softAPdisconnect(); if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
} WiFi.softAPdisconnect();
WiFi.enableAP (true); }
WiFi.enableSTA (false); WiFi.enableAP(true);
WiFi.mode(WIFI_AP); WiFi.enableSTA(false);
//Set Sleep Mode to none WiFi.mode(WIFI_AP);
#if defined (ARDUINO_ARCH_ESP8266) // Set Sleep Mode to none
WiFi.setSleepMode(WIFI_NONE_SLEEP); #if defined(ARDUINO_ARCH_ESP8266)
#endif //ARDUINO_ARCH_ESP8266 WiFi.setSleepMode(WIFI_NONE_SLEEP);
#endif // ARDUINO_ARCH_ESP8266
String SSID = Settings_ESP3D::read_string(ESP_AP_SSID); String SSID = Settings_ESP3D::read_string(ESP_AP_SSID);
String password = Settings_ESP3D::read_string(ESP_AP_PASSWORD); String password = Settings_ESP3D::read_string(ESP_AP_PASSWORD);
//channel // channel
int8_t channel = Settings_ESP3D::read_byte (ESP_AP_CHANNEL); int8_t channel = Settings_ESP3D::read_byte(ESP_AP_CHANNEL);
//IP // IP
int32_t IP = Settings_ESP3D::read_IP(ESP_AP_IP_VALUE); int32_t IP = Settings_ESP3D::read_IP(ESP_AP_IP_VALUE);
IPAddress ip(IP); IPAddress ip(IP);
IPAddress gw(0,0,0,0); IPAddress gw(0, 0, 0, 0);
IPAddress mask(DEFAULT_AP_MASK_VALUE); IPAddress mask(DEFAULT_AP_MASK_VALUE);
#if defined (ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
log_esp3d("Use: %s / %s / %s", ip.toString().c_str(),ip.toString().c_str(),mask.toString().c_str()); log_esp3d("Use: %s / %s / %s", ip.toString().c_str(), ip.toString().c_str(),
if (!WiFi.softAPConfig(ip, setupMode?ip:gw, mask)) { mask.toString().c_str());
output.printERROR("Set IP to AP failed"); if (!WiFi.softAPConfig(ip, setupMode ? ip : gw, mask)) {
output.printERROR("Set IP to AP failed");
} else {
output.printMSG(ip.toString().c_str());
}
#endif // ARDUINO_ARCH_ESP8266
// Start AP
if (WiFi.softAP(SSID.c_str(),
(password.length() > 0) ? password.c_str() : nullptr,
channel)) {
String stmp = "AP SSID: '" + SSID;
if (password.length() > 0) {
stmp += "' is started and protected by password";
} else { } else {
output.printMSG(ip.toString().c_str()); stmp += " is started not protected by password";
} }
#endif //ARDUINO_ARCH_ESP8266 if (setupMode) {
//Start AP stmp += " (setup mode)";
if(WiFi.softAP(SSID.c_str(), (password.length() > 0)?password.c_str():nullptr, channel)) { }
String stmp = "AP SSID: '" + SSID; output.printMSG(stmp.c_str());
if (password.length() > 0) { log_esp3d("%s", stmp.c_str());
stmp +="' is started and protected by password"; #if defined(ARDUINO_ARCH_ESP32)
} else { // must be done after starting AP not before
stmp +=" is started not protected by password"; // https://github.com/espressif/arduino-esp32/issues/4222
} // on some phone 100 is ok but on some other it is not enough so 2000 is ok
if (setupMode) { Hal::wait(2000);
stmp += " (setup mode)"; // Set static IP
} log_esp3d("Use: %s / %s / %s", ip.toString().c_str(), ip.toString().c_str(),
output.printMSG(stmp.c_str()); mask.toString().c_str());
log_esp3d("%s",stmp.c_str()); if (!WiFi.softAPConfig(ip, setupMode ? ip : gw, mask)) {
#if defined (ARDUINO_ARCH_ESP32) output.printERROR("Set IP to AP failed");
//must be done after starting AP not before
//https://github.com/espressif/arduino-esp32/issues/4222
//on some phone 100 is ok but on some other it is not enough so 2000 is ok
Hal::wait(2000);
//Set static IP
log_esp3d("Use: %s / %s / %s", ip.toString().c_str(),ip.toString().c_str(),mask.toString().c_str());
if (!WiFi.softAPConfig(ip, setupMode?ip:gw, mask)) {
output.printERROR("Set IP to AP failed");
} else {
output.printMSG(ip.toString().c_str());
}
WiFi.setSleep(false);
WiFi.softAPsetHostname(NetConfig::hostname(true));
#endif //ARDUINO_ARCH_ESP32
return true;
} else { } else {
output.printERROR("Starting AP failed"); output.printMSG(ip.toString().c_str());
log_esp3d("Starting AP failed");
return false;
} }
WiFi.setSleep(false);
WiFi.softAPsetHostname(NetConfig::hostname(true));
#endif // ARDUINO_ARCH_ESP32
return true;
} else {
output.printERROR("Starting AP failed");
log_esp3d_e("Starting AP failed");
return false;
}
} }
bool WiFiConfig::started() bool WiFiConfig::started() { return (WiFi.getMode() != WIFI_OFF); }
{
return (WiFi.getMode() != WIFI_OFF);
}
/** /**
* begin WiFi setup * begin WiFi setup
*/ */
bool WiFiConfig::begin(int8_t & espMode) bool WiFiConfig::begin(int8_t& espMode) {
{ bool res = false;
bool res = false; end();
end(); log_esp3d("Starting Wifi Config");
log_esp3d("Starting Wifi Config"); ESP3DOutput output(ESP_ALL_CLIENTS);
ESP3DOutput output(ESP_ALL_CLIENTS); if (Settings_ESP3D::isVerboseBoot()) {
if (Settings_ESP3D::isVerboseBoot()) { output.printMSG("Starting WiFi");
output.printMSG("Starting WiFi"); }
int8_t wifiMode = espMode;
if (wifiMode == ESP_WIFI_AP || wifiMode == ESP_AP_SETUP) {
log_esp3d("Starting AP mode");
res = StartAP(wifiMode == ESP_AP_SETUP);
} else if (wifiMode == ESP_WIFI_STA) {
log_esp3d("Starting STA");
res = StartSTA();
// AP is backup mode
if (!res) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting fallback mode");
}
espMode = Settings_ESP3D::read_byte(ESP_STA_FALLBACK_MODE);
NetConfig::setMode(espMode);
if (espMode == ESP_AP_SETUP) {
log_esp3d("Starting AP mode in setup mode");
res = StartAP(true);
} else {
// let setup to handle the change
res = true;
}
} }
int8_t wifiMode = espMode; }
if (wifiMode == ESP_WIFI_AP || wifiMode == ESP_AP_SETUP) { return res;
log_esp3d("Starting AP mode");
res = StartAP(wifiMode == ESP_AP_SETUP);
} else if (wifiMode == ESP_WIFI_STA) {
log_esp3d("Starting STA");
res = StartSTA();
//AP is backup mode
if(!res) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting fallback mode");
}
espMode = Settings_ESP3D::read_byte(ESP_STA_FALLBACK_MODE);
NetConfig::setMode(espMode);
if (espMode == ESP_AP_SETUP) {
log_esp3d("Starting AP mode in setup mode");
res = StartAP(true);
} else {
//let setup to handle the change
res = true;
}
}
}
return res;
} }
/** /**
* End WiFi * End WiFi
*/ */
void WiFiConfig::end() void WiFiConfig::end() {
{ // Sanity check
//Sanity check if ((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) { if (WiFi.isConnected()) {
if(WiFi.isConnected()) { WiFi.disconnect(true);
WiFi.disconnect(true);
}
} }
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) { }
if(WiFi.isConnected()) { if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
WiFi.softAPdisconnect(true); if (WiFi.isConnected()) {
} WiFi.softAPdisconnect(true);
} }
WiFi.mode(WIFI_OFF); }
WiFi.mode(WIFI_OFF);
} }
/** /**
* Handle not critical actions that must be done in sync environement * Handle not critical actions that must be done in sync environement
*/ */
void WiFiConfig::handle() void WiFiConfig::handle() {
{ // to avoid mixed mode
//to avoid mixed mode if (WiFi.getMode() == WIFI_AP_STA) {
if (WiFi.getMode() == WIFI_AP_STA) { if (WiFi.scanComplete() != WIFI_SCAN_RUNNING) {
if (WiFi.scanComplete() != WIFI_SCAN_RUNNING) { WiFi.enableSTA(false);
WiFi.enableSTA (false);
}
} }
}
} }
const char* WiFiConfig::getSleepModeString () const char* WiFiConfig::getSleepModeString() {
{
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (WiFi.getSleep()) { if (WiFi.getSleep()) {
return "modem"; return "modem";
} else { } else {
return "none"; return "none";
} }
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
WiFiSleepType_t ps_type = WiFi.getSleepMode(); WiFiSleepType_t ps_type = WiFi.getSleepMode();
if (ps_type == WIFI_NONE_SLEEP) { if (ps_type == WIFI_NONE_SLEEP) {
return "none"; return "none";
} else if (ps_type == WIFI_LIGHT_SLEEP) { } else if (ps_type == WIFI_LIGHT_SLEEP) {
return "light"; return "light";
} else if (ps_type == WIFI_MODEM_SLEEP) { } else if (ps_type == WIFI_MODEM_SLEEP) {
return "modem"; return "modem";
} else { } else {
return "unknown"; return "unknown";
} }
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }
const char* WiFiConfig::getPHYModeString (uint8_t wifimode) const char* WiFiConfig::getPHYModeString(uint8_t wifimode) {
{
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
uint8_t PhyMode; uint8_t PhyMode;
esp_wifi_get_protocol ((wifi_interface_t)((wifimode == WIFI_STA)?ESP_IF_WIFI_STA:ESP_IF_WIFI_AP), &PhyMode); esp_wifi_get_protocol(
#endif //ARDUINO_ARCH_ESP32 (wifi_interface_t)((wifimode == WIFI_STA) ? ESP_IF_WIFI_STA
: ESP_IF_WIFI_AP),
&PhyMode);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
(void)wifimode; (void)wifimode;
WiFiPhyMode_t PhyMode = WiFi.getPhyMode(); WiFiPhyMode_t PhyMode = WiFi.getPhyMode();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
if (PhyMode == (WIFI_PHY_MODE_11G) ) { if (PhyMode == (WIFI_PHY_MODE_11G)) {
return "11g"; return "11g";
} else if (PhyMode == (WIFI_PHY_MODE_11B) ) { } else if (PhyMode == (WIFI_PHY_MODE_11B)) {
return "11b"; return "11b";
} else if (PhyMode == (WIFI_PHY_MODE_11N) ) { } else if (PhyMode == (WIFI_PHY_MODE_11N)) {
return "11n"; return "11n";
} else { } else {
return "unknown"; return "unknown";
} }
} }
bool WiFiConfig::is_AP_visible() bool WiFiConfig::is_AP_visible() {
{
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf; wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf); esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
return (conf.ap.ssid_hidden == 0); return (conf.ap.ssid_hidden == 0);
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig; struct softap_config apconfig;
wifi_softap_get_config (&apconfig); wifi_softap_get_config(&apconfig);
return (apconfig.ssid_hidden == 0); return (apconfig.ssid_hidden == 0);
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
} }
const char * WiFiConfig::AP_SSID() const char* WiFiConfig::AP_SSID() {
{ static String ssid;
static String ssid;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf; wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf); esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
ssid = (const char*) conf.ap.ssid; ssid = (const char*)conf.ap.ssid;
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig; struct softap_config apconfig;
wifi_softap_get_config (&apconfig); wifi_softap_get_config(&apconfig);
ssid = (const char*) apconfig.ssid; ssid = (const char*)apconfig.ssid;
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
return ssid.c_str(); return ssid.c_str();
} }
const char * WiFiConfig::AP_Auth_String() const char* WiFiConfig::AP_Auth_String() {
{ uint8_t mode = 0;
uint8_t mode = 0;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf; wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf); esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
mode = conf.ap.authmode; mode = conf.ap.authmode;
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig; struct softap_config apconfig;
wifi_softap_get_config (&apconfig); wifi_softap_get_config(&apconfig);
mode = apconfig.authmode; mode = apconfig.authmode;
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
if (mode == AUTH_OPEN) { if (mode == AUTH_OPEN) {
return "none"; return "none";
} else if (mode == AUTH_WEP) { } else if (mode == AUTH_WEP) {
return "WEP"; return "WEP";
} else if (mode == AUTH_WPA_PSK) { } else if (mode == AUTH_WPA_PSK) {
return "WPA"; return "WPA";
} else if (mode == AUTH_WPA2_PSK) { } else if (mode == AUTH_WPA2_PSK) {
return "WPA2"; return "WPA2";
} else { } else {
return "WPA/WPA2"; return "WPA/WPA2";
} }
} }
const char * WiFiConfig::AP_Gateway_String() const char* WiFiConfig::AP_Gateway_String() {
{ static String tmp;
static String tmp;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP; tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info (TCPIP_ADAPTER_IF_AP, &ip_AP); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress (ip_AP.gw.addr).toString(); tmp = IPAddress(ip_AP.gw.addr).toString();
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
struct ip_info ip_AP; struct ip_info ip_AP;
if (!wifi_get_ip_info (SOFTAP_IF, &ip_AP)) { if (!wifi_get_ip_info(SOFTAP_IF, &ip_AP)) {
log_esp3d("Error getting gateway ip"); log_esp3d_e("Error getting gateway ip");
} }
tmp = IPAddress (ip_AP.gw).toString(); tmp = IPAddress(ip_AP.gw).toString();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
return tmp.c_str(); return tmp.c_str();
} }
const char * WiFiConfig::AP_Mask_String() const char* WiFiConfig::AP_Mask_String() {
{ static String tmp;
static String tmp;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP; tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info (TCPIP_ADAPTER_IF_AP, &ip_AP); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress (ip_AP.netmask.addr).toString(); tmp = IPAddress(ip_AP.netmask.addr).toString();
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
struct ip_info ip_AP; struct ip_info ip_AP;
if (!wifi_get_ip_info (SOFTAP_IF, &ip_AP)) { if (!wifi_get_ip_info(SOFTAP_IF, &ip_AP)) {
log_esp3d("Error getting mask ip"); log_esp3d_e("Error getting mask ip");
} }
tmp = IPAddress (ip_AP.netmask).toString(); tmp = IPAddress(ip_AP.netmask).toString();
#endif //ARDUINO_ARCH_ESP8266 #endif // ARDUINO_ARCH_ESP8266
return tmp.c_str(); return tmp.c_str();
} }
const char * WiFiConfig::getConnectedSTA(uint8_t * totalcount, bool reset) const char* WiFiConfig::getConnectedSTA(uint8_t* totalcount, bool reset) {
{ static uint8_t count = 0;
static uint8_t count = 0; static uint8_t current = 0;
static uint8_t current = 0; static String data;
static String data; data = "";
data = "";
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (current > count) { if (current > count) {
current =0; current = 0;
} }
static wifi_sta_list_t station; static wifi_sta_list_t station;
static tcpip_adapter_sta_list_t tcpip_sta_list; static tcpip_adapter_sta_list_t tcpip_sta_list;
if (reset) { if (reset) {
count = 0; count = 0;
} }
if (count == 0) { if (count == 0) {
current = 0; current = 0;
esp_wifi_ap_get_sta_list (&station); esp_wifi_ap_get_sta_list(&station);
tcpip_adapter_get_sta_list (&station, &tcpip_sta_list); tcpip_adapter_get_sta_list(&station, &tcpip_sta_list);
count = station.num; count = station.num;
} }
if (count > 0) { if (count > 0) {
data = IPAddress (tcpip_sta_list.sta[current].ip.addr).toString(); data = IPAddress(tcpip_sta_list.sta[current].ip.addr).toString();
data += "("; data += "(";
data += NetConfig::mac2str(tcpip_sta_list.sta[current].mac); data += NetConfig::mac2str(tcpip_sta_list.sta[current].mac);
data += ")"; data += ")";
current++; current++;
} }
#endif //ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
static struct station_info * station; static struct station_info* station;
if (current > count) { if (current > count) {
current = 0; current = 0;
count = 0; count = 0;
}
if (reset) {
count = 0;
}
if (count == 0) {
current = 0;
station = wifi_softap_get_station_info();
struct station_info* station_tmp = station;
while (station) {
// go next record
count++;
station = STAILQ_NEXT(station, next);
} }
if (reset) { station = station_tmp;
count = 0; }
if ((count > 0) && station) {
data = IPAddress((const uint8_t*)&station->ip).toString();
data += "(";
data += NetConfig::mac2str(station->bssid);
data += ")";
current++;
station = STAILQ_NEXT(station, next);
if ((current == count) || !station) {
wifi_softap_free_station_info();
} }
if (count == 0) { }
current = 0; #endif // ARDUINO_ARCH_ESP8266
station = wifi_softap_get_station_info(); if (totalcount) {
struct station_info * station_tmp = station; *totalcount = count;
while (station) { }
//go next record return data.c_str();
count++;
station = STAILQ_NEXT (station, next);
}
station = station_tmp;
}
if ((count > 0) && station) {
data = IPAddress ((const uint8_t *) &station->ip).toString();
data += "(";
data += NetConfig::mac2str(station->bssid);
data += ")";
current++;
station = STAILQ_NEXT (station, next);
if ((current == count) || !station) {
wifi_softap_free_station_info();
}
}
#endif //ARDUINO_ARCH_ESP8266
if(totalcount) {
*totalcount = count;
}
return data.c_str();
} }
#endif // WIFI_FEATURE #endif // WIFI_FEATURE