mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-06-06 02:36:49 +08:00
3224 lines
116 KiB
C++
3224 lines
116 KiB
C++
/*
|
|
webinterface.cpp - esp8266 configuration 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 <pgmspace.h>
|
|
#include "config.h"
|
|
#include "webinterface.h"
|
|
#include "wifi.h"
|
|
#include <WiFiClient.h>
|
|
#include <WiFiServer.h>
|
|
#include <WiFiUdp.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <ESP8266WebServer.h>
|
|
extern "C" {
|
|
#include "user_interface.h"
|
|
}
|
|
#include <FS.h>
|
|
#include "LinkedList.h"
|
|
#include "storestrings.h"
|
|
#include "command.h"
|
|
|
|
#ifdef SSDP_FEATURE
|
|
#include <ESP8266SSDP.h>
|
|
#endif
|
|
|
|
#define MAX_AUTH_IP 10
|
|
#define UPLOAD_STATUS_NONE 0
|
|
#define UPLOAD_STATUS_FAILED 1
|
|
#define UPLOAD_STATUS_CANCELLED 2
|
|
#define UPLOAD_STATUS_SUCCESSFUL 3
|
|
#define UPLOAD_STATUS_ONGOING 4
|
|
|
|
const char PAGE_404 [] PROGMEM ="<HTML>\n<HEAD>\n<title>Redirecting...</title> \n</HEAD>\n<BODY>\n<CENTER>Unknown page - you will be redirected...\n<BR><BR>\nif not redirected, <a href='http://$WEB_ADDRESS$'>click here</a>\n<BR><BR>\n<PROGRESS name='prg' id='prg'></PROGRESS>\n\n<script>\nvar i = 0; \nvar x = document.getElementById(\"prg\"); \nx.max=5; \nvar interval=setInterval(function(){\ni=i+1; \nvar x = document.getElementById(\"prg\"); \nx.value=i; \nif (i>5) \n{\nclearInterval(interval);\nwindow.location.href='/';\n}\n},1000);\n</script>\n</CENTER>\n</BODY>\n</HTML>\n\n";
|
|
const char PAGE_RESTART [] PROGMEM ="<HTML>\n<HEAD>\n<title>Restarting...</title> \n</HEAD>\n<BODY>\n<CENTER>Restarting, please wait....\n<BR>\n<PROGRESS name='prg' id='prg'></PROGRESS>\n</CENTER>\n<script>\nvar i = 0;\nvar interval; \nvar x = document.getElementById(\"prg\"); \nx.max=40; \ninterval = setInterval(function(){\ni=i+1; \nvar x = document.getElementById(\"prg\"); \nx.value=i; \nif (i>40) \n{\nclearInterval(interval);\nwindow.location.href='/';\n}\n},1000);\n</script>\n</BODY>\n</HTML>\n";
|
|
const char RESTARTCMD [] PROGMEM ="<script>setTimeout(function(){window.location.href='/RESTART'},3000);</script>";
|
|
const char VALUE_11B[] PROGMEM = "11b";
|
|
const char VALUE_11N[] PROGMEM = "11n";
|
|
const char VALUE_11G[] PROGMEM = "11g";
|
|
const char VALUE_NONE[] PROGMEM = "None";
|
|
const char VALUE_LIGHT[] PROGMEM = "Light";
|
|
const char VALUE_MODEM[] PROGMEM = "Modem";
|
|
const char VALUE_ENABLED[] PROGMEM = "Enabled";
|
|
const char VALUE_DISABLED[] PROGMEM = "Disabled";
|
|
const char VALUE_WEP[] PROGMEM = "WEP";
|
|
const char VALUE_WPA[] PROGMEM = "WPA";
|
|
const char VALUE_WPA2[] PROGMEM = "WPA2";
|
|
const char VALUE_WPAWPA2[] PROGMEM = "WPA/WPA2";
|
|
const char VALUE_STARTED[] PROGMEM = "Started";
|
|
const char VALUE_STOPPED[] PROGMEM = "Stopped";
|
|
const char VALUE_NO[] PROGMEM = "No";
|
|
const char VALUE_YES[] PROGMEM = "Yes";
|
|
const char VALUE_CONNECTED[] PROGMEM = "Connected";
|
|
const char VALUE_NO_SSID[] PROGMEM = "SSID not Available!";
|
|
const char VALUE_CONNECTION_FAILED[] PROGMEM = "Connection failed!";
|
|
const char VALUE_CONNECTION_FAILED2[] PROGMEM = "Connection failed! (Wrong Password)";
|
|
const char VALUE_IDLE[] PROGMEM = "Idle";
|
|
const char VALUE_DISCONNECTED[] PROGMEM = "Disconnected";
|
|
const char VALUE_ITEM_VISIBLE[] PROGMEM = "visibility:visible;";
|
|
const char VALUE_ITEM_HIDDEN[] PROGMEM ="visibility:hidden;height:0px;width:0px;padding:0px";
|
|
const char KEY_IP[] PROGMEM ="$IP$";
|
|
const char KEY_WEB_ADDRESS[] PROGMEM ="$WEB_ADDRESS$";
|
|
const char KEY_HOSTNAME[] PROGMEM ="$HOSTNAME$";
|
|
const char KEY_HOSTNAME_VISIBLE[] PROGMEM ="$HOSTNAME_VISIBLE$";
|
|
const char KEY_NOT_APPLICABLE_4_AP[] PROGMEM ="Not applicable for Access Point";
|
|
const char KEY_PAGE_TITLE[] PROGMEM ="$PAGE_TITLE$";
|
|
const char VALUE_HOME[] PROGMEM = "Home";
|
|
const char VALUE_FW_VERSION[] PROGMEM = FW_VERSION;
|
|
const char VALUE_NOT_AVAILABLE [] PROGMEM ="Not available";
|
|
const char VALUE_NO_IP [] PROGMEM = "0.0.0.0";
|
|
const char KEY_FILE_NAME [] PROGMEM ="$FILE_NAME$";
|
|
const char KEY_SHORT_FILE_NAME [] PROGMEM ="$SHORT_FILE_NAME$";
|
|
const char KEY_MENU_HOME [] PROGMEM ="$MENU_HOME$";
|
|
const char KEY_MENU_SYSTEM [] PROGMEM ="$MENU_SYSTEM$";
|
|
const char KEY_MENU_AP [] PROGMEM ="$MENU_AP$";
|
|
const char KEY_MENU_STA [] PROGMEM ="$MENU_STA$";
|
|
const char KEY_MENU_PRINTER [] PROGMEM ="$MENU_PRINTER$";
|
|
const char KEY_MENU_SETTINGS [] PROGMEM ="$MENU_SETTINGS$";
|
|
const char KEY_MENU_ADMIN [] PROGMEM ="$MENU_ADMIN$";
|
|
const char KEY_FW_VER [] PROGMEM ="$FW_VER$";
|
|
const char KEY_CHIP_ID [] PROGMEM ="$CHIP_ID$";
|
|
const char KEY_CPU_FREQ [] PROGMEM ="$CPU_FREQ$";
|
|
const char KEY_SDK_VER [] PROGMEM ="$SDK_VER$";
|
|
const char KEY_MDNS_NAME [] PROGMEM = "$MDNS_NAME$";
|
|
const char KEY_MDNS_VISIBLE [] PROGMEM ="$MDNS_VISIBLE$";
|
|
const char KEY_CONNECTED_STATIONS_NB_ITEMS [] PROGMEM = "$CONNECTED_STATIONS_NB_ITEMS$";
|
|
const char KEY_CAPTIVE_PORTAL_STATUS [] PROGMEM = "$CAPTIVE_PORTAL_STATUS$";
|
|
const char KEY_CAPTIVE_PORTAL_VISIBLE [] PROGMEM = "$CAPTIVE_PORTAL_VISIBLE$";
|
|
const char KEY_SSDP_STATUS [] PROGMEM ="$SSDP_STATUS$";
|
|
const char KEY_SSDP_VISIBLE [] PROGMEM ="$SSDP_VISIBLE$";
|
|
const char KEY_NET_PHY [] PROGMEM ="$NET_PHY$";
|
|
const char KEY_SLEEP_MODE [] PROGMEM = "$SLEEP_MODE$";
|
|
const char KEY_BOOT_VER [] PROGMEM = "$BOOT_VER$";
|
|
const char KEY_WEB_PORT [] PROGMEM = "$WEB_PORT$";
|
|
const char KEY_DATA_PORT[] PROGMEM = "$DATA_PORT$";
|
|
const char KEY_BAUD_RATE [] PROGMEM = "$BAUD_RATE$";
|
|
const char KEY_REFRESH_PAGE [] PROGMEM = "$REFRESH_PAGE$";
|
|
const char KEY_AP_STATUS_ENABLED [] PROGMEM = "$AP_STATUS_ENABLED$";
|
|
const char KEY_AP_VISIBILITY [] PROGMEM = "$AP_VISIBILITY$";
|
|
const char KEY_AP_MAC [] PROGMEM = "$AP_MAC$";
|
|
const char KEY_AP_SSID [] PROGMEM = "$AP_SSID$";
|
|
const char KEY_AP_IS_VISIBLE [] PROGMEM = "$AP_IS_VISIBLE$";
|
|
const char KEY_AP_CHANNEL [] PROGMEM = "$AP_CHANNEL$";
|
|
const char KEY_AP_AUTH [] PROGMEM = "$AP_AUTH$";
|
|
const char KEY_AP_MAX_CON [] PROGMEM = "$AP_MAX_CON$";
|
|
const char KEY_AP_DHCP_STATUS [] PROGMEM = "$AP_DHCP_STATUS$";
|
|
const char KEY_AP_IP [] PROGMEM = "$AP_IP$";
|
|
const char KEY_AP_GW [] PROGMEM = "$AP_GW$";;
|
|
const char KEY_AP_SUBNET [] PROGMEM = "$AP_SUBNET$";;
|
|
const char KEY_STA_STATUS_ENABLED [] PROGMEM = "$STA_STATUS_ENABLED$";
|
|
const char KEY_STA_VISIBILITY [] PROGMEM = "$STA_VISIBILITY$";
|
|
const char VALUE_ACTIVE [] PROGMEM = "active";
|
|
const char KEY_STA_DHCP_STATUS [] PROGMEM = "$STA_DHCP_STATUS$";
|
|
const char KEY_STA_IP [] PROGMEM = "$STA_IP$";
|
|
const char KEY_STA_GW [] PROGMEM = "$STA_GW$";
|
|
const char KEY_STA_SUBNET [] PROGMEM = "$STA_SUBNET$";
|
|
const char KEY_STA_MAC [] PROGMEM = "$STA_MAC$";
|
|
const char KEY_STA_SSID [] PROGMEM = "$STA_SSID$";
|
|
const char KEY_STA_CHANNEL [] PROGMEM = "$STA_CHANNEL$";
|
|
const char KEY_STA_STATUS [] PROGMEM = "$STA_STATUS$";
|
|
const char KEY_FREE_MEM [] PROGMEM = "$FREE_MEM$";
|
|
const char KEY_SERVICE_PAGE [] PROGMEM = "$SERVICE_PAGE$";
|
|
const char ARG_SUBMIT [] PROGMEM = "SUBMIT";
|
|
const char KEY_MODE [] PROGMEM = "$MODE$";
|
|
const char VALUE_AP [] PROGMEM = "AP";
|
|
const char VALUE_STA [] PROGMEM = "STA";
|
|
const char VALUE_AP_STA [] PROGMEM = "AP_STA";
|
|
const char KEY_BAUD_RATE_OPTIONS_LIST [] PROGMEM ="$BAUD_RATE_OPTIONS_LIST$";
|
|
const char KEY_SLEEP_MODE_OPTIONS_LIST [] PROGMEM ="$SLEEP_MODE_OPTIONS_LIST$";
|
|
const char KEY_ERROR_MSG [] PROGMEM ="$ERROR_MSG$";
|
|
const char KEY_SUCCESS_MSG [] PROGMEM ="$SUCCESS_MSG$";
|
|
const char KEY_ERROR_MSG_VISIBILITY [] PROGMEM ="$ERROR_MSG_VISIBILITY$";
|
|
const char KEY_SUCCESS_MSG_VISIBILITY[] PROGMEM ="$SUCCESS_MSG_VISIBILITY$";
|
|
const char KEY_SUBMIT_BUTTON_VISIBILITY [] PROGMEM ="$SUBMIT_BUTTON_VISIBILITY$";
|
|
const char VALUE_CONFIG_AP [] PROGMEM = "Configuration Access Point";
|
|
const char VALUE_CONFIG_STA [] PROGMEM = "Configuration Station Client";
|
|
const char VALUE_PRINTER [] PROGMEM = "Printer Interface";
|
|
const char VALUE_HAS_ERROR [] PROGMEM = "has-error";
|
|
const char VALUE_HAS_SUCCESS [] PROGMEM = "has-success";
|
|
const char KEY_BAUD_RATE_STATUS [] PROGMEM = "$BAUD_RATE_STATUS$";
|
|
const char KEY_SLEEP_MODE_STATUS [] PROGMEM ="$SLEEP_MODE_STATUS$";
|
|
const char KEY_WEB_PORT_STATUS [] PROGMEM = "$WEB_PORT_STATUS$";
|
|
const char KEY_DATA_PORT_STATUS [] PROGMEM ="$DATA_PORT_STATUS$";
|
|
const char KEY_AP_SSID_STATUS [] PROGMEM = "$AP_SSID_STATUS$";
|
|
const char KEY_AP_PASSWORD_STATUS [] PROGMEM = "$AP_PASSWORD_STATUS$";
|
|
const char KEY_NETWORK_OPTION_LIST_STATUS [] PROGMEM = "$NETWORK_OPTION_LIST_STATUS$";
|
|
const char KEY_NETWORK_OPTION_LIST [] PROGMEM = "$NETWORK_OPTION_LIST$";
|
|
const char KEY_CHANNEL_OPTION_LIST_STATUS [] PROGMEM = "$CHANNEL_OPTION_LIST_STATUS$";
|
|
const char KEY_CHANNEL_OPTION_LIST [] PROGMEM = "$CHANNEL_OPTION_LIST$";
|
|
const char KEY_AUTH_OPTION_LIST_STATUS [] PROGMEM = "$AUTH_OPTION_LIST_STATUS$";
|
|
const char KEY_AUTH_OPTION_LIST [] PROGMEM = "$AUTH_OPTION_LIST$";
|
|
const char KEY_AP_IP_STATUS [] PROGMEM = "$AP_IP_STATUS$";
|
|
const char KEY_AP_GW_STATUS [] PROGMEM = "$AP_GW_STATUS$";
|
|
const char KEY_AP_SUBNET_STATUS [] PROGMEM = "$AP_SUBNET_STATUS$";
|
|
const char KEY_AP_PASSWORD [] PROGMEM = "$AP_PASSWORD$";
|
|
const char KEY_IS_SSID_VISIBLE_STATUS [] PROGMEM = "$IS_SSID_VISIBLE_STATUS$";
|
|
const char KEY_IS_SSID_VISIBLE [] PROGMEM = "$IS_SSID_VISIBLE$";
|
|
const char VALUE_CHECKED [] PROGMEM = "checked";
|
|
const char VALUE_SELECTED [] PROGMEM ="selected";
|
|
const char KEY_IS_STATIC_IP [] PROGMEM = "$IS_STATIC_IP$";
|
|
const char KEY_AP_STATIC_IP_STATUS [] PROGMEM = "$AP_STATIC_IP_STATUS$";
|
|
const char KEY_STA_STATIC_IP_STATUS [] PROGMEM = "$STA_STATIC_IP_STATUS$";
|
|
const char KEY_STA_SSID_STATUS [] PROGMEM = "$STA_SSID_STATUS$";
|
|
const char KEY_STA_PASSWORD_STATUS [] PROGMEM = "$STA_PASSWORD_STATUS$";
|
|
const char KEY_STA_IP_STATUS [] PROGMEM = "$STA_IP_STATUS$";
|
|
const char KEY_STA_GW_STATUS [] PROGMEM = "$STA_GW_STATUS$";
|
|
const char KEY_STA_SUBNET_STATUS [] PROGMEM = "$STA_SUBNET_STATUS$";
|
|
const char KEY_STA_PASSWORD [] PROGMEM = "$STA_PASSWORD$";
|
|
const char KEY_AVAILABLE_AP_NB_ITEMS [] PROGMEM = "$AVAILABLE_AP_NB_ITEMS$";
|
|
const char KEY_AP_SCAN_VISIBILITY [] PROGMEM = "$AP_SCAN_VISIBILITY$";
|
|
const char KEY_HOSTNAME_STATUS [] PROGMEM = "$HOSTNAME_STATUS$";
|
|
const char KEY_XY_FEEDRATE [] PROGMEM = "$XY_FEEDRATE$";
|
|
const char KEY_Z_FEEDRATE [] PROGMEM = "$Z_FEEDRATE$";
|
|
const char KEY_E_FEEDRATE [] PROGMEM = "$E_FEEDRATE$";
|
|
const char KEY_XY_FEEDRATE_STATUS [] PROGMEM = "$XY_FEEDRATE_STATUS$";
|
|
const char KEY_Z_FEEDRATE_STATUS [] PROGMEM = "$Z_FEEDRATE_STATUS$";
|
|
const char KEY_E_FEEDRATE_STATUS [] PROGMEM = "$E_FEEDRATE_STATUS$";
|
|
const char VALUE_SETTINGS [] PROGMEM = "Extra Settings";
|
|
const char KEY_REFRESH_PAGE_STATUS [] PROGMEM = "$REFRESH_PAGE_STATUS$";
|
|
const char KEY_DISCONNECT_VISIBILITY [] PROGMEM = "$DISCONNECT_VISIBILITY$";
|
|
const char VALUE_LOGIN [] PROGMEM = "Login page";
|
|
const char KEY_USER_STATUS [] PROGMEM = "$USER_STATUS$";
|
|
const char KEY_USER_PASSWORD_STATUS [] PROGMEM = "$USER_PASSWORD_STATUS$";
|
|
const char KEY_USER_PASSWORD_STATUS2 [] PROGMEM = "$USER_PASSWORD_STATUS2$";
|
|
const char KEY_USER [] PROGMEM = "$USER$";
|
|
const char KEY_USER_PASSWORD [] PROGMEM = "$USER_PASSWORD$";
|
|
const char KEY_USER_PASSWORD2 [] PROGMEM = "$USER_PASSWORD2$";
|
|
const char KEY_RETURN [] PROGMEM = "$RETURN$";
|
|
const char VALUE_CHANGE_PASSWORD [] PROGMEM = "Change Password";
|
|
const char MISSING_DATA [] PROGMEM = "Error: Missing data";
|
|
const char EEPROM_NOWRITE [] PROGMEM = "Error: Cannot write to EEPROM";
|
|
const char KEY_WEB_UPDATE [] PROGMEM = "$WEB_UPDATE_VISIBILITY$";
|
|
const char KEY_STA_SIGNAL [] PROGMEM = "$STA_SIGNAL$";
|
|
const char KEY_DATA_PORT_VISIBILITY [] PROGMEM = "$DATA_PORT_VISIBILITY$";
|
|
|
|
bool WEBINTERFACE_CLASS::isHostnameValid(const char * hostname)
|
|
{
|
|
//limited size
|
|
char c;
|
|
if (strlen(hostname)>MAX_HOSTNAME_LENGTH || strlen(hostname) < 1) {
|
|
return false;
|
|
}
|
|
//only letter and digit
|
|
for (int i=0; i < strlen(hostname); i++) {
|
|
c = hostname[i];
|
|
if (!(isdigit(c) || isalpha(c) || c=='_')) {
|
|
return false;
|
|
}
|
|
if (c==' ') {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WEBINTERFACE_CLASS::isSSIDValid(const char * ssid)
|
|
{
|
|
//limited size
|
|
char c;
|
|
if (strlen(ssid)>MAX_SSID_LENGTH || strlen(ssid)<MIN_SSID_LENGTH) {
|
|
return false;
|
|
}
|
|
//only letter and digit
|
|
for (int i=0; i < strlen(ssid); i++) {
|
|
c = ssid[i];
|
|
//if (!(isdigit(c) || isalpha(c))) return false;
|
|
if (c==' ') {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WEBINTERFACE_CLASS::isPasswordValid(const char * password)
|
|
{
|
|
//limited size
|
|
if ((strlen(password)>MAX_PASSWORD_LENGTH)|| (strlen(password)<MIN_PASSWORD_LENGTH)) {
|
|
return false;
|
|
}
|
|
//no space allowed
|
|
for (int i=0; i < strlen(password); i++)
|
|
if (password[i] == ' ') {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool WEBINTERFACE_CLASS::isAdminPasswordValid(const char * password)
|
|
{
|
|
char c;
|
|
//limited size
|
|
if ((strlen(password)>MAX_ADMIN_PASSWORD_LENGTH)|| (strlen(password)<MIN_ADMIN_PASSWORD_LENGTH)) {
|
|
return false;
|
|
}
|
|
//no space allowed
|
|
for (int i=0; i < strlen(password); i++) {
|
|
c= password[i];
|
|
if (c==' ') {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool WEBINTERFACE_CLASS::isIPValid(const char * IP)
|
|
{
|
|
//limited size
|
|
int internalcount=0;
|
|
int dotcount = 0;
|
|
bool previouswasdot=false;
|
|
char c;
|
|
|
|
if (strlen(IP)>15 || strlen(IP)==0) {
|
|
return false;
|
|
}
|
|
//cannot start with .
|
|
if (IP[0]=='.') {
|
|
return false;
|
|
}
|
|
//only letter and digit
|
|
for (int i=0; i < strlen(IP); i++) {
|
|
c = IP[i];
|
|
if (isdigit(c)) {
|
|
//only 3 digit at once
|
|
internalcount++;
|
|
previouswasdot=false;
|
|
if (internalcount>3) {
|
|
return false;
|
|
}
|
|
} else if(c=='.') {
|
|
//cannot have 2 dots side by side
|
|
if (previouswasdot) {
|
|
return false;
|
|
}
|
|
previouswasdot=true;
|
|
internalcount=0;
|
|
dotcount++;
|
|
}//if not a dot neither a digit it is wrong
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
//if not 3 dots then it is wrong
|
|
if (dotcount!=3) {
|
|
return false;
|
|
}
|
|
//cannot have the last dot as last char
|
|
if (IP[strlen(IP)-1]=='.') {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//TODO should be in some tool class
|
|
char * intTostr(int value)
|
|
{
|
|
static char result [12];
|
|
sprintf(result,"%d",value);
|
|
return result;
|
|
}
|
|
|
|
//TODO: should be in webserver class
|
|
bool processTemplate(const char * filename, STORESTRINGS_CLASS & KeysList , STORESTRINGS_CLASS & ValuesList )
|
|
{
|
|
if(KeysList.size() != ValuesList.size()) { //Sanity check
|
|
Serial.print("Error");
|
|
return false;
|
|
}
|
|
|
|
LinkedList<File> myFileList = LinkedList<File>();
|
|
String buffer2send;
|
|
bool header_sent=false;
|
|
|
|
buffer2send="";
|
|
//open template file
|
|
File currentfile = SPIFFS.open(filename, "r");
|
|
//if error display error on web page
|
|
if (!currentfile) {
|
|
buffer2send = String(F("Error opening: ")) + filename;
|
|
web_interface->WebServer.send(200,"text/plain",buffer2send);
|
|
return false;
|
|
} else { //template is open
|
|
int b ;
|
|
String sLine;
|
|
bool bprocessing=true;
|
|
|
|
while (bprocessing) { //read all bytes
|
|
b = currentfile.read(); //from current open file
|
|
if (b!=-1) { //if not EOF
|
|
sLine+=char(b); //add to current line
|
|
if (b=='\n') { //end of line is reached
|
|
//change all variables by their values
|
|
for (int k=0; k<KeysList.size(); k++) {
|
|
sLine.replace(KeysList.get(k),ValuesList.get(k));
|
|
}
|
|
//is line an Include line ? no others command will be displayed
|
|
//but they can be used to build file name like
|
|
//$INCLUDE[$SHORT_FILENAME$-$MODE$.inc]$
|
|
int pos_tag=sLine.indexOf("$INCLUDE[");
|
|
if (pos_tag!=-1) { //if yes
|
|
//extract include file name
|
|
int pos_tag_end = sLine.indexOf("]$");
|
|
String includefilename = "/"+sLine.substring( pos_tag+strlen("$INCLUDE["),pos_tag_end);
|
|
//try to open include file
|
|
File includefile = SPIFFS.open(includefilename, "r");
|
|
if (!includefile) { //if error display it on web page
|
|
buffer2send+= String("Error opening: ") + includefilename;
|
|
} else { //if include is open lets read it, current open file is now include file
|
|
myFileList.add(currentfile);
|
|
currentfile=includefile;
|
|
}
|
|
} else { //if it is not include file
|
|
//check if there is a table to display
|
|
int pos_tag=sLine.indexOf("$CONNECTED_STATIONS[");
|
|
if (pos_tag!=-1) { //if yes
|
|
//extract line
|
|
int pos_tag_end = sLine.indexOf("]$",pos_tag);
|
|
int nb = -1;
|
|
int ipos = -1;
|
|
//part before repetitive section
|
|
String beforelinetoprocess=sLine.substring( 0,pos_tag);
|
|
//part after repetitive section
|
|
String afterlinetoprocess=sLine.substring( pos_tag_end+2);
|
|
//repetitive section itself
|
|
String linetoprocess =sLine.substring( pos_tag+strlen("$CONNECTED_STATIONS["),pos_tag_end);
|
|
String tablepart;
|
|
//get how many items
|
|
ipos=KeysList.get_index("$CONNECTED_STATIONS_NB_ITEMS$");
|
|
if (ipos >-1) {
|
|
//get value
|
|
nb=atoi(ValuesList.get(ipos));
|
|
ipos=ipos-(nb*3);
|
|
}
|
|
//do a sanity check data are there
|
|
String Last_IP_Key = "$IP_CONNECTED["+String(nb-1)+"]$";
|
|
if (nb>0 && (KeysList.get_index("$ROW_NUMBER[0]$")==ipos) &&(Last_IP_Key==KeysList.get(ipos-1+(nb*3)))) {
|
|
for (int j=0; j<nb; j++) {
|
|
String tmppart=linetoprocess + "\n";
|
|
if (ipos+j>-1) {
|
|
tmppart.replace("$ROW_NUMBER$",ValuesList.get(ipos+0+(j*3)));
|
|
tmppart.replace("$MAC_CONNECTED$",ValuesList.get(ipos+1+(j*3)));
|
|
tmppart.replace("$IP_CONNECTED$",ValuesList.get(ipos+2+(j*3)));
|
|
}
|
|
tablepart +=tmppart;
|
|
}
|
|
}
|
|
//now build back
|
|
sLine = beforelinetoprocess + tablepart + afterlinetoprocess;
|
|
}
|
|
|
|
pos_tag=sLine.indexOf("$AVAILABLE_AP[");
|
|
if (pos_tag!=-1) { //if yes
|
|
//extract line
|
|
int pos_tag_end = sLine.indexOf("]$",pos_tag);
|
|
int nb = -1;
|
|
int ipos = -1;
|
|
//part before repetitive section
|
|
String beforelinetoprocess=sLine.substring( 0,pos_tag);
|
|
//part after repetitive section
|
|
String afterlinetoprocess=sLine.substring( pos_tag_end+2);
|
|
//repetitive section itself
|
|
String linetoprocess =sLine.substring( pos_tag+strlen("$AVAILABLE_AP["),pos_tag_end);
|
|
String tablepart;
|
|
//get how many items
|
|
ipos=KeysList.get_index("$AVAILABLE_AP_NB_ITEMS$");
|
|
if (ipos >-1) {
|
|
//get value
|
|
nb=atoi(ValuesList.get(ipos));
|
|
ipos=ipos-(nb*4);
|
|
}
|
|
//do a sanity check data are there
|
|
String Last_IP_Key = "$IS_PROTECTED["+String(nb-1)+"]$";
|
|
if (nb>0 && (KeysList.get_index("$ROW_NUMBER[0]$")==ipos) &&(Last_IP_Key==KeysList.get(ipos-1+(nb*4)))) {
|
|
for (int j=0; j<nb; j++) {
|
|
String tmppart=linetoprocess + "\n";
|
|
if (ipos+j>-1) {
|
|
tmppart.replace("$ROW_NUMBER$",ValuesList.get(ipos+0+(j*4)));
|
|
tmppart.replace("$AP_SSID$",ValuesList.get(ipos+1+(j*4)));
|
|
tmppart.replace("$AP_SIGNAL$",ValuesList.get(ipos+2+(j*4)));
|
|
tmppart.replace("$IS_PROTECTED$",ValuesList.get(ipos+3+(j*4)));
|
|
}
|
|
tablepart +=tmppart;
|
|
}
|
|
}
|
|
//now build back
|
|
sLine = beforelinetoprocess + tablepart + afterlinetoprocess;
|
|
}
|
|
|
|
//add current line to buffer
|
|
buffer2send+=sLine;
|
|
//if buffer limit is reached
|
|
if (buffer2send.length()>1200) {
|
|
//if header is not send yet
|
|
if (!header_sent) {
|
|
//send header with calculated size
|
|
header_sent=true;
|
|
web_interface->WebServer.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
web_interface->WebServer.send(200);
|
|
web_interface->WebServer.sendHeader("Content-Type","text/html");
|
|
web_interface->WebServer.sendHeader("Cache-Control","no-cache");
|
|
}
|
|
//send data
|
|
web_interface->WebServer.sendContent(buffer2send);
|
|
//reset buffer
|
|
buffer2send="";
|
|
}
|
|
}
|
|
//reset line
|
|
sLine="";
|
|
//add a delay for safety for WDT
|
|
delay(1);
|
|
}
|
|
} else { //EOF is reached
|
|
//close current file
|
|
currentfile.close();
|
|
//if current file is not template file but included one
|
|
if (myFileList.size()>0) {
|
|
//get level +1 file description and continue
|
|
currentfile = myFileList.pop();
|
|
} else {
|
|
//we have done template parsing, let's stop reading
|
|
bprocessing=false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//check if something is still in buffer and need to be send
|
|
if (buffer2send!="") {
|
|
//if header is not send yet
|
|
if (!header_sent) {
|
|
//send header
|
|
web_interface->WebServer.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
web_interface->WebServer.send(200);
|
|
web_interface->WebServer.sendHeader("Content-Type","text/html");
|
|
web_interface->WebServer.sendHeader("Cache-Control","no-cache");
|
|
}
|
|
//send data
|
|
web_interface->WebServer.sendContent(buffer2send);
|
|
}
|
|
//close line
|
|
web_interface->WebServer.sendContent("");
|
|
return true;
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for FreeMem and Firmware
|
|
// -----------------------------------------------------------------------------
|
|
void GetFreeMem(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
//FreeMem
|
|
KeysList.add(FPSTR(KEY_FREE_MEM));
|
|
ValuesList.add(intTostr(ESP.getFreeHeap()));
|
|
//FW Version
|
|
KeysList.add(FPSTR(KEY_FW_VER));
|
|
ValuesList.add(FPSTR(VALUE_FW_VERSION));
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for IP+Web address
|
|
// -----------------------------------------------------------------------------
|
|
void GetIpWeb(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
String stmp;
|
|
|
|
KeysList.add(FPSTR(KEY_IP));
|
|
if (WiFi.getMode() == WIFI_STA ) {
|
|
stmp = WiFi.localIP().toString();
|
|
} else {
|
|
stmp = WiFi.softAPIP().toString();
|
|
}
|
|
ValuesList.add(stmp);
|
|
|
|
//Web address = ip + port
|
|
KeysList.add(FPSTR(KEY_WEB_ADDRESS));
|
|
if (wifi_config.iweb_port != 80) {
|
|
stmp.concat(":");
|
|
stmp.concat(wifi_config.iweb_port);
|
|
}
|
|
ValuesList.add(stmp);
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for Wifi Mode
|
|
// -----------------------------------------------------------------------------
|
|
void GetMode(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
if (WiFi.getMode() == WIFI_STA ) {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_STA));
|
|
} else {
|
|
if (WiFi.getMode() == WIFI_AP ) {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_AP));
|
|
} else {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_AP_STA));
|
|
}
|
|
}
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for Web ports
|
|
// -----------------------------------------------------------------------------
|
|
void GetPorts(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
//Web port
|
|
KeysList.add(FPSTR(KEY_WEB_PORT));
|
|
ValuesList.add(intTostr(wifi_config.iweb_port));
|
|
//Data port
|
|
KeysList.add(FPSTR(KEY_DATA_PORT));
|
|
KeysList.add(FPSTR(KEY_DATA_PORT_VISIBILITY));
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
ValuesList.add(intTostr(wifi_config.idata_port));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
#else
|
|
ValuesList.add(FPSTR(VALUE_NONE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
#endif
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for Page properties
|
|
// -----------------------------------------------------------------------------
|
|
void SetPageProp(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList,
|
|
const __FlashStringHelper *title, const __FlashStringHelper *filename)
|
|
{
|
|
String fullFilename(filename);
|
|
fullFilename.concat(".tpl");
|
|
|
|
//page title
|
|
KeysList.add(FPSTR(KEY_PAGE_TITLE));
|
|
ValuesList.add(title);
|
|
//tpl file name with extension
|
|
KeysList.add(FPSTR(KEY_FILE_NAME));
|
|
ValuesList.add(fullFilename);
|
|
//tpl file name without extension
|
|
KeysList.add(FPSTR(KEY_SHORT_FILE_NAME));
|
|
ValuesList.add(filename);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for DHCP (APP/STA)tus
|
|
// -----------------------------------------------------------------------------
|
|
void GetDHCPStatus(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
KeysList.add(FPSTR(KEY_AP_DHCP_STATUS));
|
|
if (wifi_softap_dhcps_status() == DHCP_STARTED) {
|
|
ValuesList.add(FPSTR(VALUE_STARTED));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_STOPPED));
|
|
}
|
|
|
|
KeysList.add(FPSTR(KEY_STA_DHCP_STATUS));
|
|
if (wifi_station_dhcpc_status()==DHCP_STARTED) {
|
|
ValuesList.add(FPSTR(VALUE_STARTED));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_STOPPED));
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for Error Msg processing
|
|
// -----------------------------------------------------------------------------
|
|
void ProcessAlertError(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList, String & smsg)
|
|
{
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG));
|
|
ValuesList.add(smsg);
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG));
|
|
ValuesList.add("");
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG_VISIBILITY ));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
KeysList.add(FPSTR(KEY_SUBMIT_BUTTON_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for Success Msg processing
|
|
// -----------------------------------------------------------------------------
|
|
void ProcessAlertSuccess(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList, String & smsg)
|
|
{
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG));
|
|
ValuesList.add("");
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG));
|
|
ValuesList.add(smsg);
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG_VISIBILITY ));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
KeysList.add(FPSTR(KEY_SUBMIT_BUTTON_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Helper for No Msg processing
|
|
// -----------------------------------------------------------------------------
|
|
void ProcessNoAlert(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList)
|
|
{
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG));
|
|
ValuesList.add("");
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG));
|
|
ValuesList.add("");
|
|
KeysList.add(FPSTR(KEY_ERROR_MSG_VISIBILITY ));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
KeysList.add(FPSTR(KEY_SUCCESS_MSG_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
KeysList.add(FPSTR(KEY_SUBMIT_BUTTON_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
}
|
|
|
|
//root insterface
|
|
void handle_web_interface_root()
|
|
{
|
|
static const char HOME_PAGE [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /HOME\r\nCache-Control: no-cache\r\n\r\n";
|
|
web_interface->WebServer.sendContent_P(HOME_PAGE);
|
|
}
|
|
|
|
//root insterface
|
|
void handle_web_interface_home()
|
|
{
|
|
String stmp;
|
|
//long lstatus;
|
|
int istatus;
|
|
//byte bbuf;
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
struct softap_config apconfig;
|
|
struct ip_info info;
|
|
uint8_t mac [WL_MAC_ADDR_LENGTH];
|
|
|
|
KeysList.add(FPSTR(KEY_DISCONNECT_VISIBILITY));
|
|
if (web_interface->is_authenticated()) {
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
|
|
//Hostname
|
|
if (WiFi.getMode()==WIFI_STA ) {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_STA));
|
|
KeysList.add(FPSTR(KEY_HOSTNAME));
|
|
ValuesList.add(wifi_config.get_hostname());
|
|
KeysList.add(FPSTR(KEY_HOSTNAME_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
KeysList.add(FPSTR(KEY_HOSTNAME));
|
|
ValuesList.add(FPSTR(KEY_NOT_APPLICABLE_4_AP));
|
|
KeysList.add(FPSTR(KEY_HOSTNAME_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
if (WiFi.getMode()==WIFI_AP ) {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_AP));
|
|
} else {
|
|
KeysList.add(FPSTR(KEY_MODE));
|
|
ValuesList.add(FPSTR(VALUE_AP_STA));
|
|
}
|
|
}
|
|
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_HOME),F("home"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_HOME));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//Chip ID
|
|
KeysList.add(FPSTR(KEY_CHIP_ID));
|
|
ValuesList.add(intTostr(system_get_chip_id()));
|
|
//CPU Freq
|
|
KeysList.add(FPSTR(KEY_CPU_FREQ));
|
|
ValuesList.add(intTostr(system_get_cpu_freq()));
|
|
//SDK Version
|
|
KeysList.add(FPSTR(KEY_SDK_VER));
|
|
ValuesList.add(system_get_sdk_version());
|
|
|
|
//MDNS Feature
|
|
#ifdef MDNS_FEATURE
|
|
KeysList.add(FPSTR(KEY_MDNS_NAME));
|
|
stmp="http://";
|
|
stmp+=wifi_config.get_hostname();
|
|
stmp+=".local";
|
|
ValuesList.add(stmp);
|
|
KeysList.add(FPSTR(KEY_MDNS_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
#else
|
|
KeysList.add(FPSTR(KEY_MDNS_NAME));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
KeysList.add(FPSTR(KEY_MDNS_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
#endif
|
|
|
|
//SSDP Feature
|
|
#ifdef SSDP_FEATURE
|
|
KeysList.add(FPSTR(KEY_SSDP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_ENABLED));
|
|
KeysList.add(FPSTR(KEY_SSDP_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
#else
|
|
KeysList.add(FPSTR(KEY_SSDP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
KeysList.add(FPSTR(KEY_SSDP_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
#endif
|
|
|
|
//Captive portal Feature
|
|
#ifdef CAPTIVE_PORTAL_FEATURE
|
|
if (WiFi.getMode()==WIFI_AP) {
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_ENABLED));
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
}
|
|
#else
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
KeysList.add(FPSTR(KEY_CAPTIVE_PORTAL_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
#endif
|
|
|
|
//network
|
|
KeysList.add(FPSTR(KEY_NET_PHY));
|
|
if (WiFi.getPhyMode()==WIFI_PHY_MODE_11B) {
|
|
ValuesList.add(FPSTR(VALUE_11B));
|
|
} else if (WiFi.getPhyMode()==WIFI_PHY_MODE_11G) {
|
|
ValuesList.add(FPSTR(VALUE_11G));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_11N));
|
|
}
|
|
//sleep mode
|
|
KeysList.add(FPSTR(KEY_SLEEP_MODE));
|
|
if (WiFi.getSleepMode()==WIFI_NONE_SLEEP) {
|
|
ValuesList.add(FPSTR(VALUE_NONE));
|
|
} else if (WiFi.getSleepMode()==WIFI_LIGHT_SLEEP) {
|
|
ValuesList.add(FPSTR(VALUE_LIGHT));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_MODEM));
|
|
}
|
|
//Boot version
|
|
KeysList.add(FPSTR(KEY_BOOT_VER));
|
|
ValuesList.add(intTostr(system_get_boot_version()));
|
|
//Baud rate
|
|
KeysList.add(FPSTR(KEY_BAUD_RATE));
|
|
ValuesList.add(intTostr(wifi_config.baud_rate));
|
|
// Web and Data ports
|
|
GetPorts(KeysList, ValuesList);
|
|
|
|
//AP part
|
|
if (WiFi.getMode()==WIFI_AP || WiFi.getMode()==WIFI_AP_STA) {
|
|
int client_counter=0;
|
|
struct station_info * station;
|
|
//AP is enabled
|
|
KeysList.add(FPSTR(KEY_AP_STATUS_ENABLED));
|
|
ValuesList.add(FPSTR(VALUE_ENABLED));
|
|
//set visible
|
|
KeysList.add(FPSTR(KEY_AP_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
//list of connected clients
|
|
station = wifi_softap_get_station_info();
|
|
while(station) {
|
|
//Row number
|
|
stmp = "$ROW_NUMBER["+String(client_counter)+"]$";
|
|
KeysList.add(stmp.c_str());
|
|
stmp=String(client_counter+1);
|
|
ValuesList.add(stmp);
|
|
//BSSID
|
|
stmp = "$MAC_CONNECTED["+String(client_counter)+"]$";
|
|
KeysList.add(stmp.c_str());
|
|
ValuesList.add(wifi_config.mac2str(station->bssid));
|
|
//IP
|
|
stmp = "$IP_CONNECTED["+String(client_counter)+"]$";
|
|
KeysList.add(stmp.c_str());
|
|
ValuesList.add(IPAddress((const uint8_t *)&station->ip).toString().c_str());
|
|
//increment counter
|
|
client_counter++;
|
|
//go next record
|
|
station = STAILQ_NEXT(station, next);
|
|
}
|
|
wifi_softap_free_station_info();
|
|
//Connected clients
|
|
KeysList.add(FPSTR(KEY_CONNECTED_STATIONS_NB_ITEMS));
|
|
ValuesList.add(intTostr(client_counter));
|
|
} else {
|
|
//AP is disabled
|
|
KeysList.add(FPSTR(KEY_AP_STATUS_ENABLED));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
//set hide
|
|
KeysList.add(FPSTR(KEY_AP_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
//Connected clients
|
|
KeysList.add(FPSTR(KEY_CONNECTED_STATIONS_NB_ITEMS));
|
|
ValuesList.add("0");
|
|
}
|
|
//AP mac address
|
|
KeysList.add(FPSTR(KEY_AP_MAC));
|
|
ValuesList.add(wifi_config.mac2str(WiFi.softAPmacAddress(mac)));
|
|
//AP configuration
|
|
if (wifi_softap_get_config(&apconfig)) {
|
|
//SSID
|
|
KeysList.add(FPSTR(KEY_AP_SSID));
|
|
ValuesList.add((char *)(apconfig.ssid));
|
|
//AP visible or hidden
|
|
KeysList.add(FPSTR(KEY_AP_IS_VISIBLE));
|
|
if(apconfig.ssid_hidden==1) {
|
|
ValuesList.add(FPSTR(VALUE_NO));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_YES));
|
|
}
|
|
//Channel
|
|
KeysList.add(FPSTR(KEY_AP_CHANNEL));
|
|
ValuesList.add(intTostr(apconfig.channel));
|
|
//Authentification mode
|
|
KeysList.add(FPSTR(KEY_AP_AUTH));
|
|
if (apconfig.authmode==AUTH_OPEN) {
|
|
ValuesList.add(FPSTR(VALUE_NONE));
|
|
} else if (apconfig.authmode==AUTH_WEP) {
|
|
ValuesList.add(FPSTR(VALUE_WEP));
|
|
} else if (apconfig.authmode==AUTH_WPA_PSK) {
|
|
ValuesList.add(FPSTR(VALUE_WPA));
|
|
} else if (apconfig.authmode==AUTH_WPA2_PSK) {
|
|
ValuesList.add(FPSTR(VALUE_WPA2));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_WPAWPA2));
|
|
}
|
|
|
|
//Max connections
|
|
KeysList.add(FPSTR(KEY_AP_MAX_CON));
|
|
ValuesList.add(intTostr(apconfig.max_connection));
|
|
} else {
|
|
//SSID
|
|
KeysList.add(FPSTR(KEY_AP_SSID));
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
//AP visible or hidden
|
|
KeysList.add(FPSTR(KEY_AP_IS_VISIBLE));
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
//Channel
|
|
KeysList.add(FPSTR(KEY_AP_CHANNEL));
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
//Authentification mode
|
|
KeysList.add(FPSTR(KEY_AP_AUTH));
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
//Max connections
|
|
KeysList.add(FPSTR(KEY_AP_MAX_CON));
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
}
|
|
//DHCP Status
|
|
GetDHCPStatus(KeysList, ValuesList);
|
|
//IP/GW/MASK
|
|
if (wifi_get_ip_info(SOFTAP_IF,&info)) {
|
|
//IP address
|
|
KeysList.add(FPSTR(KEY_AP_IP));
|
|
ValuesList.add(IPAddress((const uint8_t *)&(info.ip.addr)).toString().c_str());
|
|
//GW address
|
|
KeysList.add(FPSTR(KEY_AP_GW));
|
|
ValuesList.add(IPAddress((const uint8_t *)&(info.gw.addr)).toString().c_str());
|
|
//Sub Net Mask
|
|
KeysList.add(FPSTR(KEY_AP_SUBNET));
|
|
ValuesList.add(IPAddress((const uint8_t *)&(info.netmask.addr)).toString().c_str());
|
|
} else {
|
|
//IP address
|
|
KeysList.add(FPSTR(KEY_AP_IP));
|
|
ValuesList.add(FPSTR(VALUE_NO_IP));
|
|
//GW address
|
|
KeysList.add(FPSTR(KEY_AP_GW));
|
|
ValuesList.add(FPSTR(VALUE_NO_IP));
|
|
//Sub Net Mask
|
|
KeysList.add(FPSTR(KEY_AP_SUBNET));
|
|
ValuesList.add(FPSTR(VALUE_NO_IP));
|
|
}
|
|
//STA part
|
|
if (WiFi.getMode()==WIFI_STA || WiFi.getMode()==WIFI_AP_STA) {
|
|
//STA is enabled
|
|
KeysList.add(FPSTR(KEY_STA_STATUS_ENABLED));
|
|
ValuesList.add(FPSTR(VALUE_ENABLED));
|
|
//set visible
|
|
KeysList.add(FPSTR(KEY_STA_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
//STA is disabled
|
|
KeysList.add(FPSTR(KEY_STA_STATUS_ENABLED));
|
|
ValuesList.add(FPSTR(VALUE_DISABLED));
|
|
//set hide
|
|
KeysList.add(FPSTR(KEY_STA_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
}
|
|
//STA mac address
|
|
KeysList.add(FPSTR(KEY_STA_MAC));
|
|
ValuesList.add(wifi_config.mac2str(WiFi.macAddress(mac)));
|
|
//SSID used by STA
|
|
KeysList.add(FPSTR(KEY_STA_SSID));
|
|
if (WiFi.SSID().length()==0) {
|
|
ValuesList.add(FPSTR(VALUE_NOT_AVAILABLE));
|
|
} else {
|
|
ValuesList.add(WiFi.SSID().c_str());
|
|
}
|
|
//Channel
|
|
KeysList.add(FPSTR(KEY_STA_CHANNEL));
|
|
ValuesList.add(intTostr (wifi_get_channel()));
|
|
//Connection status
|
|
istatus = wifi_station_get_connect_status();
|
|
KeysList.add(FPSTR(KEY_STA_STATUS));
|
|
if (istatus==STATION_GOT_IP) {
|
|
ValuesList.add(FPSTR(VALUE_CONNECTED));
|
|
} else if (istatus==STATION_NO_AP_FOUND) {
|
|
ValuesList.add(FPSTR(VALUE_NO_SSID));
|
|
} else if (istatus==STATION_CONNECT_FAIL) {
|
|
ValuesList.add(FPSTR(VALUE_CONNECTION_FAILED));
|
|
} else if (istatus==STATION_WRONG_PASSWORD) {
|
|
ValuesList.add(FPSTR(VALUE_CONNECTION_FAILED2));
|
|
} else if (istatus==STATION_IDLE) {
|
|
ValuesList.add(FPSTR(VALUE_IDLE)); //should not happen
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_DISCONNECTED));
|
|
}
|
|
//Signal strength
|
|
KeysList.add(FPSTR(KEY_STA_SIGNAL));
|
|
ValuesList.add(intTostr(100+WiFi.RSSI()));
|
|
//DHCP Client status
|
|
GetDHCPStatus(KeysList, ValuesList);
|
|
//IP address
|
|
KeysList.add(FPSTR(KEY_STA_IP));
|
|
ValuesList.add(WiFi.localIP().toString().c_str());
|
|
//GW address
|
|
KeysList.add(FPSTR(KEY_STA_GW));
|
|
ValuesList.add(WiFi.gatewayIP().toString().c_str());
|
|
//Sub Net Mask
|
|
KeysList.add(FPSTR(KEY_STA_SUBNET));
|
|
ValuesList.add(WiFi.subnetMask().toString().c_str());
|
|
//Service page / no need refresh on this page
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
//Firmware & Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
//process the template file and provide list of variables
|
|
processTemplate("/home.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_web_interface_configSys()
|
|
{
|
|
static const char NOT_AUTH_CS [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=CONFIGSYS\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String stmp,smsg;
|
|
//long lstatus;
|
|
int istatus;
|
|
//byte bbuf;
|
|
long ibaud=DEFAULT_BAUD_RATE;
|
|
int iweb_port =DEFAULT_WEB_PORT;
|
|
int idata_port =DEFAULT_DATA_PORT;
|
|
byte bsleepmode=DEFAULT_SLEEP_MODE;
|
|
bool msg_alert_error=false;
|
|
bool msg_alert_success=false;
|
|
long lbaudlist[] = {9600 ,19200,38400,57600,115200,230400,250000,-1};
|
|
int bmodemvaluelist[] = {WIFI_NONE_SLEEP,WIFI_LIGHT_SLEEP,WIFI_MODEM_SLEEP, -1};
|
|
const __FlashStringHelper *smodemdisplaylist[]= {FPSTR(VALUE_NONE),FPSTR(VALUE_LIGHT),FPSTR(VALUE_MODEM),FPSTR(VALUE_MODEM)};
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_CS);
|
|
return;
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_HOME),F("system"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_SYSTEM));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//check is it is a submission or a display
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if (web_interface->WebServer.hasArg("BAUD_RATE")
|
|
&& web_interface->WebServer.hasArg("SLEEP_MODE")
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
&& web_interface->WebServer.hasArg("DATAPORT")
|
|
#endif
|
|
&& web_interface->WebServer.hasArg("WEBPORT")) {
|
|
//is each value correct ?
|
|
ibaud = web_interface->WebServer.arg("BAUD_RATE").toInt();
|
|
iweb_port = web_interface->WebServer.arg("WEBPORT").toInt();
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
idata_port = web_interface->WebServer.arg("DATAPORT").toInt();
|
|
#endif
|
|
bsleepmode = web_interface->WebServer.arg("SLEEP_MODE").toInt();
|
|
|
|
if (!(iweb_port>0 && iweb_port<65001)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: invalid port value for web port<BR>"));
|
|
KeysList.add(FPSTR(KEY_WEB_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
if (!(idata_port>0 && idata_port<65001)) {
|
|
msg_alert_error=true;
|
|
smsg.concat("Error: invalid port value for data port<BR>");
|
|
KeysList.add(FPSTR(KEY_DATA_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
#endif
|
|
if (iweb_port== idata_port) {
|
|
msg_alert_error=true;
|
|
smsg.concat("Error: web port and data port cannot be identical<BR>");
|
|
KeysList.add(FPSTR(KEY_WEB_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
KeysList.add(FPSTR(KEY_DATA_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (!(ibaud==9600 || ibaud==19200|| ibaud==38400|| ibaud==57600|| ibaud==115200|| ibaud==230400 || ibaud==250000)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: value for baud rate is not correct<BR>"));
|
|
KeysList.add(FPSTR(KEY_BAUD_RATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (!(bsleepmode==WIFI_NONE_SLEEP ||bsleepmode==WIFI_LIGHT_SLEEP ||bsleepmode==WIFI_MODEM_SLEEP )) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: value for sleeping mode is not correct<BR>"));
|
|
KeysList.add(FPSTR(KEY_SLEEP_MODE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
//if no error apply the changes
|
|
if (msg_alert_error!=true) {
|
|
if(!CONFIG::write_buffer(EP_BAUD_RATE,(const byte *)&ibaud,INTEGER_LENGTH)
|
|
||!CONFIG::write_buffer(EP_WEB_PORT,(const byte *)&iweb_port,INTEGER_LENGTH)
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
||!CONFIG::write_buffer(EP_DATA_PORT,(const byte *)&idata_port,INTEGER_LENGTH)
|
|
#endif
|
|
||!CONFIG::write_byte(EP_SLEEP_MODE,bsleepmode)) {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(EEPROM_NOWRITE);
|
|
} else {
|
|
msg_alert_success=true;
|
|
#ifdef TCP_IP_DATA_FEATURE
|
|
wifi_config.iweb_port=iweb_port;
|
|
#endif
|
|
wifi_config.idata_port=idata_port;
|
|
smsg = F("Changes saved to EEPROM, restarting....");
|
|
}
|
|
}
|
|
} else { //no submit need to get data from EEPROM
|
|
if (!CONFIG::read_buffer(EP_BAUD_RATE, (byte *)&ibaud , INTEGER_LENGTH)) {
|
|
ibaud=DEFAULT_BAUD_RATE;
|
|
}
|
|
if (!CONFIG::read_byte(EP_SLEEP_MODE, &bsleepmode )) {
|
|
bsleepmode=DEFAULT_SLEEP_MODE;
|
|
}
|
|
if (!CONFIG::read_buffer(EP_WEB_PORT, (byte *)&iweb_port , INTEGER_LENGTH)) {
|
|
iweb_port=DEFAULT_WEB_PORT;
|
|
}
|
|
wifi_config.iweb_port=iweb_port;
|
|
if (!CONFIG::read_buffer(EP_DATA_PORT, (byte *)&idata_port , INTEGER_LENGTH)) {
|
|
idata_port=DEFAULT_DATA_PORT;
|
|
}
|
|
wifi_config.idata_port=idata_port;
|
|
};
|
|
//Baud rate list
|
|
istatus = 0;
|
|
stmp="";
|
|
while (lbaudlist[istatus]>-1) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+= intTostr(lbaudlist[istatus]);
|
|
stmp+="\" ";
|
|
if (lbaudlist[istatus]==ibaud) {
|
|
stmp+=FPSTR(VALUE_SELECTED);
|
|
}
|
|
stmp+=">" ;
|
|
stmp+=intTostr(lbaudlist[istatus]);
|
|
stmp+= "</OPTION>\n";
|
|
istatus++;
|
|
}
|
|
KeysList.add(FPSTR(KEY_BAUD_RATE_OPTIONS_LIST));
|
|
ValuesList.add(stmp);
|
|
//Sleep Mode
|
|
istatus = 0;
|
|
stmp="";
|
|
while (bmodemvaluelist[istatus]>-1) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+= intTostr(bmodemvaluelist[istatus]);
|
|
stmp+="\" ";
|
|
if (bmodemvaluelist[istatus]==bsleepmode) {
|
|
stmp+=FPSTR(VALUE_SELECTED);
|
|
}
|
|
stmp+=">" ;
|
|
stmp+=smodemdisplaylist[istatus];
|
|
stmp+= "</OPTION>\n";
|
|
istatus++;
|
|
}
|
|
KeysList.add(FPSTR(KEY_SLEEP_MODE_OPTIONS_LIST));
|
|
ValuesList.add(stmp);
|
|
|
|
// Web and Data ports
|
|
GetPorts(KeysList, ValuesList);
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else if (msg_alert_success) {
|
|
ProcessAlertSuccess(KeysList, ValuesList, smsg);
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add(FPSTR(RESTARTCMD));
|
|
KeysList.add(FPSTR(KEY_BAUD_RATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_SLEEP_MODE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_WEB_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_DATA_PORT_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
ProcessNoAlert(KeysList, ValuesList);
|
|
}
|
|
KeysList.add(FPSTR(KEY_WEB_UPDATE));
|
|
#ifdef WEB_UPDATE_FEATURE
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
#else
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
#endif
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/system.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_password()
|
|
{
|
|
static const char NOT_AUTH_PW [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=PASSWORD\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String smsg;
|
|
String sPassword,sPassword2;
|
|
bool msg_alert_error=false;
|
|
bool msg_alert_success=false;
|
|
//int ipos;
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_PW);
|
|
return;
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_CHANGE_PASSWORD),F("password"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_ADMIN));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//check if it is a submission or a display
|
|
smsg="";
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if (web_interface->WebServer.hasArg("PASSWORD") && web_interface->WebServer.hasArg("PASSWORD2")) {
|
|
//Password
|
|
sPassword =web_interface->WebServer.arg("PASSWORD");
|
|
sPassword2 = web_interface->WebServer.arg("PASSWORD2");
|
|
if (!web_interface->isAdminPasswordValid(sPassword.c_str()) ) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect password<BR>"));
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (sPassword!=sPassword2) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Passwords do not match<BR>"));
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD_STATUS2));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
|
|
//if no error apply the change
|
|
if (msg_alert_error==false) {
|
|
//save
|
|
if(!CONFIG::write_string(EP_ADMIN_PWD,sPassword.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(EEPROM_NOWRITE);
|
|
} else {
|
|
msg_alert_success=true;
|
|
smsg = F("Changes saved to EEPROM");
|
|
}
|
|
}
|
|
}
|
|
|
|
else { //no submit, need to get data from EEPROM
|
|
//password
|
|
sPassword="";
|
|
sPassword2="";
|
|
}
|
|
//Display values
|
|
//password
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD));
|
|
ValuesList.add(sPassword);
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD2));
|
|
ValuesList.add(sPassword2);
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else if (msg_alert_success) {
|
|
ProcessAlertSuccess(KeysList, ValuesList, smsg);
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
//Add all green
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD_STATUS2));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
ProcessNoAlert(KeysList,ValuesList);
|
|
}
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/password.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
|
|
void handle_web_interface_configAP()
|
|
{
|
|
static const char NOT_AUTH_AP [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=CONFIGAP\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String stmp,smsg;
|
|
String sSSID,sPassword,sIP,sGW,sMask;
|
|
bool msg_alert_error=false;
|
|
bool msg_alert_success=false;
|
|
byte visible_buf;
|
|
byte static_ip_buf;
|
|
byte auth_buf;
|
|
byte channel_buf;
|
|
byte phy_mode_buf;
|
|
byte ip_sav[4];
|
|
byte gw_sav[4];
|
|
byte msk_sav[4];
|
|
int ipos;
|
|
int inetworkvaluelist []= {WIFI_PHY_MODE_11B,WIFI_PHY_MODE_11G,-1};
|
|
const __FlashStringHelper * inetworkdisplaylist []= {FPSTR(VALUE_11B),FPSTR(VALUE_11G),FPSTR(VALUE_11B)};
|
|
int iauthvaluelist[] = {AUTH_OPEN,AUTH_WPA_PSK,AUTH_WPA2_PSK,AUTH_WPA_WPA2_PSK,-1};
|
|
const __FlashStringHelper * iauthdisplaylist[] = {FPSTR(VALUE_NONE),FPSTR(VALUE_WPA),FPSTR(VALUE_WPA2),FPSTR(VALUE_WPAWPA2)};
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_AP);
|
|
return;
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_CONFIG_AP),F("config_ap"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_AP));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//check is it is a submission or a display
|
|
smsg="";
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if (web_interface->WebServer.hasArg("SSID") && web_interface->WebServer.hasArg("PASSWORD")&& web_interface->WebServer.hasArg("NETWORK")
|
|
&& web_interface->WebServer.hasArg("AUTHENTIFICATION")&& web_interface->WebServer.hasArg("IP")
|
|
&& web_interface->WebServer.hasArg("GATEWAY")&& web_interface->WebServer.hasArg("SUBNET")
|
|
&& web_interface->WebServer.hasArg("CHANNEL")) {
|
|
//SSID
|
|
sSSID = web_interface->WebServer.arg("SSID");
|
|
if (!web_interface->isSSIDValid(sSSID.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect SSID<BR>"));
|
|
KeysList.add(FPSTR(KEY_AP_SSID_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//Password
|
|
sPassword = web_interface->WebServer.arg("PASSWORD");
|
|
if (!web_interface->isPasswordValid(sPassword.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect password<BR>"));
|
|
KeysList.add(FPSTR(KEY_AP_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//ssid visible ?
|
|
if (web_interface->WebServer.hasArg("SSID_VISIBLE")) {
|
|
visible_buf=1;
|
|
} else {
|
|
visible_buf=0;
|
|
}
|
|
//phy mode
|
|
phy_mode_buf = byte(web_interface->WebServer.arg("NETWORK").toInt());
|
|
if (!(phy_mode_buf==WIFI_PHY_MODE_11B||phy_mode_buf==WIFI_PHY_MODE_11G) ) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect network<BR>"));
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//channel
|
|
channel_buf = byte (web_interface->WebServer.arg("CHANNEL").toInt());
|
|
if (channel_buf< 1|| channel_buf>11) {
|
|
msg_alert_error=true;
|
|
smsg.concat("Error: Incorrect channel<BR>");
|
|
KeysList.add(FPSTR(KEY_CHANNEL_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//authentification
|
|
auth_buf = byte(web_interface->WebServer.arg("AUTHENTIFICATION").toInt());
|
|
if (!(auth_buf == AUTH_OPEN || auth_buf == AUTH_WEP || auth_buf == AUTH_WPA_PSK ||
|
|
auth_buf == AUTH_WPA2_PSK || auth_buf == AUTH_WPA_WPA2_PSK)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect authentification method<BR>"));
|
|
KeysList.add(FPSTR(KEY_AUTH_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//Static IP ?
|
|
if (web_interface->WebServer.hasArg("STATIC_IP") ) {
|
|
static_ip_buf=STATIC_IP_MODE;
|
|
} else {
|
|
static_ip_buf=DHCP_MODE;
|
|
}
|
|
|
|
//IP
|
|
sIP = web_interface->WebServer.arg("IP");
|
|
if (!web_interface->isIPValid(sIP.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect IP fortmat<BR>"));
|
|
KeysList.add(FPSTR(KEY_AP_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//Gateway
|
|
sGW = web_interface->WebServer.arg("GATEWAY");
|
|
if (!web_interface->isIPValid(sGW.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect gateway<BR>"));
|
|
KeysList.add(FPSTR(KEY_AP_GW_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//subnet
|
|
sMask = web_interface->WebServer.arg("SUBNET");
|
|
if (!web_interface->isIPValid(sMask.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect subnet<BR>"));
|
|
KeysList.add(FPSTR(KEY_AP_SUBNET_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
|
|
//if no error apply the change
|
|
if (msg_alert_error==false) {
|
|
//save
|
|
wifi_config.split_ip(sIP.c_str(),ip_sav);
|
|
wifi_config.split_ip(sGW.c_str(),gw_sav);
|
|
wifi_config.split_ip(sMask.c_str(),msk_sav);
|
|
if((!CONFIG::write_byte(EP_WIFI_MODE,AP_MODE))||
|
|
(!CONFIG::write_string(EP_SSID,sSSID.c_str()))||
|
|
(!CONFIG::write_string(EP_PASSWORD,sPassword.c_str()))||
|
|
(!CONFIG::write_byte(EP_SSID_VISIBLE,visible_buf))||
|
|
(!CONFIG::write_byte(EP_PHY_MODE,phy_mode_buf))||
|
|
(!CONFIG::write_byte(EP_CHANNEL,channel_buf)) ||
|
|
(!CONFIG::write_byte(EP_AUTH_TYPE,auth_buf)) ||
|
|
(!CONFIG::write_byte(EP_IP_MODE,static_ip_buf)) ||
|
|
(!CONFIG::write_buffer(EP_IP_VALUE,ip_sav,IP_LENGTH))||
|
|
(!CONFIG::write_buffer(EP_GATEWAY_VALUE,gw_sav,IP_LENGTH))||
|
|
(!CONFIG::write_buffer(EP_MASK_VALUE,msk_sav,IP_LENGTH))) {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(EEPROM_NOWRITE);
|
|
} else {
|
|
msg_alert_success=true;
|
|
smsg = F("Changes saved to EEPROM, restarting...");
|
|
}
|
|
}
|
|
}
|
|
|
|
else { //no submit need to get data from EEPROM
|
|
//ssid
|
|
if (!CONFIG::read_string(EP_SSID, sSSID , MAX_SSID_LENGTH) ) {
|
|
sSSID=FPSTR(DEFAULT_SSID);
|
|
}
|
|
//password
|
|
if (!CONFIG::read_string(EP_PASSWORD, sPassword , MAX_PASSWORD_LENGTH) ) {
|
|
sPassword=FPSTR(DEFAULT_PASSWORD);
|
|
}
|
|
//ssid visible ?
|
|
if (!CONFIG::read_byte(EP_SSID_VISIBLE, &visible_buf )) {
|
|
visible_buf=DEFAULT_SSID_VISIBLE;
|
|
}
|
|
//phy mode
|
|
if (!CONFIG::read_byte(EP_PHY_MODE, &phy_mode_buf )) {
|
|
phy_mode_buf=DEFAULT_PHY_MODE;
|
|
}
|
|
//authentification
|
|
if (!CONFIG::read_byte(EP_AUTH_TYPE, &auth_buf )) {
|
|
auth_buf=DEFAULT_AUTH_TYPE;
|
|
}
|
|
//channel
|
|
if (!CONFIG::read_byte(EP_CHANNEL, &channel_buf )) {
|
|
channel_buf=DEFAULT_CHANNEL;
|
|
}
|
|
//static IP ?
|
|
if (!CONFIG::read_byte(EP_IP_MODE, &static_ip_buf )) {
|
|
static_ip_buf=DEFAULT_IP_MODE;
|
|
}
|
|
//IP for static IP
|
|
if (!CONFIG::read_buffer(EP_IP_VALUE,ip_sav , IP_LENGTH) ) {
|
|
sIP=IPAddress((const uint8_t *)DEFAULT_IP_VALUE).toString();
|
|
|
|
} else {
|
|
sIP=IPAddress((const uint8_t *)ip_sav).toString();
|
|
}
|
|
//GW for static IP
|
|
if (!CONFIG::read_buffer(EP_GATEWAY_VALUE,gw_sav , IP_LENGTH) ) {
|
|
sGW=IPAddress((const uint8_t *)DEFAULT_GATEWAY_VALUE).toString();
|
|
} else {
|
|
sGW=IPAddress((const uint8_t *)gw_sav).toString();
|
|
}
|
|
|
|
//Subnet for static IP
|
|
if (!CONFIG::read_buffer(EP_MASK_VALUE,msk_sav , IP_LENGTH) ) {
|
|
sMask=IPAddress((const uint8_t *)DEFAULT_MASK_VALUE).toString();
|
|
} else {
|
|
sMask=IPAddress((const uint8_t *)msk_sav).toString();
|
|
}
|
|
}
|
|
|
|
//Display values
|
|
|
|
//ssid
|
|
KeysList.add(FPSTR(KEY_AP_SSID));
|
|
ValuesList.add(sSSID);
|
|
|
|
//password
|
|
KeysList.add(FPSTR(KEY_AP_PASSWORD));
|
|
ValuesList.add(sPassword);
|
|
|
|
//ssid visible ?
|
|
KeysList.add(FPSTR(KEY_IS_SSID_VISIBLE));
|
|
if (visible_buf==1) {
|
|
ValuesList.add(FPSTR(VALUE_CHECKED));
|
|
} else {
|
|
ValuesList.add("");
|
|
}
|
|
|
|
//network
|
|
ipos = 0;
|
|
stmp="";
|
|
while (inetworkvaluelist[ipos]>-1) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+= intTostr(inetworkvaluelist[ipos]);
|
|
stmp+="\" ";
|
|
if (inetworkvaluelist[ipos]==phy_mode_buf) {
|
|
stmp+=FPSTR(VALUE_SELECTED);
|
|
}
|
|
stmp+=">" ;
|
|
stmp+=inetworkdisplaylist[ipos];
|
|
stmp+= "</OPTION>\n";
|
|
ipos++;
|
|
}
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST));
|
|
ValuesList.add(stmp);
|
|
|
|
//channel
|
|
stmp ="";
|
|
for (int c=1; c < 12; c++) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+=intTostr(c);
|
|
stmp+="\" ";
|
|
if (channel_buf==c) {
|
|
stmp += FPSTR(VALUE_SELECTED);
|
|
} else {
|
|
stmp+="";
|
|
}
|
|
stmp+=" >";
|
|
stmp+=intTostr(c);
|
|
stmp+= "</OPTION>\n";
|
|
}
|
|
|
|
KeysList.add(FPSTR(KEY_CHANNEL_OPTION_LIST));
|
|
ValuesList.add(stmp);
|
|
//auth
|
|
ipos = 0;
|
|
stmp="";
|
|
while (iauthvaluelist[ipos]>-1) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+= intTostr(iauthvaluelist[ipos]);
|
|
stmp+="\" ";
|
|
if (iauthvaluelist[ipos]==auth_buf) {
|
|
stmp+=FPSTR(VALUE_SELECTED);
|
|
}
|
|
stmp+=">" ;
|
|
stmp+=iauthdisplaylist[ipos];
|
|
stmp+= "</OPTION>\n";
|
|
ipos++;
|
|
}
|
|
KeysList.add(FPSTR(KEY_AUTH_OPTION_LIST));
|
|
ValuesList.add(stmp);
|
|
|
|
//static IP ?
|
|
KeysList.add(FPSTR(KEY_IS_STATIC_IP));
|
|
if (static_ip_buf==STATIC_IP_MODE) {
|
|
ValuesList.add(FPSTR(VALUE_CHECKED));
|
|
} else {
|
|
ValuesList.add("");
|
|
}
|
|
|
|
//IP for static IP
|
|
KeysList.add(FPSTR(KEY_AP_IP));
|
|
ValuesList.add(sIP);
|
|
|
|
//Gateway for static IP
|
|
KeysList.add(FPSTR(KEY_AP_GW));
|
|
ValuesList.add(sGW);
|
|
|
|
//Mask for static IP
|
|
KeysList.add(FPSTR(KEY_AP_SUBNET));
|
|
ValuesList.add(sMask);
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else if (msg_alert_success) {
|
|
ProcessAlertSuccess(KeysList, ValuesList, smsg);
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add(FPSTR(RESTARTCMD));
|
|
//Add all green
|
|
KeysList.add(FPSTR(KEY_AP_SSID_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AP_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_IS_SSID_VISIBLE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_CHANNEL_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AUTH_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AP_STATIC_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AP_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AP_GW_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_AP_SUBNET_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
ProcessNoAlert(KeysList,ValuesList);
|
|
}
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
//process the template file and provide list of variables
|
|
processTemplate("/config_ap.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_web_interface_configSTA()
|
|
{
|
|
static const char NOT_AUTH_STA [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=CONFIGSTA\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String stmp,smsg;
|
|
String sSSID,sPassword,sIP,sGW,sMask,sHostname;
|
|
bool msg_alert_error=false;
|
|
bool msg_alert_success=false;
|
|
byte static_ip_buf;
|
|
byte phy_mode_buf;
|
|
byte ip_sav[4];
|
|
byte gw_sav[4];
|
|
byte msk_sav[4];
|
|
bool revertSTA=false;
|
|
int ipos;
|
|
int inetworkvaluelist []= {WIFI_PHY_MODE_11B,WIFI_PHY_MODE_11G,WIFI_PHY_MODE_11N,-1};
|
|
const __FlashStringHelper * inetworkdisplaylist []= {FPSTR(VALUE_11B),FPSTR(VALUE_11G),FPSTR(VALUE_11N),FPSTR(VALUE_11B)};
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_STA);
|
|
return;
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_CONFIG_STA),F("config_sta"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_STA));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
smsg="";
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if (web_interface->WebServer.hasArg("SSID") && web_interface->WebServer.hasArg("PASSWORD")&& web_interface->WebServer.hasArg("NETWORK")
|
|
&& web_interface->WebServer.hasArg("IP") && web_interface->WebServer.hasArg("GATEWAY")&& web_interface->WebServer.hasArg("SUBNET")
|
|
&& web_interface->WebServer.hasArg("HOSTNAME")) {
|
|
//SSID
|
|
sSSID = web_interface->WebServer.arg("SSID");
|
|
if (!web_interface->isSSIDValid(sSSID.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect SSID<BR>"));
|
|
KeysList.add(FPSTR(KEY_STA_SSID_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//Password
|
|
sPassword = web_interface->WebServer.arg("PASSWORD");
|
|
if (!web_interface->isPasswordValid(sPassword.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect password<BR>"));
|
|
KeysList.add(FPSTR(KEY_STA_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//Hostname
|
|
sHostname = web_interface->WebServer.arg("HOSTNAME");
|
|
if (!web_interface->isHostnameValid(sHostname.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect hostname<BR>"));
|
|
KeysList.add(FPSTR(KEY_HOSTNAME_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//phy mode
|
|
phy_mode_buf = byte(web_interface->WebServer.arg("NETWORK").toInt());
|
|
if (!(phy_mode_buf==WIFI_PHY_MODE_11B||phy_mode_buf==WIFI_PHY_MODE_11G||phy_mode_buf==WIFI_PHY_MODE_11N) ) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect network<BR>"));
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//Static IP ?
|
|
if (web_interface->WebServer.hasArg("STATIC_IP") ) {
|
|
static_ip_buf=STATIC_IP_MODE;
|
|
} else {
|
|
static_ip_buf=DHCP_MODE;
|
|
}
|
|
|
|
//IP
|
|
sIP= web_interface->WebServer.arg("IP");
|
|
if (!web_interface->isIPValid(sIP.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect IP format<BR>"));
|
|
KeysList.add(FPSTR(KEY_STA_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
|
|
//Gateway
|
|
sGW = web_interface->WebServer.arg("GATEWAY");
|
|
if (!web_interface->isIPValid(sGW.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect gateway<BR>"));
|
|
KeysList.add(FPSTR(KEY_STA_GW_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//subnet
|
|
sMask = web_interface->WebServer.arg("SUBNET");
|
|
if (!web_interface->isIPValid(sMask.c_str())) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect subnet<BR>"));
|
|
KeysList.add(FPSTR(KEY_STA_SUBNET_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
|
|
//no error ? then save
|
|
if (msg_alert_error==false) {
|
|
//save
|
|
wifi_config.split_ip(sIP.c_str(),ip_sav);
|
|
wifi_config.split_ip(sGW.c_str(),gw_sav);
|
|
wifi_config.split_ip(sMask.c_str(),msk_sav);
|
|
if((!CONFIG::write_byte(EP_WIFI_MODE,CLIENT_MODE))||
|
|
(!CONFIG::write_string(EP_SSID,sSSID.c_str()))||
|
|
(!CONFIG::write_string(EP_PASSWORD,sPassword.c_str()))||
|
|
(!CONFIG::write_string(EP_HOSTNAME,sHostname.c_str()))||
|
|
(!CONFIG::write_byte(EP_PHY_MODE,phy_mode_buf))||
|
|
(!CONFIG::write_byte(EP_IP_MODE,static_ip_buf)) ||
|
|
(!CONFIG::write_buffer(EP_IP_VALUE,ip_sav,IP_LENGTH))||
|
|
(!CONFIG::write_buffer(EP_GATEWAY_VALUE,gw_sav,IP_LENGTH))||
|
|
(!CONFIG::write_buffer(EP_MASK_VALUE,msk_sav,IP_LENGTH))) {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(EEPROM_NOWRITE);
|
|
} else {
|
|
msg_alert_success=true;
|
|
smsg = F("Changes saved to EEPROM, restarting...");
|
|
}
|
|
}
|
|
} else { //no submit, need to get data from EEPROM
|
|
//ssid
|
|
if (!CONFIG::read_string(EP_SSID, sSSID , MAX_SSID_LENGTH) ) {
|
|
sSSID=FPSTR(DEFAULT_SSID);
|
|
}
|
|
//password
|
|
if (!CONFIG::read_string(EP_PASSWORD, sPassword , MAX_PASSWORD_LENGTH) ) {
|
|
sPassword=FPSTR(DEFAULT_PASSWORD);
|
|
}
|
|
//hostname
|
|
if (!CONFIG::read_string(EP_HOSTNAME, sHostname , MAX_HOSTNAME_LENGTH) ) {
|
|
sHostname=wifi_config.get_default_hostname();
|
|
}
|
|
//phy mode
|
|
if (!CONFIG::read_byte(EP_PHY_MODE, &phy_mode_buf )) {
|
|
phy_mode_buf=DEFAULT_PHY_MODE;
|
|
}
|
|
//static IP ?
|
|
if (!CONFIG::read_byte(EP_IP_MODE, &static_ip_buf )) {
|
|
static_ip_buf=DEFAULT_IP_MODE;
|
|
}
|
|
//IP for static IP
|
|
if (!CONFIG::read_buffer(EP_IP_VALUE,ip_sav , IP_LENGTH) ) {
|
|
sIP=IPAddress((const uint8_t *)DEFAULT_IP_VALUE).toString();
|
|
} else {
|
|
sIP=IPAddress((const uint8_t *)ip_sav).toString();
|
|
}
|
|
//GW for static IP
|
|
if (!CONFIG::read_buffer(EP_GATEWAY_VALUE,gw_sav , IP_LENGTH) ) {
|
|
sGW=IPAddress((const uint8_t *)DEFAULT_GATEWAY_VALUE).toString();
|
|
} else {
|
|
sGW=IPAddress((const uint8_t *)gw_sav).toString();
|
|
}
|
|
//Subnet for static IP
|
|
if (!CONFIG::read_buffer(EP_MASK_VALUE,msk_sav , IP_LENGTH) ) {
|
|
sMask=IPAddress((const uint8_t *)DEFAULT_MASK_VALUE).toString();
|
|
} else {
|
|
sMask=IPAddress((const uint8_t *)msk_sav).toString();
|
|
}
|
|
}
|
|
//Display values
|
|
//ssid
|
|
KeysList.add(FPSTR(KEY_STA_SSID));
|
|
ValuesList.add(sSSID);
|
|
|
|
//password
|
|
KeysList.add(FPSTR(KEY_STA_PASSWORD));
|
|
ValuesList.add(sPassword);
|
|
|
|
//hostname
|
|
KeysList.add(FPSTR(KEY_HOSTNAME));
|
|
ValuesList.add(sHostname);
|
|
|
|
//network
|
|
ipos = 0;
|
|
stmp="";
|
|
while (inetworkvaluelist[ipos]>-1) {
|
|
stmp+="<OPTION VALUE=\"";
|
|
stmp+= intTostr(inetworkvaluelist[ipos]);
|
|
stmp+="\" ";
|
|
if (inetworkvaluelist[ipos]==phy_mode_buf) {
|
|
stmp+=FPSTR(VALUE_SELECTED);
|
|
}
|
|
stmp+=">" ;
|
|
stmp+=inetworkdisplaylist[ipos];
|
|
stmp+= "</OPTION>\n";
|
|
ipos++;
|
|
}
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST));
|
|
ValuesList.add(stmp);
|
|
|
|
//static IP ?
|
|
KeysList.add(FPSTR(KEY_IS_STATIC_IP));
|
|
if (static_ip_buf==STATIC_IP_MODE) {
|
|
ValuesList.add(FPSTR(VALUE_CHECKED));
|
|
} else {
|
|
ValuesList.add("");
|
|
}
|
|
|
|
//IP for static IP
|
|
KeysList.add(FPSTR(KEY_STA_IP));
|
|
ValuesList.add(sIP);
|
|
|
|
//Gateway for static IP
|
|
KeysList.add(FPSTR(KEY_STA_GW));
|
|
ValuesList.add(sGW);
|
|
|
|
//Mask for static IP
|
|
KeysList.add(FPSTR(KEY_STA_SUBNET));
|
|
ValuesList.add(sMask);
|
|
|
|
//do we need to do a scan and display it ?
|
|
if (!msg_alert_success) {
|
|
//if in AP mode switch to mixed mode to be able to scan
|
|
if (WiFi.getMode()!=WIFI_STA ) {
|
|
WiFi.mode(WIFI_AP_STA);
|
|
revertSTA=true;
|
|
}
|
|
|
|
int n = WiFi.scanNetworks();
|
|
for (int i = 0; i < n; ++i) {
|
|
//row number
|
|
stmp = "$ROW_NUMBER["+String(i)+"]$";
|
|
KeysList.add(stmp);
|
|
stmp=String(i+1);
|
|
ValuesList.add(stmp);
|
|
//SSID
|
|
stmp = "$AP_SSID["+String(i)+"]$";
|
|
KeysList.add(stmp);
|
|
ValuesList.add(WiFi.SSID(i).c_str());
|
|
//signal strength
|
|
stmp = "$AP_SIGNAL["+String(i)+"]$";
|
|
KeysList.add(stmp);
|
|
stmp = intTostr(100+WiFi.RSSI(i)) ;
|
|
stmp += "%";
|
|
ValuesList.add(stmp);
|
|
//is protected
|
|
stmp = "$IS_PROTECTED["+String(i)+"]$";
|
|
KeysList.add(stmp);
|
|
if (WiFi.encryptionType(i) == ENC_TYPE_NONE) {
|
|
ValuesList.add(FPSTR(VALUE_NO));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_YES));
|
|
}
|
|
}
|
|
WiFi.scanDelete();
|
|
KeysList.add(FPSTR(KEY_AVAILABLE_AP_NB_ITEMS));
|
|
ValuesList.add(intTostr(n));
|
|
|
|
//revert to pure softAP
|
|
if (revertSTA) {
|
|
WiFi.mode(WIFI_AP);
|
|
}
|
|
KeysList.add(FPSTR(KEY_AP_SCAN_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
//no need to do a scan if we are going to restart
|
|
KeysList.add(FPSTR(KEY_AP_SCAN_VISIBILITY));
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
KeysList.add(FPSTR(KEY_AVAILABLE_AP_NB_ITEMS));
|
|
ValuesList.add(intTostr(0));
|
|
}
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else if (msg_alert_success) {
|
|
ProcessAlertSuccess(KeysList, ValuesList, smsg);
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add(FPSTR(RESTARTCMD));
|
|
//Add all green
|
|
KeysList.add(FPSTR(KEY_STA_SSID_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_STA_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_NETWORK_OPTION_LIST_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_STA_STATIC_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_STA_IP_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_STA_GW_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_STA_SUBNET_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_HOSTNAME_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
ProcessNoAlert(KeysList,ValuesList);
|
|
}
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
//process the template file and provide list of variables
|
|
processTemplate("/config_sta.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_web_interface_printer()
|
|
{
|
|
static const char NOT_AUTH_PRT [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=PRINTER\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_PRT);
|
|
return;
|
|
}
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_PRINTER),F("printer"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_PRINTER));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//Refresh page time
|
|
KeysList.add(FPSTR(KEY_REFRESH_PAGE));
|
|
byte bflag;
|
|
if (!CONFIG::read_byte(EP_REFRESH_PAGE_TIME, &bflag )) {
|
|
ValuesList.add(intTostr(DEFAULT_REFRESH_PAGE_TIME*1000));
|
|
} else {
|
|
ValuesList.add(intTostr(1000*bflag));
|
|
}
|
|
int istatus;
|
|
//xy feedrate
|
|
KeysList.add(FPSTR(KEY_XY_FEEDRATE));
|
|
if (!CONFIG::read_buffer(EP_XY_FEEDRATE, (byte *)&istatus , INTEGER_LENGTH)) {
|
|
istatus=DEFAULT_XY_FEEDRATE;
|
|
}
|
|
ValuesList.add(intTostr(istatus));
|
|
//Z feedrate
|
|
KeysList.add(FPSTR(KEY_Z_FEEDRATE));
|
|
if (!CONFIG::read_buffer(EP_Z_FEEDRATE, (byte *)&istatus , INTEGER_LENGTH)) {
|
|
istatus=DEFAULT_Z_FEEDRATE;
|
|
}
|
|
ValuesList.add(intTostr(istatus));
|
|
//E feedrate
|
|
KeysList.add(FPSTR(KEY_E_FEEDRATE));
|
|
if (!CONFIG::read_buffer(EP_E_FEEDRATE, (byte *)&istatus , INTEGER_LENGTH)) {
|
|
istatus=DEFAULT_E_FEEDRATE;
|
|
}
|
|
ValuesList.add(intTostr(istatus));
|
|
|
|
//Serial.println("M114");
|
|
Serial.println(F("M220"));
|
|
Serial.println(F("M221"));
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
processTemplate("/printer.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_web_settings()
|
|
{
|
|
static const char NOT_AUTH_SET [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=SETTINGS\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String smsg;
|
|
//int istatus;
|
|
//byte bbuf;
|
|
bool msg_alert_error=false;
|
|
bool msg_alert_success=false;
|
|
byte irefresh_page;
|
|
int ixy_feedrate,iz_feedrate,ie_feedrate;
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_SET);
|
|
return;
|
|
}
|
|
web_interface->blockserial = false;
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_SETTINGS),F("settings"));
|
|
//menu item
|
|
KeysList.add(FPSTR(KEY_MENU_SETTINGS));
|
|
ValuesList.add(FPSTR(VALUE_ACTIVE));
|
|
|
|
//check is it is a submission or a display
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if (web_interface->WebServer.hasArg("REFRESH_PAGE") && web_interface->WebServer.hasArg("XY_FEEDRATE")&& web_interface->WebServer.hasArg("Z_FEEDRATE")&& web_interface->WebServer.hasArg("E_FEEDRATE")) {
|
|
//is each value correct ?
|
|
irefresh_page = web_interface->WebServer.arg("REFRESH_PAGE").toInt();
|
|
ixy_feedrate = web_interface->WebServer.arg("XY_FEEDRATE").toInt();
|
|
iz_feedrate = web_interface->WebServer.arg("Z_FEEDRATE").toInt();
|
|
ie_feedrate = web_interface->WebServer.arg("E_FEEDRATE").toInt();
|
|
|
|
if (!(irefresh_page>1 && irefresh_page<120)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: invalid value for refresh time<BR>"));
|
|
KeysList.add(FPSTR(KEY_REFRESH_PAGE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (!(ixy_feedrate>0 && ixy_feedrate<9999)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: invalid value for XY axis feedrate<BR>"));
|
|
KeysList.add(FPSTR(KEY_XY_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (!(iz_feedrate>0 && iz_feedrate<9999)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: invalid value for Z axis feedrate<BR>"));
|
|
KeysList.add(FPSTR(KEY_Z_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
if (!(ie_feedrate>0 && ie_feedrate<9999)) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: invalid value for Extruder feedrate<BR>"));
|
|
KeysList.add(FPSTR(KEY_XY_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
//if no error apply the changes
|
|
if (msg_alert_error!=true) {
|
|
if(!CONFIG::write_buffer(EP_XY_FEEDRATE,(const byte *)&ixy_feedrate,INTEGER_LENGTH)||!CONFIG::write_buffer(EP_Z_FEEDRATE,(const byte *)&iz_feedrate,INTEGER_LENGTH)||!CONFIG::write_buffer(EP_E_FEEDRATE,(const byte *)&ie_feedrate,INTEGER_LENGTH)||!CONFIG::write_byte(EP_REFRESH_PAGE_TIME,irefresh_page)) {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(EEPROM_NOWRITE);
|
|
} else {
|
|
msg_alert_success=true;
|
|
smsg = F("Changes saved to EEPROM");
|
|
}
|
|
}
|
|
} else { //no submit need to get data from EEPROM
|
|
if (!CONFIG::read_buffer(EP_XY_FEEDRATE, (byte *)&ixy_feedrate , INTEGER_LENGTH)) {
|
|
ixy_feedrate=DEFAULT_XY_FEEDRATE;
|
|
}
|
|
if (!CONFIG::read_byte(EP_REFRESH_PAGE_TIME, &irefresh_page )) {
|
|
irefresh_page=DEFAULT_REFRESH_PAGE_TIME;
|
|
}
|
|
if (!CONFIG::read_buffer(EP_Z_FEEDRATE, (byte *)&iz_feedrate , INTEGER_LENGTH)) {
|
|
iz_feedrate=DEFAULT_Z_FEEDRATE;
|
|
}
|
|
if (!CONFIG::read_buffer(EP_E_FEEDRATE, (byte *)&ie_feedrate , INTEGER_LENGTH)) {
|
|
ie_feedrate=DEFAULT_E_FEEDRATE;
|
|
}
|
|
}
|
|
//fill the variables
|
|
//refresh page
|
|
KeysList.add(FPSTR(KEY_REFRESH_PAGE));
|
|
ValuesList.add(intTostr(irefresh_page));
|
|
//xy feedrate
|
|
KeysList.add(FPSTR(KEY_XY_FEEDRATE));
|
|
ValuesList.add(intTostr(ixy_feedrate));
|
|
//Z feedrate
|
|
KeysList.add(FPSTR(KEY_Z_FEEDRATE));
|
|
ValuesList.add(intTostr(iz_feedrate));
|
|
//E feedrate
|
|
KeysList.add(FPSTR(KEY_E_FEEDRATE));
|
|
ValuesList.add(intTostr(ie_feedrate));
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else if (msg_alert_success) {
|
|
ProcessAlertSuccess(KeysList, ValuesList, smsg);
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
KeysList.add(FPSTR(KEY_REFRESH_PAGE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_XY_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_Z_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_E_FEEDRATE_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_SUCCESS));
|
|
KeysList.add(FPSTR(KEY_SERVICE_PAGE));
|
|
ValuesList.add("");
|
|
}
|
|
|
|
else {
|
|
ProcessNoAlert(KeysList,ValuesList);
|
|
}
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/settings.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_web_interface_status()
|
|
{
|
|
static const char NO_TEMP_LINE[] PROGMEM = "\"temperature\":\"0\",\"target\":\"0\",\"active\":\"0\"";
|
|
web_interface->is_authenticated();
|
|
Serial.println(F("M114"));
|
|
int tagpos,tagpos2;
|
|
String buffer2send;
|
|
String value;
|
|
//int temperature,target;
|
|
|
|
//request temperature only if no feedback
|
|
if ((millis()-web_interface->last_temp)>120000) {
|
|
Serial.println(F("M105"));
|
|
}
|
|
|
|
if ((millis()-web_interface->last_temp)<180000) {
|
|
value="Connected";
|
|
} else if ((millis()-web_interface->last_temp)<200000) {
|
|
value="Busy";
|
|
} else {
|
|
value="Offline";
|
|
}
|
|
|
|
//start JSON answer
|
|
buffer2send="{";
|
|
//status color
|
|
buffer2send+="\"status\":\""+value +"\",";
|
|
//speed
|
|
buffer2send+="\"speed\":\""+web_interface->answer4M220 +"\",";
|
|
//flow
|
|
buffer2send+="\"flow\":\""+web_interface->answer4M221 +"\",";
|
|
//X position
|
|
tagpos = web_interface->answer4M114.indexOf("X:");
|
|
tagpos2 = web_interface->answer4M114.indexOf(" ",tagpos);
|
|
value=web_interface->answer4M114.substring(tagpos+2,tagpos2);
|
|
buffer2send+="\"Xpos\":\""+value +"\",";
|
|
//Y position
|
|
tagpos = web_interface->answer4M114.indexOf("Y:");
|
|
tagpos2 = web_interface->answer4M114.indexOf(" ",tagpos);
|
|
value=web_interface->answer4M114.substring(tagpos+2,tagpos2);
|
|
buffer2send+="\"Ypos\":\""+value +"\",";
|
|
//Z position
|
|
tagpos = web_interface->answer4M114.indexOf("Z:");
|
|
tagpos2 = web_interface->answer4M114.indexOf(" ",tagpos);
|
|
value=web_interface->answer4M114.substring(tagpos+2,tagpos2);
|
|
buffer2send+="\"Zpos\":\""+value +"\",";
|
|
//heater
|
|
buffer2send.concat(F("\"heater\":["));
|
|
//Extruder 1
|
|
buffer2send.concat(F("{\"name\":\"Extruder 1\","));
|
|
int Tpos = web_interface->answer4M105.indexOf("T0:");
|
|
byte bshift=1;
|
|
if (Tpos==-1) {
|
|
Tpos = web_interface->answer4M105.indexOf("T:");
|
|
bshift=0;
|
|
}
|
|
int slashpos = web_interface->answer4M105.indexOf(" /",Tpos);
|
|
int spacepos = web_interface->answer4M105.indexOf(" ",slashpos+2);
|
|
//have Extruder 1 ?
|
|
if(slashpos!=-1 && spacepos!=-1 ) {
|
|
buffer2send += "\"temperature\":\""+web_interface->answer4M105.substring(Tpos+2+bshift,slashpos)+
|
|
"\",\"target\":\""+web_interface->answer4M105.substring(slashpos+2,spacepos)+"\",\"active\":\"1\"";
|
|
} else { //no extruder temperature
|
|
buffer2send.concat(FPSTR(NO_TEMP_LINE));
|
|
}
|
|
|
|
buffer2send+="},";
|
|
//Extruder 2
|
|
buffer2send.concat(F("{\"name\":\"Extruder 2\","));
|
|
Tpos = web_interface->answer4M105.indexOf("T1:");
|
|
if (Tpos>-1) { //have extruder 2 ?
|
|
slashpos = web_interface->answer4M105.indexOf(" /",Tpos);
|
|
spacepos = web_interface->answer4M105.indexOf(" ",slashpos+2);
|
|
if(slashpos!=-1 && spacepos!=-1 ) {
|
|
buffer2send += "\"temperature\":\""+web_interface->answer4M105.substring(Tpos+3,slashpos)+
|
|
"\",\"target\":\""+web_interface->answer4M105.substring(slashpos+2,spacepos)+"\",\"active\":\"1\"";
|
|
} else { //no extruder temperature
|
|
buffer2send.concat(FPSTR(NO_TEMP_LINE));
|
|
}
|
|
} else { //no extruder temperature
|
|
buffer2send.concat(FPSTR(NO_TEMP_LINE));
|
|
}
|
|
buffer2send+="},";
|
|
|
|
//Bed
|
|
buffer2send.concat(F("{\"name\":\"Bed\","));
|
|
Tpos = web_interface->answer4M105.indexOf("B:");
|
|
if (Tpos>-1) {
|
|
slashpos = web_interface->answer4M105.indexOf(" /",Tpos);
|
|
spacepos = web_interface->answer4M105.indexOf(" ",slashpos+2);
|
|
if(slashpos!=-1 && spacepos!=-1 ) {
|
|
//temperature = (int)atof(web_interface->answer4M105.substring(Tpos+2,slashpos).c_str());
|
|
//target = (int)atof(web_interface->answer4M105.substring(slashpos+2,spacepos).c_str());
|
|
buffer2send += "\"temperature\":\""+web_interface->answer4M105.substring(Tpos+2,slashpos)+
|
|
"\",\"target\":\""+web_interface->answer4M105.substring(slashpos+2,spacepos)+"\",\"active\":\"1\"";
|
|
} else { //no extruder temperature
|
|
buffer2send.concat(FPSTR(NO_TEMP_LINE));
|
|
}
|
|
} else { //no extruder temperature
|
|
buffer2send.concat(FPSTR(NO_TEMP_LINE));
|
|
}
|
|
buffer2send+="}";
|
|
buffer2send+="],";
|
|
|
|
//information
|
|
buffer2send.concat(F("\"InformationMsg\":["));
|
|
for (int i=0; i<web_interface->info_msg.size(); i++) {
|
|
if (i>0) {
|
|
buffer2send+=",";
|
|
}
|
|
buffer2send+="{\"line\":\"";
|
|
buffer2send+=web_interface->info_msg.get(i);
|
|
buffer2send+="\"}";
|
|
}
|
|
buffer2send+="],";
|
|
//Error
|
|
buffer2send.concat(F("\"ErrorMsg\":["));
|
|
for (int i=0; i<web_interface->error_msg.size(); i++) {
|
|
if (i>0) {
|
|
buffer2send+=",";
|
|
}
|
|
buffer2send+="{\"line\":\"";
|
|
buffer2send+=web_interface->error_msg.get(i);
|
|
buffer2send+="\"}";
|
|
}
|
|
buffer2send+="],";
|
|
//Status
|
|
buffer2send.concat(F("\"StatusMsg\":["));
|
|
for (int i=0; i<web_interface->status_msg.size(); i++) {
|
|
if (i>0) {
|
|
buffer2send+=",";
|
|
}
|
|
buffer2send+="{\"line\":\"";
|
|
buffer2send+=web_interface->status_msg.get(i);
|
|
buffer2send+="\"}";
|
|
}
|
|
buffer2send+="]";
|
|
buffer2send+="}";
|
|
web_interface->WebServer.sendHeader("Cache-Control", "no-cache");
|
|
web_interface->WebServer.send(200, "application/json",buffer2send);
|
|
}
|
|
|
|
String formatBytes(size_t bytes)
|
|
{
|
|
if (bytes < 1024) {
|
|
return String(bytes)+" B";
|
|
} else if(bytes < (1024 * 1024)) {
|
|
return String(bytes/1024.0)+" KB";
|
|
} else if(bytes < (1024 * 1024 * 1024)) {
|
|
return String(bytes/1024.0/1024.0)+" MB";
|
|
} else {
|
|
return String(bytes/1024.0/1024.0/1024.0)+" GB";
|
|
}
|
|
}
|
|
|
|
String getContentType(String filename)
|
|
{
|
|
if(filename.endsWith(".htm")) {
|
|
return "text/html";
|
|
} else if(filename.endsWith(".html")) {
|
|
return "text/html";
|
|
} else if(filename.endsWith(".css")) {
|
|
return "text/css";
|
|
} else if(filename.endsWith(".js")) {
|
|
return "application/javascript";
|
|
} else if(filename.endsWith(".png")) {
|
|
return "image/png";
|
|
} else if(filename.endsWith(".gif")) {
|
|
return "image/gif";
|
|
} else if(filename.endsWith(".jpg")) {
|
|
return "image/jpeg";
|
|
} else if(filename.endsWith(".ico")) {
|
|
return "image/x-icon";
|
|
} else if(filename.endsWith(".xml")) {
|
|
return "text/xml";
|
|
} else if(filename.endsWith(".pdf")) {
|
|
return "application/x-pdf";
|
|
} else if(filename.endsWith(".zip")) {
|
|
return "application/x-zip";
|
|
} else if(filename.endsWith(".gz")) {
|
|
return "application/x-gzip";
|
|
} else if(filename.endsWith(".tpl")) {
|
|
return "text/plain";
|
|
} else if(filename.endsWith(".inc")) {
|
|
return "text/plain";
|
|
} else if(filename.endsWith(".txt")) {
|
|
return "text/plain";
|
|
}
|
|
return "application/octet-stream";
|
|
}
|
|
|
|
void SPIFFSFileupload()
|
|
{
|
|
HTTPUpload& upload = (web_interface->WebServer).upload();
|
|
if(upload.status == UPLOAD_FILE_START) {
|
|
String filename = upload.filename;
|
|
Serial.println("M117 Start ESP upload");
|
|
web_interface->fsUploadFile = SPIFFS.open(filename, "w");
|
|
filename = String();
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
if(web_interface->fsUploadFile) {
|
|
web_interface->fsUploadFile.write(upload.buf, upload.currentSize);
|
|
}
|
|
} else if(upload.status == UPLOAD_FILE_END) {
|
|
web_interface->_upload_status=UPLOAD_STATUS_SUCCESSFUL;
|
|
Serial.println("M117 End ESP upload");
|
|
if(web_interface->fsUploadFile) {
|
|
web_interface->fsUploadFile.close();
|
|
}
|
|
} else {
|
|
web_interface->_upload_status=UPLOAD_STATUS_CANCELLED;
|
|
Serial.println("M117 Error ESP upload");
|
|
}
|
|
delay(0);
|
|
}
|
|
#define NB_RETRY 5
|
|
#define MAX_RESEND_BUFFER 128
|
|
|
|
void SDFileupload()
|
|
{
|
|
static char buffer_line[MAX_RESEND_BUFFER]; //if need to resend
|
|
static char previous = 0;
|
|
static int buffer_size;
|
|
static bool com_error = false;
|
|
static bool is_comment = false;
|
|
String response;
|
|
//upload can be long so better to reset time out
|
|
web_interface->is_authenticated();
|
|
HTTPUpload& upload = (web_interface->WebServer).upload();
|
|
//upload start
|
|
if(upload.status == UPLOAD_FILE_START) {
|
|
//need to lock serial out to avoid garbage in file
|
|
(web_interface->blockserial) = true;
|
|
//init flags
|
|
buffer_size=0;
|
|
com_error = false;
|
|
is_comment = false;
|
|
previous = 0;
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
Serial.println("M117 Uploading...");
|
|
LOG(String(upload.filename));
|
|
LOG("\n");
|
|
//command to pritnter to start print
|
|
String filename = "M28 " + upload.filename;
|
|
Serial.println(filename);
|
|
Serial.flush();
|
|
//now need to purge all serial data
|
|
//let's sleep 1s
|
|
delay(1000);
|
|
for (int retry=0;retry < 400; retry++) { //time out is 5x400ms = 2000ms
|
|
//if there is something in serial buffer
|
|
if(Serial.available()){
|
|
//get size of buffer
|
|
size_t len = Serial.available();
|
|
uint8_t sbuf[len+1];
|
|
//read buffer
|
|
Serial.readBytes(sbuf, len);
|
|
//convert buffer to zero end array
|
|
sbuf[len]='\0';
|
|
//use string because easier to handle
|
|
response = (const char*)sbuf;
|
|
//if there is a wait it means purge is done
|
|
if (response.indexOf("wait")>-1)break;
|
|
}
|
|
delay(5);
|
|
}
|
|
//upload is on going with data coming by 2K blocks
|
|
} else if((upload.status == UPLOAD_FILE_WRITE) && (com_error == false)){//if com error no need to send more data to serial
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
for (int pos = 0; pos < upload.currentSize;pos++) //parse full post data
|
|
{
|
|
if (buffer_size < MAX_RESEND_BUFFER-1) //raise error/handle if overbuffer - copy is space available
|
|
{
|
|
//remove/ignore every comment to save transfert time and avoid over buffer issues
|
|
if (upload.buf[pos] == ';'){
|
|
is_comment = true;
|
|
previous = ';';
|
|
}
|
|
if (!is_comment){
|
|
buffer_line[buffer_size] = upload.buf[pos]; //copy current char to buffer to send/resend
|
|
buffer_size++;
|
|
//convert buffer to zero end array
|
|
buffer_line[buffer_size] = '\0';
|
|
//check it is not an end line char and line is not empty
|
|
if (((buffer_line[0] == '\n') && (buffer_size==1)) ||((buffer_line[1] == '\n') && (buffer_line[0] == '\r') && (buffer_size==2)) || ((buffer_line[0] == ' ') && (buffer_size==1)) )
|
|
{
|
|
//ignore empty line
|
|
buffer_size=0;
|
|
buffer_line[buffer_size] = '\0';
|
|
}
|
|
//line is not empty so check if last char is an end line
|
|
//if error no need to proceed
|
|
else if (((buffer_line[buffer_size-1] == '\n')) && (com_error == false)) //end of line and no error
|
|
{
|
|
//if resend use buffer
|
|
bool success = false;
|
|
|
|
//check NB_RETRY times if get no error when send line
|
|
for (int r = 0 ; r < NB_RETRY ; r++)
|
|
{
|
|
response = "";
|
|
//print out line
|
|
Serial.print(buffer_line);
|
|
LOG(buffer_line);
|
|
//ensure buffer is empty before continuing
|
|
Serial.flush();
|
|
//wait for answer with time out
|
|
for (int retry=0;retry < 30; retry++) { //time out 30x5ms = 150ms
|
|
//if there is serial data
|
|
if(Serial.available()){
|
|
//get size of available data
|
|
size_t len = Serial.available();
|
|
uint8_t sbuf[len+1];
|
|
//read serial buffer
|
|
Serial.readBytes(sbuf, len);
|
|
//convert buffer in zero end array
|
|
sbuf[len]='\0';
|
|
//use string because easier
|
|
response = (const char*)sbuf;
|
|
LOG("Retry:");
|
|
LOG(String(retry));
|
|
LOG("\n");
|
|
LOG(response);
|
|
//if buffer contain ok or wait - it means command is pass
|
|
if ((response.indexOf("wait")>-1)||(response.indexOf("ok")>-1)){
|
|
success = true;
|
|
break;
|
|
}
|
|
//if buffer contain resend then need to resend
|
|
if (response.indexOf("Resend") > -1){//if error
|
|
success = false;
|
|
break;
|
|
}
|
|
}
|
|
delay(5);
|
|
}
|
|
//if command is pass no need to retry
|
|
if (success == true)break;
|
|
//purge extra serial if any
|
|
if(Serial.available()){
|
|
//get size of available data
|
|
size_t len = Serial.available();
|
|
uint8_t sbuf[len+1];
|
|
//read serial buffer
|
|
Serial.readBytes(sbuf, len);
|
|
//convert buffer in zero end array
|
|
sbuf[len]='\0';
|
|
}
|
|
}
|
|
//if even after the number of retry still have error - then we are in error
|
|
if (!success){
|
|
//raise error
|
|
LOG("Error detected\n");
|
|
LOG(response);
|
|
com_error = true;
|
|
}
|
|
//reset buffer for next command
|
|
buffer_size = 0;
|
|
buffer_line[buffer_size] = '\0';
|
|
}
|
|
}
|
|
else { //it is a comment
|
|
if (upload.buf[pos] == '\r'){ //store if CR
|
|
previous = '\r';
|
|
}
|
|
else if (upload.buf[pos] == '\n'){ //this is the end of the comment
|
|
is_comment = false;
|
|
if (buffer_size > 0) {
|
|
if (previous == '\r') pos--;
|
|
pos--; //do a loop back and process as normal
|
|
}
|
|
previous = '\n';
|
|
}//if not just ignore and continue
|
|
else previous = upload.buf[pos];
|
|
|
|
}
|
|
}
|
|
else //raise error
|
|
{
|
|
LOG("\nlong line detected\n");
|
|
LOG(buffer_line);
|
|
com_error = true;
|
|
}
|
|
}
|
|
} else if(upload.status == UPLOAD_FILE_END) {
|
|
if (buffer_size > 0){//if last part does not have '\n'
|
|
//print the line
|
|
Serial.print(buffer_line);
|
|
if (is_comment && (previous == '\r'))Serial.print("\r\n");
|
|
else Serial.print("\n");
|
|
Serial.flush();
|
|
//if resend use buffer
|
|
bool success = false;
|
|
//check NB_RETRY times if get no error when send line
|
|
for (int r = 0 ; r < NB_RETRY ; r++)
|
|
{
|
|
response = "";
|
|
Serial.print(buffer_line);
|
|
Serial.flush();
|
|
//wait for answer with time out
|
|
for (int retry=0;retry < 20; retry++) { //time out
|
|
if(Serial.available()){
|
|
size_t len = Serial.available();
|
|
uint8_t sbuf[len+1];
|
|
Serial.readBytes(sbuf, len);
|
|
sbuf[len]='\0';
|
|
response = (const char*)sbuf;
|
|
if ((response.indexOf("wait")>-1)||(response.indexOf("ok")>-1)){
|
|
success = true;
|
|
break;
|
|
}
|
|
if (response.indexOf("Resend") > -1){//if error
|
|
success = false;
|
|
break;
|
|
}
|
|
}
|
|
delay(5);
|
|
}
|
|
if (success == true)break;
|
|
}
|
|
if (!success){
|
|
//raise error
|
|
LOG("Error detected 2\n");
|
|
LOG(response);
|
|
com_error = true;
|
|
}
|
|
//reset buffer for next command
|
|
buffer_size = 0;
|
|
buffer_line[buffer_size] = '\0';
|
|
|
|
}
|
|
LOG("Upload finished ");
|
|
buffer_size=0;
|
|
buffer_line[buffer_size] = '\0';
|
|
//send M29 command to close file on SD
|
|
Serial.print("\r\nM29\r\n");
|
|
Serial.flush();
|
|
web_interface->blockserial = false;
|
|
delay(1000);//give time to FW
|
|
//resend M29 command to close file on SD as first command may be lost
|
|
Serial.print("\r\nM29\r\n");
|
|
Serial.flush();
|
|
if (com_error){
|
|
LOG("with error\n");
|
|
web_interface->_upload_status=UPLOAD_STATUS_CANCELLED;
|
|
Serial.println("M117 SD upload failed");
|
|
Serial.flush();
|
|
}
|
|
else
|
|
{
|
|
LOG("with success\n");
|
|
web_interface->_upload_status=UPLOAD_STATUS_SUCCESSFUL;
|
|
Serial.println("M117 SD upload done");
|
|
Serial.flush();
|
|
}
|
|
} else { //UPLOAD_FILE_ABORTED
|
|
LOG("Error, Something happened\n");
|
|
com_error = true;
|
|
web_interface->_upload_status=UPLOAD_STATUS_CANCELLED;
|
|
buffer_size=0;
|
|
buffer_line[buffer_size] = '\0';
|
|
//send M29 command to close file on SD
|
|
Serial.print("\r\nM29\r\n");
|
|
Serial.flush();
|
|
web_interface->blockserial = false;
|
|
delay(1000);
|
|
//resend M29 command to close file on SD as first command may be lost
|
|
Serial.print("\r\nM29\r\n");
|
|
Serial.flush();
|
|
Serial.println("M117 SD upload failed");
|
|
Serial.flush();
|
|
}
|
|
delay(0);
|
|
}
|
|
|
|
#ifdef WEB_UPDATE_FEATURE
|
|
void WebUpdateUpload()
|
|
{
|
|
HTTPUpload& upload = (web_interface->WebServer).upload();
|
|
if(upload.status == UPLOAD_FILE_START) {
|
|
Serial.println(F("M117 Update Firmware"));
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
WiFiUDP::stopAll();
|
|
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
|
if(!Update.begin(maxSketchSpace)) { //start with max available size
|
|
}
|
|
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
|
web_interface->_upload_status= UPLOAD_STATUS_ONGOING;
|
|
if(Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
|
}
|
|
} else if(upload.status == UPLOAD_FILE_END) {
|
|
if(Update.end(true)) { //true to set the size to the current progress
|
|
//Now Reboot
|
|
web_interface->_upload_status=UPLOAD_STATUS_SUCCESSFUL;
|
|
}
|
|
} else if(upload.status == UPLOAD_FILE_ABORTED) {
|
|
Update.end();
|
|
web_interface->_upload_status=UPLOAD_STATUS_CANCELLED;
|
|
}
|
|
delay(0);
|
|
}
|
|
|
|
void handleUpdate()
|
|
{
|
|
web_interface->is_authenticated();
|
|
String jsonfile = "{\"status\":\"" ;
|
|
jsonfile+=intTostr(web_interface->_upload_status);
|
|
jsonfile+="\"}";
|
|
//send status
|
|
web_interface->WebServer.sendHeader("Cache-Control", "no-cache");
|
|
web_interface->WebServer.send(200, "application/json", jsonfile);
|
|
//if success restart
|
|
if (web_interface->_upload_status==UPLOAD_STATUS_SUCCESSFUL) {
|
|
web_interface->restartmodule=true;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void handleFileList()
|
|
{
|
|
if (!web_interface->is_authenticated()) {
|
|
return;
|
|
}
|
|
String path = "/";
|
|
String status="Ok";
|
|
|
|
if(web_interface->WebServer.hasArg("action")) {
|
|
if(web_interface->WebServer.arg("action")=="delete" && web_interface->WebServer.hasArg("filename")) {
|
|
String filename;
|
|
filename = web_interface->WebServer.arg("filename");
|
|
if(!SPIFFS.exists(filename)) {
|
|
status="Cannot delete, file not found!";
|
|
} else {
|
|
SPIFFS.remove(filename);
|
|
}
|
|
}
|
|
}
|
|
String jsonfile = "{\"path\":\"" + path + "\",";
|
|
Dir dir = SPIFFS.openDir(path);
|
|
jsonfile+="\"files\":[";
|
|
bool firstentry=true;
|
|
while (dir.next()) {
|
|
if (!firstentry) {
|
|
jsonfile+=",";
|
|
} else {
|
|
firstentry=false;
|
|
}
|
|
jsonfile+="{";
|
|
jsonfile+="\"name\":\"";
|
|
jsonfile+=dir.fileName();
|
|
jsonfile+="\",\"size\":\"";
|
|
File f = dir.openFile("r");
|
|
jsonfile+=formatBytes(f.size());
|
|
jsonfile+="\"";
|
|
jsonfile+="}";
|
|
f.close();
|
|
}
|
|
jsonfile+="],";
|
|
jsonfile+="\"status\":\"" + status + "\",";
|
|
FSInfo info;
|
|
SPIFFS.info(info);
|
|
jsonfile+="\"total\":\"" + formatBytes(info.totalBytes) + "\",";
|
|
jsonfile+="\"used\":\"" + formatBytes(info.usedBytes) + "\",";
|
|
jsonfile.concat(F("\"occupation\":\""));
|
|
jsonfile+= intTostr(100*info.usedBytes/info.totalBytes);
|
|
jsonfile+="\"";
|
|
jsonfile+="}";
|
|
path = "";
|
|
web_interface->WebServer.sendHeader("Cache-Control", "no-cache");
|
|
web_interface->WebServer.send(200, "application/json", jsonfile);
|
|
}
|
|
|
|
void handleSDFileList()
|
|
{
|
|
if (!web_interface->is_authenticated()) {
|
|
return;
|
|
}
|
|
String jsonfile = "{\"status\":\"" ;
|
|
//if action is processing do not build list
|
|
if ((web_interface->blockserial)){
|
|
LOG("Wait, blocking\n");
|
|
jsonfile+="processing\"}";
|
|
}
|
|
else{
|
|
jsonfile+="Ok\",\"file\":[";
|
|
LOG("No Blocking \n");
|
|
LOG("JSON File\n");
|
|
LOG(String(web_interface->fileslist.size()));
|
|
LOG(" entries\n");
|
|
for (int i=0; i<web_interface->fileslist.size(); i++) {
|
|
if (i>0) {
|
|
jsonfile+=",";
|
|
}
|
|
jsonfile+="{\"entry\":\"";
|
|
jsonfile+=web_interface->fileslist.get(i);
|
|
LOG(String(i+1));
|
|
LOG(web_interface->fileslist.get(i));
|
|
LOG("\n");
|
|
jsonfile+="\"}";
|
|
}
|
|
jsonfile+="]}";
|
|
LOG("JSON done\n");
|
|
}
|
|
|
|
web_interface->WebServer.sendHeader("Cache-Control", "no-cache");
|
|
web_interface->WebServer.send(200, "application/json", jsonfile);
|
|
web_interface->blockserial = false;
|
|
}
|
|
|
|
//do a redirect to avoid to many query
|
|
//and handle not registred path
|
|
void handle_not_found()
|
|
{
|
|
static const char NOT_AUTH_NF [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /HOME\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
if (!web_interface->is_authenticated()) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_NF);
|
|
return;
|
|
}
|
|
|
|
String path = web_interface->WebServer.uri();
|
|
String contentType = getContentType(path);
|
|
String pathWithGz = path + ".gz";
|
|
if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) {
|
|
if(SPIFFS.exists(pathWithGz)) {
|
|
path = pathWithGz;
|
|
}
|
|
File file = SPIFFS.open(path, "r");
|
|
web_interface->WebServer.streamFile(file, contentType);
|
|
file.close();
|
|
} else {
|
|
if (SPIFFS.exists("/404.tpl")) {
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
String stmp;
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,F("404 Page not found"),F("404"));
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/404.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
} else {
|
|
//if not template use default page
|
|
contentType=FPSTR(PAGE_404);
|
|
String stmp;
|
|
if (WiFi.getMode()==WIFI_STA ) {
|
|
stmp=WiFi.localIP().toString();
|
|
} else {
|
|
stmp=WiFi.softAPIP().toString();
|
|
}
|
|
//Web address = ip + port
|
|
String KEY_IP = FPSTR(KEY_WEB_ADDRESS);
|
|
if (wifi_config.iweb_port!=80) {
|
|
stmp+=":";
|
|
stmp+=intTostr(wifi_config.iweb_port);
|
|
}
|
|
contentType.replace(KEY_IP,stmp);
|
|
web_interface->WebServer.send(200,"text/html",contentType);
|
|
}
|
|
}
|
|
}
|
|
|
|
void handle_login()
|
|
{
|
|
static const char NOT_AUTH_LOG [] PROGMEM = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=0\r\nLocation: /LOGIN\r\nCache-Control: no-cache\r\n\r\n";
|
|
|
|
String smsg;
|
|
String sReturn;
|
|
String sUser,sPassword;
|
|
bool msg_alert_error=false;
|
|
//bool msg_alert_success=false;
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
if (web_interface->WebServer.hasArg("DISCONNECT")) {
|
|
web_interface->WebServer.sendContent_P(NOT_AUTH_LOG);
|
|
return;
|
|
}
|
|
|
|
//check is it is a submission or a display
|
|
smsg="";
|
|
if (web_interface->WebServer.hasArg("return")) {
|
|
sReturn = web_interface->WebServer.arg("return");
|
|
}
|
|
if (web_interface->WebServer.hasArg("SUBMIT")) {
|
|
//is there a correct list of values?
|
|
if ( web_interface->WebServer.hasArg("PASSWORD")&& web_interface->WebServer.hasArg("USER")) {
|
|
//USER
|
|
sUser = web_interface->WebServer.arg("USER");
|
|
#ifdef AUTHENTICATION_FEATURE
|
|
if (sUser!="admin") {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error : Incorrect User<BR>"));
|
|
KeysList.add(FPSTR(KEY_USER_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
//Password
|
|
sPassword = web_interface->WebServer.arg("PASSWORD");
|
|
String scurrentPassword;
|
|
|
|
if (!CONFIG::read_string(EP_ADMIN_PWD, scurrentPassword , MAX_ADMIN_PASSWORD_LENGTH)) {
|
|
scurrentPassword=FPSTR(DEFAULT_ADMIN);
|
|
}
|
|
|
|
if (strcmp(sPassword.c_str(),scurrentPassword.c_str())!=0) {
|
|
msg_alert_error=true;
|
|
smsg.concat(F("Error: Incorrect password<BR>"));
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD_STATUS));
|
|
ValuesList.add(FPSTR(VALUE_HAS_ERROR));
|
|
}
|
|
#endif
|
|
} else {
|
|
msg_alert_error=true;
|
|
smsg = FPSTR(MISSING_DATA);
|
|
}
|
|
|
|
//if no error login is ok
|
|
if (msg_alert_error==false) {
|
|
#ifdef AUTHENTICATION_FEATURE
|
|
auth_ip * current_auth = new auth_ip;
|
|
current_auth->ip=web_interface->WebServer.client().remoteIP();
|
|
strcpy(current_auth->sessionID,web_interface->create_session_ID());
|
|
current_auth->last_time=millis();
|
|
if (web_interface->AddAuthIP(current_auth)) {
|
|
String header = F("HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=");
|
|
header+=current_auth->sessionID;
|
|
header+="\r\nLocation: /";
|
|
header+=sReturn;
|
|
header.concat(F("\r\nCache-Control: no-cache\r\n\r\n"));
|
|
web_interface->WebServer.sendContent(header);
|
|
return;
|
|
} else {
|
|
delete current_auth;
|
|
msg_alert_error=true;
|
|
smsg = F("Error: Too many connections");
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
else { //no submit need to get data from EEPROM
|
|
sUser=String();
|
|
//password
|
|
sPassword=String();
|
|
}
|
|
|
|
//Display values
|
|
KeysList.add(FPSTR(KEY_RETURN));
|
|
ValuesList.add(sReturn);
|
|
|
|
KeysList.add(FPSTR(KEY_DISCONNECT_VISIBILITY));
|
|
if (web_interface->is_authenticated()) {
|
|
ValuesList.add(FPSTR(VALUE_ITEM_VISIBLE));
|
|
} else {
|
|
ValuesList.add(FPSTR(VALUE_ITEM_HIDDEN));
|
|
}
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,FPSTR(VALUE_LOGIN),F("login"));
|
|
//User
|
|
KeysList.add(FPSTR(KEY_USER));
|
|
ValuesList.add(sUser);
|
|
//password
|
|
KeysList.add(FPSTR(KEY_USER_PASSWORD));
|
|
ValuesList.add(sPassword);
|
|
|
|
if (msg_alert_error) {
|
|
ProcessAlertError(KeysList, ValuesList, smsg);
|
|
} else {
|
|
ProcessNoAlert(KeysList,ValuesList);
|
|
}
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/login.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
}
|
|
|
|
void handle_restart()
|
|
{
|
|
if (SPIFFS.exists("/restart.tpl")) {
|
|
STORESTRINGS_CLASS KeysList ;
|
|
STORESTRINGS_CLASS ValuesList ;
|
|
|
|
//IP+Web
|
|
GetIpWeb(KeysList, ValuesList);
|
|
//mode
|
|
GetMode(KeysList, ValuesList);
|
|
//page title and filenames
|
|
SetPageProp(KeysList,ValuesList,F("Restarting..."),F("restart"));
|
|
|
|
//Firmware and Free Mem, at the end to reflect situation
|
|
GetFreeMem(KeysList, ValuesList);
|
|
|
|
//process the template file and provide list of variables
|
|
processTemplate("/restart.tpl", KeysList , ValuesList);
|
|
//need to clean to speed up memory recovery
|
|
KeysList.clear();
|
|
ValuesList.clear();
|
|
} else {
|
|
//if not restart template use default
|
|
String contentType=FPSTR(PAGE_RESTART);
|
|
web_interface->WebServer.send(200,"text/html",contentType);
|
|
}
|
|
web_interface->restartmodule=true;
|
|
}
|
|
|
|
void handle_web_command()
|
|
{
|
|
if (!web_interface->is_authenticated()) {
|
|
return;
|
|
}
|
|
//check we have proper parameter
|
|
if (web_interface->WebServer.hasArg("COM")) {
|
|
String scmd;
|
|
//decode command
|
|
scmd = web_interface->WebServer.arg("COM");
|
|
scmd.trim();
|
|
//give an ack - we need to be polite, right ?
|
|
web_interface->WebServer.send(200,"text/plain","Ok");
|
|
//if it is for ESP module [ESPXXX]<parameter>
|
|
int ESPpos = scmd.indexOf("[ESP");
|
|
if (ESPpos>-1) {
|
|
//is there the second part?
|
|
int ESPpos2 = scmd.indexOf("]",ESPpos);
|
|
if (ESPpos2>-1) {
|
|
//Split in command and parameters
|
|
String cmd_part1=scmd.substring(ESPpos+4,ESPpos2);
|
|
String cmd_part2="";
|
|
//is there space for parameters?
|
|
if (ESPpos2<scmd.length()) {
|
|
cmd_part2=scmd.substring(ESPpos2+1);
|
|
}
|
|
//if command is a valid number then execute command
|
|
if(cmd_part1.toInt()!=0) {
|
|
COMMAND::execute_command(cmd_part1.toInt(),cmd_part2);
|
|
}
|
|
//if not is not a valid [ESPXXX] command
|
|
}
|
|
}
|
|
else {
|
|
//send command to serial as no need to transfer ESP command
|
|
//to avoid any pollution if Uploading file to SDCard
|
|
if ((web_interface->blockserial) == false)Serial.println(scmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef SSDP_FEATURE
|
|
void handle_SSDP()
|
|
{
|
|
SSDP.schema(web_interface->WebServer.client());
|
|
}
|
|
#endif
|
|
|
|
//constructor
|
|
WEBINTERFACE_CLASS::WEBINTERFACE_CLASS (int port):WebServer(port)
|
|
{
|
|
//init what will handle "/"
|
|
WebServer.on("/",HTTP_ANY, handle_web_interface_root);
|
|
WebServer.on("/HOME",HTTP_ANY, handle_web_interface_home);
|
|
WebServer.on("/CONFIGSYS",HTTP_ANY, handle_web_interface_configSys);
|
|
WebServer.on("/CONFIGAP",HTTP_ANY, handle_web_interface_configAP);
|
|
WebServer.on("/CONFIGSTA",HTTP_ANY, handle_web_interface_configSTA);
|
|
WebServer.on("/STATUS",HTTP_ANY, handle_web_interface_status);
|
|
WebServer.on("/SETTINGS",HTTP_ANY, handle_web_settings);
|
|
WebServer.on("/PRINTER",HTTP_ANY, handle_web_interface_printer);
|
|
WebServer.on("/CMD",HTTP_ANY, handle_web_command);
|
|
WebServer.on("/RESTART",HTTP_GET, handle_restart);
|
|
#ifdef WEB_UPDATE_FEATURE
|
|
WebServer.on("/UPDATE",HTTP_ANY, handleUpdate,WebUpdateUpload);
|
|
#endif
|
|
WebServer.on("/FILES", HTTP_ANY, handleFileList,SPIFFSFileupload);
|
|
WebServer.on("/SDFILES", HTTP_ANY, handleSDFileList,SDFileupload);
|
|
WebServer.on("/LOGIN", HTTP_ANY, handle_login);
|
|
WebServer.on("/PASSWORD", HTTP_ANY, handle_password);
|
|
//Captive portal Feature
|
|
#ifdef CAPTIVE_PORTAL_FEATURE
|
|
WebServer.on("/generate_204",HTTP_ANY, handle_web_interface_root);
|
|
WebServer.on("/fwlink",HTTP_ANY, handle_web_interface_root);
|
|
#endif
|
|
#ifdef SSDP_FEATURE
|
|
WebServer.on("/description.xml", HTTP_GET, handle_SSDP);
|
|
#endif
|
|
WebServer.onNotFound( handle_not_found);
|
|
answer4M105="T:0 /0 ";
|
|
answer4M114="X:0.0 Y:0.0 Z:0.000";
|
|
answer4M220="100";
|
|
answer4M221="100";
|
|
blockserial = false;
|
|
last_temp = millis();
|
|
restartmodule=false;
|
|
//rolling list of 4entries with a maximum of 50 char for each entry
|
|
error_msg.setsize(4);
|
|
error_msg.setlength(50);
|
|
info_msg.setsize(4);
|
|
info_msg.setlength(50);
|
|
status_msg.setsize(4);
|
|
status_msg.setlength(50);
|
|
fileslist.setlength(100);//12 for filename + space + size
|
|
fileslist.setsize(70); // 70 files to limite to 2K
|
|
fsUploadFile=(fs::File)0;
|
|
_head=NULL;
|
|
_nb_ip=0;
|
|
_upload_status=UPLOAD_STATUS_NONE;
|
|
}
|
|
//Destructor
|
|
WEBINTERFACE_CLASS::~WEBINTERFACE_CLASS()
|
|
{
|
|
info_msg.clear();
|
|
error_msg.clear();
|
|
status_msg.clear();
|
|
fileslist.clear();
|
|
while (_head) {
|
|
auth_ip * current = _head;
|
|
_head=_head->_next;
|
|
delete current;
|
|
}
|
|
_nb_ip=0;
|
|
}
|
|
//Session ID based on IP and time using 16 char
|
|
char * WEBINTERFACE_CLASS::create_session_ID()
|
|
{
|
|
static char sessionID[17];
|
|
//reset SESSIONID
|
|
for (int i=0; i<17; i++) {
|
|
sessionID[i]='\0';
|
|
}
|
|
//get time
|
|
uint32_t now = millis();
|
|
//get remote IP
|
|
IPAddress remoteIP=WebServer.client().remoteIP();
|
|
//generate SESSIONID
|
|
if (0>sprintf(sessionID,"%02X%02X%02X%02X%02X%02X%02X%02X",remoteIP[0],remoteIP[1],remoteIP[2],remoteIP[3],(uint8_t) ((now >> 0) & 0xff),(uint8_t) ((now >> 8) & 0xff),(uint8_t) ((now >> 16) & 0xff),(uint8_t) ((now >> 24) & 0xff))) {
|
|
strcpy(sessionID,"NONE");
|
|
}
|
|
return sessionID;
|
|
}
|
|
//check authentification
|
|
bool WEBINTERFACE_CLASS::is_authenticated()
|
|
{
|
|
#ifdef AUTHENTICATION_FEATURE
|
|
if (WebServer.hasHeader("Cookie")) {
|
|
String cookie = WebServer.header("Cookie");
|
|
int pos = cookie.indexOf("ESPSESSIONID=");
|
|
if (pos!= -1) {
|
|
int pos2 = cookie.indexOf(";",pos);
|
|
String sessionID = cookie.substring(pos+strlen("ESPSESSIONID="),pos2);
|
|
IPAddress ip = WebServer.client().remoteIP();
|
|
//check if cookie can be reset and clean table in same time
|
|
return ResetAuthIP(ip,sessionID.c_str());
|
|
}
|
|
}
|
|
return false;
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
//add the information in the linked list if possible
|
|
bool WEBINTERFACE_CLASS::AddAuthIP(auth_ip * item)
|
|
{
|
|
if (_nb_ip>MAX_AUTH_IP) {
|
|
return false;
|
|
}
|
|
item->_next=_head;
|
|
_head=item;
|
|
_nb_ip++;
|
|
return true;
|
|
}
|
|
|
|
bool WEBINTERFACE_CLASS::ResetAuthIP(IPAddress ip,const char * sessionID)
|
|
{
|
|
bool done=false;
|
|
auth_ip * current = _head;
|
|
auth_ip * previous = NULL;
|
|
//get time
|
|
//uint32_t now = millis();
|
|
while (current) {
|
|
if ((millis()-current->last_time)>400000) {
|
|
//remove
|
|
if (current==_head) {
|
|
_head=current->_next;
|
|
_nb_ip--;
|
|
delete current;
|
|
current=_head;
|
|
} else {
|
|
previous->_next=current->_next;
|
|
_nb_ip--;
|
|
delete current;
|
|
current=previous->_next;
|
|
}
|
|
} else {
|
|
if (ip==current->ip) {
|
|
if (strcmp(sessionID,current->sessionID)==0) {
|
|
//reset time
|
|
current->last_time=millis();
|
|
return true;
|
|
}
|
|
}
|
|
previous = current;
|
|
current=current->_next;
|
|
}
|
|
}
|
|
return done;
|
|
}
|
|
|
|
WEBINTERFACE_CLASS * web_interface;
|