Soft-AP Settings

Added Soft-AP settings support both in Makefile and web interface
pull/84/head
KatAst 9 years ago
parent ff5a74b20a
commit 896693b5b2
  1. 12
      Makefile
  2. 5
      esp-link/cgi.c
  3. 303
      esp-link/cgiwifi.c
  4. 2
      esp-link/cgiwifi.h
  5. 16
      esp-link/main.c
  6. 124
      html/wifi/wifiAp.html
  7. 98
      html/wifi/wifiAp.js
  8. 8
      html/wifi/wifiSta.html
  9. 0
      html/wifi/wifiSta.js

@ -35,12 +35,12 @@
# Max connections default 4, ( 1 ~ 4 ) # Max connections default 4, ( 1 ~ 4 )
# Beacon interval default 100, ( 100 ~ 60000ms ) # Beacon interval default 100, ( 100 ~ 60000ms )
AP_SSID ?=esp-link-test # AP_SSID ?=
AP_PASS ?=esp-link-test # AP_PASS ?=
# AP_AUTH_MODE ?=AUTH_WPA_WPA2_PSK # AP_AUTH_MODE ?=
# AP_SSID_HIDDEN ?=0 # AP_SSID_HIDDEN ?=
# AP_MAX_CONN ?=3 # AP_MAX_CONN ?=
# AP_BEACON_INTERVAL ?=150 # AP_BEACON_INTERVAL ?=
# If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode # If CHANGE_TO_STA is set to "yes" the esp-link module will switch to station mode

@ -106,7 +106,7 @@ int8_t ICACHE_FLASH_ATTR getUInt16Arg(HttpdConnData *connData, char *name, uint1
return 1; return 1;
} }
int8_t ICACHE_FLASH_ATTR getBoolArg(HttpdConnData *connData, char *name, bool *config) { int8_t ICACHE_FLASH_ATTR getBoolArg(HttpdConnData *connData, char *name, uint8_t *config) {
char buff[16]; char buff[16];
int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff)); int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff));
if (len < 0) return 0; // not found, skip if (len < 0) return 0; // not found, skip
@ -206,7 +206,8 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"{ " "{ "
"\"menu\": [ " "\"menu\": [ "
"\"Home\", \"/home.html\", " "\"Home\", \"/home.html\", "
"\"WiFI\", \"/wifi/wifi.html\", " "\"WiFi Station\", \"/wifi/wifiSta.html\", "
"\"WiFi Soft-AP\", \"/wifi/wifiAp.html\", "
"\"&#xb5;C Console\", \"/console.html\", " "\"&#xb5;C Console\", \"/console.html\", "
"\"Services\", \"/services.html\", " "\"Services\", \"/services.html\", "
#ifdef MQTT #ifdef MQTT

@ -1,7 +1,3 @@
/*
Cgi/template routines for the /wifi url.
*/
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
@ -11,6 +7,8 @@
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* Heavily modified and enhanced by Thorsten von Eicken in 2015 * Heavily modified and enhanced by Thorsten von Eicken in 2015
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* Once again heavily modified to add soft-ap settings by KatAst in 2015
* ----------------------------------------------------------------------------
*/ */
#include <esp8266.h> #include <esp8266.h>
@ -34,13 +32,14 @@ bool mdns_started = false;
// ===== wifi status change callbacks // ===== wifi status change callbacks
static WifiStateChangeCb wifi_state_change_cb[4]; static WifiStateChangeCb wifi_state_change_cb[4];
// Temp store for new ap info. // Temp store for new staion config
static struct station_config stconf; struct station_config stconf;
// Temp store for new ap config // Temp store for new ap config
static struct softap_config apconf; struct softap_config apconf;
uint8_t wifiState = wifiIsDisconnected; uint8_t wifiState = wifiIsDisconnected;
// reasons for which a connection failed // reasons for which a connection failed
uint8_t wifiReason = 0; uint8_t wifiReason = 0;
static char *wifiReasons[] = { static char *wifiReasons[] = {
@ -274,10 +273,19 @@ static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
} }
int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
if (connData->requestType == HTTPD_METHOD_GET) { if (connData->requestType == HTTPD_METHOD_GET) {
return cgiWiFiGetScan(connData); return cgiWiFiGetScan(connData);
} else if (connData->requestType == HTTPD_METHOD_POST) { }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); return cgiWiFiStartScan(connData);
}
}else{ }else{
jsonHeader(connData, 404); jsonHeader(connData, 404);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
@ -290,41 +298,34 @@ int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
#define RESET_TIMEOUT (15000) // 15 seconds #define RESET_TIMEOUT (15000) // 15 seconds
static ETSTimer resetTimer; static ETSTimer resetTimer;
// This routine is ran some time after a connection attempt to an access point. If /*
// the connect succeeds, this gets the module in STA-only mode. If it fails, it ensures * This routine is ran some time after a connection attempt to an access point.
// that the module is in STA+AP mode so the user has a chance to recover. * If the connection succeeds and Makefile hard-coded CHANGE_TO_STA is set to yes, this gets the module in STA-only mode.
* If it fails and only STA mode is set, it ensures that the module is in STA+AP mode so the user has a chance to recover.
*/
static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) { static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
int x = wifi_station_get_connect_status(); int x = wifi_station_get_connect_status();
int m = wifi_get_opmode() & 0x3; int m = wifi_get_opmode() & 0x3;
DBG("Wifi check: mode=%s status=%d\n", wifiMode[m], x); DBG("Wifi check: mode=%s status=%d\n", wifiMode[m], x);
if(m!=2){
if( x == STATION_GOT_IP ){ if( x == STATION_GOT_IP ){
if (m != 1) {
#ifdef CHANGE_TO_STA #ifdef CHANGE_TO_STA
// We're happily connected, go to STA mode
DBG("Wifi got IP. Going into STA mode..\n");
wifi_set_opmode(1); wifi_set_opmode(1);
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); // check one more time after switching to STA-only
#endif #endif
}
log_uart(false); log_uart(false);
// no more resetTimer at this point, gotta use physical reset to recover if in trouble
}else{ }else{
log_uart(true);
if (m != 3) { DBG("Enabling/continuing uart log\n");
DBG("Wifi connect failed. Going into STA+AP mode..\n"); if (m==1){
// Set STA+AP mode
wifi_set_opmode(3); wifi_set_opmode(3);
#ifdef AP_SSID
// Call ap set after mode change to AP or STA+AP
wifi_softap_set_config(&apconf); wifi_softap_set_config(&apconf);
#endif
} }
log_uart(true);
DBG("Enabling/continuing uart log\n");
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
} }
} }
}
// Reassociate timer to delay change of association so the original request can finish // Reassociate timer to delay change of association so the original request can finish
static ETSTimer reassTimer; static ETSTimer reassTimer;
@ -347,6 +348,14 @@ static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
// This cgi uses the routines above to connect to a specific access point with the // This cgi uses the routines above to connect to a specific access point with the
// given ESSID using the given password. // given ESSID using the given password.
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { 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 essid[128];
char passwd[128]; char passwd[128];
@ -370,6 +379,8 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
jsonHeader(connData, 400); jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse ssid or password", -1); httpdSend(connData, "Cannot parse ssid or password", -1);
} }
jsonHeader(connData, 400);
httpdSend(connData, "Invalid ssid or password", -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
@ -495,27 +506,173 @@ int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) {
return HTTPD_CGI_DONE; 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;
}
// Get Soft-Ap config, just in case
wifi_softap_get_config(&apconf);
char buff[96];
int len;
// Check extra security measure
len=httpdFindArg(connData->getArgs, "100", buff, sizeof(buff));
if(len>0){
if(atoi(buff)!=1){
jsonHeader(connData, 400);
return HTTPD_CGI_DONE;
}
}
// Get the new SSID and set
len=httpdFindArg(connData->getArgs, "ap_ssid", buff, sizeof(buff));
if(len>7 && len<30){
// STRING PREPROCESSING DONE IN CLIENT SIDE
memset(apconf.ssid, 0, 32);
os_memcpy(apconf.ssid, buff, len);
}else{
jsonHeader(connData, 400);
httpdSend(connData, "SSID name out of range", -1);
return HTTPD_CGI_DONE;
}
// Set new PASSWORD
len=httpdFindArg(connData->getArgs, "ap_password", buff, sizeof(buff));
if(len>7 && len<62){
// STRING PREPROCESSING DONE IN CLIENT SIDE
memset(apconf.password, 0, 64);
os_memcpy(apconf.password, buff, len);
}else{
jsonHeader(connData, 400);
httpdSend(connData, "PASSWORD out of range", -1);
return HTTPD_CGI_DONE;
}
// 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 authentication mode
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;
}
}
// 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
// This should apply new config values
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;
}
// ===== Wifi set mode end info functions
//This cgi changes the operating mode: STA / AP / STA+AP //This cgi changes the operating mode: STA / AP / STA+AP
int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int len; int len;
char buff[1024]; char buff[1024];
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. int previous_mode = wifi_get_opmode();
len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff));
int next_mode = atoi(buff);
if (len!=0) { if (len!=0) {
int m = atoi(buff); if (next_mode == 2){
DBG("Wifi switching to mode %d\n", m); // moving to AP mode, so disconnect before leave STA mode
wifi_set_opmode(m&3); wifi_station_disconnect();
// Call softap set after changing to AP or STA+AP }
wifi_softap_set_config(&apconf);
if (m == 1) { DBG("Wifi switching to mode %d\n", next_mode);
// STA-only mode, reset into STA+AP after a timeout if we don't get an IP address wifi_set_opmode(next_mode&3);
if (previous_mode == 2) {
// movint to STA-only mode from AP, so reset into STA+AP after a timeout if we don't get an IP address
stconf.bssid_set = 0;
wifi_station_set_config(&stconf);
wifi_station_connect();
os_timer_disarm(&resetTimer); os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
} }
if(previous_mode == 1){
// moving to STA or STA+AP, so softap config call needed
wifi_softap_set_config(&apconf);
}
jsonHeader(connData, 200); jsonHeader(connData, 200);
} else { } else {
jsonHeader(connData, 400); jsonHeader(connData, 400);
@ -523,15 +680,30 @@ int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) {
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// Collection of wifi info variables
static char *connStatuses[] = { "idle", "connecting", "wrong password", "AP not found", static char *connStatuses[] = { "idle", "connecting", "wrong password", "AP not found",
"failed", "got IP address" }; "failed", "got IP address" };
static char *wifiWarn[] = { 0, static char *wifiWarn[] = { 0,
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>", "Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>",
"<b>Can't scan in this mode!</b> Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>", "Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>",
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(1)\\\">STA mode</a>", "Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(1)\\\">STA mode</a>",
}; };
static char *apWifiWarn[] = { 0,
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>",
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>",
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(2)\\\">AP mode</a>",
};
static char *apAuthMode[] = { "OPEN",
"WEP",
"WPA_PSK",
"WPA2_PSK",
"WPA_WPA2_PSK",
};
#ifdef CHANGE_TO_STA #ifdef CHANGE_TO_STA
#define MODECHANGE "yes" #define MODECHANGE "yes"
#else #else
@ -540,10 +712,12 @@ static char *wifiWarn[] = { 0,
// print various Wifi information into json buffer // print various Wifi information into json buffer
int ICACHE_FLASH_ATTR printWifiInfo(char *buff) { int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
int len;
struct station_config stconf; int len;
//struct station_config stconf;
wifi_station_get_config(&stconf); wifi_station_get_config(&stconf);
//struct softap_config apconf;
wifi_softap_get_config(&apconf);
uint8_t op = wifi_get_opmode() & 0x3; uint8_t op = wifi_get_opmode() & 0x3;
char *mode = wifiMode[op]; char *mode = wifiMode[op];
@ -553,17 +727,22 @@ int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
int p = wifi_get_phy_mode(); int p = wifi_get_phy_mode();
char *phy = wifiPhy[p&3]; char *phy = wifiPhy[p&3];
char *warn = wifiWarn[op]; char *warn = wifiWarn[op];
char *apwarn = apWifiWarn[op];
char *apauth = apAuthMode[apconf.authmode];
sint8 rssi = wifi_station_get_rssi(); sint8 rssi = wifi_station_get_rssi();
if (rssi > 0) rssi = 0; if (rssi > 0) rssi = 0;
uint8 mac_addr[6]; uint8 mac_addr[6];
uint8 apmac_addr[6];
wifi_get_macaddr(0, mac_addr); wifi_get_macaddr(0, mac_addr);
wifi_get_macaddr(1, apmac_addr);
uint8_t chan = wifi_get_channel(); uint8_t chan = wifi_get_channel();
len = os_sprintf(buff, len = os_sprintf(buff,
"\"mode\": \"%s\", \"modechange\": \"%s\", \"ssid\": \"%s\", \"status\": \"%s\", \"phy\": \"%s\", " "\"mode\": \"%s\", \"modechange\": \"%s\", \"ssid\": \"%s\", \"status\": \"%s\", \"phy\": \"%s\", "
"\"rssi\": \"%ddB\", \"warn\": \"%s\", \"mac\":\"%02x:%02x:%02x:%02x:%02x:%02x\", \"chan\":%d", "\"rssi\": \"%ddB\", \"warn\": \"%s\", \"apwarn\": \"%s\",\"mac\":\"%02x:%02x:%02x:%02x:%02x:%02x\", \"chan\":\"%d\", \"apssid\": \"%s\", "
mode, MODECHANGE, (char*)stconf.ssid, status, phy, rssi, warn, "\"appass\": \"%s\", \"apchan\": \"%d\", \"apmaxc\": \"%d\", \"aphidd\": \"%s\", \"apbeac\": \"%d\", \"apauth\": \"%s\",\"apmac\":\"%02x:%02x:%02x:%02x:%02x:%02x\"",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], chan); 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; struct ip_info info;
if (wifi_get_ip_info(0, &info)) { if (wifi_get_ip_info(0, &info)) {
@ -610,7 +789,7 @@ int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
#endif #endif
len += os_sprintf(buff+len, "\"x\":0}\n"); len += os_sprintf(buff+len, "\"x\":0}\n");
//DBG(" -> %s\n", buff); DBG(" -> %s\n", buff);
httpdSend(connData, buff, len); httpdSend(connData, buff, len);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
@ -630,24 +809,32 @@ int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) {
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// Init the wireless, which consists of setting a timer if we expect to connect to an AP /* Init the wireless
// so we can revert to STA+AP mode if we can't connect. *
* 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() { void ICACHE_FLASH_ATTR wifiInit() {
// Check te wifi opmode // Check te wifi opmode
int x = wifi_get_opmode() & 0x3; 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);
#ifdef CGIWIFI_DBG #ifdef CGIWIFI_DBG
os_printf("Wifi init, mode=%s\n",wifiMode[x]); os_printf("Wifi init, mode=%s\n",wifiMode[x]);
#endif #endif
// STATION parameters only on a full flash // STATION parameters only on a full flash, because default opmode is 2
#if defined(STA_SSID) && defined(STA_PASS) #if defined(STA_SSID) && defined(STA_PASS)
if( x == 2 ){ if( x == 2 ){
// Create struct for station config
struct station_config stconf;
// Call it
wifi_station_get_config(&stconf);
// Set parameters // Set parameters
if (os_strlen((char*)stconf.ssid) == 0 && os_strlen((char*)stconf.password) == 0) { 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.ssid, VERS_STR(STA_SSID), 32);
@ -656,24 +843,22 @@ void ICACHE_FLASH_ATTR wifiInit() {
os_printf("Wifi pre-config trying to connect to AP %s pw %s\n",(char*)stconf.ssid, (char*)stconf.password); os_printf("Wifi pre-config trying to connect to AP %s pw %s\n",(char*)stconf.ssid, (char*)stconf.password);
#endif #endif
// wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky // wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky
// Set wifi mode
wifi_set_opmode(3); // sta+ap, will switch to sta-only 15 secs after connecting
stconf.bssid_set = 0; stconf.bssid_set = 0;
wifi_station_set_config(&stconf); wifi_station_set_config(&stconf);
} }
} }
#endif #endif
// SOFT_AP parameters // Change SOFT_AP parameters if defined
#if defined(AP_SSID) && defined(AP_PASS) #if defined(AP_SSID) && defined(AP_PASS)
// Call it
wifi_softap_get_config(&apconf);
// Clean memory and set the value of SSID // Clean memory and set the value of SSID
memset(apconf.ssid, 0, sizeof(apconf.ssid)); memset(apconf.ssid, 0, 32);
os_memcpy(apconf.ssid, VERS_STR(AP_SSID), strlen(VERS_STR(AP_SSID))); os_memcpy(apconf.ssid, VERS_STR(AP_SSID), strlen(VERS_STR(AP_SSID)));
// Clean memory and set the value of PASS // Clean memory and set the value of PASS
memset(apconf.password, 0, sizeof(apconf.password)); memset(apconf.password, 0, 64);
os_memcpy(apconf.password, VERS_STR(AP_PASS), strlen(VERS_STR(AP_PASS))); os_memcpy(apconf.password, VERS_STR(AP_PASS), strlen(VERS_STR(AP_PASS)));
// Specify the length of pass // Specify the length of pass
apconf.ssid_len= os_strlen((char*)VERS_STR(AP_PASS)); apconf.ssid_len= os_strlen((char*)VERS_STR(AP_PASS));
#ifdef AP_AUTH_MODE #ifdef AP_AUTH_MODE
@ -695,12 +880,14 @@ void ICACHE_FLASH_ATTR wifiInit() {
// If set use specified beacon interval // If set use specified beacon interval
apconf.beacon_interval = AP_BEACON_INTERVAL; apconf.beacon_interval = AP_BEACON_INTERVAL;
#endif #endif
// Set to use the new conf // Check save softap config
bool softap_set_conf = wifi_softap_set_config(&apconf);
#ifdef CGIWIFI_DBG #ifdef CGIWIFI_DBG
// Debug info
os_printf("Wifi AP parameters: %s pw %s\n",(char*)apconf.ssid, (char*)apconf.password); os_printf("Wifi AP parameters: %s pw %s\n",(char*)apconf.ssid, (char*)apconf.password);
os_printf("Wifi Soft-AP parameters set: %s\n",softap_set_conf? "success":"fail");
#endif #endif
// MUST BE called after enabling AP or STA+AP mode
wifi_softap_set_config(&apconf);
#endif // AP_SSID && AP_PASS #endif // AP_SSID && AP_PASS
configWifiIP(); configWifiIP();

@ -13,6 +13,8 @@ int cgiWiFiConnect(HttpdConnData *connData);
int cgiWiFiSetMode(HttpdConnData *connData); int cgiWiFiSetMode(HttpdConnData *connData);
int cgiWiFiConnStatus(HttpdConnData *connData); int cgiWiFiConnStatus(HttpdConnData *connData);
int cgiWiFiSpecial(HttpdConnData *connData); int cgiWiFiSpecial(HttpdConnData *connData);
int cgiApSettingsChange(HttpdConnData *connData);
int cgiApSettingsInfo(HttpdConnData *connData);
void configWifiIP(); void configWifiIP();
void wifiInit(void); void wifiInit(void);
void wifiAddStateChangeCb(WifiStateChangeCb cb); void wifiAddStateChangeCb(WifiStateChangeCb cb);

@ -72,6 +72,8 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/wifi/connstatus", cgiWiFiConnStatus, NULL }, { "/wifi/connstatus", cgiWiFiConnStatus, NULL },
{ "/wifi/setmode", cgiWiFiSetMode, NULL }, { "/wifi/setmode", cgiWiFiSetMode, NULL },
{ "/wifi/special", cgiWiFiSpecial, NULL }, { "/wifi/special", cgiWiFiSpecial, NULL },
{ "/wifi/apinfo", cgiApSettingsInfo, NULL },
{ "/wifi/apchange", cgiApSettingsChange, NULL },
{ "/system/info", cgiSystemInfo, NULL }, { "/system/info", cgiSystemInfo, NULL },
{ "/system/update", cgiSystemSet, NULL }, { "/system/update", cgiSystemSet, NULL },
{ "/services/info", cgiServicesInfo, NULL }, { "/services/info", cgiServicesInfo, NULL },
@ -86,7 +88,6 @@ HttpdBuiltInUrl builtInUrls[] = {
#ifdef SHOW_HEAP_USE #ifdef SHOW_HEAP_USE
static ETSTimer prHeapTimer; static ETSTimer prHeapTimer;
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size()); os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size());
} }
@ -109,26 +110,25 @@ void user_rf_pre_init(void) {
// Main routine to initialize esp-link. // Main routine to initialize esp-link.
void user_init(void) { void user_init(void) {
// get the flash config so we know how to init things // 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(); bool restoreOk = configRestore();
// init gpio pin registers // Init gpio pin registers
gpio_init(); gpio_init();
gpio_output_set(0, 0, 0, (1<<15)); // some people tie it to GND, gotta ensure it's disabled gpio_output_set(0, 0, 0, (1<<15)); // some people tie it to GND, gotta ensure it's disabled
// init UART // init UART
uart_init(flashConfig.baud_rate, 115200); uart_init(flashConfig.baud_rate, 115200);
logInit(); // must come after init of uart 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_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version); os_printf("\n\n** %s\n", esp_link_version);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
// Status LEDs // Status LEDs
statusInit(); statusInit();
serledInit(); serledInit();
// Wifi // Wifi
wifiInit(); wifiInit();
// init the flash filesystem with the html stuff // init the flash filesystem with the html stuff
espFsInit(&_binary_espfs_img_start); espFsInit(&_binary_espfs_img_start);
//EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
@ -154,15 +154,13 @@ void user_init(void) {
fid & 0xff, (fid&0xff00)|((fid>>16)&0xff)); fid & 0xff, (fid&0xff00)|((fid>>16)&0xff));
NOTICE("** esp-link ready"); NOTICE("** esp-link ready");
// Init SNTP service
cgiServicesSNTPInit(); cgiServicesSNTPInit();
#ifdef MQTT #ifdef MQTT
NOTICE("initializing MQTT"); NOTICE("initializing MQTT");
mqtt_client_init(); mqtt_client_init();
#endif #endif
NOTICE("initializing user application"); NOTICE("initializing user application");
app_init(); app_init();
NOTICE("Waiting for work to do...");
NOTICE("waiting for work to do...");
} }

@ -0,0 +1,124 @@
<div id="main">
<div class="header">
<h1>WiFi Soft-AP Configuration</h1>
</div>
<div class="content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
<div class="card">
<h1>Soft-AP State</h1>
<div id="wifi-spinner" class="spinner spinner-small">
</div>
<table id="wifi-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>WiFi mode</td><td id="wifi-mode"></td></tr>
<tr><td>Soft-AP SSID</td><td id="wifi-apssid"></td></tr>
<tr><td>Soft-AP Password</td><td id="wifi-appass"></td></tr>
<tr><td>Soft-AP Channel</td><td id="wifi-apchan"></td></tr>
<tr><td>Soft-AP Max Conn</td><td id="wifi-apmaxc"></td></tr>
<tr><td>Soft-AP Hidden</td><td id="wifi-aphidd"></td></tr>
<tr><td>Soft-AP Beacon Int</td><td id="wifi-apbeac"></td></tr>
<tr><td>Soft-AP Auth Mode</td><td id="wifi-apauth"></td></tr>
<tr><td>Soft-AP MAC</td><td id="wifi-apmac"></td></tr>
<tr><td colspan="2" id="wifi-apwarn"></td></tr>
</tbody> </table>
</div><!-- card-->
</div><!-- pure-u-1 -->
<div class="pure-u-1 pure-u-md-1-2">
<div class="card">
<h1>Soft-AP Settings</h1>
<div id="AP_Settings-spinner" class="spinner spinner-small"></div>
<form action="#" id="AP_Settings-form" class="pure-form" hidden>
<!-- <input type="text" id="conn_check" name="ap_connex" value="0" hidden>-->
<legend>Soft-AP main settings, use with care!</legend>
<div class="pure-form-stacked">
<label>Soft-AP SSID</label>
<input type="text" name="ap_ssid" />
<div class="popup">Change the name of your AP!</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Password</label>
<input type="text" name="ap_password" />
<div class="popup">Password must be at least 8 chars long!</div>
</div>
<div class="pure-form-stacked">
<legend>Soft-AP Advanced Settings</legend>
</div>
<div class="form-horizontal">
<label for="AP_Settings-ron" style="margin-right:1em">
<input type="radio" name="ap" value="on" id="AP_Settings-ron"/>
Show </label>
<label for="AP_Settings-roff" style="margin-right:1em">
<input type="radio" name="ap" value="off" id="AP_Settings-roff"/>
Hide </label>
</div>
<div id="AP_Settings-off" class="pure-form-stacked"></div>
<div id="AP_Settings-on" class="pure-form-stacked">
<div class="pure-form-stacked">
<label>Soft-AP Max Connections</label>
<input type="text" name="ap_maxconn" />
<div class="popup">Max 4 ( default 4 )</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Beacon Interval</label>
<input type="text" name="ap_beacon" />
<div class="popup">Between 100 - 60000 ms ( default 100ms )</div>
</div>
<div class="pure-form-stacked">
<label>Soft-AP Auth Mode</label>
<select name="ap_authmode" href="#">
<option value="0">OPEN</option>
<option value="1">WEP</option>
<option value="2">WPA_PSK</option>
<option value="3">WPA2_PSK</option>
<option value="4">WPA_WPA2_PSK</option>
</select>
<div class="popup">Default WPA_WPA2_PSK</div>
</div>
<div class="form-horizontal">
<label><input type="checkbox" name="ap_hidden" />Soft-AP SSID hidden</label>
<div class="popup">Check this box to hide you Soft-AP SSID ( default Not Hidden )</div>
</div>
</div>
<button id="AP_Settings-button" type="submit" class="pure-button button-primary">
Change Soft-AP settings!
</button>
</form>
</div>
</div><!-- pure-u-1 -->
</div><!-- pure-g -->
</div><!-- content -->
</div><!-- main -->
</div><!-- layout -->
<script type="text/javascript">
</script>
<script src="wifiAp.js"></script>
<script type="text/javascript">
onLoad(function() {
// Show info about AP
getWifiInfo();
// Fetch actual settings
fetchApSettings();
// Hide advanced settings
undoApAdvanced();
bnd($("#AP_Settings-ron"), "click", doApAdvanced);
bnd($("#AP_Settings-roff"), "click", undoApAdvanced);
bnd($("#AP_Settings-form"), "submit", changeApSettings);
});
</script>
</body></html>

@ -0,0 +1,98 @@
var specials = [];
specials["ap_ssid"] = "SSID name";
specials["ap_password"] = "PASSWORD";
specials["ap_maxconn"] = "Max Connections number";
specials["ap_beacon"] = "Beacon Interval";
function changeWifiMode(m) {
blockScan = 1;
hideWarning();
ajaxSpin("POST", "setmode?mode=" + m, function(resp) {
showNotification("Mode changed");
window.setTimeout(getWifiInfo, 100);
blockScan = 0;
}, function(s, st) {
showWarning("Error changing mode: " + st);
window.setTimeout(getWifiInfo, 100);
blockScan = 0;
});
}
function changeApSettings(e) {
e.preventDefault();
var url = "/wifi/apchange?100=1";
var i, inputs = document.querySelectorAll("#" + e.target.id + " input,select");
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
var val = (inputs[i].checked) ? 1 : 0;
url += "&" + inputs[i].name + "=" + val;
}
else{
var clean = inputs[i].value.replace(/[^\w]/gi, "");
var comp = clean.localeCompare(inputs[i].value);
if ( comp != 0 ){
showWarning("Invalid characters in " + specials[inputs[i].name]);
return;
}
url += "&" + inputs[i].name + "=" + clean;
}
};
hideWarning();
var n = e.target.id.replace("-form", "");
var cb = $("#" + n + "-button");
addClass(cb, "pure-button-disabled");
ajaxSpin("POST", url, function (resp) {
showNotification(n + " updated");
removeClass(cb, "pure-button-disabled");
window.setTimeout(getWifiInfo, 100);
}, function (s, st) {
showWarning(st);
removeClass(cb, "pure-button-disabled");
window.setTimeout(fetchApSettings, 2000);
});
}
function displayApSettings(data) {
Object.keys(data).forEach(function (v) {
el = $("#" + v);
if (el != null) {
if (el.nodeName === "INPUT") el.value = data[v];
else el.innerHTML = data[v];
return;
}
el = document.querySelector('input[name="' + v + '"]');
if (el == null)
el = document.querySelector('select[name="' + v + '"]');
if (el != null) {
if (el.type == "checkbox") {
el.checked = data[v] == "enabled";
} else el.value = data[v];
}
});
$("#AP_Settings-spinner").setAttribute("hidden", "");
$("#AP_Settings-form").removeAttribute("hidden");
showWarning("Don't modify SOFTAP parameters with active connections");
window.setTimeout(hideWarning(), 2000);
}
function fetchApSettings() {
ajaxJson("GET", "/wifi/apinfo", displayApSettings, function () {
window.setTimeout(fetchApSettings, 1000);
});
}
function doApAdvanced() {
$('#AP_Settings-on').removeAttribute('hidden');
$("#AP_Settings-off").setAttribute("hidden", "");
$("#AP_Settings-roff").removeAttribute("checked");
}
function undoApAdvanced(){
$("#AP_Settings-on").setAttribute("hidden", "");
$("#AP_Settings-off").removeAttribute("hidden");
$("#AP_Settings-roff").setAttribute("checked", "");
}

@ -1,6 +1,6 @@
<div id="main"> <div id="main">
<div class="header"> <div class="header">
<h1>WiFi Configuration</h1> <h1>WiFi Station Configuration</h1>
</div> </div>
<div class="content"> <div class="content">
@ -19,7 +19,9 @@
<tr><td>WiFi MAC</td><td id="wifi-mac"></td></tr> <tr><td>WiFi MAC</td><td id="wifi-mac"></td></tr>
<tr><td colspan="2" id="wifi-warn"></td></tr> <tr><td colspan="2" id="wifi-warn"></td></tr>
</tbody> </table> </tbody> </table>
</div></div> </div>
</div>
<div class="pure-u-1 pure-u-md-1-2"><div class="card"> <div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>WiFi Association</h1> <h1>WiFi Association</h1>
<p id="reconnect" style="color: #600" hidden></p> <p id="reconnect" style="color: #600" hidden></p>
@ -70,7 +72,7 @@
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
<script src="wifi.js"></script> <script src="wifiSta.js"></script>
<script type="text/javascript"> <script type="text/javascript">
onLoad(function() { onLoad(function() {
getWifiInfo(); getWifiInfo();
Loading…
Cancel
Save