/* commands.cpp - ESP3D commands class Copyright (c) 2014 Luc Lebosse. All rights reserved. This library 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 library 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 library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "../include/esp3d_config.h" #include "esp3d.h" #include "commands.h" #include "esp3doutput.h" #include "settings_esp3d.h" Commands esp3d_commands; Commands::Commands() { } Commands::~Commands() { } //dispatch the command void Commands::process(uint8_t * sbuf, size_t len, ESP3DOutput * output, level_authenticate_type auth, ESP3DOutput * outputonly ) { if(is_esp_command(sbuf,len)) { size_t slen = len; String tmpbuf = (const char*)sbuf; if (tmpbuf.startsWith("echo: ")) { tmpbuf.replace("echo: ", ""); slen = tmpbuf.length(); } uint8_t cmd[4]; cmd[0] = tmpbuf[4]; cmd[1] = tmpbuf[5]; cmd[2] = tmpbuf[6]; cmd[3] = 0x0; //log_esp3d("Authentication = %d client %d", auth, output->client()); execute_internal_command (String((const char*)cmd).toInt(), (slen > 8)?(const char*)&tmpbuf[8]:"", auth, (outputonly == nullptr)?output:outputonly); } else { //Dispatch to all clients but current or to define output if ((output->client() == ESP_HTTP_CLIENT) && (outputonly == nullptr)) { if (auth != LEVEL_GUEST) { output->printMSG(""); } else { output->printERROR("Wrong authentication!", 401); return; } } if (outputonly == nullptr) { output->dispatch(sbuf, len); } else { outputonly->write(sbuf, len); } } } //check if current line is an [ESPXXX] command bool Commands::is_esp_command(uint8_t * sbuf, size_t len) { //TODO //M117 should be handled here and transfered to [ESP214] if it is an host if (len < 8) { return false; } if ((char(sbuf[0]) == '[') && (char(sbuf[1]) == 'E') && (char(sbuf[2]) == 'S') && (char(sbuf[3]) == 'P') && (char(sbuf[7]) == ']')) { return true; } if((char(sbuf[0]) == 'e') && (char(sbuf[1]) == 'c') && (char(sbuf[2]) == 'h') && (char(sbuf[3]) == 'o') && (char(sbuf[4]) == ':') && (char(sbuf[5]) == ' ') && (char(sbuf[6]) == '[') && (char(sbuf[7]) == 'E')) { if (len >= 14) { if ((char(sbuf[8]) == 'S') && (char(sbuf[9]) == 'P') && (char(sbuf[13]) == ']')) { return true; } } } return false; } //find space in string //if space is has \ before it is ignored int Commands::get_space_pos(const char * string, uint from) { uint len = strlen(string); if (len < from) { return -1; } for (uint i = from; i < len; i++) { if (string[i] == ' ') { //if it is first char if (i == from) { return from; } //if not first one and previous char is not '\' if (string[i-1] != '\\') { return (i); } } } return -1; } //return first label but pwd using labelseparator (usualy =) like mylabel=myvalue will return mylabel const char* Commands::get_label (const char * cmd_params, const char * labelseparator, uint8_t startindex) { static String res; String tmp = ""; res = ""; int start = 1; int end = -1; res = cmd_params; res.replace("\r ", ""); res.replace("\n ", ""); res.trim(); if ((res.length() == 0) || (startindex >=res.length())) { return res.c_str(); } if (strlen(labelseparator) > 0) { end = res.indexOf(labelseparator, startindex); if (end == -1) { return ""; } start = end; for (int8_t p = end; p >= startindex ; p--, start--) { if (res[p]==' ') { p = -1; start+=2; } } if(start==-1) { start=0; } if (start > end) { return ""; } tmp = res.substring(start,end); if (tmp == "pwd") { res = get_label (cmd_params, labelseparator,end+1); } else { res = tmp; } } return res.c_str(); } //extract parameter with corresponding label //if label is empty give whole line without authentication label/parameter const char * Commands::get_param (const char * cmd_params, const char * label) { static String res; res = ""; int start = 1; int end = -1; String tmp = ""; String slabel = " "; res = cmd_params; res.replace("\r ", ""); res.replace("\n ", ""); res.trim(); if (res.length() == 0) { return res.c_str(); } tmp = " " + res; slabel += label; if (strlen(label) > 0) { start = tmp.indexOf(slabel); if (start == -1) { return ""; } start+=slabel.length(); end = get_space_pos(tmp.c_str(),start); } if (end == -1) { end = tmp.length(); } //extract parameter res = tmp.substring (start, end); #ifdef AUTHENTICATION_FEATURE //if no label remove authentication parameters if (strlen(label) == 0) { tmp = " " + res; start = tmp.indexOf (" pwd="); if (start != -1) { end = get_space_pos(tmp.c_str(),start+1); res = ""; if (start != 0) { res = tmp.substring(0, start); } if (end != -1) { res += " " + tmp.substring(end+1, tmp.length()); } } } #endif //AUTHENTICATION_FEATURE //remove space format res.replace("\\ ", " "); //be sure no extra space res.trim(); return res.c_str(); } bool Commands::hastag (const char * cmd_params, const char *tag) { String tmp = ""; String stag = " "; if ((strlen(cmd_params) == 0) || (strlen(tag) == 0)) { return false; } stag += tag; tmp = cmd_params; tmp.trim(); tmp = " " + tmp; if (tmp.indexOf(stag) == -1) { return false; } return true; } //execute internal command bool Commands::execute_internal_command (int cmd, const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output) { #ifndef SERIAL_COMMAND_FEATURE if (output->client() == ESP_SERIAL_CLIENT) { output->printMSG("Feature disabled"); return false; } #endif //SERIAL_COMMAND_FEATURE bool response = true; level_authenticate_type auth_type = auth_level; //log_esp3d("Authentication = %d", auth_type); //override if parameters #ifdef AUTHENTICATION_FEATURE //do not overwrite previous authetic ation level if (auth_type == LEVEL_GUEST) { String pwd=get_param (cmd_params, "pwd="); auth_type = AuthenticationService::authenticated_level(pwd.c_str()); } #endif //AUTHENTICATION_FEATURE //log_esp3d("Authentication = %d", auth_type); String parameter; switch (cmd) { #if defined (WIFI_FEATURE) //STA SSID //[ESP100][pwd=] case 100: response = ESP100(cmd_params, auth_type, output); break; //STA Password //[ESP101][pwd=] case 101: response = ESP101(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE #if defined (WIFI_FEATURE) || defined (ETH_FEATURE) //Change STA IP mode (DHCP/STATIC) //[ESP102]pwd= case 102: response = ESP102(cmd_params, auth_type, output); break; //Change STA IP/Mask/GW //[ESP103]IP= MSK= GW= pwd= case 103: response = ESP103(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE ||ETH_FEATURE #if defined (WIFI_FEATURE) //AP SSID //[ESP105][pwd=] case 105: response = ESP105(cmd_params, auth_type, output); break; //AP Password //[ESP106][pwd=] case 106: response = ESP106(cmd_params, auth_type, output); break; //Change AP IP //[ESP107] pwd= case 107: response = ESP107(cmd_params, auth_type, output); break; //Change AP channel //[ESP108]pwd= case 108: response = ESP108(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE #if defined( WIFI_FEATURE) || defined( BLUETOOTH_FEATURE) || defined (ETH_FEATURE) //Set radio state at boot which can be BT, WIFI-STA, WIFI-AP, ETH-STA, OFF //[ESP110]pwd= case 110: response = ESP110(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE || BLUETOOTH_FEATURE || ETH_FEATURE) #if defined(WIFI_FEATURE) || defined (ETH_FEATURE) //Get current IP //[ESP111] case 111: response = ESP111(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE || ETH_FEATURE) #if defined(WIFI_FEATURE) || defined(ETH_FEATURE) || defined(BT_FEATURE) //Get/Set hostname //[ESP112] pwd= case 112: response = ESP112(cmd_params, auth_type, output); break; //Get/Set immediate Network (WiFi/BT/Ethernet) state which can be ON, OFF //[ESP115]pwd= case 115: response = ESP115(cmd_params, auth_type, output); break; #endif //WIFI_FEATURE|| ETH_FEATURE || BT_FEATURE #ifdef HTTP_FEATURE //Set HTTP state which can be ON, OFF //[ESP120]pwd= case 120: response = ESP120(cmd_params, auth_type, output); break; //Set HTTP port //[ESP121]pwd= case 121: response = ESP121(cmd_params, auth_type, output); break; #endif //HTTP_FEATURE #ifdef TELNET_FEATURE //Set TELNET state which can be ON, OFF //[ESP130]pwd= case 130: response = ESP130(cmd_params, auth_type, output); break; //Set TELNET port //[ESP131]pwd= case 131: response = ESP131(cmd_params, auth_type, output); break; #endif //TELNET_FEATURE #ifdef TIMESTAMP_FEATURE //Sync / Set / Get current time //[ESP140] pwd= case 140: response = ESP140(cmd_params, auth_type, output); break; #endif //TIMESTAMP_FEATURE //Get/Set boot delay //[ESP150]