Fix indentation

pull/84/head
KatAst 9 years ago
parent 8351fb4599
commit 9dd3eac804
  1. 759
      esp-link/cgiwifi.c

@ -1,3 +1,7 @@
/*
Cgi/template routines for the /wifi url.
*/
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
@ -7,8 +11,6 @@
* ----------------------------------------------------------------------------
* 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>
@ -39,16 +41,15 @@ struct station_config stconf;
struct softap_config apconf;
uint8_t wifiState = wifiIsDisconnected;
// reasons for which a connection failed
uint8_t wifiReason = 0;
static char *wifiReasons[] = {
"", "unspecified", "auth_expire", "auth_leave", "assoc_expire", "assoc_toomany", "not_authed",
"not_assoced", "assoc_leave", "assoc_not_authed", "disassoc_pwrcap_bad", "disassoc_supchan_bad",
"ie_invalid", "mic_failure", "4way_handshake_timeout", "group_key_update_timeout",
"ie_in_4way_differs", "group_cipher_invalid", "pairwise_cipher_invalid", "akmp_invalid",
"unsupp_rsn_ie_version", "invalid_rsn_ie_cap", "802_1x_auth_failed", "cipher_suite_rejected",
"beacon_timeout", "no_ap_found" };
"", "unspecified", "auth_expire", "auth_leave", "assoc_expire", "assoc_toomany", "not_authed",
"not_assoced", "assoc_leave", "assoc_not_authed", "disassoc_pwrcap_bad", "disassoc_supchan_bad",
"ie_invalid", "mic_failure", "4way_handshake_timeout", "group_key_update_timeout",
"ie_in_4way_differs", "group_cipher_invalid", "pairwise_cipher_invalid", "akmp_invalid",
"unsupp_rsn_ie_version", "invalid_rsn_ie_cap", "802_1x_auth_failed", "cipher_suite_rejected",
"beacon_timeout", "no_ap_found" };
static char *wifiMode[] = { 0, "STA", "AP", "AP+STA" };
static char *wifiPhy[] = { 0, "11b", "11g", "11n" };
@ -56,100 +57,100 @@ static char *wifiPhy[] = { 0, "11b", "11g", "11n" };
void (*wifiStatusCb)(uint8_t); // callback when wifi status changes
static char* ICACHE_FLASH_ATTR wifiGetReason(void) {
if (wifiReason <= 24) return wifiReasons[wifiReason];
if (wifiReason >= 200 && wifiReason <= 201) return wifiReasons[wifiReason-200+24];
return wifiReasons[1];
if (wifiReason <= 24) return wifiReasons[wifiReason];
if (wifiReason >= 200 && wifiReason <= 201) return wifiReasons[wifiReason-200+24];
return wifiReasons[1];
}
// handler for wifi status change callback coming in from espressif library
static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) {
switch (evt->event) {
case EVENT_STAMODE_CONNECTED:
wifiState = wifiIsConnected;
wifiReason = 0;
DBG("Wifi connected to ssid %s, ch %d\n", evt->event_info.connected.ssid,
evt->event_info.connected.channel);
statusWifiUpdate(wifiState);
break;
case EVENT_STAMODE_DISCONNECTED:
wifiState = wifiIsDisconnected;
wifiReason = evt->event_info.disconnected.reason;
DBG("Wifi disconnected from ssid %s, reason %s (%d)\n",
evt->event_info.disconnected.ssid, wifiGetReason(), evt->event_info.disconnected.reason);
statusWifiUpdate(wifiState);
break;
case EVENT_STAMODE_AUTHMODE_CHANGE:
DBG("Wifi auth mode: %d -> %d\n",
evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode);
break;
case EVENT_STAMODE_GOT_IP:
wifiState = wifiGotIP;
wifiReason = 0;
DBG("Wifi got ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n",
IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw));
statusWifiUpdate(wifiState);
if (!mdns_started)
wifiStartMDNS(evt->event_info.got_ip.ip);
break;
case EVENT_SOFTAPMODE_STACONNECTED:
DBG("Wifi AP: station " MACSTR " joined, AID = %d\n",
MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid);
break;
case EVENT_SOFTAPMODE_STADISCONNECTED:
DBG("Wifi AP: station " MACSTR " left, AID = %d\n",
MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid);
break;
default:
break;
}
for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] != NULL) (wifi_state_change_cb[i])(wifiState);
}
switch (evt->event) {
case EVENT_STAMODE_CONNECTED:
wifiState = wifiIsConnected;
wifiReason = 0;
DBG("Wifi connected to ssid %s, ch %d\n", evt->event_info.connected.ssid,
evt->event_info.connected.channel);
statusWifiUpdate(wifiState);
break;
case EVENT_STAMODE_DISCONNECTED:
wifiState = wifiIsDisconnected;
wifiReason = evt->event_info.disconnected.reason;
DBG("Wifi disconnected from ssid %s, reason %s (%d)\n",
evt->event_info.disconnected.ssid, wifiGetReason(), evt->event_info.disconnected.reason);
statusWifiUpdate(wifiState);
break;
case EVENT_STAMODE_AUTHMODE_CHANGE:
DBG("Wifi auth mode: %d -> %d\n",
evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode);
break;
case EVENT_STAMODE_GOT_IP:
wifiState = wifiGotIP;
wifiReason = 0;
DBG("Wifi got ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n",
IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw));
statusWifiUpdate(wifiState);
if (!mdns_started)
wifiStartMDNS(evt->event_info.got_ip.ip);
break;
case EVENT_SOFTAPMODE_STACONNECTED:
DBG("Wifi AP: station " MACSTR " joined, AID = %d\n",
MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid);
break;
case EVENT_SOFTAPMODE_STADISCONNECTED:
DBG("Wifi AP: station " MACSTR " left, AID = %d\n",
MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid);
break;
default:
break;
}
for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] != NULL) (wifi_state_change_cb[i])(wifiState);
}
}
void ICACHE_FLASH_ATTR wifiAddStateChangeCb(WifiStateChangeCb cb) {
for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] == cb) return;
if (wifi_state_change_cb[i] == NULL) {
wifi_state_change_cb[i] = cb;
return;
}
}
DBG("WIFI: max state change cb count exceeded\n");
for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] == cb) return;
if (wifi_state_change_cb[i] == NULL) {
wifi_state_change_cb[i] = cb;
return;
}
}
DBG("WIFI: max state change cb count exceeded\n");
}
void ICACHE_FLASH_ATTR wifiStartMDNS(struct ip_addr ip) {
if (flashConfig.mdns_enable) {
struct mdns_info *mdns_info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info));
mdns_info->host_name = flashConfig.hostname;
mdns_info->server_name = flashConfig.mdns_servername;
mdns_info->server_port = 80;
mdns_info->ipAddr = ip.addr;
espconn_mdns_init(mdns_info);
}
else {
espconn_mdns_server_unregister();
espconn_mdns_close();
}
mdns_started = true;
if (flashConfig.mdns_enable) {
struct mdns_info *mdns_info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info));
mdns_info->host_name = flashConfig.hostname;
mdns_info->server_name = flashConfig.mdns_servername;
mdns_info->server_port = 80;
mdns_info->ipAddr = ip.addr;
espconn_mdns_init(mdns_info);
}
else {
espconn_mdns_server_unregister();
espconn_mdns_close();
}
mdns_started = true;
}
// ===== wifi scanning
//WiFi access point data
typedef struct {
char ssid[32];
sint8 rssi;
char enc;
char ssid[32];
sint8 rssi;
char enc;
} ApData;
//Scan result
typedef struct {
char scanInProgress; //if 1, don't access the underlying stuff from the webpage.
ApData **apData;
int noAps;
char scanInProgress; //if 1, don't access the underlying stuff from the webpage.
ApData **apData;
int noAps;
} ScanResultData;
//Static scan status storage.
@ -158,126 +159,124 @@ static ScanResultData cgiWifiAps;
//Callback the code calls when a wlan ap scan is done. Basically stores the result in
//the cgiWifiAps struct.
void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) {
int n;
struct bss_info *bss_link = (struct bss_info *)arg;
int n;
struct bss_info *bss_link = (struct bss_info *)arg;
if (status!=OK) {
DBG("wifiScanDoneCb status=%d\n", status);
cgiWifiAps.scanInProgress=0;
return;
}
//Clear prev ap data if needed.
if (cgiWifiAps.apData!=NULL) {
for (n=0; n<cgiWifiAps.noAps; n++) os_free(cgiWifiAps.apData[n]);
os_free(cgiWifiAps.apData);
}
//Count amount of access points found.
n=0;
while (bss_link != NULL) {
bss_link = bss_link->next.stqe_next;
n++;
}
//Allocate memory for access point data
cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n);
cgiWifiAps.noAps=n;
DBG("Scan done: found %d APs\n", n);
//Copy access point data to the static struct
n=0;
bss_link = (struct bss_info *)arg;
while (bss_link != NULL) {
if (n>=cgiWifiAps.noAps) {
//This means the bss_link changed under our nose. Shouldn't happen!
//Break because otherwise we will write in unallocated memory.
DBG("Huh? I have more than the allocated %d aps!\n", cgiWifiAps.noAps);
break;
}
//Save the ap data.
cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData));
cgiWifiAps.apData[n]->rssi=bss_link->rssi;
cgiWifiAps.apData[n]->enc=bss_link->authmode;
strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32);
DBG("bss%d: %s (%d)\n", n+1, (char*)bss_link->ssid, bss_link->rssi);
bss_link = bss_link->next.stqe_next;
n++;
}
//We're done.
if (status!=OK) {
DBG("wifiScanDoneCb status=%d\n", status);
cgiWifiAps.scanInProgress=0;
return;
}
//Clear prev ap data if needed.
if (cgiWifiAps.apData!=NULL) {
for (n=0; n<cgiWifiAps.noAps; n++) os_free(cgiWifiAps.apData[n]);
os_free(cgiWifiAps.apData);
}
//Count amount of access points found.
n=0;
while (bss_link != NULL) {
bss_link = bss_link->next.stqe_next;
n++;
}
//Allocate memory for access point data
cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n);
cgiWifiAps.noAps=n;
DBG("Scan done: found %d APs\n", n);
//Copy access point data to the static struct
n=0;
bss_link = (struct bss_info *)arg;
while (bss_link != NULL) {
if (n>=cgiWifiAps.noAps) {
//This means the bss_link changed under our nose. Shouldn't happen!
//Break because otherwise we will write in unallocated memory.
DBG("Huh? I have more than the allocated %d aps!\n", cgiWifiAps.noAps);
break;
}
//Save the ap data.
cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData));
cgiWifiAps.apData[n]->rssi=bss_link->rssi;
cgiWifiAps.apData[n]->enc=bss_link->authmode;
strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32);
DBG("bss%d: %s (%d)\n", n+1, (char*)bss_link->ssid, bss_link->rssi);
bss_link = bss_link->next.stqe_next;
n++;
}
//We're done.
cgiWifiAps.scanInProgress=0;
}
static ETSTimer scanTimer;
static void ICACHE_FLASH_ATTR scanStartCb(void *arg) {
DBG("Starting a scan\n");
wifi_station_scan(NULL, wifiScanDoneCb);
DBG("Starting a scan\n");
wifi_station_scan(NULL, wifiScanDoneCb);
}
static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
if (!cgiWifiAps.scanInProgress) {
cgiWifiAps.scanInProgress = 1;
os_timer_disarm(&scanTimer);
os_timer_setfn(&scanTimer, scanStartCb, NULL);
os_timer_arm(&scanTimer, 200, 0);
}
return HTTPD_CGI_DONE;
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
if (!cgiWifiAps.scanInProgress) {
cgiWifiAps.scanInProgress = 1;
os_timer_disarm(&scanTimer);
os_timer_setfn(&scanTimer, scanStartCb, NULL);
os_timer_arm(&scanTimer, 200, 0);
}
return HTTPD_CGI_DONE;
}
static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[1460];
const int chunk = 1460/64; // ssid is up to 32 chars
int len = 0;
os_printf("GET scan: cgiData=%d noAps=%d\n", (int)connData->cgiData, cgiWifiAps.noAps);
// handle continuation call, connData->cgiData-1 is the position in the scan results where we
// we need to continue sending from (using -1 'cause 0 means it's the first call)
if (connData->cgiData) {
int next = (int)connData->cgiData-1;
int pos = next;
while (pos < cgiWifiAps.noAps && pos < next+chunk) {
len += os_sprintf(buff+len, "{\"essid\": \"%s\", \"rssi\": %d, \"enc\": \"%d\"}%c\n",
cgiWifiAps.apData[pos]->ssid, cgiWifiAps.apData[pos]->rssi, cgiWifiAps.apData[pos]->enc,
(pos+1 == cgiWifiAps.noAps) ? ' ' : ',');
pos++;
}
// done or more?
if (pos == cgiWifiAps.noAps) {
len += os_sprintf(buff+len, "]}}\n");
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
} else {
connData->cgiData = (void*)(pos+1);
httpdSend(connData, buff, len);
return HTTPD_CGI_MORE;
}
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[1460];
const int chunk = 1460/64; // ssid is up to 32 chars
int len = 0;
os_printf("GET scan: cgiData=%d noAps=%d\n", (int)connData->cgiData, cgiWifiAps.noAps);
// handle continuation call, connData->cgiData-1 is the position in the scan results where we
// we need to continue sending from (using -1 'cause 0 means it's the first call)
if (connData->cgiData) {
int next = (int)connData->cgiData-1;
int pos = next;
while (pos < cgiWifiAps.noAps && pos < next+chunk) {
len += os_sprintf(buff+len, "{\"essid\": \"%s\", \"rssi\": %d, \"enc\": \"%d\"}%c\n",
cgiWifiAps.apData[pos]->ssid, cgiWifiAps.apData[pos]->rssi, cgiWifiAps.apData[pos]->enc,
(pos+1 == cgiWifiAps.noAps) ? ' ' : ',');
pos++;
}
// done or more?
if (pos == cgiWifiAps.noAps) {
len += os_sprintf(buff+len, "]}}\n");
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
} else {
connData->cgiData = (void*)(pos+1);
httpdSend(connData, buff, len);
return HTTPD_CGI_MORE;
}
}
jsonHeader(connData, 200);
if (cgiWifiAps.scanInProgress==1) {
//We're still scanning. Tell Javascript code that.
len = os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
}
jsonHeader(connData, 200);
len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n");
connData->cgiData = (void *)1; // start with first result next time we're called
if (cgiWifiAps.scanInProgress==1) {
//We're still scanning. Tell Javascript code that.
len = os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
httpdSend(connData, buff, len);
return HTTPD_CGI_MORE;
return HTTPD_CGI_DONE;
}
len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n");
connData->cgiData = (void *)1; // start with first result next time we're called
httpdSend(connData, buff, len);
return HTTPD_CGI_MORE;
}
int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
if (connData->requestType == HTTPD_METHOD_GET) {
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){
@ -298,13 +297,10 @@ int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
#define RESET_TIMEOUT (15000) // 15 seconds
static ETSTimer resetTimer;
/*
* This routine is ran some time after a connection attempt to an access point.
* 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.
*/
// 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
// that the module is in STA+AP mode so the user has a chance to recover.
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);
@ -312,8 +308,8 @@ static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
if(m!=2){
if( x == STATION_GOT_IP ){
#ifdef CHANGE_TO_STA
if(m != 1)
wifi_set_opmode(1);
if(m != 1)
wifi_set_opmode(1);
#endif
log_uart(false);
}else{
@ -333,178 +329,174 @@ static ETSTimer reassTimer;
// Callback actually doing reassociation
static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
DBG("Wifi changing association\n");
wifi_station_disconnect();
stconf.bssid_set = 0;
wifi_station_set_config(&stconf);
wifi_station_connect();
// Schedule check, we give some extra time (4x) 'cause the reassociation can cause the AP
// to have to change channel, and then the client needs to follow before it can see the
// IP address
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 4*RESET_TIMEOUT, 0);
DBG("Wifi changing association\n");
wifi_station_disconnect();
stconf.bssid_set = 0;
wifi_station_set_config(&stconf);
wifi_station_connect();
// Schedule check, we give some extra time (4x) 'cause the reassociation can cause the AP
// to have to change channel, and then the client needs to follow before it can see the
// IP address
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 4*RESET_TIMEOUT, 0);
}
// 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];
char essid[128];
char passwd[128];
if (connData->conn==NULL) return HTTPD_CGI_DONE;
if (connData->conn==NULL) return HTTPD_CGI_DONE;
int el = httpdFindArg(connData->getArgs, "essid", essid, sizeof(essid));
int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd));
int el = httpdFindArg(connData->getArgs, "essid", essid, sizeof(essid));
int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd));
if (el > 0 && pl >= 0) {
//Set to 0 if you want to disable the actual reconnecting bit
os_strncpy((char*)stconf.ssid, essid, 32);
os_strncpy((char*)stconf.password, passwd, 64);
DBG("Wifi try to connect to AP %s pw %s\n", essid, passwd);
if (el > 0 && pl >= 0) {
//Set to 0 if you want to disable the actual reconnecting bit
os_strncpy((char*)stconf.ssid, essid, 32);
os_strncpy((char*)stconf.password, passwd, 64);
DBG("Wifi try to connect to AP %s pw %s\n", essid, passwd);
//Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
jsonHeader(connData, 200);
} else {
jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse ssid or password", -1);
}
//Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
jsonHeader(connData, 200);
} else {
jsonHeader(connData, 400);
httpdSend(connData, "Invalid ssid or password", -1);
return HTTPD_CGI_DONE;
httpdSend(connData, "Cannot parse ssid or password", -1);
}
return HTTPD_CGI_DONE;
}
static bool ICACHE_FLASH_ATTR parse_ip(char *buff, ip_addr_t *ip_ptr) {
char *next = buff; // where to start parsing next integer
int found = 0; // number of integers parsed
uint32_t ip = 0; // the ip addres parsed
for (int i=0; i<32; i++) { // 32 is just a safety limit
char c = buff[i];
if (c == '.' || c == 0) {
// parse the preceding integer and accumulate into IP address
bool last = c == 0;
buff[i] = 0;
uint32_t v = atoi(next);
ip = ip | ((v&0xff)<<(found*8));
next = buff+i+1; // next integer starts after the '.'
found++;
if (last) { // if at end of string we better got 4 integers
ip_ptr->addr = ip;
return found == 4;
}
continue;
}
if (c < '0' || c > '9') return false;
}
return false;
char *next = buff; // where to start parsing next integer
int found = 0; // number of integers parsed
uint32_t ip = 0; // the ip addres parsed
for (int i=0; i<32; i++) { // 32 is just a safety limit
char c = buff[i];
if (c == '.' || c == 0) {
// parse the preceding integer and accumulate into IP address
bool last = c == 0;
buff[i] = 0;
uint32_t v = atoi(next);
ip = ip | ((v&0xff)<<(found*8));
next = buff+i+1; // next integer starts after the '.'
found++;
if (last) { // if at end of string we better got 4 integers
ip_ptr->addr = ip;
return found == 4;
}
continue;
}
if (c < '0' || c > '9') return false;
}
return false;
}
#ifdef DEBUGIP
static void ICACHE_FLASH_ATTR debugIP() {
struct ip_info info;
if (wifi_get_ip_info(0, &info)) {
os_printf("\"ip\": \"%d.%d.%d.%d\"\n", IP2STR(&info.ip.addr));
os_printf("\"netmask\": \"%d.%d.%d.%d\"\n", IP2STR(&info.netmask.addr));
os_printf("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr));
os_printf("\"hostname\": \"%s\"\n", wifi_station_get_hostname());
} else {
os_printf("\"ip\": \"-none-\"\n");
}
struct ip_info info;
if (wifi_get_ip_info(0, &info)) {
os_printf("\"ip\": \"%d.%d.%d.%d\"\n", IP2STR(&info.ip.addr));
os_printf("\"netmask\": \"%d.%d.%d.%d\"\n", IP2STR(&info.netmask.addr));
os_printf("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr));
os_printf("\"hostname\": \"%s\"\n", wifi_station_get_hostname());
} else {
os_printf("\"ip\": \"-none-\"\n");
}
}
#endif
// configure Wifi, specifically DHCP vs static IP address based on flash config
void ICACHE_FLASH_ATTR configWifiIP() {
if (flashConfig.staticip == 0) {
// let's DHCP!
wifi_station_set_hostname(flashConfig.hostname);
if (wifi_station_dhcpc_status() == DHCP_STARTED)
wifi_station_dhcpc_stop();
wifi_station_dhcpc_start();
DBG("Wifi uses DHCP, hostname=%s\n", flashConfig.hostname);
} else {
// no DHCP, we got static network config!
wifi_station_dhcpc_stop();
struct ip_info ipi;
ipi.ip.addr = flashConfig.staticip;
ipi.netmask.addr = flashConfig.netmask;
ipi.gw.addr = flashConfig.gateway;
wifi_set_ip_info(0, &ipi);
DBG("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr));
}
if (flashConfig.staticip == 0) {
// let's DHCP!
wifi_station_set_hostname(flashConfig.hostname);
if (wifi_station_dhcpc_status() == DHCP_STARTED)
wifi_station_dhcpc_stop();
wifi_station_dhcpc_start();
DBG("Wifi uses DHCP, hostname=%s\n", flashConfig.hostname);
} else {
// no DHCP, we got static network config!
wifi_station_dhcpc_stop();
struct ip_info ipi;
ipi.ip.addr = flashConfig.staticip;
ipi.netmask.addr = flashConfig.netmask;
ipi.gw.addr = flashConfig.gateway;
wifi_set_ip_info(0, &ipi);
DBG("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr));
}
#ifdef DEBUGIP
debugIP();
debugIP();
#endif
}
// Change special settings
int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) {
char dhcp[8];
char staticip[20];
char netmask[20];
char gateway[20];
if (connData->conn==NULL) return HTTPD_CGI_DONE;
char dhcp[8];
char staticip[20];
char netmask[20];
char gateway[20];
// get args and their string lengths
int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp));
int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip));
int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask));
int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway));
if (!(dl > 0 && sl >= 0 && nl >= 0 && gl >= 0)) {
jsonHeader(connData, 400);
httpdSend(connData, "Request is missing fields", -1);
return HTTPD_CGI_DONE;
}
char url[64]; // redirect URL
if (os_strcmp(dhcp, "off") == 0) {
// parse static IP params
struct ip_info ipi;
bool ok = parse_ip(staticip, &ipi.ip);
if (nl > 0) ok = ok && parse_ip(netmask, &ipi.netmask);
else IP4_ADDR(&ipi.netmask, 255, 255, 255, 0);
if (gl > 0) ok = ok && parse_ip(gateway, &ipi.gw);
else ipi.gw.addr = 0;
if (!ok) {
jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse static IP config", -1);
return HTTPD_CGI_DONE;
}
// save the params in flash
flashConfig.staticip = ipi.ip.addr;
flashConfig.netmask = ipi.netmask.addr;
flashConfig.gateway = ipi.gw.addr;
// construct redirect URL
os_sprintf(url, "{\"url\": \"http://%d.%d.%d.%d\"}", IP2STR(&ipi.ip));
if (connData->conn==NULL) return HTTPD_CGI_DONE;
} else {
// dynamic IP
flashConfig.staticip = 0;
os_sprintf(url, "{\"url\": \"http://%s\"}", flashConfig.hostname);
}
// get args and their string lengths
int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp));
int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip));
int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask));
int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway));
configSave(); // ignore error...
// schedule change-over
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, configWifiIP, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
// return redirect info
jsonHeader(connData, 200);
httpdSend(connData, url, -1);
if (!(dl > 0 && sl >= 0 && nl >= 0 && gl >= 0)) {
jsonHeader(connData, 400);
httpdSend(connData, "Request is missing fields", -1);
return HTTPD_CGI_DONE;
}
char url[64]; // redirect URL
if (os_strcmp(dhcp, "off") == 0) {
// parse static IP params
struct ip_info ipi;
bool ok = parse_ip(staticip, &ipi.ip);
if (nl > 0) ok = ok && parse_ip(netmask, &ipi.netmask);
else IP4_ADDR(&ipi.netmask, 255, 255, 255, 0);
if (gl > 0) ok = ok && parse_ip(gateway, &ipi.gw);
else ipi.gw.addr = 0;
if (!ok) {
jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse static IP config", -1);
return HTTPD_CGI_DONE;
}
// save the params in flash
flashConfig.staticip = ipi.ip.addr;
flashConfig.netmask = ipi.netmask.addr;
flashConfig.gateway = ipi.gw.addr;
// construct redirect URL
os_sprintf(url, "{\"url\": \"http://%d.%d.%d.%d\"}", IP2STR(&ipi.ip));
} else {
// dynamic IP
flashConfig.staticip = 0;
os_sprintf(url, "{\"url\": \"http://%s\"}", flashConfig.hostname);
}
configSave(); // ignore error...
// schedule change-over
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, configWifiIP, NULL);
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
// return redirect info
jsonHeader(connData, 200);
httpdSend(connData, url, -1);
return HTTPD_CGI_DONE;
}
// ==== Soft-AP related functions
@ -528,7 +520,7 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
// Do we need a password?
bool pass_need=true;
// Check extra security measure
// Check extra security measure, this must be 1
len=httpdFindArg(connData->getArgs, "100", buff, sizeof(buff));
if(len>0){
if(atoi(buff)!=1){
@ -543,9 +535,9 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
os_memset(apconf.ssid, 0, 32);
os_memcpy(apconf.ssid, buff, len);
apconf.ssid_len = len;
pass_need = true;
pass_need = true; // ssid ok, look for a valid password
}else{
pass_need = false;
pass_need = false; // ssid wrong, neither pass not auth mode are needed
jsonHeader(connData, 400);
httpdSend(connData, "SSID not valid or out of range", -1);
return HTTPD_CGI_DONE;
@ -553,13 +545,13 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) {
// Set new PASSWORD
if( pass_need ){
len=httpdFindArg(connData->getArgs, "ap_password", buff, sizeof(buff));
if(checkString(buff) && len>7 && len<62){
if(checkString(buff) && len>7 && len<64){
// STRING PREPROCESSING DONE IN CLIENT SIDE
os_memset(apconf.password, 0, 64);
os_memcpy(apconf.password, buff, len);
pass_need = true;
pass_need = true; // pass ok, look for auth mode
}else if (len == 0){
pass_need = false;
pass_need = false; // pass wrong, no need to look for an auth mode
os_memset(apconf.password, 0, 64);
}else{
jsonHeader(connData, 400);
@ -654,19 +646,14 @@ int ICACHE_FLASH_ATTR cgiApSettingsInfo(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
// ===== Wifi set mode end info functions
//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.
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int len;
char buff[1024];
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) {
@ -698,10 +685,8 @@ int ICACHE_FLASH_ATTR cgiWiFiSetMode(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
// Collection of wifi info variables
static char *connStatuses[] = { "idle", "connecting", "wrong password", "AP not found",
"failed", "got IP address" };
"failed", "got IP address" };
static char *wifiWarn[] = { 0,
"Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(3)\\\">STA+AP mode</a>",
@ -725,8 +710,7 @@ static char *apAuthMode[] = { "OPEN",
// print various Wifi information into json buffer
int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
int len;
int len;
//struct station_config stconf;
wifi_station_get_config(&stconf);
//struct softap_config apconf;
@ -774,53 +758,53 @@ int ICACHE_FLASH_ATTR printWifiInfo(char *buff) {
}
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
char buff[1024];
int len;
char buff[1024];
int len;
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200);
len = os_sprintf(buff, "{");
len += printWifiInfo(buff+len);
len += os_sprintf(buff+len, ", ");
len = os_sprintf(buff, "{");
len += printWifiInfo(buff+len);
len += os_sprintf(buff+len, ", ");
if (wifiReason != 0) {
len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason());
}
if (wifiReason != 0) {
len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason());
}
#if 0
// commented out 'cause often the client that requested the change can't get a request in to
// find out that it succeeded. Better to just wait the std 15 seconds...
int st=wifi_station_get_connect_status();
if (st == STATION_GOT_IP) {
if (wifi_get_opmode() != 1) {
// Reset into AP-only mode sooner.
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 1000, 0);
}
}
// commented out 'cause often the client that requested the change can't get a request in to
// find out that it succeeded. Better to just wait the std 15 seconds...
int st=wifi_station_get_connect_status();
if (st == STATION_GOT_IP) {
if (wifi_get_opmode() != 1) {
// Reset into AP-only mode sooner.
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 1000, 0);
}
}
#endif
len += os_sprintf(buff+len, "\"x\":0}\n");
DBG(" -> %s\n", buff);
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
len += os_sprintf(buff+len, "\"x\":0}\n");
//DBG(" -> %s\n", buff);
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
}
// Cgi to return various Wifi information
int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) {
char buff[1024];
char buff[1024];
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
os_strcpy(buff, "{");
printWifiInfo(buff+1);
os_strcat(buff, "}");
os_strcpy(buff, "{");
printWifiInfo(buff+1);
os_strcat(buff, "}");
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
// Check string againt invalid characters
@ -864,17 +848,17 @@ void ICACHE_FLASH_ATTR wifiInit() {
// 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);
// 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);
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);
}
// wifi_set_phy_mode(2); // limit to 802.11b/g 'cause n is flaky
stconf.bssid_set = 0;
wifi_station_set_config(&stconf);
}
#endif
@ -948,4 +932,3 @@ void ICACHE_FLASH_ATTR wifiInit() {
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
}

Loading…
Cancel
Save