From df3f839cbf8808392c38a67eb281c63732b31db1 Mon Sep 17 00:00:00 2001 From: Luc <8822552+luc-github@users.noreply.github.com> Date: Wed, 30 Dec 2020 21:38:28 +0100 Subject: [PATCH] Add message communication protocol for MKS board Note: Uplaod isnot yet implemented Add limitation for HotSpots to get at least -78 for RSSI to be listed, same as MKS do Add some API to prepare the MSK upload protocol Bump version --- esp3d/src/core/commands.cpp | 2 +- esp3d/src/core/esp3doutput.cpp | 10 +- esp3d/src/core/espcmd/ESP410.cpp | 70 ++-- esp3d/src/core/espcmd/ESP420.cpp | 20 +- esp3d/src/core/settings_esp3d.cpp | 67 ++- esp3d/src/core/settings_esp3d.h | 2 +- esp3d/src/include/version.h | 2 +- .../modules/http/handles/handle-command.cpp | 1 + esp3d/src/modules/mks/mks_service.cpp | 385 ++++++++++++++++-- esp3d/src/modules/mks/mks_service.h | 16 +- esp3d/src/modules/serial/serial_service.cpp | 108 +++++ esp3d/src/modules/serial/serial_service.h | 1 + .../modules/websocket/websocket_server.cpp | 2 +- esp3d/src/modules/wifi/wificonfig.h | 1 + 14 files changed, 586 insertions(+), 101 deletions(-) diff --git a/esp3d/src/core/commands.cpp b/esp3d/src/core/commands.cpp index 21cde1a2..85526307 100644 --- a/esp3d/src/core/commands.cpp +++ b/esp3d/src/core/commands.cpp @@ -48,7 +48,7 @@ void Commands::process(uint8_t * sbuf, size_t len, ESP3DOutput * output, level_a cmd[1] = tmpbuf[5] == ']'?0:tmpbuf[5]; cmd[2] = tmpbuf[6] == ']'?0:tmpbuf[6]; cmd[3] = 0x0; - //log_esp3d("Authentication = %d client %d", auth, output->client()); + log_esp3d("It is ESP command"); execute_internal_command (String((const char*)cmd).toInt(), (slen > (strlen((const char *)cmd)+5))?(const char*)&tmpbuf[strlen((const char *)cmd)+5]:"", auth, (outputonly == nullptr)?output:outputonly); } else { //Dispatch to all clients but current or to define output diff --git a/esp3d/src/core/esp3doutput.cpp b/esp3d/src/core/esp3doutput.cpp index 716c9c06..f6508b02 100644 --- a/esp3d/src/core/esp3doutput.cpp +++ b/esp3d/src/core/esp3doutput.cpp @@ -31,6 +31,10 @@ #if defined (TELNET_FEATURE) #include "../modules/telnet/telnet_server.h" #endif //TELNET_FEATURE +#if COMMUNICATION_PROTOCOL == MKS_SERIAL +#include "../modules/mks/mks_service.h" +#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL + uint8_t ESP3DOutput::_serialoutputflags = DEFAULT_SERIAL_OUTPUT_FLAG; uint8_t ESP3DOutput::_printerlcdoutputflags = DEFAULT_PRINTER_LCD_FLAG; uint8_t ESP3DOutput::_websocketoutputflags = DEFAULT_WEBSOCKET_FLAG; @@ -127,10 +131,14 @@ bool ESP3DOutput::isOutput(uint8_t flag, bool fromsettings) size_t ESP3DOutput::dispatch (uint8_t * sbuf, size_t len) { - log_esp3d("Dispatch %d to %d", len, _client); + //log_esp3d("Dispatch %d chars to client %d", len, _client); if (_client != ESP_SERIAL_CLIENT) { if (isOutput(ESP_SERIAL_CLIENT)) { +#if COMMUNICATION_PROTOCOL == MKS_SERIAL + MKSService::sendGcodeFrame((const char *)sbuf); +#else serial_service.write(sbuf, len); +#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL } } #if defined (HTTP_FEATURE) //no need to block it never diff --git a/esp3d/src/core/espcmd/ESP410.cpp b/esp3d/src/core/espcmd/ESP410.cpp index 7888abdc..42734132 100644 --- a/esp3d/src/core/espcmd/ESP410.cpp +++ b/esp3d/src/core/espcmd/ESP410.cpp @@ -43,6 +43,7 @@ bool Commands::ESP410(const char* cmd_params, level_authenticate_type auth_type, uint8_t currentmode = WiFi.getMode(); bool plain = hastag(cmd_params,"plain"); int n = 0; + uint8_t total = 0; if (plain) { output->printLN ("Start Scan"); output->flush(); @@ -52,46 +53,49 @@ bool Commands::ESP410(const char* cmd_params, level_authenticate_type auth_type, output->print ("{\"AP_LIST\":["); } for (int i = 0; i < n; ++i) { - if (i > 0) { - if (!plain) { - output->print (","); - } else { - output->printLN (""); + if (WiFi.RSSI (i)>= MIN_RSSI) { + if (total > 0) { + if (!plain) { + output->print (","); + } else { + output->printLN (""); + } } - } - if (!plain) { - output->print ("{\"SSID\":\""); - output->print (encodeString(WiFi.SSID (i).c_str())); - } else { - output->print (WiFi.SSID (i).c_str()); - } - if (!plain) { - output->print ("\",\"SIGNAL\":\""); - } else { - output->print ("\t"); - } - output->print (String(WiFiConfig::getSignal (WiFi.RSSI (i) ))); - if (plain) { - output->print("%"); - } - if (!plain) { - output->print ("\",\"IS_PROTECTED\":\""); - } - if (WiFi.encryptionType (i) == ENC_TYPE_NONE) { + total++; if (!plain) { - output->print ("0"); + output->print ("{\"SSID\":\""); + output->print (encodeString(WiFi.SSID (i).c_str())); } else { - output->print ("\tOpen"); + output->print (WiFi.SSID (i).c_str()); } - } else { if (!plain) { - output->print ("1"); + output->print ("\",\"SIGNAL\":\""); } else { - output->print ("\tSecure"); + output->print ("\t"); + } + output->print (String(WiFiConfig::getSignal (WiFi.RSSI (i) ))); + if (plain) { + output->print("%"); + } + if (!plain) { + output->print ("\",\"IS_PROTECTED\":\""); + } + if (WiFi.encryptionType (i) == ENC_TYPE_NONE) { + if (!plain) { + output->print ("0"); + } else { + output->print ("\tOpen"); + } + } else { + if (!plain) { + output->print ("1"); + } else { + output->print ("\tSecure"); + } + } + if (!plain) { + output->print ("\"}"); } - } - if (!plain) { - output->print ("\"}"); } } WiFi.scanDelete(); diff --git a/esp3d/src/core/espcmd/ESP420.cpp b/esp3d/src/core/espcmd/ESP420.cpp index d1f46f1e..f6776f15 100644 --- a/esp3d/src/core/espcmd/ESP420.cpp +++ b/esp3d/src/core/espcmd/ESP420.cpp @@ -1273,7 +1273,25 @@ bool Commands::ESP420(const char* cmd_params, level_authenticate_type auth_type, output->printLN(""); } #endif //ESP_DEBUG_FEATURE - +#if COMMUNICATION_PROTOCOL == MKS_SERIAL +//Target Firmware + if (!plain) { + output->print (",{\"id\":\"serial"); + } else { + output->print ("Serial"); + } + if (!plain) { + output->print ("\",\"value\":\""); + } else { + output->print (": "); + } + output->print ("MKS"); + if (!plain) { + output->print ("\"}"); + } else { + output->printLN(""); + } +#endif //COMMUNICATION_PROTOCOL //Target Firmware if (!plain) { output->print (",{\"id\":\"targetfw"); diff --git a/esp3d/src/core/settings_esp3d.cpp b/esp3d/src/core/settings_esp3d.cpp index 6e0a9480..c9c6fc51 100644 --- a/esp3d/src/core/settings_esp3d.cpp +++ b/esp3d/src/core/settings_esp3d.cpp @@ -1013,8 +1013,40 @@ bool Settings_ESP3D::write_IP(int pos, const uint32_t value) } //clear all entries -bool Settings_ESP3D::reset() +bool Settings_ESP3D::reset(bool networkonly) { + if (networkonly) { + //radio mode + Settings_ESP3D::write_byte(ESP_RADIO_MODE,Settings_ESP3D::get_default_byte_value(ESP_RADIO_MODE)); +#if defined (WIFI_FEATURE) + //STA SSID + Settings_ESP3D::write_string(ESP_STA_SSID,Settings_ESP3D::get_default_string_value(ESP_STA_SSID).c_str()); + //STA pwd + Settings_ESP3D::write_string(ESP_STA_PASSWORD,Settings_ESP3D::get_default_string_value(ESP_STA_PASSWORD).c_str()); + //AP SSID + Settings_ESP3D::write_string(ESP_AP_SSID,Settings_ESP3D::get_default_string_value(ESP_AP_SSID).c_str()); + //AP password + Settings_ESP3D::write_string(ESP_AP_PASSWORD,Settings_ESP3D::get_default_string_value(ESP_AP_PASSWORD).c_str()); + //AP static IP + Settings_ESP3D::write_IP(ESP_AP_IP_VALUE, Settings_ESP3D::get_default_IP_value(ESP_AP_IP_VALUE)); + //AP Channel + Settings_ESP3D::write_byte(ESP_AP_CHANNEL,Settings_ESP3D::get_default_byte_value(ESP_AP_CHANNEL)); + +#endif //WIFI_FEATURE + +#if defined (WIFI_FEATURE) || defined (ETH_FEATURE) + //STA IP mode + Settings_ESP3D::write_byte(ESP_STA_IP_MODE,Settings_ESP3D::get_default_byte_value(ESP_STA_IP_MODE)); + //STA static IP + Settings_ESP3D::write_IP(ESP_STA_IP_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_IP_VALUE)); + //STA static Gateway + Settings_ESP3D::write_IP(ESP_STA_GATEWAY_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_GATEWAY_VALUE)); + //STA static Mask + Settings_ESP3D::write_IP(ESP_STA_MASK_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_MASK_VALUE)); +#endif //WIFI_FEATURE || ETH_FEATURE + return true; + } + bool res = true; log_esp3d("Reset Settings"); #if ESP_SAVE_SETTINGS == SETTINGS_IN_PREFERENCES @@ -1068,39 +1100,6 @@ bool Settings_ESP3D::reset() #endif //NOTIFICATION_FEATURE //radio mode Settings_ESP3D::write_byte(ESP_RADIO_MODE,Settings_ESP3D::get_default_byte_value(ESP_RADIO_MODE)); -#if defined (WIFI_FEATURE) - //STA SSID - Settings_ESP3D::write_string(ESP_STA_SSID,Settings_ESP3D::get_default_string_value(ESP_STA_SSID).c_str()); - //STA pwd - Settings_ESP3D::write_string(ESP_STA_PASSWORD,Settings_ESP3D::get_default_string_value(ESP_STA_PASSWORD).c_str()); - //AP SSID - Settings_ESP3D::write_string(ESP_AP_SSID,Settings_ESP3D::get_default_string_value(ESP_AP_SSID).c_str()); - //AP password - Settings_ESP3D::write_string(ESP_AP_PASSWORD,Settings_ESP3D::get_default_string_value(ESP_AP_PASSWORD).c_str()); - //AP static IP - Settings_ESP3D::write_IP(ESP_AP_IP_VALUE, Settings_ESP3D::get_default_IP_value(ESP_AP_IP_VALUE)); - //AP Channel - Settings_ESP3D::write_byte(ESP_AP_CHANNEL,Settings_ESP3D::get_default_byte_value(ESP_AP_CHANNEL)); - //AP Network Mode (PHY) - //Settings_ESP3D::write_byte(ESP_AP_PHY_MODE,Settings_ESP3D::get_default_byte_value(ESP_AP_PHY_MODE)); - //AP Authentication - //Settings_ESP3D::write_byte(ESP_AP_AUTH_TYPE,Settings_ESP3D::get_default_byte_value(ESP_AP_AUTH_TYPE)); - //AP SSID visibility - //Settings_ESP3D::write_byte(ESP_SSID_VISIBLE,Settings_ESP3D::get_default_byte_value(ESP_SSID_VISIBLE)); -#endif //WIFI_FEATURE - -#if defined (WIFI_FEATURE) || defined (ETH_FEATURE) - //STA Network Mode - //Settings_ESP3D::write_byte(ESP_STA_PHY_MODE,Settings_ESP3D::get_default_byte_value(ESP_STA_PHY_MODE)); - //STA IP mode - Settings_ESP3D::write_byte(ESP_STA_IP_MODE,Settings_ESP3D::get_default_byte_value(ESP_STA_IP_MODE)); - //STA static IP - Settings_ESP3D::write_IP(ESP_STA_IP_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_IP_VALUE)); - //STA static Gateway - Settings_ESP3D::write_IP(ESP_STA_GATEWAY_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_GATEWAY_VALUE)); - //STA static Mask - Settings_ESP3D::write_IP(ESP_STA_MASK_VALUE, Settings_ESP3D::get_default_IP_value(ESP_STA_MASK_VALUE)); -#endif //WIFI_FEATURE || ETH_FEATURE #ifdef FTP_FEATURE //FTP On diff --git a/esp3d/src/core/settings_esp3d.h b/esp3d/src/core/settings_esp3d.h index b748c7ed..ac8432a7 100644 --- a/esp3d/src/core/settings_esp3d.h +++ b/esp3d/src/core/settings_esp3d.h @@ -134,7 +134,7 @@ public: static bool write_uint32 (int pos, const uint32_t value); static bool write_IP (int pos, const uint32_t value); static bool write_IP_String (int pos, const char * value); - static bool reset(); + static bool reset(bool networkonly = false); static int8_t GetSettingsVersion(); static uint8_t GetFirmwareTarget(bool fromsettings = false); static bool isVerboseBoot(bool fromsettings = false); diff --git a/esp3d/src/include/version.h b/esp3d/src/include/version.h index 96e31e71..ed68671d 100644 --- a/esp3d/src/include/version.h +++ b/esp3d/src/include/version.h @@ -22,7 +22,7 @@ #define _VERSION_ESP3D_H //version and sources location -#define FW_VERSION "3.0.0.a77" +#define FW_VERSION "3.0.0.a78" #define REPOSITORY "https://github.com/luc-github/ESP3D/tree/3.0" #endif //_VERSION_ESP3D_H diff --git a/esp3d/src/modules/http/handles/handle-command.cpp b/esp3d/src/modules/http/handles/handle-command.cpp index ee99a2d0..92efb036 100644 --- a/esp3d/src/modules/http/handles/handle-command.cpp +++ b/esp3d/src/modules/http/handles/handle-command.cpp @@ -46,6 +46,7 @@ void HTTP_Server::handle_web_command () if(!cmd.endsWith("\n")) { cmd+="\n"; //need to validate command } + log_esp3d("Web Command: %s",cmd.c_str()); esp3d_commands.process((uint8_t*)cmd.c_str(), cmd.length(), &output, auth_level); } else if (_webserver->hasArg ("ping")) { _webserver->send (200); diff --git a/esp3d/src/modules/mks/mks_service.cpp b/esp3d/src/modules/mks/mks_service.cpp index 05f22c5f..2e979424 100644 --- a/esp3d/src/modules/mks/mks_service.cpp +++ b/esp3d/src/modules/mks/mks_service.cpp @@ -25,6 +25,9 @@ #include "../../core/esp3doutput.h" #include "../network/netconfig.h" #include "../wifi/wificonfig.h" +#include "../telnet/telnet_server.h" +#include "../http/http_server.h" +#include "../network/netconfig.h" #define MKS_FRAME_DATA_MAX_SIZE (MKS_FRAME_SIZE - 5 - 4) @@ -69,9 +72,28 @@ #define MKS_FRAME_DATA_HOTSPOTS_LIST_TYPE (char)0x4 #define MKS_FRAME_DATA_STATIC_IP_TYPE (char)0x5 -#define CLOUD_HOST_ADDRESS "baizhongyun.cn" -#define CLOUD_HOST_PORT 12345 -#define CLOUD_SERVICE_PORT 8080 +#define MKS_TYPE_NET (char)0x0 +#define MKS_TYPE_PRINTER (char)0x1 +#define MKS_TYPE_TRANSFER (char)0x2 +#define MKS_TYPE_EXCEPTION (char)0x3 +#define MKS_TYPE_CLOUD (char)0x4 +#define MKS_TYPE_UNBIND (char)0x5 +#define MKS_TYPE_WID (char)0x6 +#define MKS_TYPE_SCAN_WIFI (char)0x7 +#define MKS_TYPE_MANUAL_IP (char)0x8 +#define MKS_TYPE_WIFI_CTRL (char)0x9 + +#define CONNECT_STA 0x1 +#define DISCONNECT_STA 0x2 +#define REMOVE_STA_INFO 0x3 + +#define UNKNOW_STATE 0x0 +#define ERROR_STATE 0x1 +#define SUCCESS_STATE 0x2 + + + +#define NB_HOTSPOT_MAX 15 //Timeouts #define FRAME_WAIT_TO_SEND_TIMEOUT 2000 @@ -79,26 +101,294 @@ bool MKSService::_started = false; char MKSService::_frame[MKS_FRAME_SIZE] = {0}; -char MKSService:: _moduleId[21] = {0}; +char MKSService::_moduleId[22] = {0}; +uint8_t MKSService::_uploadStatus = UNKNOW_STATE; +bool MKSService::isHead(const char c) +{ + return (c==MKS_FRAME_HEAD_FLAG); +} +bool MKSService::isTail(const char c) +{ + return (c==MKS_FRAME_TAIL_FLAG); +} +bool MKSService::isCommand(const char c) +{ + return (c==MKS_TYPE_TRANSFER); +} +bool MKSService::isFrame(const char c) +{ + if ((c>=MKS_TYPE_NET)&& (c<=MKS_TYPE_WIFI_CTRL)) { + return true; + } + return false; +} bool MKSService::begin() { //setup the pins pinMode(BOARD_FLAG_PIN, INPUT); pinMode(ESP_FLAG_PIN, OUTPUT); _started = true; - strcpy(_moduleId,"12345"); + //max size is 21 + strncpy(_moduleId,NetConfig::hostname(), 21); return true; } +void MKSService::sendWifiHotspots() +{ + + uint8_t ssid_name_length; + uint dataOffset = 1; + uint8_t total_hotspots = 0; + uint8_t currentmode = WiFi.getMode(); + clearFrame(); + //clean memory + WiFi.scanDelete(); + int n = WiFi.scanNetworks(); + log_esp3d("scan done"); + if (n == 0) { + log_esp3d("no networks found"); + } else { + log_esp3d("%d networks found", n); + clearFrame(); + _frame[MKS_FRAME_HEAD_OFFSET] = MKS_FRAME_HEAD_FLAG; + _frame[MKS_FRAME_TYPE_OFFSET] = MKS_FRAME_DATA_HOTSPOTS_LIST_TYPE; + for (uint8_t i = 0; i < n; ++i) { + int8_t signal_rssi = 0; + if(total_hotspots > NB_HOTSPOT_MAX) { + break; + } + signal_rssi = WiFi.RSSI(i); + // Print SSID and RSSI for each network found + log_esp3d("%d: %s (%d) %s",i + 1,WiFi.SSID(i).c_str(), signal_rssi,(WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*" ); + ssid_name_length = WiFi.SSID(i).length(); + if(ssid_name_length > MAX_SSID_LENGTH) { + log_esp3d("Name too long, ignored" ); + continue; + } + if(signal_rssi < MIN_RSSI) { + log_esp3d("Signal too low, ignored" ); + continue; + } + _frame[MKS_FRAME_DATA_OFFSET + dataOffset] = ssid_name_length; + for (uint8_t p = 0; p < ssid_name_length; p++) { + _frame[MKS_FRAME_DATA_OFFSET + dataOffset+1+p] = WiFi.SSID(i)[p]; + } + _frame[MKS_FRAME_DATA_OFFSET + dataOffset + ssid_name_length + 1] = WiFi.RSSI(i); + dataOffset+=ssid_name_length+2; + total_hotspots++; + } + _frame[MKS_FRAME_DATA_OFFSET] = total_hotspots; + _frame[MKS_FRAME_DATA_OFFSET + dataOffset] = MKS_FRAME_TAIL_FLAG; + _frame[MKS_FRAME_DATALEN_OFFSET] = dataOffset & 0xff; + _frame[MKS_FRAME_DATALEN_OFFSET + 1] = dataOffset >> 8; + log_esp3d("Size of data in frame %d ", dataOffset); + for (uint i =0; i< dataOffset + 5 ; i++) { + log_esp3d("%c %x",_frame[i],_frame[i]); + } + if (canSendFrame()) { + ESP3DOutput output(ESP_SERIAL_CLIENT); + if (output.write((const uint8_t *)_frame,dataOffset+5) == (dataOffset+5)) { + log_esp3d("Ok"); + sendFrameDone(); + } else { + log_esp3d("Send scan failed"); + } + } else { + log_esp3d("Cannot send scan"); + } + //clean memory + WiFi.scanDelete(); + } + //Restore mode + WiFi.mode((WiFiMode_t)currentmode); +} + +void MKSService::handleFrame(const uint8_t type, const uint8_t * dataFrame, const size_t dataSize ) +{ + log_esp3d("Command is %d", type); + switch(type) { + //wifi setup + case MKS_TYPE_NET: + log_esp3d("************MKS_TYPE_NET*************"); + messageWiFiConfig(dataFrame, dataSize); + break; + //not supported in Marlin + //Confirmed as private source + case MKS_TYPE_PRINTER : + //ignored + log_esp3d("************MKS_TYPE_PRINTER*************"); + break; + //File transfer if not command + case MKS_TYPE_TRANSFER : + //todo + log_esp3d("************MKS_TYPE_TRANSFER*************"); + break; + //Error when doing transfer + case MKS_TYPE_EXCEPTION : + log_esp3d("************MKS_TYPE_EXCEPTION*************"); + messageException(dataFrame, dataSize); + break; + //not supported (cloud) + case MKS_TYPE_CLOUD : + //ignored + log_esp3d("************MKS_TYPE_CLOUD*************"); + break; + //not supported (cloud) + case MKS_TYPE_WID : + //ignored + log_esp3d("************MKS_TYPE_WID*************"); + break; + //hot spot list + case MKS_TYPE_SCAN_WIFI : + log_esp3d("************MKS_TYPE_SCAN_WIFI*************"); + sendWifiHotspots(); + break; + //setup Manual IP + //not supported in Marlin, so do same for the moment + case MKS_TYPE_MANUAL_IP : + //ignored + log_esp3d("************MKS_TYPE_MANUAL_IP*************"); + break; + //On/Off Wifi + case MKS_TYPE_WIFI_CTRL : + log_esp3d("************MKS_TYPE_WIFI_CTRL*************"); + messageWiFiControl(dataFrame,dataSize); + break; + default: + log_esp3d("Unknow type"); + } +} + +void MKSService::messageWiFiControl(const uint8_t * dataFrame, const size_t dataSize ) +{ + if(dataSize != 1) { + return; + } + switch (dataFrame[0]) { + case CONNECT_STA: + log_esp3d("CONNECT_STA"); + if (!NetConfig::started()) { + NetConfig::begin(); + } + break; + case DISCONNECT_STA: + log_esp3d("CONNECT_STA"); + if (NetConfig::started()) { + NetConfig::end(); + } + break; + case REMOVE_STA_INFO: + log_esp3d("REMOVE_STA_INFO"); + if (NetConfig::started()) { + NetConfig::end(); + } + Settings_ESP3D::reset(true); + break; + default: + log_esp3d("WiFi control flag not supported"); + } +} + +void MKSService::messageException(const uint8_t * dataFrame, const size_t dataSize ) +{ + if(dataSize != 1) { + return; + } + if ((dataFrame[0] == ERROR_STATE) || (dataFrame[0] == SUCCESS_STATE)) { + _uploadStatus = dataFrame[0]; + log_esp3d("Tranfer: %s",dataFrame[0] == ERROR_STATE?"Error":"Success" ); + } else { + _uploadStatus = UNKNOW_STATE; + log_esp3d("Tranfer state unknown" ); + } +} + +void MKSService::messageWiFiConfig(const uint8_t * dataFrame, const size_t dataSize ) +{ + String ssid; + String password; + String savedSsid; + String savedPassword; + bool needrestart = false; + //Sanity check + if(dataSize <2) { + log_esp3d("Invalid data"); + return; + } + if((dataFrame[0] != MKS_FRAME_NETWORK_AP_MODE) && (dataFrame[0] != MKS_FRAME_NETWORK_STA_MODE)) { + log_esp3d("Invalid mode"); + return; + } + if ((dataFrame[1] > dataSize - 3) || (dataFrame[1]==0) || (dataFrame[1]>MAX_SSID_LENGTH)) { + log_esp3d("Invalid ssid size"); + return; + } + if ((uint)(dataFrame[1]+3)> dataSize) { + log_esp3d("Overflow password size"); + return; + } + if ((dataFrame[dataFrame[1]+2])> MAX_PASSWORD_LENGTH) { + log_esp3d("Invalid password size"); + return; + } + //get SSID and password + for(uint8_t i = 0; i < dataFrame[1]; i++) { + ssid+=(char)dataFrame[2+i]; + } + for(uint8_t j = 0; j < dataFrame[2+dataFrame[1]]; j++) { + password+=(char)dataFrame[3+j+dataFrame[1]]; + } + if (dataFrame[0] == MKS_FRAME_NETWORK_AP_MODE) { + if (Settings_ESP3D::read_byte(ESP_RADIO_MODE)!=ESP_WIFI_AP) { + Settings_ESP3D::write_byte(ESP_RADIO_MODE,ESP_WIFI_AP); + needrestart=true; + } + savedSsid=Settings_ESP3D::read_string(ESP_AP_SSID); + savedPassword=Settings_ESP3D::read_string(ESP_AP_PASSWORD); + if (savedSsid!=ssid) { + Settings_ESP3D::write_string(ESP_AP_SSID,ssid.c_str()); + needrestart =true; + } + if (savedPassword!=password) { + Settings_ESP3D::write_string(ESP_AP_PASSWORD,password.c_str()); + needrestart =true; + } + } else { + if (Settings_ESP3D::read_byte(ESP_RADIO_MODE)!=ESP_WIFI_STA) { + Settings_ESP3D::write_byte(ESP_RADIO_MODE,ESP_WIFI_STA); + needrestart =true; + } + savedSsid=Settings_ESP3D::read_string(ESP_STA_SSID); + savedPassword=Settings_ESP3D::read_string(ESP_STA_PASSWORD); + if (savedSsid!=ssid) { + Settings_ESP3D::write_string(ESP_STA_SSID,ssid.c_str()); + needrestart =true; + } + if (savedPassword!=password) { + Settings_ESP3D::write_string(ESP_STA_PASSWORD,password.c_str()); + needrestart =true; + } + if (needrestart) { + //change also to DHCP for new value + Settings_ESP3D::write_byte(ESP_STA_IP_MODE,DHCP_MODE); + } + + } + if (needrestart) { + log_esp3d("Modifications done - restarting network"); + NetConfig::begin(); + } +} + bool MKSService::canSendFrame() { - log_esp3d("Is board ready for frame?"); + //log_esp3d("Is board ready for frame?"); digitalWrite(ESP_FLAG_PIN, HIGH); uint32_t startTime = millis(); while( (millis() - startTime) < FRAME_WAIT_TO_SEND_TIMEOUT) { if (digitalRead(BOARD_FLAG_PIN) == BOARD_READY_FLAG_VALUE) { - log_esp3d("Yes"); + // log_esp3d("Yes"); return true; } } @@ -106,10 +396,53 @@ bool MKSService::canSendFrame() return false; } +void MKSService::sendFrameDone() +{ + digitalWrite(ESP_FLAG_PIN, LOW); + +} + +bool MKSService::sendGcodeFrame(const char* cmd) +{ + String tmp = cmd; + if (tmp.endsWith("\n")) { + tmp[tmp.length()-1]='\0'; + } + log_esp3d("Packing: *%s*, size=%d", tmp.c_str(), strlen(tmp.c_str())); + clearFrame(); + _frame[MKS_FRAME_HEAD_OFFSET] = MKS_FRAME_HEAD_FLAG; + _frame[MKS_FRAME_TYPE_OFFSET] = MKS_FRAME_DATA_COMMAND_TYPE; + for(uint i = 0 ; i < strlen(tmp.c_str()); i++) { + _frame[MKS_FRAME_DATA_OFFSET + i]=tmp[i]; + } + _frame[MKS_FRAME_DATA_OFFSET + strlen(tmp.c_str())] = '\r'; + _frame[MKS_FRAME_DATA_OFFSET + strlen(tmp.c_str())+1] = '\n'; + _frame[MKS_FRAME_DATA_OFFSET + strlen(tmp.c_str())+2] = MKS_FRAME_TAIL_FLAG; + _frame[MKS_FRAME_DATALEN_OFFSET] = (strlen(tmp.c_str())+2) & 0xff; + _frame[MKS_FRAME_DATALEN_OFFSET+1] = ((strlen(tmp.c_str())+2) >> 8) & 0xff; + + log_esp3d("Size of data in frame %d ", strlen(tmp.c_str())+2); + //for (uint i =0; i< strlen(tmp.c_str())+7;i++){ + //log_esp3d("%c %x",_frame[i],_frame[i]); + //} + + if (canSendFrame()) { + ESP3DOutput output(ESP_SERIAL_CLIENT); + if (output.write((const uint8_t *)_frame,strlen(tmp.c_str())+7) == (strlen(tmp.c_str())+7)) { + log_esp3d("Ok"); + sendFrameDone(); + return true; + } + } + log_esp3d("Failed"); + sendFrameDone(); + return false; +} + bool MKSService::sendNetworkFrame() { - size_t dataOffset = 0;; + size_t dataOffset = 0; String s; static uint32_t lastsend = 0; if ((millis() - lastsend)> NET_FRAME_REFRESH_TIME) { @@ -208,9 +541,9 @@ bool MKSService::sendNetworkFrame() ////////////////////////////////// //Cloud Services port Segment //hard coded - _frame[MKS_FRAME_DATA_OFFSET +4] = CLOUD_SERVICE_PORT & 0xff; - _frame[MKS_FRAME_DATA_OFFSET +5] = (CLOUD_SERVICE_PORT>> 8 ) & 0xff; - log_esp3d("Cloud port: %d", CLOUD_SERVICE_PORT); + _frame[MKS_FRAME_DATA_OFFSET +4] = (telnet_server.port()) & 0xff; + _frame[MKS_FRAME_DATA_OFFSET +5] = ((telnet_server.port()) >> 8 ) & 0xff; + log_esp3d("Cloud port: %d", (telnet_server.port())); ////////////////////////////////// //Cloud State Segment @@ -219,41 +552,39 @@ bool MKSService::sendNetworkFrame() dataOffset++; ////////////////////////////////// //Cloud host len Segment - //hard coded - _frame[dataOffset] = strlen(CLOUD_HOST_ADDRESS); + //Use ESP3D IP instead + s = NetConfig::localIPAddress().toString(); + _frame[dataOffset] = s.length(); dataOffset++; ////////////////////////////////// //Cloud host Segment - //hard coded - strcpy(&_frame[dataOffset], CLOUD_HOST_ADDRESS); - dataOffset+=strlen(CLOUD_HOST_ADDRESS); + //Use ESP3D IP instead + strcpy(&_frame[dataOffset], s.c_str()); + dataOffset+=s.length(); ////////////////////////////////// //Cloud host port Segment - //hard coded - _frame[dataOffset] = CLOUD_HOST_PORT & 0xff; + //use webserver port instead + _frame[dataOffset] = (HTTP_Server::port()) & 0xff; dataOffset++; - _frame[dataOffset] = (CLOUD_HOST_PORT>> 8 ) & 0xff; + _frame[dataOffset] = ((HTTP_Server::port())>> 8 ) & 0xff; dataOffset++; ////////////////////////////////// //Module id len Segment - //??? + //Use hostname instead _frame[dataOffset] = strlen(_moduleId); dataOffset++; ////////////////////////////////// //Module id Segment - //??? strcpy(&_frame[dataOffset], _moduleId); dataOffset+=strlen(_moduleId); ////////////////////////////////// //FW version len Segment - //??? _frame[dataOffset] = strlen(FW_VERSION); dataOffset++; ////////////////////////////////// //FW version Segment - //??? - strcpy(&_frame[dataOffset], FW_VERSION); - dataOffset+=strlen(FW_VERSION); + strcpy(&_frame[dataOffset], "ESP3D_" FW_VERSION); + dataOffset+=strlen(FW_VERSION)+6; ////////////////////////////////// //Tail Segment _frame[dataOffset] = MKS_FRAME_TAIL_FLAG; @@ -268,14 +599,17 @@ bool MKSService::sendNetworkFrame() ESP3DOutput output(ESP_SERIAL_CLIENT); if (output.write((const uint8_t *)_frame,dataOffset+1) == (dataOffset+1)) { log_esp3d("Ok"); + sendFrameDone(); return true; } } + sendFrameDone(); log_esp3d("Failed"); } return false; } + void MKSService::clearFrame() { memset(_frame, 0, sizeof(_frame)); @@ -294,5 +628,4 @@ void MKSService::end() - #endif //COMMUNICATION_PROTOCOL == MKS_SERIAL diff --git a/esp3d/src/modules/mks/mks_service.h b/esp3d/src/modules/mks/mks_service.h index ba293ad3..d65e5c5f 100644 --- a/esp3d/src/modules/mks/mks_service.h +++ b/esp3d/src/modules/mks/mks_service.h @@ -27,19 +27,31 @@ class MKSService { public: static bool begin(); - static bool sendNetworkFrame(); + static bool sendNetworkFrame(); + static bool sendGcodeFrame(const char* cmd); static void handle(); + static void handleFrame(const uint8_t type, const uint8_t * dataFrame, const size_t dataSize ); static void end(); static bool started() { return _started; } + static bool isHead(const char c); + static bool isTail(const char c); + static bool isFrame(const char c); + static bool isCommand(const char c); private: + static uint8_t _uploadStatus; + static void sendWifiHotspots(); + static void messageWiFiControl(const uint8_t * dataFrame, const size_t dataSize); + static void messageException(const uint8_t * dataFrame, const size_t dataSize); + static void messageWiFiConfig(const uint8_t * dataFrame, const size_t dataSize); static void clearFrame(); static bool canSendFrame(); + static void sendFrameDone(); static bool _started; static char _frame[MKS_FRAME_SIZE]; - static char _moduleId[21]; + static char _moduleId[22]; }; diff --git a/esp3d/src/modules/serial/serial_service.cpp b/esp3d/src/modules/serial/serial_service.cpp index f58432dc..630c1312 100644 --- a/esp3d/src/modules/serial/serial_service.cpp +++ b/esp3d/src/modules/serial/serial_service.cpp @@ -23,6 +23,9 @@ #include "../../core/settings_esp3d.h" #include "../../core/esp3doutput.h" #include "../../core/commands.h" +#if COMMUNICATION_PROTOCOL == MKS_SERIAL +#include "../mks/mks_service.h" +#endif //COMMUNICATION_PROTOCOL == MKS_SERIAL //Serial Parameters #define ESP_SERIAL_PARAM SERIAL_8N1 @@ -160,6 +163,7 @@ void SerialService::process() 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); @@ -201,6 +205,101 @@ void SerialService::flushbuffer() //push collected data to buffer and proceed accordingly void SerialService::push2buffer(uint8_t * sbuf, size_t len) { + 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; + } + + } + } 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; + } + } + } +#else for (size_t i = 0; i < len; i++) { _lastflush = millis(); //command is defined @@ -230,6 +329,7 @@ void SerialService::push2buffer(uint8_t * sbuf, size_t len) flushbuffer(); } } +#endif } //Reset Serial Setting (baud rate) @@ -239,6 +339,14 @@ bool SerialService::reset() return Settings_ESP3D::write_uint32 (ESP_BAUD_RATE, Settings_ESP3D::get_default_int32_value(ESP_BAUD_RATE)); } +void SerialService::updateBaudRate(long br) +{ + if (br!=baudRate()) { + ESP3D_SERIAL.flush(); + ESP3D_SERIAL.updateBaudRate(br); + } +} + //Get current baud rate long SerialService::baudRate() { diff --git a/esp3d/src/modules/serial/serial_service.h b/esp3d/src/modules/serial/serial_service.h index 6f91ca3c..cd4460e0 100644 --- a/esp3d/src/modules/serial/serial_service.h +++ b/esp3d/src/modules/serial/serial_service.h @@ -32,6 +32,7 @@ public: ~SerialService(); bool begin(); bool end(); + void updateBaudRate(long br); void handle(); void process(); bool reset(); diff --git a/esp3d/src/modules/websocket/websocket_server.cpp b/esp3d/src/modules/websocket/websocket_server.cpp index ba2e3459..5dc645e8 100644 --- a/esp3d/src/modules/websocket/websocket_server.cpp +++ b/esp3d/src/modules/websocket/websocket_server.cpp @@ -118,7 +118,7 @@ void handle_Websocket_Terminal_Event(uint8_t num, uint8_t type, uint8_t * payloa } } #endif //AUTHENTICATION_FEATURE - log_esp3d("[IGNORED][%u] get Text: %s port %d", num, payload, websocket_terminal_server.port()); + //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 diff --git a/esp3d/src/modules/wifi/wificonfig.h b/esp3d/src/modules/wifi/wificonfig.h index ea333f6a..cef0a815 100644 --- a/esp3d/src/modules/wifi/wificonfig.h +++ b/esp3d/src/modules/wifi/wificonfig.h @@ -19,6 +19,7 @@ */ //boundaries +#define MIN_RSSI -78 #define MAX_SSID_LENGTH 32 #define MIN_SSID_LENGTH 1 #define MIN_CHANNEL 1