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

View File

@ -20,25 +20,25 @@
#ifndef _ESP3D_H
#define _ESP3D_H
//be sure correct IDE and settings are used for ESP8266 or ESP32
#if !(defined( ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32))
// be sure correct IDE and settings are used for ESP8266 or 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.
#endif // ARDUINO_ARCH_ESP8266 + ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP8266 + ARDUINO_ARCH_ESP32
#include <Arduino.h>
class Esp3D
{
public:
Esp3D();
~Esp3D();
bool begin();
void handle();
bool end();
bool started();
static bool reset();
static void restart_esp(bool need_restart = true);
private:
static bool restart;
bool _started;
void restart_now();
class Esp3D {
public:
Esp3D();
~Esp3D();
bool begin();
void handle();
bool end();
bool started();
static bool reset();
static void restart_esp(bool need_restart = true);
private:
static bool restart;
bool _started;
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
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"
#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 "../esp3doutput.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) {
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);
#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");
}
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
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"
#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 "../esp3doutput.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>
bool Commands::ESP701(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
{
bool noError = true;
bool json = has_tag (cmd_params, "json");
String response;
String parameter;
int errorCode = 200; //unless it is a server error use 200 as default and set error in json instead
bool Commands::ESP701(const char* cmd_params, level_authenticate_type auth_type,
ESP3DOutput* output) {
bool noError = true;
bool json = has_tag(cmd_params, "json");
String response;
String parameter;
int errorCode = 200; // unless it is a server error use 200 as default and
// set error in json instead
#ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) {
response = format_response(COMMANDID, json, false, "Wrong authentication level");
noError = false;
errorCode = 401;
}
if (auth_type != LEVEL_ADMIN) {
response =
format_response(COMMANDID, json, false, "Wrong authentication level");
noError = false;
errorCode = 401;
}
#else
(void)auth_type;
#endif //AUTHENTICATION_FEATURE
if (noError) {
parameter = (get_param (cmd_params, "action="));
if (parameter.length() != 0) {
if (parameter.equalsIgnoreCase("PAUSE")) {
if (esp3d_gcode_host.pause()) {
response = format_response(COMMANDID, json, true, "Stream paused");
} else {
response = format_response(COMMANDID, json, false, "No stream to pause");
noError = false;
}
} else if (parameter.equalsIgnoreCase("RESUME")) {
if (esp3d_gcode_host.resume()) {
response = format_response(COMMANDID, json, true, "Stream resumed");
} else {
response = format_response(COMMANDID, json, false, "No stream to resume");
noError = false;
}
} else if (parameter.equalsIgnoreCase("ABORT")) {
if (esp3d_gcode_host.abort()) {
response = format_response(COMMANDID, json, true, "Stream aborted");
} else {
response = format_response(COMMANDID, json, false, "No stream to abort");
noError = false;
}
}
if (parameter.equalsIgnoreCase("CLEAR_ERROR")) {
esp3d_gcode_host.setErrorNum(ERROR_NO_ERROR);
response = format_response(COMMANDID, json, true, "Error cleared");
} else {
response = format_response(COMMANDID, json, false, "Unknown action");
noError = false;
}
(void)auth_type;
#endif // AUTHENTICATION_FEATURE
if (noError) {
parameter = (get_param(cmd_params, "action="));
if (parameter.length() != 0) {
if (parameter.equalsIgnoreCase("PAUSE")) {
if (esp3d_gcode_host.pause()) {
response = format_response(COMMANDID, json, true, "Stream paused");
} else {
response =
format_response(COMMANDID, json, false, "No stream to pause");
noError = false;
}
} else if (parameter.equalsIgnoreCase("RESUME")) {
if (esp3d_gcode_host.resume()) {
response = format_response(COMMANDID, json, true, "Stream resumed");
} else {
response =
format_response(COMMANDID, json, false, "No stream to resume");
noError = false;
}
} else if (parameter.equalsIgnoreCase("ABORT")) {
if (esp3d_gcode_host.abort()) {
response = format_response(COMMANDID, json, true, "Stream aborted");
} else {
response =
format_response(COMMANDID, json, false, "No stream to abort");
noError = false;
}
}
if (parameter.equalsIgnoreCase("CLEAR_ERROR")) {
esp3d_gcode_host.setErrorNum(ERROR_NO_ERROR);
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 {
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)
#include <ESP8266WiFi.h>
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
#include <soc/soc.h>
#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>
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#include <soc/rtc_cntl_reg.h>
#endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#include <WiFi.h>
#include <esp_task_wdt.h>
#include <driver/adc.h>
#include <esp_task_wdt.h>
#include <soc/rtc_cntl_reg.h>
TaskHandle_t Hal::xHandle = nullptr;
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
#include "esp3doutput.h"
uint32_t Hal::_analogRange = 255;
uint32_t Hal::_analogWriteFreq = 1000;
void Hal::pinMode(uint8_t pin, uint8_t mode)
{
#if defined (ARDUINO_ARCH_ESP8266)
if ((pin == 16) && (mode == INPUT_PULLUP)) {
::pinMode(pin, INPUT_PULLDOWN_16);
return;
}
void Hal::pinMode(uint8_t pin, uint8_t mode) {
#if defined(ARDUINO_ARCH_ESP8266)
if ((pin == 16) && (mode == INPUT_PULLUP)) {
::pinMode(pin, INPUT_PULLDOWN_16);
return;
}
#endif
::pinMode(pin, mode);
::pinMode(pin, mode);
}
int Hal::analogRead(uint8_t pin)
{
#ifdef ARDUINO_ARCH_ESP8266 //only one ADC on ESP8266 A0
(void)pin;
return ::analogRead (A0);
int Hal::analogRead(uint8_t pin) {
#ifdef ARDUINO_ARCH_ESP8266 // only one ADC on ESP8266 A0
(void)pin;
return ::analogRead(A0);
#else
return ::analogRead (pin);
return ::analogRead(pin);
#endif
}
bool Hal::analogWrite(uint8_t pin, uint value)
{
if (value > (_analogRange-1)) {
return false;
}
bool Hal::analogWrite(uint8_t pin, uint value) {
if (value > (_analogRange - 1)) {
return false;
}
#ifdef ARDUINO_ARCH_ESP8266
::analogWrite(pin, value);
#endif //ARDUINO_ARCH_ESP8266
::analogWrite(pin, value);
#endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
::analogWrite(pin, value);
#endif //ARDUINO_ARCH_ESP32
return true;
::analogWrite(pin, value);
#endif // ARDUINO_ARCH_ESP32
return true;
}
void Hal::analogWriteFreq(uint32_t freq)
{
_analogWriteFreq = freq;
void Hal::analogWriteFreq(uint32_t freq) {
_analogWriteFreq = freq;
#ifdef ARDUINO_ARCH_ESP8266
::analogWriteFreq(_analogWriteFreq);
#endif //ARDUINO_ARCH_ESP8266
::analogWriteFreq(_analogWriteFreq);
#endif // ARDUINO_ARCH_ESP8266
}
void Hal::analogRange(uint32_t range)
{
_analogRange = range;
uint8_t resolution = 0;
switch(_analogRange) {
void Hal::analogRange(uint32_t range) {
_analogRange = range;
uint8_t resolution = 0;
switch (_analogRange) {
case 8191:
resolution=13;
break;
resolution = 13;
break;
case 1024:
resolution=10;
break;
resolution = 10;
break;
case 2047:
resolution=11;
break;
resolution = 11;
break;
case 4095:
resolution=12;
break;
resolution = 12;
break;
default:
resolution=8;
_analogRange = 255;
break;
}
resolution = 8;
_analogRange = 255;
break;
}
#if defined(ARDUINO_ARCH_ESP32)
analogReadResolution(resolution);
#endif //ARDUINO_ARCH_ESP32
analogReadResolution(resolution);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
(void)resolution;
::analogWriteRange(_analogRange);
#endif //ARDUINO_ARCH_ESP8266
(void)resolution;
::analogWriteRange(_analogRange);
#endif // ARDUINO_ARCH_ESP8266
}
//Setup
bool Hal::begin()
{
// Setup
bool Hal::begin() {
#if defined(ARDUINO_ARCH_ESP32) && defined(CAMERA_DEVICE)
log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
#endif //ARDUINO_ARCH_ESP32 && CAMERA_DEVICE
//Clear all wifi state
WiFi.persistent(false);
WiFi.disconnect(true);
WiFi.enableSTA (false);
WiFi.enableAP (false);
WiFi.mode (WIFI_OFF);
log_esp3d("Disable brown out");
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable brownout detector
#endif // ARDUINO_ARCH_ESP32 && CAMERA_DEVICE
// Clear all wifi state
WiFi.persistent(false);
WiFi.disconnect(true);
WiFi.enableSTA(false);
WiFi.enableAP(false);
WiFi.mode(WIFI_OFF);
#if SD_DEVICE_CONNECTION == ESP_SHARED_SD
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
pinMode (ESP_SD_DETECT_PIN, INPUT);
pinMode(ESP_SD_DETECT_PIN, INPUT);
#endif
#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 true;
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 true;
}
//End ESP3D
void Hal::end()
{
}
// End ESP3D
void Hal::end() {}
//Watchdog feeder
void Hal::wdtFeed()
{
// Watchdog feeder
void Hal::wdtFeed() {
#ifdef ARDUINO_ARCH_ESP8266
ESP.wdtFeed();
#endif //ARDUINO_ARCH_ESP8266
ESP.wdtFeed();
#endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
static uint64_t lastYield = 0;
uint64_t now = millis();
if((now - lastYield) > 2000) {
lastYield = now;
vTaskDelay(5); //delay 1 RTOS tick
}
static uint64_t lastYield = 0;
uint64_t now = millis();
if ((now - lastYield) > 2000) {
lastYield = now;
vTaskDelay(5); // delay 1 RTOS tick
}
#if !defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
#if CONFIG_IDF_TARGET_ESP32
//FIXME: not implemented
rtc_wdt_feed();
#endif //CONFIG_IDF_TARGET_ESP32S2
#endif//!defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
// FIXME: not implemented
rtc_wdt_feed();
#endif // CONFIG_IDF_TARGET_ESP32S2
#endif //! defined(DISABLE_WDT_ESP3DLIB_TASK) && !defined(DISABLE_WDT_CORE_0)
#ifndef DISABLE_WDT_ESP3DLIB_TASK
if (xHandle && esp_task_wdt_status(xHandle)==ESP_OK) {
if (esp_task_wdt_reset()!=ESP_OK) {
log_esp3d("WDT Reset failed");
}
if (xHandle && esp_task_wdt_status(xHandle) == ESP_OK) {
if (esp_task_wdt_reset() != ESP_OK) {
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
void Hal::wait (uint32_t milliseconds)
{
// wait function
void Hal::wait(uint32_t milliseconds) {
#if defined(ASYNCWEBSERVER)
uint32_t timeout = millis();
while ( (millis() - timeout) < milliseconds) {
wdtFeed();
}
#else // !(ASYNCWEBSERVER
uint32_t timeout = millis();
while ((millis() - timeout) < milliseconds) {
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
}
#else // !(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
return ESP.getChipId();
#endif //ARDUINO_ARCH_ESP8266
return ESP.getChipId();
#endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
return (uint16_t) (ESP.getEfuseMac() >> 32);
#endif //ARDUINO_ARCH_ESP32
return (uint16_t)(ESP.getEfuseMac() >> 32);
#endif // ARDUINO_ARCH_ESP32
}
bool Hal::has_temperature_sensor()
{
bool Hal::has_temperature_sensor() {
#ifdef ARDUINO_ARCH_ESP8266
return false;
#endif //ARDUINO_ARCH_ESP8266
return false;
#endif // ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_ESP32
#if CONFIG_IDF_TARGET_ESP32S3
//FIXME: not yet implemented
return false;
// FIXME: not yet implemented
return false;
#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;
#endif //CONFIG_IDF_TARGET_ESP32S3
#endif //ARDUINO_ARCH_ESP32
}
float Hal::temperature()
{
#ifdef ARDUINO_ARCH_ESP8266
return 0.0;
#endif //ARDUINO_ARCH_ESP8266
} else {
return false;
}
#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;
} 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
// 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 "********"
// Debug
#define DEBUG_OUTPUT_SERIAL0 1
#define DEBUG_OUTPUT_SERIAL1 2
#define DEBUG_OUTPUT_SERIAL2 3
#define DEBUG_OUTPUT_TELNET 4
#define DEBUG_OUTPUT_WEBSOCKET 5
#define LOG_OUTPUT_SERIAL0 1
#define LOG_OUTPUT_SERIAL1 2
#define LOG_OUTPUT_SERIAL2 3
#define LOG_OUTPUT_TELNET 4
#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
#define USE_SERIAL_0 1

View File

@ -21,15 +21,17 @@
#ifndef _ESP3D_CONFIG_H
#define _ESP3D_CONFIG_H
#include <Arduino.h>
#include "../include/defines.h"
#if defined __has_include
# if __has_include ("../../configuration.h")
#if __has_include("../../configuration.h")
#include "../../configuration.h"
#define ESP3D_CODE_BASE "ESP3D"
#else
#undef DISABLED
#undef _BV
# if __has_include ("../esp3dlib_config.h")
#if __has_include("../esp3dlib_config.h")
#include "../esp3dlib_config.h"
#define ESP3D_CODE_BASE "ESP3DLib"
#else
@ -38,22 +40,23 @@
#endif
#endif
#include "../core/hal.h"
#include "../core/log_esp3d.h"
#include "../include/pins.h"
#include "../include/sanity_esp3d.h"
#include "../core/hal.h"
#include "../core/debug_esp3d.h"
#include "../include/version.h"
#if defined(ARDUINO_ARCH_ESP8266)
/************************************
*
* SSL Client
*
* **********************************/
//Using BearSSL need to decrease size of packet to not be OOM on ESP8266
#define BEARSSL_MFLN_SIZE 512
#define BEARSSL_MFLN_SIZE_FALLBACK 4096
#endif // ARDUINO_ARCH_ESP8266
// Using BearSSL need to decrease size of packet to not be OOM on ESP8266
#define BEARSSL_MFLN_SIZE 512
#define BEARSSL_MFLN_SIZE_FALLBACK 4096
#endif // ARDUINO_ARCH_ESP8266
/************************************
*
@ -61,13 +64,17 @@
*
* **********************************/
//Make Flag more generic
#if (defined(PIN_RESET_FEATURE) && defined(ESP3D_RESET_PIN) && ESP3D_RESET_PIN!=-1) || defined(SD_RECOVERY_FEATURE)
// Make Flag more generic
#if (defined(PIN_RESET_FEATURE) && defined(ESP3D_RESET_PIN) && \
ESP3D_RESET_PIN != -1) || \
defined(SD_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
#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_SERIAL_BRIDGE_OUTPUT
#ifndef ESP_DEBUG_RX_PIN
#define ESP_DEBUG_RX_PIN -1
#endif // ESP_DEBUG_RX_PIN
#ifndef ESP_DEBUG_TX_PIN
#define ESP_DEBUG_TX_PIN -1
#endif // ESP_DEBUG_TX_PIN
#ifndef ESP_LOG_RX_PIN
#define ESP_LOG_RX_PIN -1
#endif // ESP_LOG_RX_PIN
#ifndef ESP_LOG_TX_PIN
#define ESP_LOG_TX_PIN -1
#endif // ESP_LOG_TX_PIN
// I2C Pins
#ifndef ESP_SDA_PIN

View File

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

View File

@ -20,379 +20,364 @@
#include "../../include/esp3d_config.h"
#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>
#if defined (SD_DEVICE)
#include "../filesystem/esp_sd.h"
#endif //SD_DEVICE
#include <esp_camera.h>
#include <soc/rtc_cntl_reg.h>
#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 JPEG_COMPRESSION 80
Camera esp3d_camera;
bool Camera::handle_snap(WebServer * webserver, const char *path, const char* filename)
{
log_esp3d("Camera stream reached");
if (!_initialised) {
log_esp3d("Camera not started");
if (webserver) {
webserver->send (500, "text/plain", "Camera not started");
}
return false;
}
sensor_t * s = esp_camera_sensor_get();
bool Camera::handle_snap(WebServer *webserver, const char *path,
const char *filename) {
log_esp3d("Camera stream reached");
if (!_initialised) {
log_esp3d_e("Camera not started");
if (webserver) {
if (webserver->hasArg ("framesize") ) {
if(s->status.framesize != webserver->arg ("framesize").toInt()) {
command("framesize", webserver->arg ("framesize").c_str());
}
}
if (webserver->hasArg ("hmirror") ) {
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());
}
webserver->send(500, "text/plain", "Camera not started");
}
return false;
}
sensor_t *s = esp_camera_sensor_get();
if (webserver) {
if (webserver->hasArg("framesize")) {
if (s->status.framesize != webserver->arg("framesize").toInt()) {
command("framesize", webserver->arg("framesize").c_str());
}
}
if (webserver->hasArg("hmirror")) {
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
webserver->enableCrossOrigin(true);
#endif //ESP_ACCESS_CONTROL_ALLOw_ORIGIN
}
camera_fb_t * fb = NULL;
bool res_error = false;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
webserver->enableCrossOrigin(true);
#endif // ESP_ACCESS_CONTROL_ALLOw_ORIGIN
}
camera_fb_t *fb = NULL;
bool res_error = false;
size_t _jpg_buf_len = 0;
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) {
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);
webserver->send(500, "text/plain", "Capture failed");
}
log_esp3d("Camera capture ongoing");
fb = esp_camera_fb_get();
if (!fb) {
log_esp3d("Camera capture failed");
if (webserver) {
webserver->send (500, "text/plain", "Capture failed");
}
res_error=true;
res_error = true;
} else {
if (fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted =
frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if (!jpeg_converted) {
log_esp3d_e("JPEG compression failed");
res_error = true;
}
} else {
if(fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted = frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len);
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;
}
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
if (!res_error) {
if(webserver) {
webserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len);
}
#if defined (SD_DEVICE)
if (filename!=nullptr && path!=nullptr) {
if (!ESP_SD::accessFS()) {
res_error = true;
log_esp3d("SD not available");
}
if (!res_error) {
if (webserver) {
webserver->sendContent_P((const char *)_jpg_buf, _jpg_buf_len);
}
#if defined(SD_DEVICE)
if (filename != nullptr && path != nullptr) {
if (!ESP_SD::accessFS()) {
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 {
if (ESP_SD::getState(true) == ESP_SDCARD_NOT_PRESENT) {
res_error = true;
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();
res_error = true;
log_esp3d_e("Failed to open file for writing");
}
}
#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) {
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf) {
free(_jpg_buf);
_jpg_buf = NULL;
}
if(webserver) {
webserver->sendContent("");
}
return !res_error;
if (fb) {
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if (_jpg_buf) {
free(_jpg_buf);
_jpg_buf = NULL;
}
if (webserver) {
webserver->sendContent("");
}
return !res_error;
}
Camera::Camera()
{
_started = false;
_initialised = false;
Camera::Camera() {
_started = false;
_initialised = false;
}
Camera::~Camera()
{
end();
}
Camera::~Camera() { end(); }
int Camera::command(const char * param, const char * value)
{
log_esp3d("Camera: %s=%s\n",param, value);
int res = 0;
int val = atoi(value);
sensor_t * s = esp_camera_sensor_get();
if (s == nullptr) {
res = -1;
}
int Camera::command(const char *param, const char *value) {
log_esp3d("Camera: %s=%s\n", param, value);
int res = 0;
int val = atoi(value);
sensor_t *s = esp_camera_sensor_get();
if (s == nullptr) {
res = -1;
}
#if CAM_LED_PIN != -1
if (!strcmp(param, "light")) {
digitalWrite(CAM_LED_PIN, val==1?HIGH:LOW);
} else
#endif //CAM_LED_PIN
if(!strcmp(param, "framesize")) {
if(s->pixformat == PIXFORMAT_JPEG) {
res = s->set_framesize(s, (framesize_t)val);
}
} else if(!strcmp(param, "quality")) {
res = s->set_quality(s, val);
} else if(!strcmp(param, "contrast")) {
res = s->set_contrast(s, val);
} else if(!strcmp(param, "brightness")) {
res = s->set_brightness(s, val);
} else if(!strcmp(param, "saturation")) {
res = s->set_saturation(s, val);
} else if(!strcmp(param, "gainceiling")) {
res = s->set_gainceiling(s, (gainceiling_t)val);
} else if(!strcmp(param, "colorbar")) {
res = s->set_colorbar(s, val);
} else if(!strcmp(param, "awb")) {
res = s->set_whitebal(s, val);
} else if(!strcmp(param, "agc")) {
res = s->set_gain_ctrl(s, val);
} else if(!strcmp(param, "aec")) {
res = s->set_exposure_ctrl(s, val);
} else if(!strcmp(param, "hmirror")) {
res = s->set_hmirror(s, val);
} else if(!strcmp(param, "vflip")) {
res = s->set_vflip(s, val);
} else if(!strcmp(param, "awb_gain")) {
res = s->set_awb_gain(s, val);
} else if(!strcmp(param, "agc_gain")) {
res = s->set_agc_gain(s, val);
} else if(!strcmp(param, "aec_value")) {
res = s->set_aec_value(s, val);
} else if(!strcmp(param, "aec2")) {
res = s->set_aec2(s, val);
} else if(!strcmp(param, "dcw")) {
res = s->set_dcw(s, val);
} else if(!strcmp(param, "bpc")) {
res = s->set_bpc(s, val);
} else if(!strcmp(param, "wpc")) {
res = s->set_wpc(s, val);
} else if(!strcmp(param, "raw_gma")) {
res = s->set_raw_gma(s, val);
} else if(!strcmp(param, "lenc")) {
res = s->set_lenc(s, val);
} else if(!strcmp(param, "special_effect")) {
res = s->set_special_effect(s, val);
} else if(!strcmp(param, "wb_mode")) {
res = s->set_wb_mode(s, val);
} else if(!strcmp(param, "ae_level")) {
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);
if (!strcmp(param, "light")) {
digitalWrite(CAM_LED_PIN, val == 1 ? HIGH : LOW);
} else
#endif // CAM_LED_PIN
if (!strcmp(param, "framesize")) {
if (s->pixformat == PIXFORMAT_JPEG) {
res = s->set_framesize(s, (framesize_t)val);
}
} else if (!strcmp(param, "quality")) {
res = s->set_quality(s, val);
} else if (!strcmp(param, "contrast")) {
res = s->set_contrast(s, val);
} else if (!strcmp(param, "brightness")) {
res = s->set_brightness(s, val);
} else if (!strcmp(param, "saturation")) {
res = s->set_saturation(s, val);
} else if (!strcmp(param, "gainceiling")) {
res = s->set_gainceiling(s, (gainceiling_t)val);
} else if (!strcmp(param, "colorbar")) {
res = s->set_colorbar(s, val);
} else if (!strcmp(param, "awb")) {
res = s->set_whitebal(s, val);
} else if (!strcmp(param, "agc")) {
res = s->set_gain_ctrl(s, val);
} else if (!strcmp(param, "aec")) {
res = s->set_exposure_ctrl(s, val);
} else if (!strcmp(param, "hmirror")) {
res = s->set_hmirror(s, val);
} else if (!strcmp(param, "vflip")) {
res = s->set_vflip(s, val);
} else if (!strcmp(param, "awb_gain")) {
res = s->set_awb_gain(s, val);
} else if (!strcmp(param, "agc_gain")) {
res = s->set_agc_gain(s, val);
} else if (!strcmp(param, "aec_value")) {
res = s->set_aec_value(s, val);
} else if (!strcmp(param, "aec2")) {
res = s->set_aec2(s, val);
} else if (!strcmp(param, "dcw")) {
res = s->set_dcw(s, val);
} else if (!strcmp(param, "bpc")) {
res = s->set_bpc(s, val);
} else if (!strcmp(param, "wpc")) {
res = s->set_wpc(s, val);
} else if (!strcmp(param, "raw_gma")) {
res = s->set_raw_gma(s, val);
} else if (!strcmp(param, "lenc")) {
res = s->set_lenc(s, val);
} else if (!strcmp(param, "special_effect")) {
res = s->set_special_effect(s, val);
} else if (!strcmp(param, "wb_mode")) {
res = s->set_wb_mode(s, val);
} else if (!strcmp(param, "ae_level")) {
res = s->set_ae_level(s, val);
} else {
_initialised = true;
res = -1;
}
return _initialised;
return res;
}
bool Camera::stopHardware()
{
return true;
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_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::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
}
bool Camera::stopHardware() { return true; }
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)
s->set_hmirror(s, 1);
#endif //CAMERA_DEVICE_FLIP_HORIZONTALY
s->set_hmirror(s, 1);
#endif // CAMERA_DEVICE_FLIP_HORIZONTALY
#if defined(CAMERA_DEVICE_FLIP_VERTICALY)
s->set_vflip(s, 1);
#endif //CAMERA_DEVICE_FLIP_VERTICALY
} else {
log_esp3d("Cannot access camera sensor");
}
_started = _initialised;
return _started;
s->set_vflip(s, 1);
#endif // CAMERA_DEVICE_FLIP_VERTICALY
} else {
log_esp3d("Cannot access camera sensor");
}
_started = _initialised;
return _started;
}
void Camera::end()
{
_started = false;
void Camera::end() { _started = false; }
void Camera::handle() {
// nothing to do
}
void Camera::handle()
{
//nothing to do
}
uint8_t Camera::GetModel() { return CAMERA_DEVICE; }
uint8_t Camera::GetModel()
{
return CAMERA_DEVICE;
}
const char *Camera::GetModelString()
{
const char *Camera::GetModelString() {
#if defined(CUSTOM_CAMERA_NAME)
return CUSTOM_CAMERA_NAME;
return CUSTOM_CAMERA_NAME;
#else
switch(CAMERA_DEVICE) {
switch (CAMERA_DEVICE) {
case CAMERA_MODEL_WROVER_KIT:
return "WROVER Kit";
break;
return "WROVER Kit";
break;
case CAMERA_MODEL_ESP32S3_EYE:
case CAMERA_MODEL_ESP_EYE:
return "ESP Eye";
break;
return "ESP Eye";
break;
case CAMERA_MODEL_M5STACK_WIDE:
case CAMERA_MODEL_M5STACK_V2_PSRAM:
case CAMERA_MODEL_M5STACK_PSRAM:
return "M5Stack";
break;
return "M5Stack";
break;
case CAMERA_MODEL_ESP32_CAM_BOARD:
case CAMERA_MODEL_ESP32S2_CAM_BOARD:
case CAMERA_MODEL_ESP32S3_CAM_LCD:
case CAMERA_MODEL_AI_THINKER:
return "ESP32 Cam";
break;
return "ESP32 Cam";
break;
default:
return "Unknow Camera";
}
#endif //CUSTOM_CAMERA_NAME
return "Unknow Camera";
}
#endif // CUSTOM_CAMERA_NAME
}
#endif //CAMERA_DEVICE
#endif // CAMERA_DEVICE

View File

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

View File

@ -19,33 +19,33 @@
*/
#include "../../include/esp3d_config.h"
#if defined (ETH_FEATURE)
#if defined(ETH_FEATURE)
#ifdef ARDUINO_ARCH_ESP32
#include "esp_eth.h"
#include "dhcpserver/dhcpserver_options.h"
#endif //ARDUINO_ARCH_ESP32
#include "esp_eth.h"
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP8266
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "../network/netconfig.h"
#include "ethconfig.h"
bool EthConfig::_started = 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 res = true;
if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) {
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_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 DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
res = ETH.config(ip, gateway,mask,dns);
}
return res;
bool EthConfig::StartSTA() {
bool res = true;
if ((Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE)) {
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_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 DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
res = ETH.config(ip, gateway, mask, dns);
}
return res;
}
/*bool EthConfig::StartSRV()
{
@ -55,7 +55,7 @@ bool EthConfig::StartSTA()
IPAddress ip(IP), mask(DEFAULT_AP_MASK_VALUE), gateway(IP);
if (!ETH.config(ip, gateway,mask)) {
res = false;
log_esp3d("Set static IP error");
log_esp3d_e("Set static IP error");
}
//start DHCP server
if(res) {
@ -72,97 +72,86 @@ bool EthConfig::StartSTA()
if (tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_ETH) != ESP_OK){
res = false;
log_esp3d("Start DHCP server failed");
log_esp3d_e("Start DHCP server failed");
}
}
return res;
}*/
bool EthConfig::linkUp()
{
#if defined( ESP_IDF_VERSION_MAJOR )
//patch for https://github.com/espressif/arduino-esp32/issues/6105
return _connected;
bool EthConfig::linkUp() {
#if defined(ESP_IDF_VERSION_MAJOR)
// patch for https://github.com/espressif/arduino-esp32/issues/6105
return _connected;
#else
return ETH.linkUp();
return ETH.linkUp();
#endif
}
/**
* begin WiFi setup
*/
bool EthConfig::begin(int8_t & espMode)
{
bool res = false;
ESP3DOutput output(ESP_ALL_CLIENTS);
end();
_started = ETH.begin();
if (_started) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting Ethernet");
}
res=true;
bool EthConfig::begin(int8_t& espMode) {
bool res = false;
ESP3DOutput output(ESP_ALL_CLIENTS);
end();
_started = ETH.begin();
if (_started) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting Ethernet");
}
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 {
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 {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG ("Client started");
}
}
} else {
//if(!StartSRV()){
// res = false;
// output.printMSG ("Failed Starting Server");
//} else {
// output.printMSG ("Server started");
//}
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Client 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)) {
//as no event to display static IP
output.printMSG (ETH.localIP().toString().c_str());
}
// 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)) {
// as no event to display static IP
output.printMSG(ETH.localIP().toString().c_str());
}
return res;
return res;
}
/**
* End WiFi
*/
void EthConfig::end()
{
//esp_eth_disable();
_started = false;
void EthConfig::end() {
// esp_eth_disable();
_started = false;
}
bool EthConfig::started()
{
return _started;
}
bool EthConfig::started() { return _started; }
/**
* Handle not critical actions that must be done in sync environement
*/
void EthConfig::handle()
{
}
#endif // ETH_FEATURE
void EthConfig::handle() {}
#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
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"
#ifdef SD_DEVICE
#include <time.h>
@ -152,7 +152,7 @@ bool ESP_SD::accessFS(uint8_t FS) {
log_esp3d("Access SD ok");
return true;
} else {
log_esp3d("Enable shared SD failed");
log_esp3d_e("Enable shared SD failed");
return false;
}
#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
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"
#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM)
#include "../esp_filesystem.h"
#include <stack>
#include <FS.h>
#include <stack>
#include "../esp_filesystem.h"
#include "FFat.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin()
{
_started = FFat.begin();
bool ESP_FileSystem::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;
}
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();
}
res = FFat.exists(path);
if (!res) {
ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
return res;
root.close();
}
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("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 = 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();
bool ESP_FileSystem::remove(const char *path) { return FFat.remove(path); }
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 FFat.mkdir(p);
}
bool ESP_FileSystem::exists(const char* path)
{
bool res = false;
//root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
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);
}
res = FFat.exists(path);
if (!res) {
ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ);
if (root) {
res = root.isDirectory();
}
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;
}
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)
{
return FFat.remove(path);
void ESP_FileSystem::closeAll() {
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
tFile_handle[i].close();
tFile_handle[i] = 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);
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;
}
return FFat.mkdir(p);
}
if (!set) {
log_esp3d("No handle available");
}
}
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 = 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;
bool ESP_File::seek(uint32_t pos, uint8_t mode) {
return tFile_handle[_index].seek(pos, (SeekMode)mode);
}
void ESP_FileSystem::closeAll()
{
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
tFile_handle[i].close();
tFile_handle[i] = File();
void ESP_File::close() {
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();
}
}
}
ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
_isfakedir = false;
tFile_handle[_index] = File();
_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)
{
return tFile_handle[_index].seek(pos, (SeekMode)mode);
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();
}
void ESP_File::close()
{
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
#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
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"
#if (FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32)
#include "../esp_filesystem.h"
#include <stack>
#if (FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM) && \
defined(ARDUINO_ARCH_ESP32)
#include <FS.h>
#include <LittleFS.h>
#include <stack>
#include "../esp_filesystem.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin()
{
_started = LittleFS.begin(true);
bool ESP_FileSystem::begin() {
_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;
}
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)
{
return LittleFS.rename(oldpath,newpath);
}
const char * ESP_FileSystem::FilesystemName()
{
return "LittleFS";
}
bool ESP_FileSystem::format()
{
bool res = LittleFS.format();
if (res) {
res = begin();
}
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();
}
return res;
root.close();
}
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();
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);
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d("%s is invalid path", path);
return ESP_File();
}
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);
}
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;
}
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("open %s failed", path);
return ESP_File();
log_esp3d("File %d busy", i);
log_esp3d("%s", tFile_handle[i].name());
}
}
bool ESP_FileSystem::exists(const char* path)
{
bool res = false;
//root should always be there if started
if (strcmp(path, "/") == 0) {
return _started;
}
if (!set) {
log_esp3d("No handle available");
#if defined(ESP_LOG_FEATURE)
for (uint8_t i = 0; (i < ESP_MAX_OPENHANDLE); i++) {
log_esp3d("%s", tFile_handle[i].name());
}
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
}
}
}
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 = LittleFS.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
} else {
log_esp3d("Error opening %s", _filename.c_str());
}
}
tFile_handle[_index] = File();
_index = -1;
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 = LittleFS.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
} else {
log_esp3d("Error opening %s", _filename.c_str());
}
}
tFile_handle[_index] = File();
_index = -1;
}
}
bool ESP_File::seek(uint32_t pos, uint8_t mode)
{
return tFile_handle[_index].seek(pos, (SeekMode)mode);
bool ESP_File::seek(uint32_t pos, uint8_t mode) {
return tFile_handle[_index].seek(pos, (SeekMode)mode);
}
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();
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_LITTLEFS_FILESYSTEM
#endif // ESP_LITTLEFS_FILESYSTEM

View File

@ -17,331 +17,319 @@
License along with This code; if not, write to the Free Software
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"
#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32)
#include "../esp_filesystem.h"
#include <stack>
#include <FS.h>
#include <SPIFFS.h>
#include <stack>
#include "../esp_filesystem.h"
extern File tFile_handle[ESP_MAX_OPENHANDLE];
bool ESP_FileSystem::begin()
{
_started = SPIFFS.begin(true);
bool ESP_FileSystem::begin() {
_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;
}
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();
}
String spath = path;
spath.trim();
if (spath[spath.length() - 1] == '/') {
if (spath != "/") {
spath.remove(spath.length() - 1);
}
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();
}
res = SPIFFS.exists(spath.c_str());
if (!res) {
String newpath = spath;
if (newpath[newpath.length() - 1] != '/') {
newpath += "/";
}
// 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;
}
String spath = path;
spath.trim();
if (spath[spath.length()-1] == '/') {
if (spath!="/") {
spath.remove(spath.length()-1);
}
}
res = SPIFFS.exists(spath.c_str());
newpath += ".";
log_esp3d("Check %s", newpath.c_str());
res = SPIFFS.exists(newpath);
if (!res) {
String newpath = spath;
if (newpath[newpath.length()-1] != '/') {
newpath+="/";
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;
}
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();
return true;
} else {
return false;
}
}
}
return res;
}
bool ESP_FileSystem::rmdir(const char *path)
{
String spath = path;
spath.trim();
if (!spath.startsWith("/")) {
spath = '/'+spath;
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();
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("/")) {
spath.remove(spath.length()-1);
}
}
log_esp3d("Deleting : %s", spath.c_str());
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());
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();
ftmp.close();
return true;
} else {
return false;
}
}
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();
// 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();
return true;
} else {
return false;
}
}
}
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;
tFile_handle[_index] = File();
_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;
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();
}
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();
}
}
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
#endif // ESP_SPIFFS_FILESYSTEM

View File

@ -150,6 +150,7 @@ uint64_t ESP_SD::freeBytes(bool refresh) {
uint ESP_SD::maxPathLength() { return 255; }
bool ESP_SD::rename(const char *oldpath, const char *newpath) {
log_esp3d("rename %s to %s", 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;
p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path);
log_esp3d_e("Error opening: %s", path);
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
*/
#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)
#define FS_NO_GLOBALS
#include "../esp_sd.h"
#include <stack>
#include "../../../core/settings_esp3d.h"
#include <SD.h>
#include <SDFS.h>
#include <stack>
#include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
void dateTime (uint16_t* date, uint16_t* dtime)
{
struct tm tmstruct;
time_t now;
time (&now);
localtime_r (&now, &tmstruct);
*date = FAT_DATE ( (tmstruct.tm_year) + 1900, ( tmstruct.tm_mon) + 1, tmstruct.tm_mday);
*dtime = FAT_TIME (tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
void dateTime(uint16_t* date, uint16_t* dtime) {
struct tm tmstruct;
time_t now;
time(&now);
localtime_r(&now, &tmstruct);
*date = FAT_DATE((tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1,
tmstruct.tm_mday);
*dtime = FAT_TIME(tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
}
time_t getDateTimeFile(File & filehandle)
{
static time_t dt = 0;
time_t getDateTimeFile(File& filehandle) {
static time_t dt = 0;
#ifdef SD_TIMESTAMP_FEATURE
struct tm timefile;
dir_t d;
if(filehandle) {
if (filehandle.dirEntry(&d)) {
timefile.tm_year = FAT_YEAR(d.lastWriteDate) - 1900;
timefile.tm_mon = FAT_MONTH(d.lastWriteDate) - 1;
timefile.tm_mday = FAT_DAY(d.lastWriteDate);
timefile.tm_hour = FAT_HOUR(d.lastWriteTime);
timefile.tm_min = FAT_MINUTE(d.lastWriteTime);
timefile.tm_sec = FAT_SECOND(d.lastWriteTime);
timefile.tm_isdst = -1;
dt = mktime(&timefile);
if (dt == -1) {
log_esp3d("mktime failed");
}
} else {
log_esp3d("stat file failed");
}
struct tm timefile;
dir_t d;
if (filehandle) {
if (filehandle.dirEntry(&d)) {
timefile.tm_year = FAT_YEAR(d.lastWriteDate) - 1900;
timefile.tm_mon = FAT_MONTH(d.lastWriteDate) - 1;
timefile.tm_mday = FAT_DAY(d.lastWriteDate);
timefile.tm_hour = FAT_HOUR(d.lastWriteTime);
timefile.tm_min = FAT_MINUTE(d.lastWriteTime);
timefile.tm_sec = FAT_SECOND(d.lastWriteTime);
timefile.tm_isdst = -1;
dt = mktime(&timefile);
if (dt == -1) {
log_esp3d_e("mktime failed");
}
} else {
log_esp3d("check file for stat failed");
log_esp3d_e("stat file failed");
}
#endif //SD_TIMESTAMP_FEATURE
return dt;
} else {
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
//no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) {
log_esp3d("No SD State %d vs %d", digitalRead (ESP_SD_DETECT_PIN), ESP_SD_DETECT_VALUE);
_state = ESP_SDCARD_NOT_PRESENT;
return _state;
} 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
// no need to go further if SD detect is not correct
if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
: false)) {
log_esp3d("No SD State %d vs %d", digitalRead(ESP_SD_DETECT_PIN),
ESP_SD_DETECT_VALUE);
_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;
}
bool ESP_SD::begin()
{
_started = true;
_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;
}
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)
{
} 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;
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)
{
return SD.mkdir(path);
bool ESP_SD::begin() {
_started = true;
_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;
if (!p.endsWith("/")) {
p+= '/';
}
if (!p.startsWith("/")) {
p = '/'+p;
}
p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) {
return false;
log_esp3d("Error opening: %s", path);
return ESP_SDFile();
}
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;
}
f = dir.openNextFile();
}
}
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;
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) {
if (pathlist.top() !="/") {
res = SD.rmdir(pathlist.top().c_str());
}
pathlist.pop();
}
dir.close();
f = dir.openNextFile();
}
}
p = String();
log_esp3d("count %d", pathlist.size());
return res;
}
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();
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;
}
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
{
_isdir = isdir;
_dirlist = "";
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();
}
}
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;
_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;
ESP_SDFile ESP_SDFile::openNextFile() {
if ((_index == -1) || !_isdir) {
log_esp3d_e("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();
}
ESP_SDFile ESP_SDFile::openNextFile()
{
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() { return "SD native"; }
const char * ESP_SD::FilesystemName()
{
return "SD native";
}
#endif //SD_DEVICE == ESP_SD_NATIVE
#endif //ARCH_ESP8266 && SD_DEVICE
#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;
dt = mktime(&timefile);
if (dt == -1) {
log_esp3d("mktime failed");
log_esp3d_e("mktime failed");
}
} else {
log_esp3d("stat file failed");
log_esp3d_e("stat file failed");
}
} else {
log_esp3d("check file for stat failed");
log_esp3d_e("check file for stat failed");
}
#endif // SD_TIMESTAMP_FEATURE
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))) ||
(strlen(path) == 0)) {
_sizechanged = true;
log_esp3d("reject %s", path);
log_esp3d_e("reject %s", path);
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d("%s is invalid path", path);
log_esp3d_e("%s is invalid path", path);
return ESP_SDFile();
}
if (mode != ESP_FILE_READ) {
@ -332,7 +332,7 @@ ESP_SDFile ESP_SD::open(const char* path, uint8_t mode) {
String p = path;
p.remove(p.lastIndexOf('/') + 1);
if (!exists(p.c_str())) {
log_esp3d("Error opening: %s", path);
log_esp3d_e("Error opening: %s", path);
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");
return esptmp;
} else {
log_esp3d("open %s failed", path);
log_esp3d_e("open %s failed", path);
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
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"
#if defined (ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE)
#if defined(ARDUINO_ARCH_ESP8266) && defined(SD_DEVICE)
#if (SD_DEVICE == ESP_SDFAT2)
#define FS_NO_GLOBALS
#include "../esp_sd.h"
#include <stack>
#include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
#define NO_GLOBAL_SD
#include <SdFat.h>
#include <sdios.h>
@ -33,509 +35,491 @@ sd_sdfat2_esp8266.cpp - ESP3D sd support class
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#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
#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
extern sdfat::File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
using namespace sdfat;
SdFat SD;
void dateTime (uint16_t* date, uint16_t* dtime)
{
struct tm tmstruct;
time_t now;
time (&now);
localtime_r (&now, &tmstruct);
*date = FAT_DATE ( (tmstruct.tm_year) + 1900, ( tmstruct.tm_mon) + 1, tmstruct.tm_mday);
*dtime = FAT_TIME (tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
void dateTime(uint16_t* date, uint16_t* dtime) {
struct tm tmstruct;
time_t now;
time(&now);
localtime_r(&now, &tmstruct);
*date = FAT_DATE((tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1,
tmstruct.tm_mday);
*dtime = FAT_TIME(tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);
}
time_t getDateTimeFile(sdfat::File & filehandle)
{
static time_t dt = 0;
time_t getDateTimeFile(sdfat::File& filehandle) {
static time_t dt = 0;
#ifdef SD_TIMESTAMP_FEATURE
struct tm timefile;
uint16_t date;
uint16_t time;
if(filehandle) {
if (filehandle.getModifyDateTime(&date, &time)) {
timefile.tm_year = FS_YEAR(date) - 1900;
timefile.tm_mon = FS_MONTH(date) - 1;
timefile.tm_mday = FS_DAY(date);
timefile.tm_hour = FS_HOUR(time);
timefile.tm_min = FS_MINUTE(time);
timefile.tm_sec = FS_SECOND(time);
timefile.tm_isdst = -1;
dt = mktime(&timefile);
if (dt == -1) {
log_esp3d("mktime failed");
}
} else {
log_esp3d("stat file failed");
}
struct tm timefile;
uint16_t date;
uint16_t time;
if (filehandle) {
if (filehandle.getModifyDateTime(&date, &time)) {
timefile.tm_year = FS_YEAR(date) - 1900;
timefile.tm_mon = FS_MONTH(date) - 1;
timefile.tm_mday = FS_DAY(date);
timefile.tm_hour = FS_HOUR(time);
timefile.tm_min = FS_MINUTE(time);
timefile.tm_sec = FS_SECOND(time);
timefile.tm_isdst = -1;
dt = mktime(&timefile);
if (dt == -1) {
log_esp3d_e("mktime failed");
}
} else {
log_esp3d("check file for stat failed");
log_esp3d_e("stat file failed");
}
#endif //SD_TIMESTAMP_FEATURE
return dt;
} else {
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
//no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) {
log_esp3d("No SD State %d vs %d", digitalRead (ESP_SD_DETECT_PIN), ESP_SD_DETECT_VALUE);
_state = ESP_SDCARD_NOT_PRESENT;
return _state;
} 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
// no need to go further if SD detect is not correct
if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
: false)) {
log_esp3d("No SD State %d vs %d", digitalRead(ESP_SD_DETECT_PIN),
ESP_SD_DETECT_VALUE);
_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;
}
bool ESP_SD::begin()
{
_started = true;
_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;
}
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)
{
} 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;
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;
}
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;
}
// 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");
csd_t m_csd;
if (SD.card()->readCSD(&m_csd) && sdCardCapacity(&m_csd) > 0) {
_state = ESP_SDCARD_IDLE;
} 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()
{
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();
}
bool ESP_SD::begin() {
_started = true;
_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;
}
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();
//log_esp3d("Closing File at index %d",_index);
_index = -1;
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_SDFile::openNextFile()
{
if ((_index == -1) || !_isdir) {
log_esp3d("openNextFile failed");
return ESP_SDFile();
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 = 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+="/";
}
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;
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;
ESP_SDFile esptmp(&tmp, tmp.isDir(),false, s.c_str());
esptmp.close();
return esptmp;
f = dir.openNextFile();
}
}
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()
{
return "SDFat - " SD_FAT_VERSION_STR ;
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);
}
#endif //SD_DEVICE == ESP_SDFAT2
#endif //ARCH_ESP8266 && SD_DEVICE
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 {
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
*/
#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)
#include "../esp_sd.h"
#include <stack>
#include "../../../core/settings_esp3d.h"
#include "../esp_sd.h"
#include "FS.h"
#include "SD_MMC.h"
extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
#define SDMMC_FORCE_BEGIN
#ifndef SDIO_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)
{
static bool lastinitok = false;
uint8_t ESP_SD::getState(bool refresh) {
static bool lastinitok = false;
#ifdef SDMMC_FORCE_BEGIN
lastinitok = false;
#endif //SDMMC_LIGHT_CHECK
lastinitok = false;
#endif // SDMMC_LIGHT_CHECK
#if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
//no need to go further if SD detect is not correct
if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) {
_state = ESP_SDCARD_NOT_PRESENT;
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
// no need to go further if SD detect is not correct
if (!((digitalRead(ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true
: false)) {
_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;
}
bool ESP_SD::begin()
{
#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)
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()
{
}
#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;
// refresh content if card was removed
if (!lastinitok) {
log_esp3d("last init was failed try sd_mmc begin");
SD_MMC.end();
_state = ESP_SDCARD_NOT_PRESENT;
_started = false;
}
void ESP_SD::refreshStats(bool force)
{
if (force || _sizechanged) {
freeBytes(true);
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_e("sd_mmc card type failed");
}
} else {
log_esp3d_e("sd_mmc begin failed");
}
_sizechanged = false;
}
uint64_t ESP_SD::totalBytes(bool refresh)
{
static uint64_t _totalBytes = 0;
if (refresh || _totalBytes==0) {
_totalBytes = SD_MMC.totalBytes();;
} 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_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)
{
static uint64_t _usedBytes = 0;
if (refresh || _usedBytes==0) {
_usedBytes = SD_MMC.usedBytes();
bool ESP_SD::begin() {
#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)
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)
{
return (totalBytes(refresh) - usedBytes(refresh));
}
bool ESP_SD::exists(const char *path) {
bool res = false;
String p = path;
// root should always be there if started
if (p == "/") {
return _started;
}
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!");
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) { 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;
}
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("File open check : failed");
return ESP_SDFile();
}
// path must start by '/'
if (path[0] != '/') {
log_esp3d("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("Error opening: %s, %s does not exists", path,p.c_str());
return ESP_SDFile();
}
bool res = true;
std::stack<String> pathlist;
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();
}
}
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;
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;
}
bool ESP_SD::exists(const char* path)
{
bool res = false;
String p = path;
//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;
void ESP_SD::closeAll() {
for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
tSDFile_handle[i].close();
tSDFile_handle[i] = File();
}
}
bool ESP_SD::remove(const char *path)
{
return SD_MMC.remove(path);
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
_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)
{
String p = path;
if (p.endsWith("/")) {
p.remove( p.length() - 1,1);
}
return SD_MMC.mkdir(p.c_str());
bool ESP_SDFile::seek(uint32_t pos, uint8_t mode) {
return tSDFile_handle[_index].seek(pos, (SeekMode)mode);
}
bool ESP_SD::rmdir(const char *path)
{
if (!exists(path)) {
return false;
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_MMC.open(_filename.c_str());
if (ftmp) {
_size = ftmp.size();
_lastwrite = ftmp.getLastWrite();
ftmp.close();
}
}
bool res = true;
std::stack <String > pathlist;
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 = "";
tSDFile_handle[_index] = File();
// log_esp3d("Closing File at index %d",_index);
_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)
{
return tSDFile_handle[_index].seek(pos, (SeekMode)mode);
ESP_SDFile ESP_SDFile::openNextFile() {
if ((_index == -1) || !_isdir) {
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()
{
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;
}
}
// TODO need to find reliable way
const char *ESP_SDFile::shortname() const { return _name.c_str(); }
ESP_SDFile ESP_SDFile::openNextFile()
{
if ((_index == -1) || !_isdir) {
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
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
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"
#if defined(HTTP_FEATURE) && defined(SD_DEVICE)
#include "../http_server.h"

View File

@ -18,104 +18,107 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE)
#if defined(HTTP_FEATURE)
#include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h"
#endif // ARDUINO_ARCH_ESP8266
#include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_filesystem.h"
#if defined(SD_DEVICE)
#include "../../filesystem/esp_sd.h"
#endif //SD_DEVICE
#endif // SD_DEVICE
#include "../favicon.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#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 ///////////////////////
void HTTP_Server:: handle_not_found()
{
if (AuthenticationService::authenticated_level() == LEVEL_GUEST) {
_webserver->send (401, "text/plain", "Wrong authentication!");
return;
// Handle not registred path on FS neither SD ///////////////////////
void HTTP_Server::handle_not_found() {
if (AuthenticationService::authenticated_level() == LEVEL_GUEST) {
_webserver->send(401, "text/plain", "Wrong authentication!");
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());
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())) {
if (!StreamFSFile(path.c_str(), contentType.c_str())) {
log_esp3d_e("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;
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
Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
if(!StreamSDFile(path.c_str(),contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str());
}
Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
if (!StreamSDFile(path.c_str(), contentType.c_str())) {
log_esp3d_e("Stream `%s` failed", path.c_str());
}
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
ESP_SD::releaseFS();
return;
}
}
ESP_SD::releaseFS();
Serial2Socket.pause(false);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
ESP_SD::releaseFS();
return;
}
}
ESP_SD::releaseFS();
}
#endif //#if defined (SD_DEVICE)
}
#endif // #if defined (SD_DEVICE)
#ifdef FILESYSTEM_FEATURE
//check local page
path = "/404.htm";
contentType = getContentType(path.c_str());
pathWithGz = path + ".gz";
if(ESP_FileSystem::exists(pathWithGz.c_str()) || ESP_FileSystem::exists(path.c_str())) {
if(ESP_FileSystem::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
}
if(!StreamFSFile(path.c_str(),contentType.c_str())) {
log_esp3d("Stream `%s` failed", path.c_str());
}
return;
// check local page
path = "/404.htm";
contentType = getContentType(path.c_str());
pathWithGz = path + ".gz";
if (ESP_FileSystem::exists(pathWithGz.c_str()) ||
ESP_FileSystem::exists(path.c_str())) {
if (ESP_FileSystem::exists(pathWithGz.c_str())) {
_webserver->sendHeader("Content-Encoding", "gzip");
path = pathWithGz;
}
#endif //FILESYSTEM_FEATURE
//let's keep simple just send minimum
_webserver->send(404);
if (!StreamFSFile(path.c_str(), contentType.c_str())) {
log_esp3d_e("Stream `%s` failed", path.c_str());
}
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
*/
#include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE)
#if defined(HTTP_FEATURE)
#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"
#if defined (ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h"
//Root of Webserver/////////////////////////////////////////////////////
void HTTP_Server::handle_root()
{
String path = ESP3D_HOST_PATH;
//Some sanity check
if (path[0]!='/') {
path ="/" + path;
// Root of Webserver/////////////////////////////////////////////////////
void HTTP_Server::handle_root() {
String path = ESP3D_HOST_PATH;
// Some sanity check
if (path[0] != '/') {
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]!='/') {
path = path + "/";
if (!StreamFSFile(path.c_str(), contentType.c_str())) {
log_esp3d_e("Stream `%s` failed", path.c_str());
}
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(!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);
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
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"
#if defined (HTTP_FEATURE) && defined(SD_DEVICE)
#if defined(HTTP_FEATURE) && defined(SD_DEVICE)
#include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_sd.h"
#endif // ARDUINO_ARCH_ESP8266
#include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_sd.h"
#ifdef ESP_BENCHMARK_FEATURE
#include "../../../core/benchmark.h"
#endif //ESP_BENCHMARK_FEATURE
#endif // ESP_BENCHMARK_FEATURE
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../serial2socket/serial2socket.h"
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../websocket/websocket_server.h"
//SD files uploader handle
void HTTP_Server::SDFileupload ()
{
// SD files uploader handle
void HTTP_Server::SDFileupload() {
#ifdef ESP_BENCHMARK_FEATURE
static uint64_t bench_start;
static size_t bench_transfered;
#endif//ESP_BENCHMARK_FEATURE
static uint64_t last_WS_update;
//get authentication status
level_authenticate_type auth_level= AuthenticationService::authenticated_level();
static String filename;
static ESP_SDFile fsUploadFile;
//Guest cannot upload - only admin
if (auth_level == LEVEL_GUEST) {
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
_upload_status=UPLOAD_STATUS_FAILED;
} else {
HTTPUpload& upload = _webserver->upload();
String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) || (upload.status == UPLOAD_FILE_START)) {
static uint64_t bench_start;
static size_t bench_transfered;
#endif // ESP_BENCHMARK_FEATURE
static uint64_t last_WS_update;
// get authentication status
level_authenticate_type auth_level =
AuthenticationService::authenticated_level();
static String filename;
static ESP_SDFile fsUploadFile;
// Guest cannot upload - only admin
if (auth_level == LEVEL_GUEST) {
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
_upload_status = UPLOAD_STATUS_FAILED;
} else {
HTTPUpload& upload = _webserver->upload();
String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) ||
(upload.status == UPLOAD_FILE_START)) {
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause(true);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload start
if (upload.status == UPLOAD_FILE_START) {
last_WS_update = millis();
Serial2Socket.pause(true);
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
// Upload start
if (upload.status == UPLOAD_FILE_START) {
last_WS_update = millis();
#ifdef ESP_BENCHMARK_FEATURE
bench_start = millis();
bench_transfered = 0;
#endif//ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING;
if (!ESP_SD::accessFS()) {
_upload_status=UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NO_SD, "Upload rejected");
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
}
}
bench_start = millis();
bench_transfered = 0;
#endif // ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING;
if (!ESP_SD::accessFS()) {
_upload_status = UPLOAD_STATUS_FAILED;
pushError(ESP_ERROR_NO_SD, "Upload rejected");
return;
}
}
if(_upload_status == UPLOAD_STATUS_FAILED) {
cancelUpload();
if(fsUploadFile) {
fsUploadFile.close();
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;
}
if (auth_level != LEVEL_GUEST) {
if (ESP_SD::exists (filename.c_str())) {
ESP_SD::remove (filename.c_str());
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_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");
ESP_SD::releaseFS();
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
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
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"
#if defined (HTTP_FEATURE) && defined(FILESYSTEM_FEATURE)
#if defined(HTTP_FEATURE) && defined(FILESYSTEM_FEATURE)
#include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266
#include "../../filesystem/esp_filesystem.h"
#endif // ARDUINO_ARCH_ESP8266
#include "../../authentication/authentication_service.h"
#include "../../filesystem/esp_filesystem.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include "../../serial2socket/serial2socket.h"
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#ifdef ESP_BENCHMARK_FEATURE
#include "../../../core/benchmark.h"
#endif //ESP_BENCHMARK_FEATURE
#endif // ESP_BENCHMARK_FEATURE
//FS files uploader handle
void HTTP_Server::FSFileupload ()
{
// FS files uploader handle
void HTTP_Server::FSFileupload() {
#ifdef ESP_BENCHMARK_FEATURE
static uint64_t bench_start;
static size_t bench_transfered;
#endif//ESP_BENCHMARK_FEATURE
//get authentication status
level_authenticate_type auth_level= AuthenticationService::authenticated_level();
static String filename;
static ESP_File fsUploadFile;
//Guest cannot upload - only admin
if (auth_level == LEVEL_GUEST) {
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
_upload_status=UPLOAD_STATUS_FAILED;
} else {
HTTPUpload& upload = _webserver->upload();
String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) || (upload.status == UPLOAD_FILE_START)) {
static uint64_t bench_start;
static size_t bench_transfered;
#endif // ESP_BENCHMARK_FEATURE
// get authentication status
level_authenticate_type auth_level =
AuthenticationService::authenticated_level();
static String filename;
static ESP_File fsUploadFile;
// Guest cannot upload - only admin
if (auth_level == LEVEL_GUEST) {
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
_upload_status = UPLOAD_STATUS_FAILED;
} else {
HTTPUpload& upload = _webserver->upload();
String upload_filename = upload.filename;
if ((_upload_status != UPLOAD_STATUS_FAILED) ||
(upload.status == UPLOAD_FILE_START)) {
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
//Upload start
if (upload.status == UPLOAD_FILE_START) {
Serial2Socket.pause();
#endif // ESP3DLIB_ENV && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
// Upload start
if (upload.status == UPLOAD_FILE_START) {
#ifdef ESP_BENCHMARK_FEATURE
bench_start = millis();
bench_transfered = 0;
#endif//ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING;
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_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;
}
}
bench_start = millis();
bench_transfered = 0;
#endif // ESP_BENCHMARK_FEATURE
_upload_status = UPLOAD_STATUS_ONGOING;
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload.filename;
}
}
if(_upload_status == UPLOAD_STATUS_FAILED) {
cancelUpload();
if(fsUploadFile) {
fsUploadFile.close();
if (_webserver->hasArg("rpath")) {
upload_filename = _webserver->arg("rpath") + filename;
if (upload_filename[0] != '/') {
filename = "/" + upload_filename;
} else {
filename = upload_filename;
}
}
if (auth_level != LEVEL_GUEST) {
if (ESP_FileSystem::exists (filename.c_str())) {
ESP_FileSystem::remove (filename.c_str());
// 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_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
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
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"
#ifdef MDNS_FEATURE
@ -97,38 +97,38 @@ void mDNS_Service::end() {
if (_hMDNSServiceQuery) {
log_esp3d("Remove mdns service for %s", _hostname.c_str());
if (!MDNS.removeServiceQuery(_hMDNSServiceQuery)) {
log_esp3d("failed");
log_esp3d_e("failed");
}
}
_hMDNSServiceQuery = 0;
log_esp3d("Remove mdns for %s", _hostname.c_str());
if (!MDNS.removeService(_hostname.c_str(), MDNS_SERVICE_NAME,
MDNS_SERVICE_TYPE)) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#if defined(HTTP_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "http", "tcp")) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#endif // HTTP_FEATURE
#if defined(FTP_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "ftp", "tcp")) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#endif // FTP_FEATURE
#if defined(TELNET_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "telnet", "tcp")) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#endif // TELNET_FEATURE
#if defined(WEBDAV_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "webdav", "tcp")) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#endif // WEBDAV_FEATURE
#if defined(WS_DATA_FEATURE)
if (!MDNS.removeService(_hostname.c_str(), "websocket", "tcp")) {
log_esp3d("failed");
log_esp3d_e("failed");
}
#endif // WS_DATA_FEATURE
#endif // ARDUINO_ARCH_ESP8266
@ -194,7 +194,7 @@ void mDNS_Service::addESP3DServices(uint16_t port) {
if (_hMDNSServiceQuery) {
log_esp3d("MDNS Service query services installed.");
} else {
log_esp3d("MDNS Service query services installation failed.");
log_esp3d_e("MDNS Service query services installation failed.");
}
#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"
#if defined (WIFI_FEATURE) || defined (ETH_FEATURE) || defined (BLUETOOTH_FEATURE)
#if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BLUETOOTH_FEATURE)
#ifdef ARDUINO_ARCH_ESP32
#define WIFI_EVENT_STAMODE_CONNECTED ARDUINO_EVENT_WIFI_STA_CONNECTED
#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_SOFTAPMODE_STACONNECTED ARDUINO_EVENT_WIFI_AP_STACONNECTED
#define RADIO_OFF_MSG "Radio Off"
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
#define RADIO_OFF_MSG "WiFi Off"
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP8266
#include "netconfig.h"
#if defined (WIFI_FEATURE)
#if defined(WIFI_FEATURE)
#include "../wifi/wificonfig.h"
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
#include "../ethernet/ethconfig.h"
#endif //ETH_FEATURE
#if defined (BLUETOOTH_FEATURE)
#endif // ETH_FEATURE
#if defined(BLUETOOTH_FEATURE)
#include "../bluetooth/BT_service.h"
#endif //BLUETOOTH_FEATURE
#include "netservices.h"
#endif // BLUETOOTH_FEATURE
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "netservices.h"
String NetConfig::_hostname = "";
bool NetConfig::_needReconnect2AP = false;
@ -50,428 +50,407 @@ bool NetConfig::_events_registered = false;
bool NetConfig::_started = false;
uint8_t NetConfig::_mode = ESP_NO_NETWORK;
//just simple helper to convert mac address to string
char * NetConfig::mac2str (uint8_t mac [8])
{
static char macstr [18];
if (0 > sprintf (macstr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ) {
strcpy (macstr, "00:00:00:00:00:00");
}
return macstr;
// just simple helper to convert mac address to string
char* NetConfig::mac2str(uint8_t mac[8]) {
static char macstr[18];
if (0 > sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1],
mac[2], mac[3], mac[4], mac[5])) {
strcpy(macstr, "00:00:00:00:00:00");
}
return macstr;
}
/**
* Helper to convert IP string to int
*/
uint32_t NetConfig::IP_int_from_string(const char * s)
{
uint32_t ip_int = 0;
IPAddress ipaddr;
if (ipaddr.fromString(s)) {
ip_int = ipaddr;
}
return ip_int;
uint32_t NetConfig::IP_int_from_string(const char* s) {
uint32_t ip_int = 0;
IPAddress ipaddr;
if (ipaddr.fromString(s)) {
ip_int = ipaddr;
}
return ip_int;
}
/**
* Helper to convert int to IP string
*/
String NetConfig::IP_string_from_int(uint32_t ip_int)
{
IPAddress ipaddr(ip_int);
return ipaddr.toString();
String NetConfig::IP_string_from_int(uint32_t ip_int) {
IPAddress ipaddr(ip_int);
return ipaddr.toString();
}
/**
* Check if Hostname string is valid
*/
bool NetConfig::isHostnameValid (const char * hostname)
{
//limited size
char c;
if (strlen (hostname) > MAX_HOSTNAME_LENGTH || strlen (hostname) < MIN_HOSTNAME_LENGTH) {
return false;
bool NetConfig::isHostnameValid(const char* hostname) {
// limited size
char c;
if (strlen(hostname) > MAX_HOSTNAME_LENGTH ||
strlen(hostname) < MIN_HOSTNAME_LENGTH) {
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
for (uint i = 0; i < strlen (hostname); i++) {
c = hostname[i];
if (! (isdigit (c) || isalpha (c) || c == '-') ) {
return false;
}
if (c == ' ') {
return false;
}
if (c == ' ') {
return false;
}
return true;
}
return true;
}
/**
* Get IP Integer what ever is enabled
*/
IPAddress NetConfig::localIPAddress()
{
IPAddress current_ip = IPAddress(0,0,0,0);
#if defined( WIFI_FEATURE)
if (WiFi.getMode() == WIFI_STA) {
current_ip = WiFi.localIP();
} else if (WiFi.getMode() == WIFI_AP) {
current_ip = WiFi.softAPIP();
}
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
if (EthConfig::started()) {
current_ip = ETH.localIP();
}
#endif //ETH_FEATURE
IPAddress NetConfig::localIPAddress() {
IPAddress current_ip = IPAddress(0, 0, 0, 0);
#if defined(WIFI_FEATURE)
if (WiFi.getMode() == WIFI_STA) {
current_ip = WiFi.localIP();
} else if (WiFi.getMode() == WIFI_AP) {
current_ip = WiFi.softAPIP();
}
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
if (EthConfig::started()) {
current_ip = ETH.localIP();
}
#endif // ETH_FEATURE
return current_ip;
return current_ip;
}
/**
* Get IP string what ever is enabled
*/
String NetConfig::localIP()
{
static String currentIP = "";
#if defined( WIFI_FEATURE)
if (WiFi.getMode() == WIFI_STA) {
currentIP = WiFi.localIP().toString();
} else if (WiFi.getMode() == WIFI_AP) {
currentIP = WiFi.softAPIP().toString();
}
#endif //WIFI_FEATURE
#if defined (ETH_FEATURE)
if (EthConfig::started()) {
currentIP = ETH.localIP().toString();
}
#endif //ETH_FEATURE
if (currentIP.length() == 0) {
currentIP = "0.0.0.0";
}
return currentIP;
String NetConfig::localIP() {
static String currentIP = "";
#if defined(WIFI_FEATURE)
if (WiFi.getMode() == WIFI_STA) {
currentIP = WiFi.localIP().toString();
} else if (WiFi.getMode() == WIFI_AP) {
currentIP = WiFi.softAPIP().toString();
}
#endif // WIFI_FEATURE
#if defined(ETH_FEATURE)
if (EthConfig::started()) {
currentIP = ETH.localIP().toString();
}
#endif // ETH_FEATURE
if (currentIP.length() == 0) {
currentIP = "0.0.0.0";
}
return currentIP;
}
/**
* Check if IP string is valid
*/
bool NetConfig::isValidIP(const char * string)
{
IPAddress ip;
return ip.fromString(string);
bool NetConfig::isValidIP(const char* string) {
IPAddress ip;
return ip.fromString(string);
}
//wifi event
void NetConfig::onWiFiEvent(WiFiEvent_t event)
{
ESP3DOutput output(ESP_ALL_CLIENTS);
switch (event) {
// wifi event
void NetConfig::onWiFiEvent(WiFiEvent_t event) {
ESP3DOutput output(ESP_ALL_CLIENTS);
switch (event) {
case WIFI_EVENT_STAMODE_CONNECTED:
_needReconnect2AP = false;
break;
_needReconnect2AP = false;
break;
case WIFI_EVENT_STAMODE_DISCONNECTED: {
if(_started) {
output.printMSG ("Disconnected");
//_needReconnect2AP = true;
}
}
break;
if (_started) {
output.printMSG("Disconnected");
//_needReconnect2AP = true;
}
} break;
case WIFI_EVENT_STAMODE_GOT_IP: {
#if COMMUNICATION_PROTOCOL != MKS_SERIAL
output.printMSG (WiFi.localIP().toString().c_str());
#endif //#if COMMUNICATION_PROTOCOL == MKS_SERIAL
}
break;
output.printMSG(WiFi.localIP().toString().c_str());
#endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
} break;
case WIFI_EVENT_SOFTAPMODE_STACONNECTED: {
output.printMSG ("New client");
}
break;
output.printMSG("New client");
} break;
#ifdef ARDUINO_ARCH_ESP32
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
if(_started) {
_needReconnect2AP = true;
}
break;
if (_started) {
_needReconnect2AP = true;
}
break;
#ifdef ETH_FEATURE
case ARDUINO_EVENT_ETH_START: {
EthConfig::setConnected(false);
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG ("Checking connection");
}
}
break;
EthConfig::setConnected(false);
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Checking connection");
}
} break;
case ARDUINO_EVENT_ETH_CONNECTED: {
output.printMSG ("Cable connected");
EthConfig::setConnected(true);
}
break;
output.printMSG("Cable connected");
EthConfig::setConnected(true);
} break;
case ARDUINO_EVENT_ETH_DISCONNECTED: {
output.printMSG ("Cable disconnected");
EthConfig::setConnected(false);
}
break;
output.printMSG("Cable disconnected");
EthConfig::setConnected(false);
} break;
case ARDUINO_EVENT_ETH_GOT_IP:
output.printMSG (ETH.localIP().toString().c_str());
EthConfig::setConnected(true);
break;
output.printMSG(ETH.localIP().toString().c_str());
EthConfig::setConnected(true);
break;
case ARDUINO_EVENT_ETH_STOP:
EthConfig::setConnected(false);
break;
#endif //ETH_FEATURE
#endif //ARDUINO_ARCH_ESP32
EthConfig::setConnected(false);
break;
#endif // ETH_FEATURE
#endif // ARDUINO_ARCH_ESP32
default:
break;
}
break;
}
}
void NetConfig::setMode(uint8_t mode)
{
_mode=mode;
}
void NetConfig::setMode(uint8_t mode) { _mode = mode; }
uint8_t NetConfig::getMode()
{
return _mode;
}
uint8_t NetConfig::getMode() { return _mode; }
/**
* begin WiFi setup
*/
bool NetConfig::begin()
{
bool res = false;
//clear everything
end();
int8_t espMode =Settings_ESP3D::read_byte(ESP_RADIO_MODE);
ESP3DOutput output(ESP_ALL_CLIENTS);
log_esp3d("Starting Network");
if (espMode != ESP_NO_NETWORK) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting Network");
}
bool NetConfig::begin() {
bool res = false;
// clear everything
end();
int8_t espMode = Settings_ESP3D::read_byte(ESP_RADIO_MODE);
ESP3DOutput output(ESP_ALL_CLIENTS);
log_esp3d("Starting Network");
if (espMode != ESP_NO_NETWORK) {
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting Network");
}
//setup events
if(!_events_registered) {
}
// setup events
if (!_events_registered) {
#ifdef ARDUINO_ARCH_ESP8266
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
WiFi.onEvent(NetConfig::onWiFiEvent, WIFI_EVENT_ANY);
WiFi.onEvent(NetConfig::onWiFiEvent, WIFI_EVENT_ANY);
#pragma GCC diagnostic pop
#endif
#ifdef ARDUINO_ARCH_ESP32
WiFi.onEvent(NetConfig::onWiFiEvent);
WiFi.onEvent(NetConfig::onWiFiEvent);
#endif
_events_registered = true;
}
//Get hostname
_hostname = Settings_ESP3D::read_string(ESP_HOSTNAME);
_mode = espMode;
if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr);
if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG);
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);
_events_registered = true;
}
// Get hostname
_hostname = Settings_ESP3D::read_string(ESP_HOSTNAME);
_mode = espMode;
if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG);
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);
}
#else
//if Eth and no Eth enabled let's go to no network
if (espMode == ESP_ETH_STA) {
espMode = ESP_NO_NETWORK;
}
#endif //ETH_FEATURE
// if Eth and no Eth enabled let's go to no network
if (espMode == ESP_ETH_STA) {
espMode = ESP_NO_NETWORK;
}
#endif // ETH_FEATURE
#if defined (BLUETOOTH_FEATURE)
if (espMode == ESP_BT) {
WiFi.mode(WIFI_OFF);
String msg = "BT On";
ESP3DOutput::toScreen(ESP_OUTPUT_STATUS, msg.c_str());
res = bt_service.begin();
}
#if defined(BLUETOOTH_FEATURE)
if (espMode == ESP_BT) {
WiFi.mode(WIFI_OFF);
String msg = "BT On";
ESP3DOutput::toScreen(ESP_OUTPUT_STATUS, msg.c_str());
res = bt_service.begin();
}
#else
//if BT and no BT enabled let's go to no network
if (espMode == ESP_BT) {
espMode = ESP_NO_NETWORK;
}
#endif //BLUETOOTH_FEATURE
// if BT and no BT enabled let's go to no network
if (espMode == ESP_BT) {
espMode = ESP_NO_NETWORK;
}
#endif // BLUETOOTH_FEATURE
if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr);
if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG);
output.flush();
}
return true;
if (espMode == ESP_NO_NETWORK) {
output.printMSG("Disable Network");
WiFi.mode(WIFI_OFF);
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
if (Settings_ESP3D::isVerboseBoot()) {
ESP3DOutput output(ESP_ALL_CLIENTS);
output.printMSG(RADIO_OFF_MSG);
output.flush();
}
//if network is up, let's start services
if (res) {
_started = true;
bool start_services = false;
#if defined (ETH_FEATURE)
if (EthConfig::started()) {
start_services = true;
}
#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();
}
return true;
}
// if network is up, let's start services
if (res) {
_started = true;
bool start_services = false;
#if defined(ETH_FEATURE)
if (EthConfig::started()) {
start_services = true;
}
//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
#if defined (WIFI_FEATURE)
if (WiFi.getMode() == WIFI_AP) {
WiFi.softAPsetHostname(_hostname.c_str());
}
#endif //WIFI_FEATURE
#endif //ARDUINO_ARCH_ESP32
DEBUG_ESP3D_NETWORK_INIT
if (res) {
log_esp3d("Network config started");
} else {
end();
log_esp3d("Network config failed");
}
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS,nullptr);
return res;
#if defined(WIFI_FEATURE)
if (WiFi.getMode() == WIFI_AP) {
WiFi.softAPsetHostname(_hostname.c_str());
}
#endif // WIFI_FEATURE
#endif // ARDUINO_ARCH_ESP32
LOG_ESP3D_NETWORK_INIT
if (res) {
log_esp3d("Network config started");
} else {
end();
log_esp3d_e("Network config failed");
}
ESP3DOutput::toScreen(ESP_OUTPUT_IP_ADDRESS, nullptr);
return res;
}
/**
* End WiFi
*/
void NetConfig::end()
{
NetServices::end();
DEBUG_ESP3D_NETWORK_END
_mode = ESP_NO_NETWORK;
#if defined (WIFI_FEATURE)
WiFiConfig::end();
_needReconnect2AP=false;
void NetConfig::end() {
NetServices::end();
LOG_ESP3D_NETWORK_END
_mode = ESP_NO_NETWORK;
#if defined(WIFI_FEATURE)
WiFiConfig::end();
_needReconnect2AP = false;
#else
WiFi.mode(WIFI_OFF);
#endif //WIFI_FEATURE
WiFi.mode(WIFI_OFF);
#endif // WIFI_FEATURE
#if defined (ETH_FEATURE)
EthConfig::end();
#endif //ETH_FEATURE
#if defined (BLUETOOTH_FEATURE)
bt_service.end();
#endif //BLUETOOTH_FEATURE
_started = false;
#if defined(ETH_FEATURE)
EthConfig::end();
#endif // ETH_FEATURE
#if defined(BLUETOOTH_FEATURE)
bt_service.end();
#endif // BLUETOOTH_FEATURE
_started = false;
}
const char* NetConfig::hostname(bool fromsettings)
{
if (fromsettings) {
_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
const char* NetConfig::hostname(bool fromsettings) {
if (fromsettings) {
_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();
}
/**
* Handle not critical actions that must be done in sync environement
*/
void NetConfig::handle()
{
if (_started) {
#if defined (WIFI_FEATURE)
if(_needReconnect2AP) {
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
void NetConfig::handle() {
if (_started) {
#if defined(WIFI_FEATURE)
if (_needReconnect2AP) {
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
LOG_ESP3D_NETWORK_HANDLE
}
}
bool NetConfig::isIPModeDHCP (uint8_t mode)
{
bool started = false;
bool NetConfig::isIPModeDHCP(uint8_t mode) {
bool started = false;
#ifdef ARDUINO_ARCH_ESP32
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);
started = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP32
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);
started = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
(void)mode;
started = (wifi_station_dhcpc_status() == DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP8266
return started;
(void)mode;
started = (wifi_station_dhcpc_status() == DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP8266
return started;
}
bool NetConfig::isDHCPServer (uint8_t mode)
{
bool itis = false;
bool NetConfig::isDHCPServer(uint8_t mode) {
bool itis = false;
#ifdef ARDUINO_ARCH_ESP32
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);
itis = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP32
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);
itis = (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
(void)mode;
itis = (wifi_softap_dhcps_status() == DHCP_STARTED);
#endif //ARDUINO_ARCH_ESP8266
return itis;
(void)mode;
itis = (wifi_softap_dhcps_status() == DHCP_STARTED);
#endif // ARDUINO_ARCH_ESP8266
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"
#ifdef SENSOR_DEVICE
#if SENSOR_DEVICE==BMP280_DEVICE || SENSOR_DEVICE==BME280_DEVICE
#include "bmx280.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#if SENSOR_DEVICE == BMP280_DEVICE || SENSOR_DEVICE == BME280_DEVICE
#include <BMx280I2C.h>
#include <Wire.h>
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "bmx280.h"
#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};
BMx280I2C * bmx280_device;
BMx280I2C *bmx280_device;
BMX280SensorDevice::BMX280SensorDevice()
{
bmx280_device = nullptr;
}
BMX280SensorDevice::BMX280SensorDevice() { bmx280_device = nullptr; }
BMX280SensorDevice::~BMX280SensorDevice()
{
end();
}
BMX280SensorDevice::~BMX280SensorDevice() { end(); }
bool BMX280SensorDevice::begin()
{
end();
uint8_t sensortype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
if (sensortype == 0) {
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);
}
bool BMX280SensorDevice::begin() {
end();
uint8_t sensortype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
if (sensortype == 0) {
log_esp3d("No Sensor active");
return true;
}
void BMX280SensorDevice::end()
{
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;
}
}
}
if (!isModelValid(sensortype)) {
log_esp3d_e("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_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)
{
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
log_esp3d("checking %s with %s",s, SENSOR_NAME[i]);
if (strcmp(s, SENSOR_NAME[i])==0) {
log_esp3d("found %d",SENSOR_ID[i]);
return SENSOR_ID[i];
}
void BMX280SensorDevice::end() {
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 0;
}
return false;
}
uint8_t BMX280SensorDevice::nbType()
{
return NB_TYPE_SENSOR;
}
uint8_t BMX280SensorDevice::GetModel(uint8_t i)
{
if (i <NB_TYPE_SENSOR) {
return SENSOR_ID[i];
uint8_t BMX280SensorDevice::getIDFromString(const char *s) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
log_esp3d("checking %s with %s", s, SENSOR_NAME[i]);
if (strcmp(s, SENSOR_NAME[i]) == 0) {
log_esp3d("found %d", SENSOR_ID[i]);
return SENSOR_ID[i];
}
return 0;
}
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++) {
uint8_t BMX280SensorDevice::nbType() { return NB_TYPE_SENSOR; }
uint8_t BMX280SensorDevice::GetModel(uint8_t 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]) {
return SENSOR_NAME[i];
return SENSOR_NAME[i];
}
}
return "NONE";
}
return "NONE";
}
const char * BMX280SensorDevice::GetModelString(uint8_t i)
{
if (i <NB_TYPE_SENSOR) {
const char *BMX280SensorDevice::GetModelString(uint8_t i) {
if (i < NB_TYPE_SENSOR) {
return SENSOR_NAME[i];
}
return "NONE";
}
return "NONE";
}
//helper function
float toFahrenheit(float fromCelcius)
{
return 1.8 * fromCelcius + 32.0;
};
// helper function
float toFahrenheit(float fromCelcius) { return 1.8 * fromCelcius + 32.0; };
const char * BMX280SensorDevice::GetData()
{
static String s;
if (bmx280_device) {
const char *BMX280SensorDevice::GetData() {
static String s;
if (bmx280_device) {
if (!bmx280_device->measure()) {
s="BUSY";
log_esp3d("sensor is busy");
s = "BUSY";
log_esp3d("sensor is busy");
} else {
uint8_t nbtry = 0;
do {
log_esp3d("try sensor %d",nbtry);
Hal::wait(100);
nbtry ++;
} while (!bmx280_device->hasValue() && nbtry < 3);
if (bmx280_device->hasValue()) {
float temperature = bmx280_device->getTemperature();
float pressure = bmx280_device->getPressure();
float humidity=0;
if (bmx280_device->isBME280()) {
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");
uint8_t nbtry = 0;
do {
log_esp3d("try sensor %d", nbtry);
Hal::wait(100);
nbtry++;
} while (!bmx280_device->hasValue() && nbtry < 3);
if (bmx280_device->hasValue()) {
float temperature = bmx280_device->getTemperature();
float pressure = bmx280_device->getPressure();
float humidity = 0;
if (bmx280_device->isBME280()) {
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_e("No valid data");
}
} else {
s = "DISCONNECTED";
log_esp3_ed("No valid data");
}
}
} else {
s="DISCONNECTED";
log_esp3d("No device");
}
return s.c_str();
} else {
s = "DISCONNECTED";
log_esp3d_e("No device");
}
return s.c_str();
}
#endif //BMP280_DEVICE || BME280_DEVICE
#endif //SENSOR_DEVICE
#endif // BMP280_DEVICE || BME280_DEVICE
#endif // SENSOR_DEVICE

View File

@ -20,146 +20,134 @@
#include "../../include/esp3d_config.h"
#ifdef SENSOR_DEVICE
#if SENSOR_DEVICE==DHT11_DEVICE || SENSOR_DEVICE==DHT22_DEVICE
#include "dht.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#if SENSOR_DEVICE == DHT11_DEVICE || SENSOR_DEVICE == DHT22_DEVICE
#include <DHTesp.h>
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "dht.h"
#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 DHTesp::DHT_MODEL_t SENSOR_TYPE[NB_TYPE_SENSOR] = {DHTesp::DHT11, DHTesp::DHT22};
DHTesp * dht_device;
const DHTesp::DHT_MODEL_t SENSOR_TYPE[NB_TYPE_SENSOR] = {DHTesp::DHT11,
DHTesp::DHT22};
DHTesp *dht_device;
DHTSensorDevice::DHTSensorDevice()
{
dht_device = nullptr;
}
DHTSensorDevice::DHTSensorDevice() { dht_device = nullptr; }
DHTSensorDevice::~DHTSensorDevice()
{
end();
}
DHTSensorDevice::~DHTSensorDevice() { end(); }
bool DHTSensorDevice::begin()
{
end();
uint8_t dhttype= Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
log_esp3d("Read %d, %s", dhttype, dhttype==1?"DHT11":dhttype==2?"DHT22":dhttype==0?"NONE":"Unknow type");
if (dhttype == 0) {
log_esp3d("No Sensor active");
return true;
}
if (!isModelValid(dhttype)) {
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");
bool DHTSensorDevice::begin() {
end();
uint8_t dhttype = Settings_ESP3D::read_byte(ESP_SENSOR_TYPE);
log_esp3d("Read %d, %s", dhttype,
dhttype == 1 ? "DHT11"
: dhttype == 2 ? "DHT22"
: dhttype == 0 ? "NONE"
: "Unknow type");
if (dhttype == 0) {
log_esp3d("No Sensor active");
return true;
}
void DHTSensorDevice::end()
{
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;
}
}
}
if (!isModelValid(dhttype)) {
log_esp3d_e("No valid id ");
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)
{
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
log_esp3d("checking %s with %s",s, SENSOR_NAME[i]);
if (strcmp(s, SENSOR_NAME[i])==0) {
log_esp3d("found %d",SENSOR_ID[i]);
return SENSOR_ID[i];
}
void DHTSensorDevice::end() {
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 0;
}
return false;
}
uint8_t DHTSensorDevice::nbType()
{
return NB_TYPE_SENSOR;
}
uint8_t DHTSensorDevice::GetModel(uint8_t i)
{
if (i <NB_TYPE_SENSOR) {
return SENSOR_ID[i];
uint8_t DHTSensorDevice::getIDFromString(const char *s) {
for (uint8_t i = 0; i < NB_TYPE_SENSOR; i++) {
log_esp3d("checking %s with %s", s, SENSOR_NAME[i]);
if (strcmp(s, SENSOR_NAME[i]) == 0) {
log_esp3d("found %d", SENSOR_ID[i]);
return SENSOR_ID[i];
}
return 0;
}
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];
}
uint8_t DHTSensorDevice::nbType() { return NB_TYPE_SENSOR; }
uint8_t DHTSensorDevice::GetModel(uint8_t i) {
if (i < NB_TYPE_SENSOR) {
return SENSOR_ID[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)
{
if (i <NB_TYPE_SENSOR) {
return SENSOR_NAME[i];
const char *DHTSensorDevice::GetModelString(uint8_t i) {
if (i < NB_TYPE_SENSOR) {
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";
}
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);
}
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");
}
if (String(humidity, 1) != "nan") {
s = String(temperature, 1);
s += "[";
s += SENSOR__UNIT;
s += "] " + String(humidity, 1) + "[%]";
} else {
s="DISCONNECTED";
log_esp3d("No device");
s = "DISCONNECTED";
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 //SENSOR_DEVICE
#endif // DHT11_DEVICE || DHT22_DEVICE
#endif // SENSOR_DEVICE

View File

@ -20,166 +20,148 @@
#include "../../include/esp3d_config.h"
#ifdef SENSOR_DEVICE
#include "sensor.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
//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
#include "../../core/settings_esp3d.h"
#include "sensor.h"
#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"
#endif // WIFI_FEATURE || ETH_FEATURE
#endif // WIFI_FEATURE || ETH_FEATURE
ESP3DSensor esp3d_sensor;
ESP3DSensor::ESP3DSensor()
{
_started = false;
_interval = 0;
_device = nullptr;
ESP3DSensor::ESP3DSensor() {
_started = false;
_interval = 0;
_device = nullptr;
}
ESP3DSensor::~ESP3DSensor()
{
end();
}
ESP3DSensor::~ESP3DSensor() { end(); }
bool ESP3DSensor::begin()
{
log_esp3d("Sensor Begin");
bool res = true;
end();
//new _device
#if SENSOR_DEVICE==ANALOG_DEVICE
_device = (ESP3DSensorDevice * )new AnalogSensorDevice();
#endif //ANALOG_DEVICE
#if SENSOR_DEVICE==DHT11_DEVICE || SENSOR_DEVICE==DHT22_DEVICE
_device = (ESP3DSensorDevice * )new DHTSensorDevice();
#endif //DHT11_DEVICE || DHT22_DEVICE
#if SENSOR_DEVICE==BMP280_DEVICE || SENSOR_DEVICE==BME280_DEVICE
_device = (ESP3DSensorDevice * )new BMX280SensorDevice();
#endif //DHT11_DEVICE || DHT22_DEVICE
if (!_device) {
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);
}
bool ESP3DSensor::begin() {
log_esp3d("Sensor Begin");
bool res = true;
end();
// new _device
#if SENSOR_DEVICE == ANALOG_DEVICE
_device = (ESP3DSensorDevice*)new AnalogSensorDevice();
#endif // ANALOG_DEVICE
#if SENSOR_DEVICE == DHT11_DEVICE || SENSOR_DEVICE == DHT22_DEVICE
_device = (ESP3DSensorDevice*)new DHTSensorDevice();
#endif // DHT11_DEVICE || DHT22_DEVICE
#if SENSOR_DEVICE == BMP280_DEVICE || SENSOR_DEVICE == BME280_DEVICE
_device = (ESP3DSensorDevice*)new BMX280SensorDevice();
#endif // DHT11_DEVICE || DHT22_DEVICE
if (!_device) {
log_esp3d_e("No device created");
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;
}
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;
}
const char * ESP3DSensor::GetData()
{
if (_started && _device) {
return _device->GetData();
}
return "";
void ESP3DSensor::end() {
if (_device) {
delete _device;
_device = nullptr;
}
_started = false;
_interval = 0;
}
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
}
}
uint8_t ESP3DSensor::GetModel(uint8_t i) {
if (_device) {
return _device->GetModel(i);
} else {
return 0;
}
}
#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"
#if COMMUNICATION_PROTOCOL == MKS_SERIAL || COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT)
#include "serial_service.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#if COMMUNICATION_PROTOCOL == MKS_SERIAL || \
COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT)
#include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "serial_service.h"
#if COMMUNICATION_PROTOCOL == MKS_SERIAL
#include "../mks/mks_service.h"
#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL
#endif // COMMUNICATION_PROTOCOL == MKS_SERIAL
#include "../authentication/authentication_service.h"
#if defined (ARDUINO_ARCH_ESP8266)
#if defined(ARDUINO_ARCH_ESP8266)
#define MAX_SERIAL 2
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1};
#endif //ARDUINO_ARCH_ESP8266
HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
#endif // ARDUINO_ARCH_ESP8266
#if defined (ARDUINO_ARCH_ESP32)
#if defined(ARDUINO_ARCH_ESP32)
#if defined (CONFIG_IDF_TARGET_ESP32C3)
#define MAX_SERIAL 2
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1};
#else
#define MAX_SERIAL 3
HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1, &Serial2};
#endif
#if defined(CONFIG_IDF_TARGET_ESP32C3)
#define MAX_SERIAL 2
HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1};
#else
#define MAX_SERIAL 3
HardwareSerial *Serials[MAX_SERIAL] = {&Serial, &Serial1, &Serial2};
#endif
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
//Serial Parameters
// Serial Parameters
#define ESP_SERIAL_PARAM SERIAL_8N1
#define ESP3DSERIAL_RUNNING_PRIORITY 1
@ -56,492 +57,486 @@ HardwareSerial * Serials[MAX_SERIAL] = {&Serial, &Serial1};
SerialService serial_service = SerialService(MAIN_SERIAL);
#if defined(ESP_SERIAL_BRIDGE_OUTPUT)
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)
TaskHandle_t _hserialtask= nullptr;
#endif //ARDUINO_ARCH_ESP32
TaskHandle_t _hserialtask = nullptr;
#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
//Constructor
SerialService::SerialService(uint8_t id)
{
_buffer_size = 0;
_started = false;
_needauthentication = true;
_id = id;
switch (_id) {
// Constructor
SerialService::SerialService(uint8_t id) {
_buffer_size = 0;
_started = false;
_needauthentication = true;
_id = id;
switch (_id) {
case MAIN_SERIAL:
_rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN;
_client=ESP_SERIAL_CLIENT;
break;
_rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN;
_client = ESP_SERIAL_CLIENT;
break;
#if defined(ESP_SERIAL_BRIDGE_OUTPUT)
case BRIDGE_SERIAL:
_rxPin = ESP_BRIDGE_RX_PIN;
_txPin = ESP_BRIDGE_TX_PIN;
_client=ESP_SERIAL_BRIDGE_CLIENT;
break;
#endif //ESP_SERIAL_BRIDGE_OUTPUT
_rxPin = ESP_BRIDGE_RX_PIN;
_txPin = ESP_BRIDGE_TX_PIN;
_client = ESP_SERIAL_BRIDGE_CLIENT;
break;
#endif // ESP_SERIAL_BRIDGE_OUTPUT
default:
_rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN;
_client=ESP_SERIAL_CLIENT;
break;
}
_rxPin = ESP_RX_PIN;
_txPin = ESP_TX_PIN;
_client = ESP_SERIAL_CLIENT;
break;
}
}
//Destructor
SerialService::~SerialService()
{
end();
}
// Destructor
SerialService::~SerialService() { end(); }
//dedicated serial task
// dedicated serial task
#if defined(ARDUINO_ARCH_ESP32) && defined(SERIAL_INDEPENDANT_TASK)
void ESP3DSerialTaskfn( void * parameter )
{
for(;;) {
serial_service.process();
Hal::wait(SERIAL_YIELD); // Yield to other tasks
}
vTaskDelete( NULL );
void ESP3DSerialTaskfn(void *parameter) {
for (;;) {
serial_service.process();
Hal::wait(SERIAL_YIELD); // Yield to other tasks
}
vTaskDelete(NULL);
}
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
//extra parameters that do not need a begin
void SerialService::setParameters()
{
#if defined (AUTHENTICATION_FEATURE)
_needauthentication = (Settings_ESP3D::read_byte (ESP_SECURE_SERIAL)==0)?false:true;
// extra parameters that do not need a begin
void SerialService::setParameters() {
#if defined(AUTHENTICATION_FEATURE)
_needauthentication =
(Settings_ESP3D::read_byte(ESP_SECURE_SERIAL) == 0) ? false : true;
#else
_needauthentication = false;
#endif //AUTHENTICATION_FEATURE
_needauthentication = false;
#endif // AUTHENTICATION_FEATURE
}
//Setup Serial
bool SerialService::begin(uint8_t serialIndex)
{
_serialIndex = serialIndex-1;
log_esp3d("Serial %d begin for %d", _serialIndex, _id);
if (_id== BRIDGE_SERIAL && Settings_ESP3D::read_byte(ESP_SERIAL_BRIDGE_ON)==0) {
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);
// Setup Serial
bool SerialService::begin(uint8_t serialIndex) {
_serialIndex = serialIndex - 1;
log_esp3d("Serial %d begin for %d", _serialIndex, _id);
if (_id == BRIDGE_SERIAL &&
Settings_ESP3D::read_byte(ESP_SERIAL_BRIDGE_ON) == 0) {
log_esp3d("Serial %d for %d is disabled", _serialIndex, _id);
return true;
}
//End serial
bool SerialService::end()
{
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;
}
}
}
if (_serialIndex >= MAX_SERIAL) {
log_esp3d_e("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_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
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();
}
// 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;
}
//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..
// 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;
}
// 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 (_id==MAIN_SERIAL) {
return;
}
#endif //ARDUINO_ARCH_ESP32 && SERIAL_INDEPENDANT_TASK0
process();
if (_id == MAIN_SERIAL) {
return;
}
#endif // ARDUINO_ARCH_ESP32 && SERIAL_INDEPENDANT_TASK0
process();
}
void SerialService::flushbuffer()
{
ESP3DOutput output(_client);
_buffer[_buffer_size] = 0x0;
//dispatch command
if (_started) {
esp3d_commands.process(_buffer, _buffer_size, &output,_needauthentication?LEVEL_GUEST:LEVEL_ADMIN);
}
_lastflush = millis();
_buffer_size = 0;
void SerialService::flushbuffer() {
ESP3DOutput output(_client);
_buffer[_buffer_size] = 0x0;
// dispatch command
if (_started) {
esp3d_commands.process(_buffer, _buffer_size, &output,
_needauthentication ? LEVEL_GUEST : LEVEL_ADMIN);
}
_lastflush = millis();
_buffer_size = 0;
}
//push collected data to buffer and proceed accordingly
void SerialService::push2buffer(uint8_t * sbuf, size_t len)
{
if (!_started) {
return;
}
log_esp3d("buffer get %d data ", len);
// push collected data to buffer and proceed accordingly
void SerialService::push2buffer(uint8_t *sbuf, size_t len) {
if (!_started) {
return;
}
log_esp3d("buffer get %d data ", len);
#if COMMUNICATION_PROTOCOL == MKS_SERIAL
static bool isFrameStarted = false;
static bool isCommandFrame = false;
static uint8_t type;
//expected size
static int16_t framePos = -1;
//currently received
static uint datalen = 0;
for (size_t i = 0; i < len; i++) {
log_esp3d("Data : %c %x", sbuf[i],sbuf[i]);
framePos++;
_lastflush = millis();
//so frame head was detected
if (isFrameStarted) {
//checking it is a valid Frame header
if (framePos==1) {
log_esp3d("type = %x",sbuf[i]);
if(MKSService::isFrame(char(sbuf[i]))) {
if (MKSService::isCommand(char(sbuf[i]))) {
isCommandFrame =true;
log_esp3d("type: Command");
} else {
log_esp3d("type: other");
type = sbuf[i];
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;
}
}
static bool isFrameStarted = false;
static bool isCommandFrame = false;
static uint8_t type;
// expected size
static int16_t framePos = -1;
// currently received
static uint datalen = 0;
for (size_t i = 0; i < len; i++) {
log_esp3d("Data : %c %x", sbuf[i], sbuf[i]);
framePos++;
_lastflush = millis();
// so frame head was detected
if (isFrameStarted) {
// checking it is a valid Frame header
if (framePos == 1) {
log_esp3d("type = %x", sbuf[i]);
if (MKSService::isFrame(char(sbuf[i]))) {
if (MKSService::isCommand(char(sbuf[i]))) {
isCommandFrame = true;
log_esp3d("type: Command");
} else {
log_esp3d("type: other");
type = sbuf[i];
isCommandFrame = false;
}
} 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("Unidentified data : %c %x", sbuf[i],sbuf[i]);
isCommandFrame = false;
framePos = -1;
datalen = 0;
}
log_esp3d_e("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_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
for (size_t i = 0; i < len; i++) {
_lastflush = millis();
//command is defined
if ((char(sbuf[i]) == '\n')|| (char(sbuf[i]) == '\r')) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
}
flushbuffer();
} else if (isPrintable (char(sbuf[i]) )) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
} else {
flushbuffer();
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
}
} else { //it is not printable char
//clean buffer first
if (_buffer_size > 0) {
flushbuffer();
}
//process char
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
flushbuffer();
}
for (size_t i = 0; i < len; i++) {
_lastflush = millis();
// command is defined
if ((char(sbuf[i]) == '\n') || (char(sbuf[i]) == '\r')) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
}
flushbuffer();
} else if (isPrintable(char(sbuf[i]))) {
if (_buffer_size < ESP3D_SERIAL_BUFFER_SIZE) {
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
} else {
flushbuffer();
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
}
} else { // it is not printable char
// clean buffer first
if (_buffer_size > 0) {
flushbuffer();
}
// process char
_buffer[_buffer_size] = sbuf[i];
_buffer_size++;
flushbuffer();
}
}
#endif
}
//Reset Serial Setting (baud rate)
bool SerialService::reset()
{
log_esp3d("Reset serial");
bool res = false;
switch (_id) {
// Reset Serial Setting (baud rate)
bool SerialService::reset() {
log_esp3d("Reset serial");
bool res = false;
switch (_id) {
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)
case BRIDGE_SERIAL:
res = Settings_ESP3D::write_byte (ESP_SERIAL_BRIDGE_ON, 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
res = Settings_ESP3D::write_byte(
ESP_SERIAL_BRIDGE_ON,
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:
return res;
}
return res;
}
}
void SerialService::updateBaudRate(long br)
{
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 ;
}
void SerialService::updateBaudRate(long br) {
if (br != baudRate()) {
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
Serials[_serialIndex]->swap();
#endif //ARDUINO_ARCH_ESP8266
Serials[_serialIndex]->swap();
#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
*/
//#define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0
// #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h"
#if defined(ESP3DLIB_ENV) && COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#include <Arduino.h>
#include "serial2socket.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "serial2socket.h"
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()
{
end();
}
Serial_2_Socket::~Serial_2_Socket()
{
end();
}
void Serial_2_Socket::begin(long speed)
{
end();
}
void Serial_2_Socket::enable(bool enable) { _started = enable; }
void Serial_2_Socket::enable(bool enable)
{
_started = enable;
}
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()
{
void Serial_2_Socket::pause(bool state) {
_paused = state;
if (_paused) {
_TXbufferSize = 0;
_RXbufferSize = 0;
_RXbufferpos = 0;
_started = false;
_paused = false;
} else {
_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 _RXbufferSize;
}
bool Serial_2_Socket::started()
{
return _started;
size_t Serial_2_Socket::write(uint8_t c) {
if (!_started || _paused) {
return 1;
}
return write(&c, 1);
}
Serial_2_Socket::operator bool() const
{
return true;
}
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();
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;
}
int Serial_2_Socket::peek(void)
{
if (_RXbufferSize > 0 && _started) {
return _RXbuffer[_RXbufferpos];
} else {
return -1;
}
int Serial_2_Socket::peek(void) {
if (_RXbufferSize > 0 && _started) {
return _RXbuffer[_RXbufferpos];
} else {
return -1;
}
}
bool Serial_2_Socket::push (const uint8_t *buffer, size_t size)
{
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;
}
bool Serial_2_Socket::push(const uint8_t *buffer, size_t size) {
if (buffer == NULL || size == 0 || !_started || _paused) {
return false;
}
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;
}
int data_size = size;
if ((data_size + _RXbufferSize) <= S2S_RXBUFFERSIZE) {
int current = _RXbufferpos + _RXbufferSize;
if (current > S2S_RXBUFFERSIZE) {
current = current - S2S_RXBUFFERSIZE;
}
}
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;
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;
}
#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");
// allow not to set seconds for lazy guys typing command line
if (strptime(stime, "%Y-%m-%dT%H:%M", &tmstruct) == nullptr) {
log_esp3d("Invalid time format");
log_esp3d_e("Invalid time format");
return false;
}
}

View File

@ -21,255 +21,245 @@
#include "../../include/esp3d_config.h"
#ifdef SD_UPDATE_FEATURE
#include "esp_config_file.h"
#include "../filesystem/esp_sd.h"
#include "esp_config_file.h"
#define LINE_MAX_SIZE 255
#define SECTION_MAX_SIZE 10
#define KEY_MAX_SIZE 30
#define VALUE_MAX_SIZE 128
#define LINE_MAX_SIZE 255
#define SECTION_MAX_SIZE 10
#define KEY_MAX_SIZE 30
#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)
{
_filename = (char *)malloc(strlen(path)+1);
strcpy(_filename, path);
_pfunction = fn;
ESP_ConfigFile::ESP_ConfigFile(const char *path, TProcessingFunction fn) {
_filename = (char *)malloc(strlen(path) + 1);
strcpy(_filename, path);
_pfunction = fn;
}
bool ESP_ConfigFile::processFile()
{
bool res = true;
if (!ESP_SD::exists(_filename)) {
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");
bool ESP_ConfigFile::processFile() {
bool res = true;
if (!ESP_SD::exists(_filename)) {
log_esp3d_e("No ini file");
return false;
}
bool ESP_ConfigFile::isComment(char * line)
{
if (strlen(line) > 0) {
if((line[0]==';') || (line[0]=='#')) {
return true;
}
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++;
}
}
return false;
}
bool ESP_ConfigFile::isSection(char * line)
{
if (strlen(line) > 0) {
if((line[0]=='[') && (line[strlen(line)-1]==']')) {
return true;
}
}
return false;
}
bool ESP_ConfigFile::isValue(char * line)
{
if (strlen(line) > 3) {
for(uint8_t i = 1; i < strlen(line)-2; i++) {
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;
}
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';
}
}
return false;
rFile.close();
return res;
}
log_esp3d_e("Cannot open ini file");
return false;
}
bool ESP_ConfigFile::revokeFile()
{
char * filename;
if (!ESP_SD::exists(_filename)) {
log_esp3d("No ini file to revoke");
return false;
bool ESP_ConfigFile::isComment(char *line) {
if (strlen(line) > 0) {
if ((line[0] == ';') || (line[0] == '#')) {
return true;
}
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 false;
}
bool ESP_ConfigFile::isSection(char *line) {
if (strlen(line) > 0) {
if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) {
return true;
}
}
return false;
}
bool ESP_ConfigFile::isValue(char *line) {
if (strlen(line) > 3) {
for (uint8_t i = 1; i < strlen(line) - 2; i++) {
if (line[i] == '=') {
return true;
}
}
log_esp3d("Cannot open / create revoked file");
if (wFile ) {
wFile.close();
}
if (rFile ) {
rFile.close();
}
return false;
}
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"
#ifdef SD_UPDATE_FEATURE
#include "update_service.h"
#include "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h"
#include "esp_config_file.h"
#include "../filesystem/esp_sd.h"
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.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>
#define U_FS U_SPIFFS
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#endif //ARDUINO_ARCH_ESP8266
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#endif // ARDUINO_ARCH_ESP8266
UpdateService update_service;
@ -42,57 +42,32 @@ UpdateService update_service;
#define FW_FILE "/esp3dfw.bin"
#define FS_FILE "/esp3dfs.bin"
const char * NetstringKeysVal[] = {"hostname",
"STA_SSID",
"STA_Password",
"AP_SSID",
"AP_Password"
} ;
const char* NetstringKeysVal[] = {"hostname", "STA_SSID", "STA_Password",
"AP_SSID", "AP_Password"};
const uint16_t NetstringKeysPos[] = {ESP_HOSTNAME,
ESP_STA_SSID,
ESP_STA_PASSWORD,
ESP_AP_SSID,
ESP_AP_PASSWORD
} ;
const uint16_t NetstringKeysPos[] = {
ESP_HOSTNAME, ESP_STA_SSID, ESP_STA_PASSWORD, ESP_AP_SSID, ESP_AP_PASSWORD};
const char * ServstringKeysVal[] = {
"Time_server1",
"Time_server2",
"Time_server3",
"ADMIN_PASSWORD",
"USER_PASSWORD",
"NOTIF_TOKEN1",
"NOTIF_TOKEN2",
"NOTIF_TOKEN_Settings"
} ;
const char* ServstringKeysVal[] = {
"Time_server1", "Time_server2", "Time_server3", "ADMIN_PASSWORD",
"USER_PASSWORD", "NOTIF_TOKEN1", "NOTIF_TOKEN2", "NOTIF_TOKEN_Settings"};
const uint16_t ServstringKeysPos[] = {
ESP_TIME_SERVER1,
ESP_TIME_SERVER2,
ESP_TIME_SERVER3,
ESP_ADMIN_PWD,
ESP_USER_PWD,
ESP_NOTIFICATION_TOKEN1,
ESP_NOTIFICATION_TOKEN2,
ESP_NOTIFICATION_SETTINGS
} ;
const uint16_t ServstringKeysPos[] = {ESP_TIME_SERVER1,
ESP_TIME_SERVER2,
ESP_TIME_SERVER3,
ESP_ADMIN_PWD,
ESP_USER_PWD,
ESP_NOTIFICATION_TOKEN1,
ESP_NOTIFICATION_TOKEN2,
ESP_NOTIFICATION_SETTINGS};
const char * IPKeysVal[] = {"STA_IP",
"STA_GW",
"STA_MSK",
"STA_DNS",
"AP_IP"
} ;
const char* IPKeysVal[] = {"STA_IP", "STA_GW", "STA_MSK", "STA_DNS", "AP_IP"};
const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE,
ESP_STA_GATEWAY_VALUE,
ESP_STA_MASK_VALUE,
ESP_STA_DNS_VALUE,
ESP_AP_IP_VALUE
} ;
const uint16_t IPKeysPos[] = {ESP_STA_IP_VALUE, ESP_STA_GATEWAY_VALUE,
ESP_STA_MASK_VALUE, ESP_STA_DNS_VALUE,
ESP_AP_IP_VALUE};
const char * ServintKeysVal[] = {
const char* ServintKeysVal[] = {
"Serial_Bridge_Baud"
"HTTP_Port",
"TELNET_Port",
@ -101,65 +76,48 @@ const char * ServintKeysVal[] = {
"WebDav_Port",
"FTP_Control_Port",
"FTP_Active_Port ",
"FTP_Passive_Port"
} ;
"FTP_Passive_Port"};
const uint16_t ServintKeysPos[] = {
ESP_SERIAL_BRIDGE_BAUD,
ESP_HTTP_PORT,
ESP_TELNET_PORT,
ESP_SENSOR_INTERVAL,
ESP_WEBSOCKET_PORT,
ESP_WEBDAV_PORT,
ESP_FTP_CTRL_PORT,
ESP_FTP_DATA_ACTIVE_PORT,
ESP_FTP_DATA_PASSIVE_PORT
} ;
ESP_SERIAL_BRIDGE_BAUD, ESP_HTTP_PORT,
ESP_TELNET_PORT, ESP_SENSOR_INTERVAL,
ESP_WEBSOCKET_PORT, ESP_WEBDAV_PORT,
ESP_FTP_CTRL_PORT, ESP_FTP_DATA_ACTIVE_PORT,
ESP_FTP_DATA_PASSIVE_PORT};
const char * SysintKeysVal[] = {"Baud_rate",
"Boot_delay"
} ;
const char* SysintKeysVal[] = {"Baud_rate", "Boot_delay"};
const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE,
ESP_BOOT_DELAY
} ;
const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE, ESP_BOOT_DELAY};
const char * ServboolKeysVal[] = {"Serial_Bridge_active",
"AUTONOTIFICATION",
"HTTP_active",
"TELNET_active",
"WebSocket_active",
"WebDav_active",
"Time_DST",
"CHECK_FOR_UPDATE",
"Active_buzzer",
"Active_Internet_time",
"Radio_enabled"
} ;
const char* ServboolKeysVal[] = {"Serial_Bridge_active",
"AUTONOTIFICATION",
"HTTP_active",
"TELNET_active",
"WebSocket_active",
"WebDav_active",
"Time_DST",
"CHECK_FOR_UPDATE",
"Active_buzzer",
"Active_Internet_time",
"Radio_enabled"};
const uint16_t ServboolKeysPos[] = {ESP_SERIAL_BRIDGE_ON,
ESP_AUTO_NOTIFICATION,
ESP_HTTP_ON,
ESP_TELNET_ON,
ESP_WEBSOCKET_ON,
ESP_WEBDAV_ON,
ESP_TIME_IS_DST,
ESP_SD_CHECK_UPDATE_AT_BOOT,
ESP_BUZZER,
ESP_INTERNET_TIME,
ESP_BOOT_RADIO_STATE
} ;
const uint16_t ServboolKeysPos[] = {
ESP_SERIAL_BRIDGE_ON, ESP_AUTO_NOTIFICATION,
ESP_HTTP_ON, ESP_TELNET_ON,
ESP_WEBSOCKET_ON, ESP_WEBDAV_ON,
ESP_TIME_IS_DST, ESP_SD_CHECK_UPDATE_AT_BOOT,
ESP_BUZZER, ESP_INTERNET_TIME,
ESP_BOOT_RADIO_STATE};
const char * SysboolKeysVal[] = {"Active_Serial_Bridge",
"Active_Remote_Screen",
"Active_ESP3D_Screen",
"Active_Serial ",
"Active_WebSocket",
"Active_Telnet",
"Active_BT",
"Boot_verbose",
"Secure_serial"
} ;
const char* SysboolKeysVal[] = {"Active_Serial_Bridge",
"Active_Remote_Screen",
"Active_ESP3D_Screen",
"Active_Serial ",
"Active_WebSocket",
"Active_Telnet",
"Active_BT",
"Boot_verbose",
"Secure_serial"};
const uint16_t SysboolKeysPos[] = {ESP_SERIAL_BRIDGE_FLAG,
ESP_REMOTE_SCREEN_FLAG,
@ -169,381 +127,389 @@ const uint16_t SysboolKeysPos[] = {ESP_SERIAL_BRIDGE_FLAG,
ESP_TELNET_FLAG,
ESP_BT_FLAG,
ESP_VERBOSE_BOOT,
ESP_SECURE_SERIAL
} ;
ESP_SECURE_SERIAL};
const char * NetbyteKeysVal[] = {
"AP_channel"
} ;
const char* NetbyteKeysVal[] = {"AP_channel"};
const uint16_t NetbyteKeysPos[] = {
ESP_AP_CHANNEL
} ;
const char * ServbyteKeysVal[] = {"Time_zone",
"Sesion_timeout",
"SD_SPEED"
} ;
const uint16_t NetbyteKeysPos[] = {ESP_AP_CHANNEL};
const char* ServbyteKeysVal[] = {"Time_zone", "Sesion_timeout", "SD_SPEED"};
const uint16_t ServbyteKeysPos[] = {ESP_TIMEZONE,
ESP_SESSION_TIMEOUT,
ESP_SD_SPEED_DIV
} ;
const uint16_t ServbyteKeysPos[] = {ESP_TIMEZONE, ESP_SESSION_TIMEOUT,
ESP_SD_SPEED_DIV};
bool processString(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++) {
if (strcasecmp(keysval[i],key)==0) {
//if it is a previouly saved scrambled password ignore it
if (strcasecmp(value,"********")!=0) {
T='S';
P=keypos[i];
return true;
}
}
bool processString(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++) {
if (strcasecmp(keysval[i], key) == 0) {
// if it is a previouly saved scrambled password ignore it
if (strcasecmp(value, "********") != 0) {
T = 'S';
P = keypos[i];
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)
{
for(uint i=0; i< size ; i++) {
if (strcasecmp(keysval[i],key)==0) {
T='I';
P=keypos[i];
v=String(value).toInt();
return true;
}
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) {
for (uint i = 0; i < size; i++) {
if (strcasecmp(keysval[i], key) == 0) {
T = 'I';
P = keypos[i];
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)
{
for(uint i=0; i< size ; i++) {
if (strcasecmp(keysval[i],key)==0) {
T='B';
P=keypos[i];
if ((strcasecmp("yes",value)==0)||(strcasecmp("on", value)==0)||(strcasecmp("true", value)==0)||(strcasecmp("1", value)==0) ) {
b = 1;
} else if ((strcasecmp("no", value)==0)||(strcasecmp("off", value)==0)||(strcasecmp("false", value)==0)||(strcasecmp("0", value)==0) ) {
b = 0;
} else {
P=-1;
}
return true;
}
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) {
for (uint i = 0; i < size; i++) {
if (strcasecmp(keysval[i], key) == 0) {
T = 'B';
P = keypos[i];
if ((strcasecmp("yes", value) == 0) || (strcasecmp("on", value) == 0) ||
(strcasecmp("true", value) == 0) || (strcasecmp("1", value) == 0)) {
b = 1;
} else if ((strcasecmp("no", value) == 0) ||
(strcasecmp("off", value) == 0) ||
(strcasecmp("false", value) == 0) ||
(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
bool processingFileFunction (const char * section, const char * key, const char * value)
{
bool res = true;
char T = '\0';
int P = -1;
uint32_t v = 0;
byte b = 0;
bool done=false;
log_esp3d("[%s]%s=%s",section, key,value);
//network / services / system sections
if (strcasecmp("network",section)==0) {
if (!done) {
done = processString(NetstringKeysVal,NetstringKeysPos,sizeof(NetstringKeysVal)/sizeof(char*), key, value, T, P );
// 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,
const char* value) {
bool res = true;
char T = '\0';
int P = -1;
uint32_t v = 0;
byte b = 0;
bool done = false;
log_esp3d("[%s]%s=%s", section, key, value);
// network / services / system sections
if (strcasecmp("network", section) == 0) {
if (!done) {
done = processString(NetstringKeysVal, NetstringKeysPos,
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) {
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
}
}
}
//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
}
}
}
}
// 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
}
}
}
//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");
// 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
}
}
}
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() {}
bool UpdateService::flash(const char * filename, int type)
{
bool res = false;
if (ESP_SD::exists (filename)) {
log_esp3d("Update found");
bool issucess = false;
ESP_SDFile sdfile;
String finalName = filename;
sdfile = ESP_SD::open(filename);
if(sdfile) {
size_t s = sdfile.size();
size_t rs = 0;
uint8_t v[1] ;
if(Update.begin(s, type)) {
log_esp3d("Update started");
while (sdfile.available() && (rs <= (s+1))) {
rs++;
v[0]=sdfile.read();
Update.write(v,1);
Hal::wait(0);
}
if (rs==s) {
log_esp3d("Update done");
if(Update.end(true)) {
log_esp3d("Update success");
issucess = true;
}
} else {
Update.end();
log_esp3d("Wrong size");
}
}
sdfile.close();
bool UpdateService::flash(const char* filename, int type) {
bool res = false;
if (ESP_SD::exists(filename)) {
log_esp3d("Update found");
bool issucess = false;
ESP_SDFile sdfile;
String finalName = filename;
sdfile = ESP_SD::open(filename);
if (sdfile) {
size_t s = sdfile.size();
size_t rs = 0;
uint8_t v[1];
if (Update.begin(s, type)) {
log_esp3d("Update started");
while (sdfile.available() && (rs <= (s + 1))) {
rs++;
v[0] = sdfile.read();
Update.write(v, 1);
Hal::wait(0);
}
if (rs == s) {
log_esp3d("Update done");
if (Update.end(true)) {
log_esp3d("Update success");
issucess = true;
}
} else {
log_esp3d("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;
}
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();
Update.end();
log_esp3d_e("Wrong size");
}
}
sdfile.close();
} 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;
}
void UpdateService::end()
{
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_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() {}
#endif //SD_UPDATE_FEATURE
#endif // SD_UPDATE_FEATURE

View File

@ -27,7 +27,7 @@
Lebosse (ESP3D Integration)
*/
// #define ESP_DEBUG_FEATURE DEBUG_OUTPUT_SERIAL0
// #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
#include "../../include/esp3d_config.h"
#if defined(WEBDAV_FEATURE)
@ -35,7 +35,6 @@
#include "ESPWebDAV.h"
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <PolledTimeout.h>
@ -821,7 +820,7 @@ void ESPWebDAVCore::handleGet(ResourceType resource, WebDavFile& file,
// no lock on GET
#if defined(ESP_DEBUG_FEATURE)
#if defined(ESP_LOG_FEATURE)
long tStart = millis();
#endif
@ -899,7 +898,7 @@ void ESPWebDAVCore::handleGet(ResourceType resource, WebDavFile& file,
break;
}
#if defined(ESP_DEBUG_FEATURE)
#if defined(ESP_LOG_FEATURE)
for (size_t i = 0; i < 80 && i < numRead; i++) {
log_esp3ds("%c", buf[i] < 32 || buf[i] > 127 ? '.' : buf[i]);
}
@ -953,7 +952,7 @@ void ESPWebDAVCore::handlePut(ResourceType resource) {
if (contentLengthHeader != 0) {
uint8_t buf[BUFFER_SIZE];
#if defined(ESP_DEBUG_FEATURE)
#if defined(ESP_LOG_FEATURE)
long tStart = millis();
#endif
size_t numRemaining = contentLengthHeader;
@ -1542,7 +1541,7 @@ void ESPWebDAVCore::send(const String& code, const char* content_type,
if (content.length()) {
sendContent(content);
#if defined(ESP_DEBUG_FEATURE)
#if defined(ESP_LOG_FEATURE)
log_esp3d("send content (%d bytes):", (int)content.length());
for (size_t i = 0; i < DEBUG_LEN && i < content.length(); 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);
}
#if defined(ESP_DEBUG_FEATURE)
#if defined(ESP_LOG_FEATURE)
log_esp3d("---- %scontent (%d bytes):", _chunked ? "chunked " : "",
(int)size);
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 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"
#if defined (WEBDAV_FEATURE)
#if defined(WEBDAV_FEATURE)
#include "ESPWebDAV.h"
// Sections are copied from ESP8266Webserver
String ESPWebDAV::getMimeType(const String& path)
{
if (path.endsWith(".html")) {
return "text/html";
} else if (path.endsWith(".htm")) {
return "text/html";
} else if (path.endsWith(".css")) {
return "text/css";
} else if (path.endsWith(".txt")) {
return "text/plain";
} else if (path.endsWith(".js")) {
return "application/javascript";
} else if (path.endsWith(".json")) {
return "application/json";
} else if (path.endsWith(".png")) {
return "image/png";
} else if (path.endsWith(".gif")) {
return "image/gif";
} else if (path.endsWith(".jpg")) {
return "image/jpeg";
} else if (path.endsWith(".ico")) {
return "image/x-icon";
} else if (path.endsWith(".svg")) {
return "image/svg+xml";
} else if (path.endsWith(".ttf")) {
return "application/x-font-ttf";
} else if (path.endsWith(".otf")) {
return "application/x-font-opentype";
} else if (path.endsWith(".woff")) {
return "application/font-woff";
} else if (path.endsWith(".woff2")) {
return "application/font-woff2";
} else if (path.endsWith(".eot")) {
return "application/vnd.ms-fontobject";
} else if (path.endsWith(".sfnt")) {
return "application/font-sfnt";
} else if (path.endsWith(".xml")) {
return "text/xml";
} else if (path.endsWith(".pdf")) {
return "application/pdf";
} else if (path.endsWith(".zip")) {
return "application/zip";
} else if (path.endsWith(".gz")) {
return "application/x-gzip";
} else if (path.endsWith(".appcache")) {
return "text/cache-manifest";
}
String ESPWebDAV::getMimeType(const String& path) {
if (path.endsWith(".html")) {
return "text/html";
} else if (path.endsWith(".htm")) {
return "text/html";
} else if (path.endsWith(".css")) {
return "text/css";
} else if (path.endsWith(".txt")) {
return "text/plain";
} else if (path.endsWith(".js")) {
return "application/javascript";
} else if (path.endsWith(".json")) {
return "application/json";
} else if (path.endsWith(".png")) {
return "image/png";
} else if (path.endsWith(".gif")) {
return "image/gif";
} else if (path.endsWith(".jpg")) {
return "image/jpeg";
} else if (path.endsWith(".ico")) {
return "image/x-icon";
} else if (path.endsWith(".svg")) {
return "image/svg+xml";
} else if (path.endsWith(".ttf")) {
return "application/x-font-ttf";
} else if (path.endsWith(".otf")) {
return "application/x-font-opentype";
} else if (path.endsWith(".woff")) {
return "application/font-woff";
} else if (path.endsWith(".woff2")) {
return "application/font-woff2";
} else if (path.endsWith(".eot")) {
return "application/vnd.ms-fontobject";
} else if (path.endsWith(".sfnt")) {
return "application/font-sfnt";
} else if (path.endsWith(".xml")) {
return "text/xml";
} else if (path.endsWith(".pdf")) {
return "application/pdf";
} else if (path.endsWith(".zip")) {
return "application/zip";
} else if (path.endsWith(".gz")) {
return "application/x-gzip";
} else if (path.endsWith(".appcache")) {
return "text/cache-manifest";
}
return "application/octet-stream";
return "application/octet-stream";
}
String ESPWebDAV::urlDecode(const String& text)
{
String decoded = "";
char temp[] = "0x00";
unsigned int len = text.length();
unsigned int i = 0;
while (i < len) {
char decodedChar;
char encodedChar = text.charAt(i++);
if ((encodedChar == '%') && (i + 1 < len)) {
temp[2] = text.charAt(i++);
temp[3] = text.charAt(i++);
decodedChar = strtol(temp, NULL, 16);
} else {
if (encodedChar == '+') {
decodedChar = ' ';
} else {
decodedChar = encodedChar; // normal ascii char
}
}
decoded += decodedChar;
String ESPWebDAV::urlDecode(const String& text) {
String decoded = "";
char temp[] = "0x00";
unsigned int len = text.length();
unsigned int i = 0;
while (i < len) {
char decodedChar;
char encodedChar = text.charAt(i++);
if ((encodedChar == '%') && (i + 1 < len)) {
temp[2] = text.charAt(i++);
temp[3] = text.charAt(i++);
decodedChar = strtol(temp, NULL, 16);
} else {
if (encodedChar == '+') {
decodedChar = ' ';
} else {
decodedChar = encodedChar; // normal ascii char
}
}
return decoded;
decoded += decodedChar;
}
return decoded;
}
void ESPWebDAV::handleClient()
{
if (!server) {
log_esp3d("handleClient: server is null");
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-------------------------------------------------------");
}
}
void ESPWebDAV::handleClient() {
if (!server) {
log_esp3d_e("handleClient: server is null");
return;
}
if (server->hasClient()) {
if (!locClient || !locClient.available()) {
// no current client
//do not put debug here or it will flood the serial
return;
// no or sleeping current client
// take it over
locClient = server->available();
m_persistent_timer_ms = millis();
log_esp3d(
"NEW CLIENT-------------------------------------------------------");
}
}
// extract uri, headers etc
parseRequest();
if (!locClient || !locClient.available()) {
// no current client
// do not put debug here or it will flood the serial
return;
}
if (!m_persistent)
// close the connection
{
log_esp3d("CLOSE CONNECTION-------------------------------------------------------");
locClient.stop();
}
// extract uri, headers etc
parseRequest();
if (!m_persistent)
// 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()
{
// Read the first line of HTTP request
String req = locClient.readStringUntil('\r');
locClient.readStringUntil('\n');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
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;
}
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
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);
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
*/
#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 "../../core/settings_esp3d.h"
#include "../../core/esp3doutput.h"
#include "../../core/commands.h"
#include "../../core/esp3doutput.h"
#include "../../core/settings_esp3d.h"
#include "../authentication/authentication_service.h"
#include "websocket_server.h"
WebSocket_Server websocket_terminal_server("webui-v3");
#if defined(WS_DATA_FEATURE)
WebSocket_Server websocket_data_server("arduino");
#endif //WS_DATA_FEATURE
void WebSocket_Server::pushMSG (const char * data)
{
if (_websocket_server) {
_websocket_server->broadcastTXT(data);
log_esp3d("[%u]Broadcast %s", _current_id,data);
}
#endif // WS_DATA_FEATURE
void WebSocket_Server::pushMSG(const char *data) {
if (_websocket_server) {
_websocket_server->broadcastTXT(data);
log_esp3d("[%u]Broadcast %s", _current_id, data);
}
}
void WebSocket_Server::enableOnly (uint num)
{
//some sanity check
if (_websocket_server) {
for (uint8_t i=0; i<WEBSOCKETS_SERVER_CLIENT_MAX; i++)
if(i!=num && _websocket_server->clientIsConnected(i)) {
_websocket_server->disconnect(i);
}
}
void WebSocket_Server::enableOnly(uint num) {
// some sanity check
if (_websocket_server) {
for (uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++)
if (i != num && _websocket_server->clientIsConnected(i)) {
_websocket_server->disconnect(i);
}
}
}
void WebSocket_Server::pushMSG (uint num, const char * data)
{
if (_websocket_server) {
_websocket_server->sendTXT(num, data);
log_esp3d("[%u]Send %s", num,data);
}
void WebSocket_Server::pushMSG(uint num, const char *data) {
if (_websocket_server) {
_websocket_server->sendTXT(num, data);
log_esp3d("[%u]Send %s", num, data);
}
}
void WebSocket_Server::closeClients()
{
if (_websocket_server) {
_websocket_server->disconnect();
}
void WebSocket_Server::closeClients() {
if (_websocket_server) {
_websocket_server->disconnect();
}
}
#if defined(WS_DATA_FEATURE)
//Events for Websocket bridge
void handle_Websocket_Server_Event(uint8_t num, uint8_t type, uint8_t * payload, size_t length)
{
(void)num;
switch(type) {
// Events for Websocket bridge
void handle_Websocket_Server_Event(uint8_t num, uint8_t type, uint8_t *payload,
size_t length) {
(void)num;
switch (type) {
case WStype_DISCONNECTED:
log_esp3d("[%u] Disconnected! port %d", num,websocket_data_server.port());
break;
log_esp3d("[%u] Disconnected! port %d", num,
websocket_data_server.port());
break;
case WStype_CONNECTED: {
log_esp3d("[%u] Connected! port %d, %s", num,websocket_data_server.port(), payload);
}
break;
log_esp3d("[%u] Connected! port %d, %s", num,
websocket_data_server.port(), payload);
} break;
case WStype_TEXT:
log_esp3d("[%u] get Text: %s port %d", num, payload,websocket_data_server.port());
websocket_data_server.push2RXbuffer(payload, length);
break;
log_esp3d("[%u] get Text: %s port %d", num, payload,
websocket_data_server.port());
websocket_data_server.push2RXbuffer(payload, length);
break;
case WStype_BIN:
log_esp3d("[%u] get binary length: %u port %d", num, length,websocket_data_server.port());
websocket_data_server.push2RXbuffer(payload, length);
break;
log_esp3d("[%u] get binary length: %u port %d", num, length,
websocket_data_server.port());
websocket_data_server.push2RXbuffer(payload, length);
break;
default:
break;
}
break;
}
}
#endif //WS_DATA_FEATURE
#if defined (HTTP_FEATURE)
//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)payload;
(void)length;
String msg;
switch(type) {
#endif // WS_DATA_FEATURE
#if defined(HTTP_FEATURE)
// 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)payload;
(void)length;
String msg;
switch (type) {
case WStype_DISCONNECTED:
log_esp3d("[%u] Socket Disconnected port %d!", num,websocket_terminal_server.port());
break;
log_esp3d("[%u] Socket Disconnected port %d!", num,
websocket_terminal_server.port());
break;
case WStype_CONNECTED: {
log_esp3d("[%u] Connected! port %d, %s", num,websocket_terminal_server.port(), (const char *)payload);
msg = "currentID:" + String(num);
// send message to client
websocket_terminal_server.set_currentID(num);
websocket_terminal_server.pushMSG(num, msg.c_str());
msg = "activeID:" + String(num);
websocket_terminal_server.pushMSG(msg.c_str());
websocket_terminal_server.enableOnly(num);
log_esp3d("[%u] Socket connected port %d", num,websocket_terminal_server.port());
}
break;
log_esp3d("[%u] Connected! port %d, %s", num,
websocket_terminal_server.port(), (const char *)payload);
msg = "currentID:" + String(num);
// send message to client
websocket_terminal_server.set_currentID(num);
websocket_terminal_server.pushMSG(num, msg.c_str());
msg = "activeID:" + String(num);
websocket_terminal_server.pushMSG(msg.c_str());
websocket_terminal_server.enableOnly(num);
log_esp3d("[%u] Socket connected port %d", num,
websocket_terminal_server.port());
} break;
case WStype_TEXT:
#if defined (AUTHENTICATION_FEATURE)
//we do not expect any input but ping to get session timeout if any
if (AuthenticationService::getSessionTimeout() != 0) {
msg = (const char*)payload;
if (msg.startsWith("PING:")) {
String session = msg.substring(5);
String response = "PING:"+String(AuthenticationService::getSessionRemaining(session.c_str()));
response += ":"+String(AuthenticationService::getSessionTimeout());
websocket_terminal_server.pushMSG(num, response.c_str());
}
#if defined(AUTHENTICATION_FEATURE)
// we do not expect any input but ping to get session timeout if any
if (AuthenticationService::getSessionTimeout() != 0) {
msg = (const char *)payload;
if (msg.startsWith("PING:")) {
String session = msg.substring(5);
String response =
"PING:" + String(AuthenticationService::getSessionRemaining(
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());
break;
}
#endif // AUTHENTICATION_FEATURE
// log_esp3d("[IGNORED][%u] get Text: %s port %d", num, payload,
// websocket_terminal_server.port());
break;
case WStype_BIN:
//we do not expect any input
//log_esp3d("[IGNORED][%u] get binary length: %u port %d", num, length, websocket_terminal_server.port());
break;
// we do not expect any input
// log_esp3d("[IGNORED][%u] get binary length: %u port %d", num, length,
// websocket_terminal_server.port());
break;
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;
}
}
#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;
void WebSocket_Server::end() {
_current_id = 0;
_TXbufferSize = 0;
if (_RXbuffer) {
free(_RXbuffer);
_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()
{
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;
}
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;
}
_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!="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();
if (_TXbufferSize == 0) {
_lastTXflush = millis();
}
return _started;
}
void WebSocket_Server::end()
{
_current_id = 0;
_TXbufferSize = 0;
if(_RXbuffer) {
free(_RXbuffer);
_RXbuffer = nullptr;
// send full line
if (_TXbufferSize + size > TXBUFFERSIZE) {
flushTXbuffer();
}
_RXbufferSize = 0;
if (_websocket_server) {
_websocket_server->close();
delete _websocket_server;
_websocket_server = nullptr;
_port = 0;
if (_websocket_server->connectedClients() == 0) {
return 0;
}
_started = false;
}
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;
// 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 0;
return size;
}
return 0;
}
void WebSocket_Server::push2RXbuffer(uint8_t * sbuf, size_t len)
{
if (!_RXbuffer || !_started) {
return;
}
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);
void WebSocket_Server::push2RXbuffer(uint8_t *sbuf, size_t len) {
if (!_RXbuffer || !_started) {
return;
}
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();
_RXbufferSize = 0;
}
void WebSocket_Server::handle()
{
Hal::wait(0);
if (_started) {
if (_TXbufferSize > 0) {
if ((_TXbufferSize>=TXBUFFERSIZE) || ((millis()- _lastTXflush) > FLUSHTIMEOUT)) {
flushTXbuffer();
}
}
if (_RXbufferSize > 0) {
if ((_RXbufferSize>=RXBUFFERSIZE) || ((millis()- _lastRXflush) > FLUSHTIMEOUT)) {
flushRXbuffer();
}
}
if (_websocket_server) {
_websocket_server->loop();
}
void WebSocket_Server::handle() {
Hal::wait(0);
if (_started) {
if (_TXbufferSize > 0) {
if ((_TXbufferSize >= TXBUFFERSIZE) ||
((millis() - _lastTXflush) > FLUSHTIMEOUT)) {
flushTXbuffer();
}
}
}
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();
}
if (_RXbufferSize > 0) {
if ((_RXbufferSize >= RXBUFFERSIZE) ||
((millis() - _lastRXflush) > FLUSHTIMEOUT)) {
flushRXbuffer();
}
}
//reset buffer
_TXbufferSize = 0;
if (_websocket_server) {
_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"
#if defined (WIFI_FEATURE)
#if defined(WIFI_FEATURE)
#ifdef ARDUINO_ARCH_ESP32
#include <esp_wifi.h>
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
#endif //ARDUINO_ARCH_ESP8266
#include "../wifi/wificonfig.h"
#include "../network/netconfig.h"
#endif // ARDUINO_ARCH_ESP8266
#include "../../core/esp3doutput.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
*/
bool WiFiConfig::isSSIDValid (const char * ssid)
{
//limited size
//char c;
if (strlen (ssid) > MAX_SSID_LENGTH || strlen (ssid) < MIN_SSID_LENGTH) {
return false;
bool WiFiConfig::isSSIDValid(const char* ssid) {
// limited size
// char c;
if (strlen(ssid) > MAX_SSID_LENGTH || strlen(ssid) < MIN_SSID_LENGTH) {
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++) {
if (!isPrintable (ssid[i]) ) {
return false;
}
}
return true;
}
return true;
}
const char * WiFiConfig::hostname()
{
static String tmp;
#if defined (ARDUINO_ARCH_ESP8266)
if (WiFi.getMode() == WIFI_AP) {
//No API for AP
tmp = NetConfig::hostname(true);
} else {
tmp = WiFi.hostname();
}
#endif //ARDUINO_ARCH_ESP8266
#if defined (ARDUINO_ARCH_ESP32)
if (WiFi.getMode() == WIFI_AP) {
//tmp = NetConfig::hostname(true);
//Set API is not working so far
tmp = WiFi.softAPgetHostname();
} else {
tmp = WiFi.getHostname();
}
#endif //ARDUINO_ARCH_ESP8266
return tmp.c_str();
const char* WiFiConfig::hostname() {
static String tmp;
#if defined(ARDUINO_ARCH_ESP8266)
if (WiFi.getMode() == WIFI_AP) {
// No API for AP
tmp = NetConfig::hostname(true);
} else {
tmp = WiFi.hostname();
}
#endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
if (WiFi.getMode() == WIFI_AP) {
// tmp = NetConfig::hostname(true);
// Set API is not working so far
tmp = WiFi.softAPgetHostname();
} else {
tmp = WiFi.getHostname();
}
#endif // ARDUINO_ARCH_ESP8266
return tmp.c_str();
}
/**
* Check if password string is valid
*/
bool WiFiConfig::isPasswordValid (const char * password)
{
if (strlen (password) == 0) {
return true; //open network
}
//limited size
if ((strlen (password) > MAX_PASSWORD_LENGTH) || (strlen (password) < MIN_PASSWORD_LENGTH)) {
return false;
}
return true;
bool WiFiConfig::isPasswordValid(const char* password) {
if (strlen(password) == 0) {
return true; // open network
}
// limited size
if ((strlen(password) > MAX_PASSWORD_LENGTH) ||
(strlen(password) < MIN_PASSWORD_LENGTH)) {
return false;
}
return true;
}
/*
* Get WiFi signal strength
*/
int32_t WiFiConfig::getSignal (int32_t RSSI, bool filter)
{
if (RSSI < MIN_RSSI && filter) {
return 0;
}
if (RSSI <= -100 && !filter) {
return 0;
}
if (RSSI >= -50) {
return 100;
}
return (2 * (RSSI + 100) );
int32_t WiFiConfig::getSignal(int32_t RSSI, bool filter) {
if (RSSI < MIN_RSSI && filter) {
return 0;
}
if (RSSI <= -100 && !filter) {
return 0;
}
if (RSSI >= -50) {
return 100;
}
return (2 * (RSSI + 100));
}
/*
* Connect client to AP
*/
bool WiFiConfig::ConnectSTA2AP()
{
String msg, msg_out;
uint8_t count = 0;
uint8_t dot = 0;
wl_status_t status = WiFi.status();
ESP3DOutput output(ESP_ALL_CLIENTS);
log_esp3d("Connecting");
bool WiFiConfig::ConnectSTA2AP() {
String msg, msg_out;
uint8_t count = 0;
uint8_t dot = 0;
wl_status_t status = WiFi.status();
ESP3DOutput output(ESP_ALL_CLIENTS);
log_esp3d("Connecting");
#if COMMUNICATION_PROTOCOL != MKS_SERIAL
if (!Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Connecting");
output.flush();
}
#endif //#if COMMUNICATION_PROTOCOL == MKS_SERIAL
while (status != WL_CONNECTED && count < 40) {
switch (status) {
case WL_NO_SSID_AVAIL:
msg="No SSID";
break;
case WL_CONNECT_FAILED:
msg="Connection failed";
break;
case WL_CONNECTED:
break;
default:
if ((dot>3) || (dot==0) ) {
dot=0;
msg_out = "Connecting";
}
msg_out+=".";
msg= msg_out;
log_esp3d("...");
dot++;
break;
if (!Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Connecting");
output.flush();
}
#endif // #if COMMUNICATION_PROTOCOL == MKS_SERIAL
while (status != WL_CONNECTED && count < 40) {
switch (status) {
case WL_NO_SSID_AVAIL:
msg = "No SSID";
break;
case WL_CONNECT_FAILED:
msg = "Connection failed";
break;
case WL_CONNECTED:
break;
default:
if ((dot > 3) || (dot == 0)) {
dot = 0;
msg_out = "Connecting";
}
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG(msg.c_str());
output.flush();
}
Hal::wait (500);
count++;
status = WiFi.status();
msg_out += ".";
msg = msg_out;
log_esp3d("...");
dot++;
break;
}
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)
*/
bool WiFiConfig::StartSTA()
{
log_esp3d("StartSTA");
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
WiFi.softAPdisconnect();
}
WiFi.enableAP (false);
WiFi.enableSTA (true);
WiFi.mode(WIFI_STA);
#if defined (ARDUINO_ARCH_ESP32)
esp_wifi_start();
WiFi.setMinSecurity(WIFI_AUTH_WEP);
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
#endif //ARDUINO_ARCH_ESP32
//Get parameters for STA
String SSID = Settings_ESP3D::read_string(ESP_STA_SSID);
String password = Settings_ESP3D::read_string(ESP_STA_PASSWORD);
bool WiFiConfig::StartSTA() {
log_esp3d("StartSTA");
if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
WiFi.softAPdisconnect();
}
WiFi.enableAP(false);
WiFi.enableSTA(true);
WiFi.mode(WIFI_STA);
#if defined(ARDUINO_ARCH_ESP32)
esp_wifi_start();
WiFi.setMinSecurity(WIFI_AUTH_WEP);
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
#endif // ARDUINO_ARCH_ESP32
// Get parameters for STA
String SSID = Settings_ESP3D::read_string(ESP_STA_SSID);
String password = Settings_ESP3D::read_string(ESP_STA_PASSWORD);
if (Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) {
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_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 DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
WiFi.config(ip, gateway,mask,dns);
}
ESP3DOutput output(ESP_ALL_CLIENTS);
if (Settings_ESP3D::isVerboseBoot()) {
String stmp;
stmp = "Connecting to '" + SSID + "'";;
output.printMSG(stmp.c_str());
}
if (WiFi.begin(SSID.c_str(), (password.length() > 0)?password.c_str():nullptr)) {
#if defined (ARDUINO_ARCH_ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.hostname(NetConfig::hostname(true));
#endif //ARDUINO_ARCH_ESP8266
#if defined (ARDUINO_ARCH_ESP32)
WiFi.setSleep(false);
WiFi.setHostname(NetConfig::hostname(true));
#endif //ARDUINO_ARCH_ESP32
return ConnectSTA2AP();
} else {
output.printERROR("Starting client failed");
return false;
}
if (Settings_ESP3D::read_byte(ESP_STA_IP_MODE) != DHCP_MODE) {
int32_t IP = Settings_ESP3D::read_IP(ESP_STA_IP_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 DNS = Settings_ESP3D::read_IP(ESP_STA_DNS_VALUE);
IPAddress ip(IP), mask(MK), gateway(GW), dns(DNS);
WiFi.config(ip, gateway, mask, dns);
}
ESP3DOutput output(ESP_ALL_CLIENTS);
if (Settings_ESP3D::isVerboseBoot()) {
String stmp;
stmp = "Connecting to '" + SSID + "'";
;
output.printMSG(stmp.c_str());
}
if (WiFi.begin(SSID.c_str(),
(password.length() > 0) ? password.c_str() : nullptr)) {
#if defined(ARDUINO_ARCH_ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.hostname(NetConfig::hostname(true));
#endif // ARDUINO_ARCH_ESP8266
#if defined(ARDUINO_ARCH_ESP32)
WiFi.setSleep(false);
WiFi.setHostname(NetConfig::hostname(true));
#endif // ARDUINO_ARCH_ESP32
return ConnectSTA2AP();
} else {
output.printERROR("Starting client failed");
return false;
}
}
/**
* Setup and start Access point
*/
bool WiFiConfig::StartAP(bool setupMode)
{
ESP3DOutput output(ESP_ALL_CLIENTS);
//Sanity check
if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if(WiFi.isConnected()) {
WiFi.disconnect();
}
bool WiFiConfig::StartAP(bool setupMode) {
ESP3DOutput output(ESP_ALL_CLIENTS);
// Sanity check
if ((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if (WiFi.isConnected()) {
WiFi.disconnect();
}
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
WiFi.softAPdisconnect();
}
WiFi.enableAP (true);
WiFi.enableSTA (false);
WiFi.mode(WIFI_AP);
//Set Sleep Mode to none
#if defined (ARDUINO_ARCH_ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
#endif //ARDUINO_ARCH_ESP8266
}
if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
WiFi.softAPdisconnect();
}
WiFi.enableAP(true);
WiFi.enableSTA(false);
WiFi.mode(WIFI_AP);
// Set Sleep Mode to none
#if defined(ARDUINO_ARCH_ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
#endif // ARDUINO_ARCH_ESP8266
String SSID = Settings_ESP3D::read_string(ESP_AP_SSID);
String password = Settings_ESP3D::read_string(ESP_AP_PASSWORD);
//channel
int8_t channel = Settings_ESP3D::read_byte (ESP_AP_CHANNEL);
//IP
int32_t IP = Settings_ESP3D::read_IP(ESP_AP_IP_VALUE);
String SSID = Settings_ESP3D::read_string(ESP_AP_SSID);
String password = Settings_ESP3D::read_string(ESP_AP_PASSWORD);
// channel
int8_t channel = Settings_ESP3D::read_byte(ESP_AP_CHANNEL);
// IP
int32_t IP = Settings_ESP3D::read_IP(ESP_AP_IP_VALUE);
IPAddress ip(IP);
IPAddress gw(0,0,0,0);
IPAddress mask(DEFAULT_AP_MASK_VALUE);
#if defined (ARDUINO_ARCH_ESP8266)
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");
IPAddress ip(IP);
IPAddress gw(0, 0, 0, 0);
IPAddress mask(DEFAULT_AP_MASK_VALUE);
#if defined(ARDUINO_ARCH_ESP8266)
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());
}
#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 {
output.printMSG(ip.toString().c_str());
stmp += " is started not protected by password";
}
#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 {
stmp +=" is started not protected by password";
}
if (setupMode) {
stmp += " (setup mode)";
}
output.printMSG(stmp.c_str());
log_esp3d("%s",stmp.c_str());
#if defined (ARDUINO_ARCH_ESP32)
//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;
if (setupMode) {
stmp += " (setup mode)";
}
output.printMSG(stmp.c_str());
log_esp3d("%s", stmp.c_str());
#if defined(ARDUINO_ARCH_ESP32)
// 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.printERROR("Starting AP failed");
log_esp3d("Starting AP failed");
return false;
output.printMSG(ip.toString().c_str());
}
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()
{
return (WiFi.getMode() != WIFI_OFF);
}
bool WiFiConfig::started() { return (WiFi.getMode() != WIFI_OFF); }
/**
* begin WiFi setup
*/
bool WiFiConfig::begin(int8_t & espMode)
{
bool res = false;
end();
log_esp3d("Starting Wifi Config");
ESP3DOutput output(ESP_ALL_CLIENTS);
if (Settings_ESP3D::isVerboseBoot()) {
output.printMSG("Starting WiFi");
bool WiFiConfig::begin(int8_t& espMode) {
bool res = false;
end();
log_esp3d("Starting Wifi Config");
ESP3DOutput output(ESP_ALL_CLIENTS);
if (Settings_ESP3D::isVerboseBoot()) {
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) {
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;
}
return res;
}
/**
* End WiFi
*/
void WiFiConfig::end()
{
//Sanity check
if((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if(WiFi.isConnected()) {
WiFi.disconnect(true);
}
void WiFiConfig::end() {
// Sanity check
if ((WiFi.getMode() == WIFI_STA) || (WiFi.getMode() == WIFI_AP_STA)) {
if (WiFi.isConnected()) {
WiFi.disconnect(true);
}
if((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
if(WiFi.isConnected()) {
WiFi.softAPdisconnect(true);
}
}
if ((WiFi.getMode() == WIFI_AP) || (WiFi.getMode() == WIFI_AP_STA)) {
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
*/
void WiFiConfig::handle()
{
//to avoid mixed mode
if (WiFi.getMode() == WIFI_AP_STA) {
if (WiFi.scanComplete() != WIFI_SCAN_RUNNING) {
WiFi.enableSTA (false);
}
void WiFiConfig::handle() {
// to avoid mixed mode
if (WiFi.getMode() == WIFI_AP_STA) {
if (WiFi.scanComplete() != WIFI_SCAN_RUNNING) {
WiFi.enableSTA(false);
}
}
}
const char* WiFiConfig::getSleepModeString ()
{
const char* WiFiConfig::getSleepModeString() {
#ifdef ARDUINO_ARCH_ESP32
if (WiFi.getSleep()) {
return "modem";
} else {
return "none";
}
#endif //ARDUINO_ARCH_ESP32
if (WiFi.getSleep()) {
return "modem";
} else {
return "none";
}
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
WiFiSleepType_t ps_type = WiFi.getSleepMode();
if (ps_type == WIFI_NONE_SLEEP) {
return "none";
} else if (ps_type == WIFI_LIGHT_SLEEP) {
return "light";
} else if (ps_type == WIFI_MODEM_SLEEP) {
return "modem";
} else {
return "unknown";
}
#endif //ARDUINO_ARCH_ESP8266
WiFiSleepType_t ps_type = WiFi.getSleepMode();
if (ps_type == WIFI_NONE_SLEEP) {
return "none";
} else if (ps_type == WIFI_LIGHT_SLEEP) {
return "light";
} else if (ps_type == WIFI_MODEM_SLEEP) {
return "modem";
} else {
return "unknown";
}
#endif // ARDUINO_ARCH_ESP8266
}
const char* WiFiConfig::getPHYModeString (uint8_t wifimode)
{
const char* WiFiConfig::getPHYModeString(uint8_t wifimode) {
#ifdef ARDUINO_ARCH_ESP32
uint8_t PhyMode;
esp_wifi_get_protocol ((wifi_interface_t)((wifimode == WIFI_STA)?ESP_IF_WIFI_STA:ESP_IF_WIFI_AP), &PhyMode);
#endif //ARDUINO_ARCH_ESP32
uint8_t PhyMode;
esp_wifi_get_protocol(
(wifi_interface_t)((wifimode == WIFI_STA) ? ESP_IF_WIFI_STA
: ESP_IF_WIFI_AP),
&PhyMode);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
(void)wifimode;
WiFiPhyMode_t PhyMode = WiFi.getPhyMode();
#endif //ARDUINO_ARCH_ESP8266
if (PhyMode == (WIFI_PHY_MODE_11G) ) {
return "11g";
} else if (PhyMode == (WIFI_PHY_MODE_11B) ) {
return "11b";
} else if (PhyMode == (WIFI_PHY_MODE_11N) ) {
return "11n";
} else {
return "unknown";
}
(void)wifimode;
WiFiPhyMode_t PhyMode = WiFi.getPhyMode();
#endif // ARDUINO_ARCH_ESP8266
if (PhyMode == (WIFI_PHY_MODE_11G)) {
return "11g";
} else if (PhyMode == (WIFI_PHY_MODE_11B)) {
return "11b";
} else if (PhyMode == (WIFI_PHY_MODE_11N)) {
return "11n";
} else {
return "unknown";
}
}
bool WiFiConfig::is_AP_visible()
{
bool WiFiConfig::is_AP_visible() {
#ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
return (conf.ap.ssid_hidden == 0);
#endif //ARDUINO_ARCH_ESP32
wifi_config_t conf;
esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
return (conf.ap.ssid_hidden == 0);
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig;
wifi_softap_get_config (&apconfig);
return (apconfig.ssid_hidden == 0);
#endif //ARDUINO_ARCH_ESP8266
struct softap_config apconfig;
wifi_softap_get_config(&apconfig);
return (apconfig.ssid_hidden == 0);
#endif // ARDUINO_ARCH_ESP8266
}
const char * WiFiConfig::AP_SSID()
{
static String ssid;
const char* WiFiConfig::AP_SSID() {
static String ssid;
#ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
ssid = (const char*) conf.ap.ssid;
#endif //ARDUINO_ARCH_ESP32
wifi_config_t conf;
esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
ssid = (const char*)conf.ap.ssid;
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig;
wifi_softap_get_config (&apconfig);
ssid = (const char*) apconfig.ssid;
#endif //ARDUINO_ARCH_ESP8266
return ssid.c_str();
struct softap_config apconfig;
wifi_softap_get_config(&apconfig);
ssid = (const char*)apconfig.ssid;
#endif // ARDUINO_ARCH_ESP8266
return ssid.c_str();
}
const char * WiFiConfig::AP_Auth_String()
{
uint8_t mode = 0;
const char* WiFiConfig::AP_Auth_String() {
uint8_t mode = 0;
#ifdef ARDUINO_ARCH_ESP32
wifi_config_t conf;
esp_wifi_get_config ((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
mode = conf.ap.authmode;
wifi_config_t conf;
esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_AP, &conf);
mode = conf.ap.authmode;
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
struct softap_config apconfig;
wifi_softap_get_config (&apconfig);
mode = apconfig.authmode;
#endif //ARDUINO_ARCH_ESP8266
if (mode == AUTH_OPEN) {
return "none";
} else if (mode == AUTH_WEP) {
return "WEP";
} else if (mode == AUTH_WPA_PSK) {
return "WPA";
} else if (mode == AUTH_WPA2_PSK) {
return "WPA2";
} else {
return "WPA/WPA2";
}
struct softap_config apconfig;
wifi_softap_get_config(&apconfig);
mode = apconfig.authmode;
#endif // ARDUINO_ARCH_ESP8266
if (mode == AUTH_OPEN) {
return "none";
} else if (mode == AUTH_WEP) {
return "WEP";
} else if (mode == AUTH_WPA_PSK) {
return "WPA";
} else if (mode == AUTH_WPA2_PSK) {
return "WPA2";
} else {
return "WPA/WPA2";
}
}
const char * WiFiConfig::AP_Gateway_String()
{
static String tmp;
const char* WiFiConfig::AP_Gateway_String() {
static String tmp;
#ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info (TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress (ip_AP.gw.addr).toString();
#endif //ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress(ip_AP.gw.addr).toString();
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
struct ip_info ip_AP;
if (!wifi_get_ip_info (SOFTAP_IF, &ip_AP)) {
log_esp3d("Error getting gateway ip");
}
tmp = IPAddress (ip_AP.gw).toString();
#endif //ARDUINO_ARCH_ESP8266
return tmp.c_str();
struct ip_info ip_AP;
if (!wifi_get_ip_info(SOFTAP_IF, &ip_AP)) {
log_esp3d_e("Error getting gateway ip");
}
tmp = IPAddress(ip_AP.gw).toString();
#endif // ARDUINO_ARCH_ESP8266
return tmp.c_str();
}
const char * WiFiConfig::AP_Mask_String()
{
static String tmp;
const char* WiFiConfig::AP_Mask_String() {
static String tmp;
#ifdef ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info (TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress (ip_AP.netmask.addr).toString();
#endif //ARDUINO_ARCH_ESP32
tcpip_adapter_ip_info_t ip_AP;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_AP);
tmp = IPAddress(ip_AP.netmask.addr).toString();
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
struct ip_info ip_AP;
if (!wifi_get_ip_info (SOFTAP_IF, &ip_AP)) {
log_esp3d("Error getting mask ip");
}
tmp = IPAddress (ip_AP.netmask).toString();
#endif //ARDUINO_ARCH_ESP8266
return tmp.c_str();
struct ip_info ip_AP;
if (!wifi_get_ip_info(SOFTAP_IF, &ip_AP)) {
log_esp3d_e("Error getting mask ip");
}
tmp = IPAddress(ip_AP.netmask).toString();
#endif // ARDUINO_ARCH_ESP8266
return tmp.c_str();
}
const char * WiFiConfig::getConnectedSTA(uint8_t * totalcount, bool reset)
{
static uint8_t count = 0;
static uint8_t current = 0;
static String data;
data = "";
const char* WiFiConfig::getConnectedSTA(uint8_t* totalcount, bool reset) {
static uint8_t count = 0;
static uint8_t current = 0;
static String data;
data = "";
#ifdef ARDUINO_ARCH_ESP32
if (current > count) {
current =0;
}
static wifi_sta_list_t station;
static tcpip_adapter_sta_list_t tcpip_sta_list;
if (reset) {
count = 0;
}
if (count == 0) {
current = 0;
esp_wifi_ap_get_sta_list (&station);
tcpip_adapter_get_sta_list (&station, &tcpip_sta_list);
count = station.num;
}
if (count > 0) {
data = IPAddress (tcpip_sta_list.sta[current].ip.addr).toString();
data += "(";
data += NetConfig::mac2str(tcpip_sta_list.sta[current].mac);
data += ")";
current++;
}
if (current > count) {
current = 0;
}
static wifi_sta_list_t station;
static tcpip_adapter_sta_list_t tcpip_sta_list;
if (reset) {
count = 0;
}
if (count == 0) {
current = 0;
esp_wifi_ap_get_sta_list(&station);
tcpip_adapter_get_sta_list(&station, &tcpip_sta_list);
count = station.num;
}
if (count > 0) {
data = IPAddress(tcpip_sta_list.sta[current].ip.addr).toString();
data += "(";
data += NetConfig::mac2str(tcpip_sta_list.sta[current].mac);
data += ")";
current++;
}
#endif //ARDUINO_ARCH_ESP32
#endif // ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP8266
static struct station_info * station;
if (current > count) {
current = 0;
count = 0;
static struct station_info* station;
if (current > count) {
current = 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) {
count = 0;
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();
}
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);
}
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 // ARDUINO_ARCH_ESP8266
if (totalcount) {
*totalcount = count;
}
return data.c_str();
}
#endif // WIFI_FEATURE
#endif // WIFI_FEATURE