indentation changes

pull/47/head
Thorsten von Eicken 9 years ago
parent 0bb7dba498
commit da7a1b913f
  1. 824
      esp-link/cgiwifi.c

@ -31,12 +31,12 @@ 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[] = {
"", "unspecified", "auth_expire", "auth_leave", "assoc_expire", "assoc_toomany", "not_authed", "", "unspecified", "auth_expire", "auth_leave", "assoc_expire", "assoc_toomany", "not_authed",
"not_assoced", "assoc_leave", "assoc_not_authed", "disassoc_pwrcap_bad", "disassoc_supchan_bad", "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_invalid", "mic_failure", "4way_handshake_timeout", "group_key_update_timeout",
"ie_in_4way_differs", "group_cipher_invalid", "pairwise_cipher_invalid", "akmp_invalid", "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", "unsupp_rsn_ie_version", "invalid_rsn_ie_cap", "802_1x_auth_failed", "cipher_suite_rejected",
"beacon_timeout", "no_ap_found" }; "beacon_timeout", "no_ap_found" };
static char *wifiMode[] = { 0, "STA", "AP", "AP+STA" }; static char *wifiMode[] = { 0, "STA", "AP", "AP+STA" };
static char *wifiPhy[] = { 0, "11b", "11g", "11n" }; static char *wifiPhy[] = { 0, "11b", "11g", "11n" };
@ -44,51 +44,51 @@ static char *wifiPhy[] = { 0, "11b", "11g", "11n" };
void (*wifiStatusCb)(uint8_t); // callback when wifi status changes void (*wifiStatusCb)(uint8_t); // callback when wifi status changes
static char* ICACHE_FLASH_ATTR wifiGetReason(void) { static char* ICACHE_FLASH_ATTR wifiGetReason(void) {
if (wifiReason <= 24) return wifiReasons[wifiReason]; if (wifiReason <= 24) return wifiReasons[wifiReason];
if (wifiReason >= 200 && wifiReason <= 201) return wifiReasons[wifiReason-200+24]; if (wifiReason >= 200 && wifiReason <= 201) return wifiReasons[wifiReason-200+24];
return wifiReasons[1]; return wifiReasons[1];
} }
// handler for wifi status change callback coming in from espressif library // handler for wifi status change callback coming in from espressif library
static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) { static void ICACHE_FLASH_ATTR wifiHandleEventCb(System_Event_t *evt) {
switch (evt->event) { switch (evt->event) {
case EVENT_STAMODE_CONNECTED: case EVENT_STAMODE_CONNECTED:
wifiState = wifiIsConnected; wifiState = wifiIsConnected;
wifiReason = 0; wifiReason = 0;
os_printf("Wifi connected to ssid %s, ch %d\n", evt->event_info.connected.ssid, os_printf("Wifi connected to ssid %s, ch %d\n", evt->event_info.connected.ssid,
evt->event_info.connected.channel); evt->event_info.connected.channel);
statusWifiUpdate(wifiState); statusWifiUpdate(wifiState);
break; break;
case EVENT_STAMODE_DISCONNECTED: case EVENT_STAMODE_DISCONNECTED:
wifiState = wifiIsDisconnected; wifiState = wifiIsDisconnected;
wifiReason = evt->event_info.disconnected.reason; wifiReason = evt->event_info.disconnected.reason;
os_printf("Wifi disconnected from ssid %s, reason %s (%d)\n", os_printf("Wifi disconnected from ssid %s, reason %s (%d)\n",
evt->event_info.disconnected.ssid, wifiGetReason(), evt->event_info.disconnected.reason); evt->event_info.disconnected.ssid, wifiGetReason(), evt->event_info.disconnected.reason);
statusWifiUpdate(wifiState); statusWifiUpdate(wifiState);
break; break;
case EVENT_STAMODE_AUTHMODE_CHANGE: case EVENT_STAMODE_AUTHMODE_CHANGE:
os_printf("Wifi auth mode: %d -> %d\n", os_printf("Wifi auth mode: %d -> %d\n",
evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode); evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode);
break; break;
case EVENT_STAMODE_GOT_IP: case EVENT_STAMODE_GOT_IP:
wifiState = wifiGotIP; wifiState = wifiGotIP;
wifiReason = 0; wifiReason = 0;
os_printf("Wifi got ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", os_printf("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.ip), IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw)); IP2STR(&evt->event_info.got_ip.gw));
statusWifiUpdate(wifiState); statusWifiUpdate(wifiState);
break; break;
case EVENT_SOFTAPMODE_STACONNECTED: case EVENT_SOFTAPMODE_STACONNECTED:
os_printf("Wifi AP: station " MACSTR " joined, AID = %d\n", os_printf("Wifi AP: station " MACSTR " joined, AID = %d\n",
MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid); MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid);
break; break;
case EVENT_SOFTAPMODE_STADISCONNECTED: case EVENT_SOFTAPMODE_STADISCONNECTED:
os_printf("Wifi AP: station " MACSTR " left, AID = %d\n", os_printf("Wifi AP: station " MACSTR " left, AID = %d\n",
MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid); MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid);
break; break;
default: default:
break; break;
} }
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (wifi_state_change_cb[i] != NULL) (wifi_state_change_cb[i])(wifiState); if (wifi_state_change_cb[i] != NULL) (wifi_state_change_cb[i])(wifiState);
@ -110,16 +110,16 @@ wifiAddStateChangeCb(WifiStateChangeCb cb) {
//WiFi access point data //WiFi access point data
typedef struct { typedef struct {
char ssid[32]; char ssid[32];
sint8 rssi; sint8 rssi;
char enc; char enc;
} ApData; } ApData;
//Scan result //Scan result
typedef struct { typedef struct {
char scanInProgress; //if 1, don't access the underlying stuff from the webpage. char scanInProgress; //if 1, don't access the underlying stuff from the webpage.
ApData **apData; ApData **apData;
int noAps; int noAps;
} ScanResultData; } ScanResultData;
//Static scan status storage. //Static scan status storage.
@ -128,109 +128,109 @@ static ScanResultData cgiWifiAps;
//Callback the code calls when a wlan ap scan is done. Basically stores the result in //Callback the code calls when a wlan ap scan is done. Basically stores the result in
//the cgiWifiAps struct. //the cgiWifiAps struct.
void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) { void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) {
int n; int n;
struct bss_info *bss_link = (struct bss_info *)arg; struct bss_info *bss_link = (struct bss_info *)arg;
if (status!=OK) { if (status!=OK) {
os_printf("wifiScanDoneCb status=%d\n", status); os_printf("wifiScanDoneCb status=%d\n", status);
cgiWifiAps.scanInProgress=0; cgiWifiAps.scanInProgress=0;
return; return;
} }
//Clear prev ap data if needed. //Clear prev ap data if needed.
if (cgiWifiAps.apData!=NULL) { if (cgiWifiAps.apData!=NULL) {
for (n=0; n<cgiWifiAps.noAps; n++) os_free(cgiWifiAps.apData[n]); for (n=0; n<cgiWifiAps.noAps; n++) os_free(cgiWifiAps.apData[n]);
os_free(cgiWifiAps.apData); os_free(cgiWifiAps.apData);
} }
//Count amount of access points found. //Count amount of access points found.
n=0; n=0;
while (bss_link != NULL) { while (bss_link != NULL) {
bss_link = bss_link->next.stqe_next; bss_link = bss_link->next.stqe_next;
n++; n++;
} }
//Allocate memory for access point data //Allocate memory for access point data
cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n); cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n);
cgiWifiAps.noAps=n; cgiWifiAps.noAps=n;
os_printf("Scan done: found %d APs\n", n); os_printf("Scan done: found %d APs\n", n);
//Copy access point data to the static struct //Copy access point data to the static struct
n=0; n=0;
bss_link = (struct bss_info *)arg; bss_link = (struct bss_info *)arg;
while (bss_link != NULL) { while (bss_link != NULL) {
if (n>=cgiWifiAps.noAps) { if (n>=cgiWifiAps.noAps) {
//This means the bss_link changed under our nose. Shouldn't happen! //This means the bss_link changed under our nose. Shouldn't happen!
//Break because otherwise we will write in unallocated memory. //Break because otherwise we will write in unallocated memory.
os_printf("Huh? I have more than the allocated %d aps!\n", cgiWifiAps.noAps); os_printf("Huh? I have more than the allocated %d aps!\n", cgiWifiAps.noAps);
break; break;
} }
//Save the ap data. //Save the ap data.
cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData)); cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData));
cgiWifiAps.apData[n]->rssi=bss_link->rssi; cgiWifiAps.apData[n]->rssi=bss_link->rssi;
cgiWifiAps.apData[n]->enc=bss_link->authmode; cgiWifiAps.apData[n]->enc=bss_link->authmode;
strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32); strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32);
os_printf("bss%d: %s (%d)\n", n+1, (char*)bss_link->ssid, bss_link->rssi); os_printf("bss%d: %s (%d)\n", n+1, (char*)bss_link->ssid, bss_link->rssi);
bss_link = bss_link->next.stqe_next; bss_link = bss_link->next.stqe_next;
n++; n++;
} }
//We're done. //We're done.
cgiWifiAps.scanInProgress=0; cgiWifiAps.scanInProgress=0;
} }
static ETSTimer scanTimer; static ETSTimer scanTimer;
static void ICACHE_FLASH_ATTR scanStartCb(void *arg) { static void ICACHE_FLASH_ATTR scanStartCb(void *arg) {
os_printf("Starting a scan\n"); os_printf("Starting a scan\n");
wifi_station_scan(NULL, wifiScanDoneCb); wifi_station_scan(NULL, wifiScanDoneCb);
} }
static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) { static int ICACHE_FLASH_ATTR cgiWiFiStartScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200); jsonHeader(connData, 200);
if (!cgiWifiAps.scanInProgress) { if (!cgiWifiAps.scanInProgress) {
cgiWifiAps.scanInProgress = 1; cgiWifiAps.scanInProgress = 1;
os_timer_disarm(&scanTimer); os_timer_disarm(&scanTimer);
os_timer_setfn(&scanTimer, scanStartCb, NULL); os_timer_setfn(&scanTimer, scanStartCb, NULL);
os_timer_arm(&scanTimer, 1000, 0); os_timer_arm(&scanTimer, 1000, 0);
} }
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) { static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
char buff[2048]; char buff[2048];
int len; int len;
jsonHeader(connData, 200); jsonHeader(connData, 200);
if (cgiWifiAps.scanInProgress==1) { if (cgiWifiAps.scanInProgress==1) {
//We're still scanning. Tell Javascript code that. //We're still scanning. Tell Javascript code that.
len = os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n"); len = os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
httpdSend(connData, buff, len); httpdSend(connData, buff, len);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n"); len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n");
for (int pos=0; pos<cgiWifiAps.noAps; pos++) { for (int pos=0; pos<cgiWifiAps.noAps; pos++) {
len += os_sprintf(buff+len, "{\"essid\": \"%s\", \"rssi\": %d, \"enc\": \"%d\"}%s\n", len += os_sprintf(buff+len, "{\"essid\": \"%s\", \"rssi\": %d, \"enc\": \"%d\"}%s\n",
cgiWifiAps.apData[pos]->ssid, cgiWifiAps.apData[pos]->rssi, cgiWifiAps.apData[pos]->ssid, cgiWifiAps.apData[pos]->rssi,
cgiWifiAps.apData[pos]->enc, (pos==cgiWifiAps.noAps-1)?"":","); cgiWifiAps.apData[pos]->enc, (pos==cgiWifiAps.noAps-1)?"":",");
} }
len += os_sprintf(buff+len, "]}}\n"); len += os_sprintf(buff+len, "]}}\n");
//os_printf("Sending %d bytes: %s\n", len, buff); //os_printf("Sending %d bytes: %s\n", len, buff);
httpdSend(connData, buff, len); httpdSend(connData, buff, len);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
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) {
return cgiWiFiStartScan(connData); return cgiWiFiStartScan(connData);
} else { } else {
jsonHeader(connData, 404); jsonHeader(connData, 404);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
} }
// ===== timers to change state and rescue from failed associations // ===== timers to change state and rescue from failed associations
@ -243,31 +243,31 @@ static ETSTimer resetTimer;
// the connect succeeds, this gets the module in STA-only mode. If it fails, it ensures // 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. // 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;
os_printf("Wifi check: mode=%s status=%d\n", wifiMode[m], x); os_printf("Wifi check: mode=%s status=%d\n", wifiMode[m], x);
if (x == STATION_GOT_IP) { if (x == STATION_GOT_IP) {
if (m != 1) { if (m != 1) {
#ifdef CHANGE_TO_STA #ifdef CHANGE_TO_STA
// We're happily connected, go to STA mode // We're happily connected, go to STA mode
os_printf("Wifi got IP. Going into STA mode..\n"); os_printf("Wifi got IP. Going into STA mode..\n");
wifi_set_opmode(1); wifi_set_opmode(1);
wifi_set_sleep_type(SLEEP_MODE); wifi_set_sleep_type(SLEEP_MODE);
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
#endif #endif
} }
log_uart(false); log_uart(false);
// no more resetTimer at this point, gotta use physical reset to recover if in trouble // no more resetTimer at this point, gotta use physical reset to recover if in trouble
} else { } else {
if (m != 3) { if (m != 3) {
os_printf("Wifi connect failed. Going into STA+AP mode..\n"); os_printf("Wifi connect failed. Going into STA+AP mode..\n");
wifi_set_opmode(3); wifi_set_opmode(3);
} }
log_uart(true); log_uart(true);
os_printf("Enabling/continuing uart log\n"); os_printf("Enabling/continuing uart log\n");
os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0);
} }
} }
// Temp store for new ap info. // Temp store for new ap info.
@ -277,206 +277,206 @@ static ETSTimer reassTimer;
// Callback actually doing reassociation // Callback actually doing reassociation
static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) { static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
os_printf("Wifi changing association\n"); os_printf("Wifi changing association\n");
wifi_station_disconnect(); wifi_station_disconnect();
stconf.bssid_set = 0; stconf.bssid_set = 0;
wifi_station_set_config(&stconf); wifi_station_set_config(&stconf);
wifi_station_connect(); wifi_station_connect();
// Schedule check // Schedule check
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);
} }
// 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) {
char essid[128]; char essid[128];
char passwd[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 el = httpdFindArg(connData->getArgs, "essid", essid, sizeof(essid));
int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd)); int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd));
if (el > 0 && pl >= 0) { if (el > 0 && pl >= 0) {
//Set to 0 if you want to disable the actual reconnecting bit //Set to 0 if you want to disable the actual reconnecting bit
os_strncpy((char*)stconf.ssid, essid, 32); os_strncpy((char*)stconf.ssid, essid, 32);
os_strncpy((char*)stconf.password, passwd, 64); os_strncpy((char*)stconf.password, passwd, 64);
os_printf("Wifi try to connect to AP %s pw %s\n", essid, passwd); os_printf("Wifi try to connect to AP %s pw %s\n", essid, passwd);
//Schedule disconnect/connect //Schedule disconnect/connect
os_timer_disarm(&reassTimer); os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL); os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0); os_timer_arm(&reassTimer, 1000, 0);
jsonHeader(connData, 200); jsonHeader(connData, 200);
} else { } else {
jsonHeader(connData, 400); jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse ssid or password", -1); httpdSend(connData, "Cannot parse ssid or password", -1);
} }
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
static bool parse_ip(char *buff, ip_addr_t *ip_ptr) { static bool parse_ip(char *buff, ip_addr_t *ip_ptr) {
char *next = buff; // where to start parsing next integer char *next = buff; // where to start parsing next integer
int found = 0; // number of integers parsed int found = 0; // number of integers parsed
uint32_t ip = 0; // the ip addres parsed uint32_t ip = 0; // the ip addres parsed
for (int i=0; i<32; i++) { // 32 is just a safety limit for (int i=0; i<32; i++) { // 32 is just a safety limit
char c = buff[i]; char c = buff[i];
if (c == '.' || c == 0) { if (c == '.' || c == 0) {
// parse the preceding integer and accumulate into IP address // parse the preceding integer and accumulate into IP address
bool last = c == 0; bool last = c == 0;
buff[i] = 0; buff[i] = 0;
uint32_t v = atoi(next); uint32_t v = atoi(next);
ip = ip | ((v&0xff)<<(found*8)); ip = ip | ((v&0xff)<<(found*8));
next = buff+i+1; // next integer starts after the '.' next = buff+i+1; // next integer starts after the '.'
found++; found++;
if (last) { // if at end of string we better got 4 integers if (last) { // if at end of string we better got 4 integers
ip_ptr->addr = ip; ip_ptr->addr = ip;
return found == 4; return found == 4;
} }
continue; continue;
} }
if (c < '0' || c > '9') return false; if (c < '0' || c > '9') return false;
} }
return false; return false;
} }
#define DEBUGIP #define DEBUGIP
#ifdef DEBUGIP #ifdef DEBUGIP
static void ICACHE_FLASH_ATTR debugIP() { static void ICACHE_FLASH_ATTR debugIP() {
struct ip_info info; struct ip_info info;
if (wifi_get_ip_info(0, &info)) { if (wifi_get_ip_info(0, &info)) {
os_printf("\"ip\": \"%d.%d.%d.%d\"\n", IP2STR(&info.ip.addr)); 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("\"netmask\": \"%d.%d.%d.%d\"\n", IP2STR(&info.netmask.addr));
os_printf("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr)); os_printf("\"gateway\": \"%d.%d.%d.%d\"\n", IP2STR(&info.gw.addr));
os_printf("\"hostname\": \"%s\"\n", wifi_station_get_hostname()); os_printf("\"hostname\": \"%s\"\n", wifi_station_get_hostname());
} else { } else {
os_printf("\"ip\": \"-none-\"\n"); os_printf("\"ip\": \"-none-\"\n");
} }
} }
#endif #endif
// configure Wifi, specifically DHCP vs static IP address based on flash config // configure Wifi, specifically DHCP vs static IP address based on flash config
static void ICACHE_FLASH_ATTR configWifiIP() { static void ICACHE_FLASH_ATTR configWifiIP() {
if (flashConfig.staticip == 0) { if (flashConfig.staticip == 0) {
// let's DHCP! // let's DHCP!
wifi_station_set_hostname(flashConfig.hostname); wifi_station_set_hostname(flashConfig.hostname);
if (wifi_station_dhcpc_status() == DHCP_STARTED) if (wifi_station_dhcpc_status() == DHCP_STARTED)
wifi_station_dhcpc_stop(); wifi_station_dhcpc_stop();
wifi_station_dhcpc_start(); wifi_station_dhcpc_start();
os_printf("Wifi uses DHCP, hostname=%s\n", flashConfig.hostname); os_printf("Wifi uses DHCP, hostname=%s\n", flashConfig.hostname);
} else { } else {
// no DHCP, we got static network config! // no DHCP, we got static network config!
wifi_station_dhcpc_stop(); wifi_station_dhcpc_stop();
struct ip_info ipi; struct ip_info ipi;
ipi.ip.addr = flashConfig.staticip; ipi.ip.addr = flashConfig.staticip;
ipi.netmask.addr = flashConfig.netmask; ipi.netmask.addr = flashConfig.netmask;
ipi.gw.addr = flashConfig.gateway; ipi.gw.addr = flashConfig.gateway;
wifi_set_ip_info(0, &ipi); wifi_set_ip_info(0, &ipi);
os_printf("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr)); os_printf("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr));
} }
#ifdef DEBUGIP #ifdef DEBUGIP
debugIP(); debugIP();
#endif #endif
} }
// Change special settings // Change special settings
int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) {
char dhcp[8]; char dhcp[8];
char hostname[32]; char hostname[32];
char staticip[20]; char staticip[20];
char netmask[20]; char netmask[20];
char gateway[20]; char gateway[20];
if (connData->conn==NULL) return HTTPD_CGI_DONE; if (connData->conn==NULL) return HTTPD_CGI_DONE;
// get args and their string lengths // get args and their string lengths
int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp)); int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp));
int hl = httpdFindArg(connData->getArgs, "hostname", hostname, sizeof(hostname)); int hl = httpdFindArg(connData->getArgs, "hostname", hostname, sizeof(hostname));
int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip)); int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip));
int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask)); int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask));
int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway)); int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway));
if (!(dl > 0 && hl >= 0 && sl >= 0 && nl >= 0 && gl >= 0)) { if (!(dl > 0 && hl >= 0 && sl >= 0 && nl >= 0 && gl >= 0)) {
jsonHeader(connData, 400); jsonHeader(connData, 400);
httpdSend(connData, "Request is missing fields", -1); httpdSend(connData, "Request is missing fields", -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
char url[64]; // redirect URL char url[64]; // redirect URL
if (os_strcmp(dhcp, "off") == 0) { if (os_strcmp(dhcp, "off") == 0) {
// parse static IP params // parse static IP params
struct ip_info ipi; struct ip_info ipi;
bool ok = parse_ip(staticip, &ipi.ip); bool ok = parse_ip(staticip, &ipi.ip);
if (nl > 0) ok = ok && parse_ip(netmask, &ipi.netmask); if (nl > 0) ok = ok && parse_ip(netmask, &ipi.netmask);
else IP4_ADDR(&ipi.netmask, 255, 255, 255, 0); else IP4_ADDR(&ipi.netmask, 255, 255, 255, 0);
if (gl > 0) ok = ok && parse_ip(gateway, &ipi.gw); if (gl > 0) ok = ok && parse_ip(gateway, &ipi.gw);
else ipi.gw.addr = 0; else ipi.gw.addr = 0;
if (!ok) { if (!ok) {
jsonHeader(connData, 400); jsonHeader(connData, 400);
httpdSend(connData, "Cannot parse static IP config", -1); httpdSend(connData, "Cannot parse static IP config", -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// save the params in flash // save the params in flash
flashConfig.staticip = ipi.ip.addr; flashConfig.staticip = ipi.ip.addr;
flashConfig.netmask = ipi.netmask.addr; flashConfig.netmask = ipi.netmask.addr;
flashConfig.gateway = ipi.gw.addr; flashConfig.gateway = ipi.gw.addr;
// construct redirect URL // construct redirect URL
os_sprintf(url, "{\"url\": \"http://%d.%d.%d.%d\"}", IP2STR(&ipi.ip)); os_sprintf(url, "{\"url\": \"http://%d.%d.%d.%d\"}", IP2STR(&ipi.ip));
} else { } else {
// no static IP, set hostname // no static IP, set hostname
if (hl == 0) os_strcpy(hostname, "esp-link"); if (hl == 0) os_strcpy(hostname, "esp-link");
flashConfig.staticip = 0; flashConfig.staticip = 0;
os_strcpy(flashConfig.hostname, hostname); os_strcpy(flashConfig.hostname, hostname);
os_sprintf(url, "{\"url\": \"http://%s\"}", hostname); os_sprintf(url, "{\"url\": \"http://%s\"}", hostname);
} }
configSave(); // ignore error... configSave(); // ignore error...
// schedule change-over // schedule change-over
os_timer_disarm(&reassTimer); os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, configWifiIP, NULL); os_timer_setfn(&reassTimer, configWifiIP, NULL);
os_timer_arm(&reassTimer, 1000, 0); os_timer_arm(&reassTimer, 1000, 0);
// return redirect info // return redirect info
jsonHeader(connData, 200); jsonHeader(connData, 200);
httpdSend(connData, url, -1); httpdSend(connData, url, -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
//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) {
int len; int len;
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.
len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); len=httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff));
if (len!=0) { if (len!=0) {
int m = atoi(buff); int m = atoi(buff);
os_printf("Wifi switching to mode %d\n", m); os_printf("Wifi switching to mode %d\n", m);
wifi_set_opmode(m&3); wifi_set_opmode(m&3);
if (m == 1) { if (m == 1) {
wifi_set_sleep_type(SLEEP_MODE); wifi_set_sleep_type(SLEEP_MODE);
// STA-only mode, reset into STA+AP after a timeout // STA-only mode, reset into STA+AP after a timeout
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);
} }
jsonHeader(connData, 200); jsonHeader(connData, 200);
} else { } else {
jsonHeader(connData, 400); jsonHeader(connData, 400);
} }
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
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>", "<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(1)\\\">STA mode</a>", "Switch to <a href=\\\"#\\\" onclick=\\\"changeWifiMode(1)\\\">STA mode</a>",
}; };
#ifdef CHANGE_TO_STA #ifdef CHANGE_TO_STA
@ -487,109 +487,109 @@ 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; int len;
struct station_config stconf; struct station_config stconf;
wifi_station_get_config(&stconf); wifi_station_get_config(&stconf);
uint8_t op = wifi_get_opmode() & 0x3; uint8_t op = wifi_get_opmode() & 0x3;
char *mode = wifiMode[op]; char *mode = wifiMode[op];
char *status = "unknown"; char *status = "unknown";
int st = wifi_station_get_connect_status(); int st = wifi_station_get_connect_status();
if (st >= 0 && st < sizeof(connStatuses)) status = connStatuses[st]; if (st >= 0 && st < sizeof(connStatuses)) status = connStatuses[st];
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];
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];
wifi_get_macaddr(0, mac_addr); wifi_get_macaddr(0, mac_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\", \"mac\":\"%02x:%02x:%02x:%02x:%02x:%02x\", \"chan\":%d",
mode, MODECHANGE, (char*)stconf.ssid, status, phy, rssi, warn, mode, MODECHANGE, (char*)stconf.ssid, status, phy, rssi, warn,
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], chan); mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], chan);
struct ip_info info; struct ip_info info;
if (wifi_get_ip_info(0, &info)) { if (wifi_get_ip_info(0, &info)) {
len += os_sprintf(buff+len, ", \"ip\": \"%d.%d.%d.%d\"", IP2STR(&info.ip.addr)); len += os_sprintf(buff+len, ", \"ip\": \"%d.%d.%d.%d\"", IP2STR(&info.ip.addr));
len += os_sprintf(buff+len, ", \"netmask\": \"%d.%d.%d.%d\"", IP2STR(&info.netmask.addr)); len += os_sprintf(buff+len, ", \"netmask\": \"%d.%d.%d.%d\"", IP2STR(&info.netmask.addr));
len += os_sprintf(buff+len, ", \"gateway\": \"%d.%d.%d.%d\"", IP2STR(&info.gw.addr)); len += os_sprintf(buff+len, ", \"gateway\": \"%d.%d.%d.%d\"", IP2STR(&info.gw.addr));
len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", flashConfig.hostname); len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", flashConfig.hostname);
} else { } else {
len += os_sprintf(buff+len, ", \"ip\": \"-none-\""); len += os_sprintf(buff+len, ", \"ip\": \"-none-\"");
} }
len += os_sprintf(buff+len, ", \"staticip\": \"%d.%d.%d.%d\"", IP2STR(&flashConfig.staticip)); len += os_sprintf(buff+len, ", \"staticip\": \"%d.%d.%d.%d\"", IP2STR(&flashConfig.staticip));
len += os_sprintf(buff+len, ", \"dhcp\": \"%s\"", flashConfig.staticip > 0 ? "off" : "on"); len += os_sprintf(buff+len, ", \"dhcp\": \"%s\"", flashConfig.staticip > 0 ? "off" : "on");
return len; return len;
} }
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
char buff[1024]; char buff[1024];
int len; int len;
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
jsonHeader(connData, 200); jsonHeader(connData, 200);
len = os_sprintf(buff, "{"); len = os_sprintf(buff, "{");
len += printWifiInfo(buff+len); len += printWifiInfo(buff+len);
len += os_sprintf(buff+len, ", "); len += os_sprintf(buff+len, ", ");
if (wifiReason != 0) { if (wifiReason != 0) {
len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason()); len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason());
} }
#if 0 #if 0
// commented out 'cause often the client that requested the change can't get a request in to // 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... // find out that it succeeded. Better to just wait the std 15 seconds...
int st=wifi_station_get_connect_status(); int st=wifi_station_get_connect_status();
if (st == STATION_GOT_IP) { if (st == STATION_GOT_IP) {
if (wifi_get_opmode() != 1) { if (wifi_get_opmode() != 1) {
// Reset into AP-only mode sooner. // Reset into AP-only mode sooner.
os_timer_disarm(&resetTimer); os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 1000, 0); os_timer_arm(&resetTimer, 1000, 0);
} }
} }
#endif #endif
len += os_sprintf(buff+len, "\"x\":0}\n"); len += os_sprintf(buff+len, "\"x\":0}\n");
os_printf(" -> %s\n", buff); os_printf(" -> %s\n", buff);
httpdSend(connData, buff, len); httpdSend(connData, buff, len);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
// Cgi to return various Wifi information // Cgi to return various Wifi information
int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) { 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, "{"); os_strcpy(buff, "{");
printWifiInfo(buff+1); printWifiInfo(buff+1);
os_strcat(buff, "}"); os_strcat(buff, "}");
jsonHeader(connData, 200); jsonHeader(connData, 200);
httpdSend(connData, buff, -1); httpdSend(connData, buff, -1);
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, which consists of setting a timer if we expect to connect to an AP
// so we can revert to STA+AP mode if we can't connect. // so we can revert to STA+AP mode if we can't connect.
void ICACHE_FLASH_ATTR wifiInit() { void ICACHE_FLASH_ATTR wifiInit() {
wifi_set_phy_mode(2); wifi_set_phy_mode(2);
int x = wifi_get_opmode() & 0x3; int x = wifi_get_opmode() & 0x3;
os_printf("Wifi init, mode=%s\n", wifiMode[x]); os_printf("Wifi init, mode=%s\n", wifiMode[x]);
configWifiIP(); configWifiIP();
wifi_set_event_handler_cb(wifiHandleEventCb); wifi_set_event_handler_cb(wifiHandleEventCb);
// check on the wifi in a few seconds to see whether we need to switch mode // check on the wifi in a few seconds to see whether we need to switch mode
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);
} }

Loading…
Cancel
Save