diff --git a/esp-link/cgiwifi.c b/esp-link/cgiwifi.c old mode 100644 new mode 100755 index 6ca78d8..af496ee --- a/esp-link/cgiwifi.c +++ b/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 @@ -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; - - 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; nnext.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. + 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; nnext.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; - } - } - - 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; + 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; } - - len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n"); - connData->cgiData = (void *)1; // start with first result next time we're called + } + + 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_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]; - - 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)); - - 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); - } + char essid[128]; + char passwd[128]; + + 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)); + + 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, "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; - - // 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)); - - } 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); + char dhcp[8]; + char staticip[20]; + char netmask[20]; + char gateway[20]; + + if (connData->conn==NULL) return HTTPD_CGI_DONE; + + // 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)); + + } 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 @@ -522,13 +514,13 @@ int ICACHE_FLASH_ATTR cgiApSettingsChange(HttpdConnData *connData) { httpdSend(connData, "No changes allowed in STA mode", -1); return HTTPD_CGI_DONE; } - + char buff[96]; int len; // 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) { - - 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)); - + 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)); 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 STA+AP mode", @@ -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; - - 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, ", "); - - if (wifiReason != 0) { - len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason()); - } - + char buff[1024]; + int len; + + 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, ", "); + + 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]; - - if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. - - os_strcpy(buff, "{"); - printWifiInfo(buff+1); - os_strcat(buff, "}"); - - jsonHeader(connData, 200); - httpdSend(connData, buff, -1); - return HTTPD_CGI_DONE; + char buff[1024]; + + if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. + + os_strcpy(buff, "{"); + printWifiInfo(buff+1); + os_strcat(buff, "}"); + + jsonHeader(connData, 200); + httpdSend(connData, buff, -1); + return HTTPD_CGI_DONE; } // Check string againt invalid characters @@ -857,24 +841,24 @@ void ICACHE_FLASH_ATTR wifiInit() { 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); - } + + // 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 @@ -931,7 +915,7 @@ void ICACHE_FLASH_ATTR wifiInit() { // 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 @@ -947,5 +931,4 @@ void ICACHE_FLASH_ATTR wifiInit() { os_timer_disarm(&resetTimer); os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); -} - +} \ No newline at end of file