/* 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 #include "config.h" #include "webinterface.h" #include "wifi.h" #include #include #include #include extern "C" { #include "user_interface.h" } #include #include "LinkedList.h" #include "storestrings.h" #include "command.h" #ifdef SSDP_FEATURE #include #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 ="\n\nRedirecting... \n\n\n
Unknown page - you will be redirected...\n

\nif not redirected, click here\n

\n\n\n\n
\n\n\n\n"; const char PAGE_RESTART [] PROGMEM ="\n\nRestarting... \n\n\n
Restarting, please wait....\n
\n\n
\n\n\n\n"; const char RESTARTCMD [] PROGMEM =""; 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_MAX[] PROGMEM = "MAX"; 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_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"; 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)MAX_PASSWORD_LENGTH)|| (strlen(password)MAX_ADMIN_PASSWORD_LENGTH)|| (strlen(password)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 ) { LinkedList myFileList = LinkedList(); String buffer2send; String bufferheader; int size_content=0; bool header_sent=false; //one loop to calculate size + one loop to really send //size_content is a mandatory element to avoid memory leak for(int processing_step=0;processing_step<2;processing_step++) { buffer2send=""; //open template file File currentfile = SPIFFS.open(filename, "r"); //if error display error on web page if (!currentfile) { buffer2send = String("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-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-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-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 we are just doing size calculation if (processing_step==0) { //add buffer size size_content+=buffer2send.length(); } else //if no size calculation, send data { //if header is not send yet if (!header_sent) {//send header with calculated size header_sent=true; web_interface->WebServer.sendContent(bufferheader); } //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 incled 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 we are doing size calculation if (processing_step==0) { //add buffer size size_content+=buffer2send.length(); } else //if no size calculation, send data { //if header is not send yet if (!header_sent) {//send header with calculated size web_interface->WebServer.sendContent(bufferheader); } //send data web_interface->WebServer.sendContent(buffer2send); } } //if we end size calculation loop if (processing_step==0) { //let's build the header with correct size' bufferheader = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: "+String(size_content)+"\r\nConnection: close\r\nAccess-Control-Allow-Origin: *\r\n\r\n"; } } return true; } //root insterface void handle_web_interface_root() { 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)); //Free Mem, put at the end to reflect situation KeysList.add(FPSTR(KEY_FREE_MEM)); ValuesList.add(intTostr(system_get_free_heap_size())); //IP stmp=FPSTR(KEY_IP); KeysList.add(stmp); if (wifi_get_opmode()==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+=":"; stmp+=intTostr(wifi_config.iweb_port); } ValuesList.add(stmp); //Hostname if (wifi_get_opmode()==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_get_opmode()==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 KeysList.add(FPSTR(KEY_PAGE_TITLE)); ValuesList.add(FPSTR(VALUE_HOME)); //tpl file name with extension KeysList.add(FPSTR(KEY_FILE_NAME)); ValuesList.add("home.tpl"); //tpl file name without extension KeysList.add(FPSTR(KEY_SHORT_FILE_NAME)); ValuesList.add("home"); //menu item KeysList.add(FPSTR(KEY_MENU_HOME)); ValuesList.add(FPSTR(VALUE_ACTIVE)); //FW Version KeysList.add(FPSTR(KEY_FW_VER)); ValuesList.add(FPSTR(VALUE_FW_VERSION)); //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_get_opmode()==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_get_phy_mode()==PHY_MODE_11B) ValuesList.add(FPSTR(VALUE_11B)); else if (wifi_get_phy_mode()==PHY_MODE_11G)ValuesList.add(FPSTR(VALUE_11G)); else ValuesList.add(FPSTR(VALUE_11N)); //sleep mode KeysList.add(FPSTR(KEY_SLEEP_MODE)); if (wifi_get_sleep_type()==NONE_SLEEP_T) ValuesList.add(FPSTR(VALUE_NONE)); else if (wifi_get_sleep_type()==LIGHT_SLEEP_T) 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 Port KeysList.add(FPSTR(KEY_WEB_PORT)); ValuesList.add(intTostr(wifi_config.iweb_port)); //Web Port KeysList.add(FPSTR(KEY_DATA_PORT)); ValuesList.add(intTostr(wifi_config.idata_port)); //AP part if (wifi_get_opmode()==WIFI_AP || wifi_get_opmode()==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(wifi_config.ip2str((byte *)&station->ip)); //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 visibile 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 if (apconfig.authmode==AUTH_WPA_WPA2_PSK)ValuesList.add(FPSTR(VALUE_WPAWPA2)); else ValuesList.add(FPSTR(VALUE_MAX)); //what is this one ? WPS ? Cannot find information //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 visibile 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)); } 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)); //IP/GW/MASK if (wifi_get_ip_info(SOFTAP_IF,&info)) { //IP address KeysList.add(FPSTR(KEY_AP_IP)); ValuesList.add(wifi_config.ip2str(info.ip.addr)); //GW address KeysList.add(FPSTR(KEY_AP_GW)); ValuesList.add(wifi_config.ip2str(info.gw.addr)); //Sub Net Mask KeysList.add(FPSTR(KEY_AP_SUBNET)); ValuesList.add(wifi_config.ip2str(info.netmask.addr)); } 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_get_opmode()==WIFI_STA || wifi_get_opmode()==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)); //DHCP Client status 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)); //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(""); //process the template file and provide list of variables if(KeysList.size()==ValuesList.size()) //Sanity check processTemplate("/home.tpl", KeysList , ValuesList); //need to clean to speed up memory recovery KeysList.clear(); ValuesList.clear(); } void handle_web_interface_configSys() { 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[] = {NONE_SLEEP_T,LIGHT_SLEEP_T,MODEM_SLEEP_T, -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()) { String header = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=CONFIGSYS\r\nCache-Control: no-cache\r\n\r\n"; web_interface->WebServer.sendContent(header); return; } //Free Mem, put at the end to reflect situation KeysList.add(FPSTR(KEY_FREE_MEM)); ValuesList.add(intTostr(system_get_free_heap_size())); //IP stmp=FPSTR(KEY_IP); KeysList.add(stmp); if (wifi_get_opmode()==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+=":"; stmp+=intTostr(wifi_config.iweb_port); } ValuesList.add(stmp); //mode if (wifi_get_opmode()==WIFI_STA ) { KeysList.add(FPSTR(KEY_MODE)); ValuesList.add(FPSTR(VALUE_STA)); } else { if (wifi_get_opmode()==WIFI_AP ) { KeysList.add(FPSTR(KEY_MODE)); ValuesList.add(FPSTR(VALUE_AP)); } else { KeysList.add(FPSTR(KEY_MODE)); ValuesList.add(FPSTR(VALUE_AP_STA)); } } //FW Version KeysList.add(FPSTR(KEY_FW_VER)); ValuesList.add(FPSTR(VALUE_FW_VERSION)); //page title KeysList.add(FPSTR(KEY_PAGE_TITLE)); ValuesList.add(FPSTR(VALUE_HOME)); //tpl file name with extension KeysList.add(FPSTR(KEY_FILE_NAME)); ValuesList.add("system.tpl"); //tpl file name without extension KeysList.add(FPSTR(KEY_SHORT_FILE_NAME)); ValuesList.add("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")&& web_interface->WebServer.hasArg("DATAPORT")&& 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(); idata_port = web_interface->WebServer.arg("DATAPORT").toInt(); bsleepmode = web_interface->WebServer.arg("SLEEP_MODE").toInt(); if (!(iweb_port>0 && iweb_port<65001)) { msg_alert_error=true; smsg+="Error : invalid port value for web port
"; KeysList.add(FPSTR(KEY_WEB_PORT_STATUS)); ValuesList.add(FPSTR(VALUE_HAS_ERROR)); } if (!(idata_port>0 && idata_port<65001)) { msg_alert_error=true; smsg+="Error : invalid port value for data port
"; KeysList.add(FPSTR(KEY_DATA_PORT_STATUS)); ValuesList.add(FPSTR(VALUE_HAS_ERROR)); } if (iweb_port== idata_port) { msg_alert_error=true; smsg+="Error : web port and data port cannot be identical
"; 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+="Error : value for baud rate is not correct
"; KeysList.add(FPSTR(KEY_BAUD_RATE_STATUS)); ValuesList.add(FPSTR(VALUE_HAS_ERROR)); } if (!(bsleepmode==NONE_SLEEP_T ||bsleepmode==LIGHT_SLEEP_T ||bsleepmode==MODEM_SLEEP_T )) { msg_alert_error=true; smsg+="Error : value for sleeping mode is not correct
"; KeysList.add(FPSTR(KEY_SLEEP_MODE_STATUS)); ValuesList.add(FPSTR(VALUE_HAS_ERROR)); } } else { msg_alert_error=true; smsg="Error : 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)||!CONFIG::write_buffer(EP_DATA_PORT,(const byte *)&idata_port,INTEGER_LENGTH)||!CONFIG::write_byte(EP_SLEEP_MODE,bsleepmode)) { msg_alert_error=true; smsg="Error : Cannot write to EEPROM"; } else { msg_alert_success=true; wifi_config.iweb_port=iweb_port; wifi_config.idata_port=idata_port; smsg="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; if (!CONFIG::read_buffer(EP_DATA_PORT, (byte *)&idata_port , INTEGER_LENGTH))idata_port=DEFAULT_DATA_PORT; } //Baud rate list istatus = 0; stmp=""; while (lbaudlist[istatus]>-1) { stmp+="