diff --git a/include/espmissingincludes.h b/include/espmissingincludes.h index 47bc1c1..c69b9fc 100644 --- a/include/espmissingincludes.h +++ b/include/espmissingincludes.h @@ -10,6 +10,7 @@ typedef struct espconn espconn; bool wifi_station_set_hostname(char *); +char *wifi_station_get_hostname(void); int atoi(const char *nptr); diff --git a/user/cgiwifi.c b/user/cgiwifi.c index 1ce00d1..1d5c245 100644 --- a/user/cgiwifi.c +++ b/user/cgiwifi.c @@ -348,13 +348,37 @@ static void ICACHE_FLASH_ATTR debugIP() { 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\"", flashConfig.hostname); + 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 +static 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(); + os_printf("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); + os_printf("Wifi uses static IP %d.%d.%d.%d\n", IP2STR(&ipi.ip.addr)); + } +#ifdef DEBUGIP + debugIP(); +#endif +} + // Change special settings int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) { char hostname[32]; @@ -370,46 +394,49 @@ int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) { int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask)); int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway)); - if (hl >= 0 && sl >= 0 && nl >= 0 && gl >= 0) { - if (sl > 0) { - // static IP overrides hostname (HDCP stuff) - wifi_station_dhcpc_stop(); - 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) { - os_printf("Setting static IP: %s\n", staticip); - ok = wifi_set_ip_info(0, &ipi); - if (ok) os_printf("Static IP set: %s\n", staticip); -#ifdef DEBUGIP - debugIP(); -#endif - jsonHeader(connData, ok ? 200: 400); - return HTTPD_CGI_DONE; - } - } else { - // no static IP, set hostname - if (hl == 0) os_strcpy(hostname, "esp-link"); - if (wifi_station_dhcpc_status() == DHCP_STARTED) - wifi_station_dhcpc_stop(); - bool hok = wifi_station_set_hostname(hostname); - if (hok) { - os_strcpy(flashConfig.hostname, hostname); - hok = hok && configSave(); - } - hok = hok && wifi_station_dhcpc_start(); - if (hok) os_printf("DHCP hostname set: %s\n", hostname); - jsonHeader(connData, hok ? 200 : 400); - if (!hok) httpdSend(connData, "Error setting hostname or starting DHCP", -1); + if (!(hl >= 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 (sl > 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 { + // no static IP, set hostname + if (hl == 0) os_strcpy(hostname, "esp-link"); + flashConfig.staticip = 0; + os_strcpy(flashConfig.hostname, hostname); + os_sprintf(url, "{\"url\": \"http://%s\"}", hostname); } - jsonHeader(connData, 400); - httpdSend(connData, "Cannot parse hostname or staticip", -1); + configSave(); // ignore error... + // schedule change-over + os_timer_disarm(&reassTimer); + os_timer_setfn(&reassTimer, configWifiIP, NULL); + os_timer_arm(&reassTimer, 1000, 0); + // return redirect info + jsonHeader(connData, 200); + httpdSend(connData, url, -1); return HTTPD_CGI_DONE; } @@ -485,10 +512,11 @@ int ICACHE_FLASH_ATTR printWifiInfo(char *buff) { len += os_sprintf(buff+len, ", \"ip\": \"%d.%d.%d.%d\"", IP2STR(&info.ip.addr)); len += os_sprintf(buff+len, ", \"netmask\": \"%d.%d.%d.%d\"", IP2STR(&info.netmask.addr)); len += os_sprintf(buff+len, ", \"gateway\": \"%d.%d.%d.%d\"", IP2STR(&info.gw.addr)); - len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", flashConfig.hostname); + len += os_sprintf(buff+len, ", \"hostname\": \"%s\"", wifi_station_get_hostname()); } else { len += os_sprintf(buff+len, ", \"ip\": \"-none-\""); } + len += os_sprintf(buff+len, ", \"staticip\": \"%d.%d.%d.%d\"", IP2STR(&flashConfig.staticip)); return len; } @@ -546,10 +574,11 @@ int ICACHE_FLASH_ATTR cgiWifiInfo(HttpdConnData *connData) { // Init the wireless, which consists of setting a timer if we expect to connect to an AP // so we can revert to STA+AP mode if we can't connect. void ICACHE_FLASH_ATTR wifiInit() { - wifi_station_set_hostname(flashConfig.hostname); + wifi_set_phy_mode(2); int x = wifi_get_opmode() & 0x3; os_printf("Wifi init, mode=%s\n", wifiMode[x]); - wifi_set_phy_mode(2); + configWifiIP(); + wifi_set_event_handler_cb(wifiHandleEventCb); // check on the wifi in a few seconds to see whether we need to switch mode os_timer_disarm(&resetTimer); diff --git a/user/config.c b/user/config.c index 1f659f8..90b9905 100644 --- a/user/config.c +++ b/user/config.c @@ -11,9 +11,12 @@ FlashConfig flashDefault = { 33, 0, MCU_RESET_PIN, MCU_ISP_PIN, LED_CONN_PIN, LED_SERIAL_PIN, 115200, - "esp-link\0 ", + "esp-link\0 ", // hostname + 0, 0x00ffffff, 0, // static ip, netmask, gateway }; +#define FLASH_MAGIC (0xaa55aa55) + #define FLASH_ADDR (0x3E000) #define FLASH_SECT (4096) static int flash_pri; // primary flash sector (0 or 1, or -1 for error) @@ -28,7 +31,7 @@ bool ICACHE_FLASH_ATTR configSave(void) { return false; // no harm done, give up // write primary with incorrect seq fc.seq = 0xffffffff; - fc.crc = 0x55aa55aa; + fc.crc = FLASH_MAGIC; if (spi_flash_write(addr, (void *)&fc, sizeof(FlashConfig)) != SPI_FLASH_RESULT_OK) return false; // no harm done, give up // fill in correct seq @@ -77,8 +80,8 @@ bool ICACHE_FLASH_ATTR configRestore(void) { } static uint32_t ICACHE_FLASH_ATTR selectPrimary(FlashConfig *fc0, FlashConfig *fc1) { - bool fc0_crc_ok = fc0->crc == 0x55aa55aa && fc0->seq != 0xffffffff; // need real crc checksum... - bool fc1_crc_ok = fc1->crc == 0x55aa55aa && fc1->seq != 0xffffffff; // need real crc checksum... + bool fc0_crc_ok = fc0->crc == FLASH_MAGIC && fc0->seq != 0xffffffff; // need real crc checksum... + bool fc1_crc_ok = fc1->crc == FLASH_MAGIC && fc1->seq != 0xffffffff; // need real crc checksum... if (fc0_crc_ok) if (!fc1_crc_ok || fc0->seq >= fc1->seq) return 0; // use first sector as primary diff --git a/user/config.h b/user/config.h index b4bed48..1ec4400 100644 --- a/user/config.h +++ b/user/config.h @@ -4,9 +4,10 @@ typedef struct { uint32_t seq; // flash write sequence number uint32_t crc; // FlashConfig crc - int8_t reset_pin, isp_pin, conn_led_pin, ser_led_pin; - int32_t baud_rate; - char hostname[32]; + int8_t reset_pin, isp_pin, conn_led_pin, ser_led_pin; + int32_t baud_rate; + char hostname[32]; // if using DHCP + uint32_t staticip, netmask, gateway; // using DHCP if staticip==0 } FlashConfig; extern FlashConfig flashConfig;