diff --git a/Makefile b/Makefile
index 3a6dfbb..8de4074 100644
--- a/Makefile
+++ b/Makefile
@@ -19,9 +19,37 @@
# The Wifi station configuration can be hard-coded here, which makes esp-link come up in STA+AP
# mode trying to connect to the specified AP *only* if the flash wireless settings are empty!
# This happens on a full serial flash and avoids having to hunt for the AP...
-# STA_SSID ?=
+# STA_SSID ?=
# STA_PASS ?=
+# The SOFTAP configuration can be hard-coded here, the minimum parameters to set are AP_SSID && AP_PASS
+# The AP SSID has to be at least 8 characters long, same for AP PASSWORD
+# The AP AUTH MODE can be set to:
+# 0 = AUTH_OPEN,
+# 1 = AUTH_WEP,
+# 2 = AUTH_WPA_PSK,
+# 3 = AUTH_WPA2_PSK,
+# 4 = AUTH_WPA_WPA2_PSK
+# SSID hidden default 0, ( 0 | 1 )
+# Max connections default 4, ( 1 ~ 4 )
+# Beacon interval default 100, ( 100 ~ 60000ms )
+
+# AP_SSID ?=esp_link_test
+# AP_PASS ?=esp_link_test
+# AP_AUTH_MODE ?=4
+# AP_SSID_HIDDEN ?=0
+# AP_MAX_CONN ?=4
+# AP_BEACON_INTERVAL ?=100
+
+
+# If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode
+# once successfully connected to an access point. Else it will stay in STA+AP mode.
+
+CHANGE_TO_STA ?= yes
+
+# hostname or IP address for wifi flashing
+ESP_HOSTNAME ?= esp-link
+
# --------------- toolchain configuration ---------------
# Base directory for the compiler. Needs a / at the end.
@@ -39,15 +67,6 @@ ESPTOOL ?= $(abspath ../esp-open-sdk/esptool/esptool.py)
ESPPORT ?= /dev/ttyUSB0
ESPBAUD ?= 460800
-# The Wifi station configuration can be hard-coded here, which makes esp-link come up in STA+AP
-# mode trying to connect to the specified AP *only* if the flash wireless settings are empty!
-# This happens on a full serial flash and avoids having to hunt for the AP...
-# STA_SSID ?=
-# STA_PASS ?=
-
-# hostname or IP address for wifi flashing
-ESP_HOSTNAME ?= esp-link
-
# --------------- chipset configuration ---------------
# Pick your flash size: "512KB", "1MB", or "4MB"
@@ -64,14 +83,9 @@ LED_CONN_PIN ?= 0
# GPIO pin used for "serial activity" LED, active low
LED_SERIAL_PIN ?= 14
-# --------------- esp-link config options ---------------
+# --------------- esp-link modules config options ---------------
-# If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode
-# once successfully connected to an access point. Else it will stay in AP+STA mode.
-
-CHANGE_TO_STA ?= yes
-
-# Optional Modules
+# Optional Modules mqtt
MODULES ?= mqtt rest syslog
# --------------- esphttpd config options ---------------
@@ -268,6 +282,30 @@ ifneq ($(strip $(STA_PASS)),)
CFLAGS += -DSTA_PASS="$(STA_PASS)"
endif
+ifneq ($(strip $(AP_SSID)),)
+CFLAGS += -DAP_SSID="$(AP_SSID)"
+endif
+
+ifneq ($(strip $(AP_PASS)),)
+CFLAGS += -DAP_PASS="$(AP_PASS)"
+endif
+
+ifneq ($(strip $(AP_AUTH_MODE)),)
+CFLAGS += -DAP_AUTH_MODE="$(AP_AUTH_MODE)"
+endif
+
+ifneq ($(strip $(AP_SSID_HIDDEN)),)
+CFLAGS += -DAP_SSID_HIDDEN="$(AP_SSID_HIDDEN)"
+endif
+
+ifneq ($(strip $(AP_MAX_CONN)),)
+CFLAGS += -DAP_MAX_CONN="$(AP_MAX_CONN)"
+endif
+
+ifneq ($(strip $(AP_BEACON_INTERVAL)),)
+CFLAGS += -DAP_BEACON_INTERVAL="$(AP_BEACON_INTERVAL)"
+endif
+
ifeq ("$(GZIP_COMPRESSION)","yes")
CFLAGS += -DGZIP_COMPRESSION
endif
diff --git a/esp-link/cgi.c b/esp-link/cgi.c
index 081ef49..6879cd6 100644
--- a/esp-link/cgi.c
+++ b/esp-link/cgi.c
@@ -206,7 +206,8 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"{ "
"\"menu\": [ "
"\"Home\", \"/home.html\", "
- "\"WiFI\", \"/wifi/wifi.html\", "
+ "\"WiFi Station\", \"/wifi/wifiSta.html\", "
+ "\"WiFi Soft-AP\", \"/wifi/wifiAp.html\", "
"\"µC Console\", \"/console.html\", "
"\"Services\", \"/services.html\", "
#ifdef MQTT
diff --git a/esp-link/cgiwifi.c b/esp-link/cgiwifi.c
old mode 100644
new mode 100755
index b83a330..f5da2a3
--- a/esp-link/cgiwifi.c
+++ b/esp-link/cgiwifi.c
@@ -26,11 +26,20 @@ Cgi/template routines for the /wifi url.
#define DBG(format, ...) do { } while(0)
#endif
+# define VERS_STR_STR(V) #V
+# define VERS_STR(V) VERS_STR_STR(V)
+
bool mdns_started = false;
// ===== wifi status change callbacks
static WifiStateChangeCb wifi_state_change_cb[4];
+// Temp store for new staion config
+struct station_config stconf;
+
+// Temp store for new ap config
+struct softap_config apconf;
+
uint8_t wifiState = wifiIsDisconnected;
// reasons for which a connection failed
uint8_t wifiReason = 0;
@@ -265,14 +274,21 @@ static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
}
int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
- if (connData->requestType == HTTPD_METHOD_GET) {
- return cgiWiFiGetScan(connData);
- } else if (connData->requestType == HTTPD_METHOD_POST) {
- return cgiWiFiStartScan(connData);
- } else {
- jsonHeader(connData, 404);
- return HTTPD_CGI_DONE;
- }
+ if (connData->requestType == HTTPD_METHOD_GET) {
+ return cgiWiFiGetScan(connData);
+ }else if(connData->requestType == HTTPD_METHOD_POST) {
+ // DO NOT start APs scan in AP mode
+ int mode = wifi_get_opmode();
+ if(mode==2){
+ jsonHeader(connData, 400);
+ return HTTPD_CGI_DONE;
+ }else{
+ return cgiWiFiStartScan(connData);
+ }
+ }else{
+ jsonHeader(connData, 404);
+ return HTTPD_CGI_DONE;
+ }
}
// ===== timers to change state and rescue from failed associations
@@ -288,9 +304,10 @@ static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
int x = wifi_station_get_connect_status();
int m = wifi_get_opmode() & 0x3;
DBG("Wifi check: mode=%s status=%d\n", wifiMode[m], x);
-
- if (x == STATION_GOT_IP) {
- if (m != 1) {
+
+ if(m!=2){
+ if ( x == STATION_GOT_IP ) {
+ if (m != 1) {
#ifdef CHANGE_TO_STA
// We're happily connected, go to STA mode
DBG("Wifi got IP. Going into STA mode..\n");
@@ -300,19 +317,19 @@ static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
}
log_uart(false);
// no more resetTimer at this point, gotta use physical reset to recover if in trouble
- } else {
- if (m != 3) {
- DBG("Wifi connect failed. Going into STA+AP mode..\n");
- wifi_set_opmode(3);
+ } else {
+ if (m != 3) {
+ DBG("Wifi connect failed. Going into STA+AP mode..\n");
+ wifi_set_opmode(3);
+ wifi_softap_set_config(&apconf);
}
log_uart(true);
DBG("Enabling/continuing uart log\n");
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
+ }
}
}
-// Temp store for new ap info.
-static struct station_config stconf;
// Reassociate timer to delay change of association so the original request can finish
static ETSTimer reassTimer;
@@ -334,6 +351,12 @@ static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
// This cgi uses the routines above to connect to a specific access point with the
// given ESSID using the given password.
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
+ int mode = wifi_get_opmode();
+ if(mode == 2){
+ jsonHeader(connData, 400);
+ httpdSend(connData, "Can't associate to an AP en SoftAP mode", -1);
+ return HTTPD_CGI_DONE;
+ }
char essid[128];
char passwd[128];
@@ -482,38 +505,206 @@ int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
+// ==== Soft-AP related functions
+
+// Change Soft-AP main settings
+int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
+
+ if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
+
+ // No changes for Soft-AP in STA mode
+ int mode = wifi_get_opmode();
+ if ( mode == 1 ){
+ jsonHeader(connData, 400);
+ httpdSend(connData, "No changes allowed in STA mode", -1);
+ return HTTPD_CGI_DONE;
+ }
+
+ char buff[96];
+ int len;
+ // Do we need a password or auth mode?
+ bool pass_need=true;
+
+ // Check extra security measure, this must be 1
+ len=httpdFindArg(connData->getArgs, "100", buff, sizeof(buff));
+ if(len>0){
+ if(atoi(buff)!=1){
+ jsonHeader(connData, 400);
+ return HTTPD_CGI_DONE;
+ }
+ }
+ // Set new SSID
+ len=httpdFindArg(connData->getArgs, "ap_ssid", buff, sizeof(buff));
+ if(checkString(buff) && len>7 && len<32){
+ // STRING PREPROCESSING DONE IN CLIENT SIDE
+ os_memset(apconf.ssid, 0, 32);
+ os_memcpy(apconf.ssid, buff, len);
+ apconf.ssid_len = len;
+ pass_need = true; // ssid ok, look for a valid password
+ }else{
+ pass_need = false; // ssid wrong, neither pass nor auth mode are needed
+ jsonHeader(connData, 400);
+ httpdSend(connData, "SSID not valid or out of range", -1);
+ return HTTPD_CGI_DONE;
+ }
+ // Set new PASSWORD
+ if( pass_need ){
+ len=httpdFindArg(connData->getArgs, "ap_password", buff, sizeof(buff));
+ if(checkString(buff) && len>7 && len<64){
+ // String preprocessing done in client side, wifiap.js line 31
+ os_memset(apconf.password, 0, 64);
+ os_memcpy(apconf.password, buff, len);
+ pass_need = true; // pass ok, look for auth mode
+ }else if (len == 0){
+ pass_need = false; // pass wrong, don't look for auth mode
+ os_memset(apconf.password, 0, 64);
+ }else{
+ jsonHeader(connData, 400);
+ httpdSend(connData, "PASSWORD not valid or out of range", -1);
+ return HTTPD_CGI_DONE;
+ }
+ }
+ // Set auth mode
+ if(pass_need){
+ // Set authentication mode, before password to check open settings
+ len=httpdFindArg(connData->getArgs, "ap_authmode", buff, sizeof(buff));
+ if(len>0){
+ int value = atoi(buff);
+ if(value >= 0 && value <= 4){
+ apconf.authmode = value;
+ }else{
+ // If out of range set by default
+ apconf.authmode = 4;
+ }
+ }else{
+ // Valid password but wrong auth mode, default 4
+ apconf.authmode = 4;
+ }
+ }else{
+ apconf.authmode = 0;
+ }
+ // Set max connection number
+ len=httpdFindArg(connData->getArgs, "ap_maxconn", buff, sizeof(buff));
+ if(len>0){
+
+ int value = atoi(buff);
+ if(value > 0 && value <= 4){
+ apconf.max_connection = value;
+ }else{
+ // If out of range, set by default
+ apconf.max_connection = 4;
+ }
+ }
+ // Set beacon interval value
+ len=httpdFindArg(connData->getArgs, "ap_beacon", buff, sizeof(buff));
+ if(len>0){
+ int value = atoi(buff);
+ if(value >= 100 && value <= 60000){
+ apconf.beacon_interval = value;
+ }else{
+ // If out of range, set by default
+ apconf.beacon_interval = 100;
+ }
+ }
+ // Set ssid to be hidden or not
+ len=httpdFindArg(connData->getArgs, "ap_hidden", buff, sizeof(buff));
+ if(len>0){
+ int value = atoi(buff);
+ if(value == 0 || value == 1){
+ apconf.ssid_hidden = value;
+ }else{
+ // If out of range, set by default
+ apconf.ssid_hidden = 0;
+ }
+ }
+ // Store new configuration
+ wifi_softap_set_config(&apconf);
+
+ jsonHeader(connData, 200);
+ return HTTPD_CGI_DONE;
+}
+
+// Get current Soft-AP settings
+int ICACHE_FLASH_ATTR cgiApSettingsInfo(HttpdConnData *connData) {
+
+ char buff[1024];
+ if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
+ os_sprintf(buff,
+ "{ "
+ "\"ap_ssid\": \"%s\", "
+ "\"ap_password\": \"%s\", "
+ "\"ap_authmode\": %d, "
+ "\"ap_maxconn\": %d, "
+ "\"ap_beacon\": %d, "
+ "\"ap_hidden\": \"%s\" "
+ " }",
+ apconf.ssid,
+ apconf.password,
+ apconf.authmode,
+ apconf.max_connection,
+ apconf.beacon_interval,
+ apconf.ssid_hidden ? "enabled" : "disabled"
+ );
+
+ jsonHeader(connData, 200);
+ httpdSend(connData, buff, -1);
+ return HTTPD_CGI_DONE;
+}
+
//This cgi changes the operating mode: STA / AP / STA+AP
int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) {
int len;
char buff[1024];
-
+ int previous_mode = wifi_get_opmode();
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff));
- if (len!=0) {
- int m = atoi(buff);
- DBG("Wifi switching to mode %d\n", m);
- wifi_set_opmode(m&3);
- if (m == 1) {
- // STA-only mode, reset into STA+AP after a timeout if we don't get an IP address
- os_timer_disarm(&resetTimer);
- os_timer_setfn(&resetTimer, resetTimerCb, NULL);
- os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
+ int next_mode = atoi(buff);
+
+ if (len!=0) {
+ if (next_mode == 2){
+ // moving to AP mode, so disconnect before leave STA mode
+ wifi_station_disconnect();
+ }
+
+ DBG("Wifi switching to mode %d\n", next_mode);
+ wifi_set_opmode(next_mode&3);
+
+ if (previous_mode == 2) {
+ // moving to STA or STA+AP mode from AP, try to connect and set timer
+ stconf.bssid_set = 0;
+ wifi_station_set_config(&stconf);
+ wifi_station_connect();
+ os_timer_disarm(&resetTimer);
+ os_timer_setfn(&resetTimer, resetTimerCb, NULL);
+ os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
+ }
+ if(previous_mode == 1){
+ // moving to AP or STA+AP from STA, so softap config call needed
+ wifi_softap_set_config(&apconf);
+ }
+ jsonHeader(connData, 200);
+ } else {
+ jsonHeader(connData, 400);
}
- jsonHeader(connData, 200);
- } else {
- jsonHeader(connData, 400);
- }
- return HTTPD_CGI_DONE;
+ return HTTPD_CGI_DONE;
}
static char *connStatuses[] = { "idle", "connecting", "wrong password", "AP not found",
"failed", "got IP address" };
static char *wifiWarn[] = { 0,
- "Switch to STA+AP mode",
- "Can't scan in this mode! Switch to STA+AP mode",
- "Switch to STA mode",
+ "Switch to STA+AP mode",
+ "Switch to STA+AP mode",
+ "Switch to STA mode",
+ "Switch to AP mode",
+};
+
+static char *apAuthMode[] = { "OPEN",
+ "WEP",
+ "WPA_PSK",
+ "WPA2_PSK",
+ "WPA_WPA2_PSK",
};
#ifdef CHANGE_TO_STA
@@ -525,43 +716,50 @@ static char *wifiWarn[] = { 0,
// print various Wifi information into json buffer
int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
int len;
-
- struct station_config stconf;
- wifi_station_get_config(&stconf);
-
- uint8_t op = wifi_get_opmode() & 0x3;
- char *mode = wifiMode[op];
- char *status = "unknown";
- int st = wifi_station_get_connect_status();
- if (st >= 0 && st < sizeof(connStatuses)) status = connStatuses[st];
- int p = wifi_get_phy_mode();
- char *phy = wifiPhy[p&3];
- char *warn = wifiWarn[op];
- sint8 rssi = wifi_station_get_rssi();
- if (rssi > 0) rssi = 0;
- uint8 mac_addr[6];
- wifi_get_macaddr(0, mac_addr);
- uint8_t chan = wifi_get_channel();
-
- len = os_sprintf(buff,
- "\"mode\": \"%s\", \"modechange\": \"%s\", \"ssid\": \"%s\", \"status\": \"%s\", \"phy\": \"%s\", "
- "\"rssi\": \"%ddB\", \"warn\": \"%s\", \"mac\":\"%02x:%02x:%02x:%02x:%02x:%02x\", \"chan\":%d",
- mode, MODECHANGE, (char*)stconf.ssid, status, phy, rssi, warn,
- mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], chan);
-
- struct ip_info info;
- if (wifi_get_ip_info(0, &info)) {
- len += os_sprintf(buff+len, ", \"ip\": \"%d.%d.%d.%d\"", IP2STR(&info.ip.addr));
- len += os_sprintf(buff+len, ", \"netmask\": \"%d.%d.%d.%d\"", IP2STR(&info.netmask.addr));
- len += os_sprintf(buff+len, ", \"gateway\": \"%d.%d.%d.%d\"", IP2STR(&info.gw.addr));
- len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", flashConfig.hostname);
- } else {
- len += os_sprintf(buff+len, ", \"ip\": \"-none-\"");
- }
- len += os_sprintf(buff+len, ", \"staticip\": \"%d.%d.%d.%d\"", IP2STR(&flashConfig.staticip));
- len += os_sprintf(buff+len, ", \"dhcp\": \"%s\"", flashConfig.staticip > 0 ? "off" : "on");
-
- return len;
+ //struct station_config stconf;
+ wifi_station_get_config(&stconf);
+ //struct softap_config apconf;
+ wifi_softap_get_config(&apconf);
+
+ uint8_t op = wifi_get_opmode() & 0x3;
+ char *mode = wifiMode[op];
+ char *status = "unknown";
+ int st = wifi_station_get_connect_status();
+ if (st >= 0 && st < sizeof(connStatuses)) status = connStatuses[st];
+ int p = wifi_get_phy_mode();
+ char *phy = wifiPhy[p&3];
+ char *warn = wifiWarn[op];
+ if (op == 3) op = 4; // Done to let user switch to AP only mode from Soft-AP settings page, using only one set of warnings
+ char *apwarn = wifiWarn[op];
+ char *apauth = apAuthMode[apconf.authmode];
+ sint8 rssi = wifi_station_get_rssi();
+ if (rssi > 0) rssi = 0;
+ uint8 mac_addr[6];
+ uint8 apmac_addr[6];
+ wifi_get_macaddr(0, mac_addr);
+ wifi_get_macaddr(1, apmac_addr);
+ uint8_t chan = wifi_get_channel();
+
+ len = os_sprintf(buff,
+ "\"mode\": \"%s\", \"modechange\": \"%s\", \"ssid\": \"%s\", \"status\": \"%s\", \"phy\": \"%s\", "
+ "\"rssi\": \"%ddB\", \"warn\": \"%s\", \"apwarn\": \"%s\",\"mac\":\"%02x:%02x:%02x:%02x:%02x:%02x\", \"chan\":\"%d\", \"apssid\": \"%s\", "
+ "\"appass\": \"%s\", \"apchan\": \"%d\", \"apmaxc\": \"%d\", \"aphidd\": \"%s\", \"apbeac\": \"%d\", \"apauth\": \"%s\",\"apmac\":\"%02x:%02x:%02x:%02x:%02x:%02x\"",
+ mode, MODECHANGE, (char*)stconf.ssid, status, phy, rssi, warn, apwarn,
+ mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], chan, (char*)apconf.ssid,(char*)apconf.password,apconf.channel,apconf.max_connection,apconf.ssid_hidden?"enabled":"disabled",apconf.beacon_interval, apauth,apmac_addr[0], apmac_addr[1], apmac_addr[2], apmac_addr[3], apmac_addr[4], apmac_addr[5]);
+
+ struct ip_info info;
+ if (wifi_get_ip_info(0, &info)) {
+ len += os_sprintf(buff+len, ", \"ip\": \"%d.%d.%d.%d\"", IP2STR(&info.ip.addr));
+ len += os_sprintf(buff+len, ", \"netmask\": \"%d.%d.%d.%d\"", IP2STR(&info.netmask.addr));
+ len += os_sprintf(buff+len, ", \"gateway\": \"%d.%d.%d.%d\"", IP2STR(&info.gw.addr));
+ len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", flashConfig.hostname);
+ } else {
+ len += os_sprintf(buff+len, ", \"ip\": \"-none-\"");
+ }
+ len += os_sprintf(buff+len, ", \"staticip\": \"%d.%d.%d.%d\"", IP2STR(&flashConfig.staticip));
+ len += os_sprintf(buff+len, ", \"dhcp\": \"%s\"", flashConfig.staticip > 0 ? "off" : "on");
+
+ return len;
}
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
@@ -614,24 +812,123 @@ int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
-// Init the wireless, which consists of setting a timer if we expect to connect to an AP
-// so we can revert to STA+AP mode if we can't connect.
-void ICACHE_FLASH_ATTR wifiInit() {
- // wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky
- int x = wifi_get_opmode() & 0x3;
- x = x;
- DBG("Wifi init, mode=%s\n", wifiMode[x]);
- configWifiIP();
-
- // The default sleep mode should be modem_sleep, but we set it here explicitly for good
- // measure. We can't use light_sleep because that powers off everthing and we would loose
- // all connections.
- wifi_set_sleep_type(MODEM_SLEEP_T);
-
- wifi_set_event_handler_cb(wifiHandleEventCb);
- // check on the wifi in a few seconds to see whether we need to switch mode
- os_timer_disarm(&resetTimer);
- os_timer_setfn(&resetTimer, resetTimerCb, NULL);
- os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
+// Check string againt invalid characters
+int ICACHE_FLASH_ATTR checkString(char *str){
+ int i = 0;
+ for(; i < os_strlen(str); i++)
+ {
+ // Alphanumeric and underscore allowed
+ if (!(isalnum((unsigned char)str[i]) || str[i] == '_'))
+ {
+ DBG("Error: String has non alphanumeric chars\n");
+ return 0;
+ }
+ }
+ return 1;
}
+/* Init the wireless
+ *
+ * Call both Soft-AP and Station default config
+ * Change values according to Makefile hard-coded variables
+ * Anyway set wifi opmode to STA+AP, it will change to STA if CHANGE_TO_STA is set to yes in Makefile
+ * Call a timer to check the STA connection
+ */
+void ICACHE_FLASH_ATTR wifiInit() {
+
+ // Check te wifi opmode
+ int x = wifi_get_opmode() & 0x3;
+
+ // Set opmode to 3 to let system scan aps, otherwise it won't scan
+ wifi_set_opmode(3);
+
+ // Call both STATION and SOFTAP default config
+ wifi_station_get_config_default(&stconf);
+ wifi_softap_get_config_default(&apconf);
+
+ DBG("Wifi init, mode=%s\n",wifiMode[x]);
+
+ // STATION parameters
+#if defined(STA_SSID) && defined(STA_PASS)
+ // Set parameters
+ if (os_strlen((char*)stconf.ssid) == 0 && os_strlen((char*)stconf.password) == 0) {
+ os_strncpy((char*)stconf.ssid, VERS_STR(STA_SSID), 32);
+ os_strncpy((char*)stconf.password, VERS_STR(STA_PASS), 64);
+
+ DBG("Wifi pre-config trying to connect to AP %s pw %s\n",(char*)stconf.ssid, (char*)stconf.password);
+
+ // wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky
+ stconf.bssid_set = 0;
+ wifi_station_set_config(&stconf);
+ }
+#endif
+
+ // Change SOFT_AP settings if defined
+#if defined(AP_SSID)
+ // Check if ssid and pass are alphanumeric values
+ int ssidlen = os_strlen(VERS_STR(AP_SSID));
+ if(checkString(VERS_STR(AP_SSID)) && ssidlen > 7 && ssidlen < 32){
+ // Clean memory and set the value of SSID
+ os_memset(apconf.ssid, 0, 32);
+ os_memcpy(apconf.ssid, VERS_STR(AP_SSID), os_strlen(VERS_STR(AP_SSID)));
+ // Specify the length of ssid
+ apconf.ssid_len= ssidlen;
+#if defined(AP_PASS)
+ // If pass is at least 8 and less than 64
+ int passlen = os_strlen(VERS_STR(AP_PASS));
+ if( checkString(VERS_STR(AP_PASS)) && passlen > 7 && passlen < 64 ){
+ // Clean memory and set the value of PASS
+ os_memset(apconf.password, 0, 64);
+ os_memcpy(apconf.password, VERS_STR(AP_PASS), passlen);
+ // Can't choose auth mode without a valid ssid and password
+#ifdef AP_AUTH_MODE
+ // If set, use specified auth mode
+ if(AP_AUTH_MODE >= 0 && AP_AUTH_MODE <=4)
+ apconf.authmode = AP_AUTH_MODE;
+#else
+ // If not, use WPA2
+ apconf.authmode = AUTH_WPA_WPA2_PSK;
+#endif
+ }else if ( passlen == 0){
+ // If ssid is ok and no pass, set auth open
+ apconf.authmode = AUTH_OPEN;
+ // Remove stored password
+ os_memset(apconf.password, 0, 64);
+ }
+#endif
+ }// end of ssid and pass check
+#ifdef AP_SSID_HIDDEN
+ // If set, use specified ssid hidden parameter
+ if(AP_SSID_HIDDEN == 0 || AP_SSID_HIDDEN ==1)
+ apconf.ssid_hidden = AP_SSID_HIDDEN;
+#endif
+#ifdef AP_MAX_CONN
+ // If set, use specified max conn number
+ if(AP_MAX_CONN > 0 && AP_MAX_CONN <5)
+ apconf.max_connection = AP_MAX_CONN;
+#endif
+#ifdef AP_BEACON_INTERVAL
+ // If set use specified beacon interval
+ if(AP_BEACON_INTERVAL >= 100 && AP_BEACON_INTERVAL <= 60000)
+ apconf.beacon_interval = AP_BEACON_INTERVAL;
+#endif
+ // Check softap config
+ bool softap_set_conf = wifi_softap_set_config(&apconf);
+ // Debug info
+
+ DBG("Wifi Soft-AP parameters change: %s\n",softap_set_conf? "success":"fail");
+#endif // AP_SSID && AP_PASS
+
+ configWifiIP();
+
+ // The default sleep mode should be modem_sleep, but we set it here explicitly for good
+ // measure. We can't use light_sleep because that powers off everthing and we would loose
+ // all connections.
+ wifi_set_sleep_type(MODEM_SLEEP_T);
+
+ wifi_set_event_handler_cb(wifiHandleEventCb);
+ // check on the wifi in a few seconds to see whether we need to switch mode
+ os_timer_disarm(&resetTimer);
+ os_timer_setfn(&resetTimer, resetTimerCb, NULL);
+ os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
+}
\ No newline at end of file
diff --git a/esp-link/cgiwifi.h b/esp-link/cgiwifi.h
index e2e98bc..667f27d 100644
--- a/esp-link/cgiwifi.h
+++ b/esp-link/cgiwifi.h
@@ -13,10 +13,13 @@ int cgiWiFiConnect(HttpdConnData *connData);
int cgiWiFiSetMode(HttpdConnData *connData);
int cgiWiFiConnStatus(HttpdConnData *connData);
int cgiWiFiSpecial(HttpdConnData *connData);
+int cgiApSettingsChange(HttpdConnData *connData);
+int cgiApSettingsInfo(HttpdConnData *connData);
void configWifiIP();
void wifiInit(void);
void wifiAddStateChangeCb(WifiStateChangeCb cb);
void wifiStartMDNS(struct ip_addr);
+int checkString(char *str);
extern uint8_t wifiState;
extern bool mdns_started;
diff --git a/esp-link/main.c b/esp-link/main.c
index 09904e1..4f7de35 100644
--- a/esp-link/main.c
+++ b/esp-link/main.c
@@ -72,6 +72,8 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/wifi/connstatus", cgiWiFiConnStatus, NULL },
{ "/wifi/setmode", cgiWiFiSetMode, NULL },
{ "/wifi/special", cgiWiFiSpecial, NULL },
+ { "/wifi/apinfo", cgiApSettingsInfo, NULL },
+ { "/wifi/apchange", cgiApSettingsChange, NULL },
{ "/system/info", cgiSystemInfo, NULL },
{ "/system/update", cgiSystemSet, NULL },
{ "/services/info", cgiServicesInfo, NULL },
@@ -86,7 +88,6 @@ HttpdBuiltInUrl builtInUrls[] = {
#ifdef SHOW_HEAP_USE
static ETSTimer prHeapTimer;
-
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size());
}
@@ -110,47 +111,23 @@ void user_rf_pre_init(void) {
// Main routine to initialize esp-link.
void user_init(void) {
// get the flash config so we know how to init things
-// configWipe(); // uncomment to reset the config for testing purposes
+ //configWipe(); // uncomment to reset the config for testing purposes
bool restoreOk = configRestore();
- // init gpio pin registers
+ // Init gpio pin registers
gpio_init();
gpio_output_set(0, 0, 0, (1<<15)); // some people tie it to GND, gotta ensure it's disabled
// init UART
uart_init(flashConfig.baud_rate, 115200);
logInit(); // must come after init of uart
- // say hello (leave some time to cause break in TX after boot loader's msg
+ // Say hello (leave some time to cause break in TX after boot loader's msg
os_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
-
-#if defined(STA_SSID) && defined(STA_PASS)
- int x = wifi_get_opmode() & 0x3;
- if (x == 2) {
- // we only force the STA settings when a full flash of the module has been made, which
- // resets the wifi settings not to have anything configured
- struct station_config stconf;
- wifi_station_get_config(&stconf);
-
- if (os_strlen((char*)stconf.ssid) == 0 && os_strlen((char*)stconf.password) == 0) {
- os_strncpy((char*)stconf.ssid, VERS_STR(STA_SSID), 32);
- os_strncpy((char*)stconf.password, VERS_STR(STA_PASS), 64);
-#ifdef CGIWIFI_DBG
- os_printf("Wifi pre-config trying to connect to AP %s pw %s\n",
- (char*)stconf.ssid, (char*)stconf.password);
-#endif
- wifi_set_opmode(3); // sta+ap, will switch to sta-only 15 secs after connecting
- stconf.bssid_set = 0;
- wifi_station_set_config(&stconf);
- }
- }
-#endif
-
// Status LEDs
statusInit();
serledInit();
// Wifi
wifiInit();
-
// init the flash filesystem with the html stuff
espFsInit(&_binary_espfs_img_start);
//EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
@@ -175,16 +152,14 @@ void user_init(void) {
NOTICE("Flash map %s, manuf 0x%02lX chip 0x%04lX", flash_maps[system_get_flash_size_map()],
fid & 0xff, (fid&0xff00)|((fid>>16)&0xff));
NOTICE("** esp-link ready");
-
+
+ // Init SNTP service
cgiServicesSNTPInit();
-
#ifdef MQTT
NOTICE("initializing MQTT");
mqtt_client_init();
#endif
-
NOTICE("initializing user application");
app_init();
-
- NOTICE("waiting for work to do...");
+ NOTICE("Waiting for work to do...");
}
diff --git a/html/wifi/wifiAp.html b/html/wifi/wifiAp.html
new file mode 100644
index 0000000..e93e54d
--- /dev/null
+++ b/html/wifi/wifiAp.html
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
Soft-AP State
+
+
+
+ WiFi mode | |
+ Soft-AP SSID | |
+ Soft-AP Password | |
+ Soft-AP Channel | |
+ Soft-AP Max Conn | |
+ Soft-AP Hidden | |
+ Soft-AP Beacon Int | |
+ Soft-AP Auth Mode | |
+ Soft-AP MAC | |
+ |
+
+
+
+
+
+
+
Soft-AP Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+