ESP3D/esp3d/src/core/commands.cpp
Luc cb726b51d5 Add Camera streaming server
add  ESP command 170/171/172
apply astyle
add flag to distinguish websocket terminal vs data
2019-09-29 19:47:32 +08:00

548 lines
16 KiB
C++

/*
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 <time=YYYY-MM-DD#H24:MM:SS>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]<SSID>[pwd=<admin password>]
case 100:
response = ESP100(cmd_params, auth_type, output);
break;
//STA Password
//[ESP101]<Password>[pwd=<admin password>]
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]<mode>pwd=<admin password>
case 102:
response = ESP102(cmd_params, auth_type, output);
break;
//Change STA IP/Mask/GW
//[ESP103]IP=<IP> MSK=<IP> GW=<IP> pwd=<admin password>
case 103:
response = ESP103(cmd_params, auth_type, output);
break;
#endif //WIFI_FEATURE ||ETH_FEATURE
#if defined (WIFI_FEATURE)
//AP SSID
//[ESP105]<SSID>[pwd=<admin password>]
case 105:
response = ESP105(cmd_params, auth_type, output);
break;
//AP Password
//[ESP106]<Password>[pwd=<admin password>]
case 106:
response = ESP106(cmd_params, auth_type, output);
break;
//Change AP IP
//[ESP107]<IP> pwd=<admin password>
case 107:
response = ESP107(cmd_params, auth_type, output);
break;
//Change AP channel
//[ESP108]<channel>pwd=<admin password>
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]<state>pwd=<admin password>
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]<Hostname> pwd=<admin password>
case 112:
response = ESP112(cmd_params, auth_type, output);
break;
//Get/Set immediate Network (WiFi/BT/Ethernet) state which can be ON, OFF
//[ESP115]<state>pwd=<admin password>
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]<state>pwd=<admin password>
case 120:
response = ESP120(cmd_params, auth_type, output);
break;
//Set HTTP port
//[ESP121]<port>pwd=<admin password>
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]<state>pwd=<admin password>
case 130:
response = ESP130(cmd_params, auth_type, output);
break;
//Set TELNET port
//[ESP131]<port>pwd=<admin password>
case 131:
response = ESP131(cmd_params, auth_type, output);
break;
#endif //TELNET_FEATURE
#ifdef TIMESTAMP_FEATURE
//Sync / Set / Get current time
//[ESP140]<SYNC> <srv1=XXXXX> <srv2=XXXXX> <srv3=XXXXX> <zone=xxx> <dst=YES/NO> <time=YYYY-MM-DD#H24:MM:SS> pwd=<admin password>
case 140:
response = ESP140(cmd_params, auth_type, output);
break;
#endif //TIMESTAMP_FEATURE
//Get/Set boot delay
//[ESP150]<time>[pwd=<admin password>]
case 150:
response = ESP150(cmd_params, auth_type, output);
break;
#ifdef WS_DATA_FEATURE
//Set WebSocket state which can be ON, OFF
//[ESP160]<state>pwd=<admin password>
case 160:
response = ESP160(cmd_params, auth_type, output);
break;
//Set WebSocket port
//[ESP161]<port>pwd=<admin password>
case 161:
response = ESP161(cmd_params, auth_type, output);
break;
#endif //WS_DATA_FEATURE
#ifdef CAMERA_DEVICE
//Set carmera server state which can be ON, OFF
//[ESP170]<state>pwd=<admin password>
case 170:
response = ESP170(cmd_params, auth_type, output);
break;
case 171:
response = ESP171(cmd_params, auth_type, output);
break;
case 172:
response = ESP172(cmd_params, auth_type, output);
break;
#endif //CAMERA_DEVICE
#ifdef DIRECT_PIN_FEATURE
//Get/Set pin value
//[ESP201]P<pin> V<value> [PULLUP=YES RAW=YES]pwd=<admin password>
case 201:
response = ESP201(cmd_params, auth_type, output);
break;
#endif //DIRECT_PIN_FEATURE
#ifdef DHT_DEVICE
//Get DHT Value / type/Set DHT type
//[ESP210] <TYPE> <type=NONE/11/22/xxx> <interval=XXX in millisec>
case 210:
response = ESP210(cmd_params, auth_type, output);
break;
#endif //#ifdef DHT_DEVICE
#if defined (DISPLAY_DEVICE)
//Output to esp screen status
//[ESP214]<Text>pwd=<user password>
case 214:
response = ESP214(cmd_params, auth_type, output);
break;
#if defined(DISPLAY_TOUCH_DRIVER)
//Touch Calibration
//[ESP215]<CALIBRATE>[pwd=<user password>]
case 215:
response = ESP215(cmd_params, auth_type, output);
break;
#endif //DISPLAY_TOUCH_DRIVER
#if defined(DISPLAY_SNAPSHOT_FEATURE)
//Take screen snapshot
//[ESP216]<SNAP>[pwd=<user password>]
case 216:
response = ESP216(cmd_params, auth_type, output);
break;
#endif //DISPLAY_SNAPSHOT_FEATURE
#ifdef BUZZER_DEVICE
//Play sound
//[ESP250]F=<frequency> D=<duration> [pwd=<user password>]
case 250:
response = ESP250(cmd_params, auth_type, output);
break;
#endif //BUZZER_DEVICE
#endif //DISPLAY_DEVICE
//Delay command
//[ESP290]<delay in ms>[pwd=<user password>]
case 290:
response = ESP290(cmd_params, auth_type, output);
break;
//Get full ESP3D settings
//[ESP400]<pwd=admin>
case 400:
response = ESP400(cmd_params, auth_type, output);
break;
//Set EEPROM setting
//[ESP401]P=<position> T=<type> V=<value> pwd=<user/admin password>
case 401:
response = ESP401(cmd_params, auth_type, output);
break;
#if defined (WIFI_FEATURE)
//Get available AP list (limited to 30)
//output is JSON or plain text according parameter
//[ESP410]<plain>
case 410:
response = ESP410(cmd_params, auth_type, output);
break;
#endif //WIFI_FEATURE
//Get ESP current status
//output is JSON or plain text according parameter
//[ESP420]<plain>
case 420:
response = ESP420(cmd_params, auth_type, output);
break;
//Set ESP State
//cmd are RESTART / RESET
//[ESP444]<cmd><pwd=admin>
case 444:
response = ESP444(cmd_params, auth_type, output);
break;
#ifdef AUTHENTICATION_FEATURE
//Change admin password
//[ESP550]<password>pwd=<admin password>
case 550:
response = ESP550(cmd_params, auth_type, output);
break;
//Change user password
//[ESP555]<password>pwd=<admin/user password>
case 555:
response = ESP555(cmd_params, auth_type, output);
break;
#endif //AUTHENTICATION_FEATURE
#if defined(NOTIFICATION_FEATURE)
//Send Notification
//[ESP600]<msg>[pwd=<admin password>]
case 600:
response = ESP600(cmd_params, auth_type, output);
break;
//Set/Get Notification settings
//[ESP610]type=<NONE/PUSHOVER/EMAIL/LINE> T1=<token1> T2=<token2> TS=<Settings> [pwd=<admin password>]
//Get will give type and settings only not the protected T1/T2
case 610:
response = ESP610(cmd_params, auth_type, output);
break;
#endif //NOTIFICATION_FEATURE
#ifdef FILESYSTEM_FEATURE
//Format ESP Filesystem
//[ESP710]FORMAT pwd=<admin password>
case 710:
response = ESP710(cmd_params, auth_type, output);
break;
//List ESP Filesystem
//[ESP720]<Root> pwd=<admin password>
case 720:
response = ESP720(cmd_params, auth_type, output);
break;
//Action on ESP Filesystem
//rmdir / remove / mkdir / exists
//[ESP730]<Action>=<path> pwd=<admin password>
case 730:
response = ESP730(cmd_params, auth_type, output);
break;
#endif //FILESYSTEM_FEATURE
//Get fw version firmare target and fw version
//eventually set time with pc time
//output is JSON or plain text according parameter
//[ESP800]<plain><time=YYYY-MM-DD-HH-MM-SS>
case 800:
response = ESP800(cmd_params, auth_type, output);
break;
//Get state / Set Enable / Disable Serial Communication
//[ESP900]<ENABLE/DISABLE>
case 900:
response = ESP900(cmd_params, auth_type, output);
break;
#ifdef BUZZER_DEVICE
//Get state / Set Enable / Disable buzzer
//[ESP910]<ENABLE/DISABLE>
case 910:
response = ESP910(cmd_params, auth_type, output);
break;
#endif //BUZZER_DEVICE
default:
output->printERROR ("Invalid Command");
response = false;
}
return response;
}