| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 | 
							- #include "common.h"
 
- #include "WiFi.h"
 
- #include "wifi.h"
 
- #include "config.h"
 
- #include "httpd.h"
 
- #include "led.h"
 
- #include <lwip/dns.h>
 
- #include <lwip/inet.h>
 
- #include <lwip/apps/sntp.h>
 
- #include <esp_sntp.h>
 
- #include <esp_wifi.h>
 
- static String ssid, password, hostname, dnsserver;
 
- static TimerHandle_t sta_failure_timer;
 
- static bool sta_timeout_enabled;
 
- static void sta_timeout(void)
 
- {
 
-     // Enable the AP if the STA doesn't connect after a timeout
 
-     WiFi.enableAP(true);
 
- }
 
- static void sta_timeout_enable(void)
 
- {
 
-     if (!sta_failure_timer || sta_timeout_enabled)
 
- 	return;
 
-     sta_timeout_enabled =
 
- 	xTimerStart(sta_failure_timer, 1);
 
- }
 
- static void sta_timeout_disable(void)
 
- {
 
-     if (!sta_failure_timer || !sta_timeout_enabled)
 
- 	return;
 
-     sta_timeout_enabled =
 
- 	!xTimerStop(sta_failure_timer, 1);
 
- }
 
- static void sntp_sync_cb(struct timeval *tv)
 
- {
 
-     static uint8_t prev_sync_status = SNTP_SYNC_STATUS_RESET;
 
-     uint8_t sync_status = sntp_get_sync_status();
 
-     switch (sync_status) {
 
-     case SNTP_SYNC_STATUS_RESET:
 
- 	sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED); // Until first sync
 
- 	time_net_sync(NULL);
 
- 	break;
 
-     case SNTP_SYNC_STATUS_COMPLETED:
 
- 	sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH); // After successful sync
 
- 	time_net_sync(tv);
 
- 	break;
 
-     default:
 
- 	break;
 
-     }
 
-     prev_sync_status = sync_status;
 
- }
 
- static void my_sntp_start(void)
 
- {
 
-     setenv_bool("status.net.sntp.sync", false);
 
-     if (getenv_bool("sntp.enabled")) {
 
- 	sntp_set_time_sync_notification_cb(sntp_sync_cb);
 
- 	sntp_setoperatingmode(SNTP_OPMODE_POLL);
 
- 	sntp_servermode_dhcp(!getenv_bool("ip4.dhcp.nosntp"));
 
- 	sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED); // Until first sync
 
- 	sntp_init();
 
-     } else {
 
- 	sntp_stop();
 
-     }
 
- }
 
- static bool services_started;
 
- static void stop_services(void)
 
- {
 
-     if (services_started) {
 
- 	esp_unregister_shutdown_handler(stop_services);
 
- 	my_httpd_stop();
 
- 	services_started = false;
 
-     }
 
- }
 
- static inline bool invalid_ip(const ip_addr_t *ip)
 
- {
 
-     return !memcmp(ip, &ip_addr_any, sizeof *ip);
 
- }
 
- static void sntp_server_show(void)
 
- {
 
-     const ip_addr_t *sntp_ip = sntp_getserver(0);
 
-     if (!invalid_ip(sntp_ip)) {
 
- 	const char *sntp_server = inet_ntoa(*sntp_ip);
 
- 	printf("[SNTP] Time server: %s\n", sntp_server);
 
- 	setenv_cond("status.net.sntp.server", sntp_server);
 
-     } else {
 
- 	unsetenv("status.net.sntp.server");
 
-     }
 
- }
 
- static void sntp_server_found(const char *name, const ip_addr_t *addr,
 
- 			      void *arg)
 
- {
 
-     (void)name;
 
-     (void)arg;
 
-     if (invalid_ip(addr))
 
- 	return;
 
-     sntp_setserver(0, addr);
 
-     sntp_server_show();
 
- }
 
- static void sntp_set_server(const char *name)
 
- {
 
-     if (!name || !*name)
 
- 	return;
 
-     ip_addr_t addr;
 
-     err_t err = dns_gethostbyname(name, &addr, sntp_server_found, NULL);
 
-     if (err == ERR_OK)
 
- 	sntp_server_found(name, &addr, NULL);
 
- }
 
- static void start_services(void)
 
- {
 
-     /* Always run after (re)connect */
 
-     const ip_addr_t *dns_ip = dns_getserver(0);
 
-     if (invalid_ip(dns_ip) || getenv_bool("ip4.dhcp.nodns")) {
 
- 	/* Static DNS server configuration */
 
- 	ip_addr_t addr;
 
- 	if (dnsserver != "" && inet_aton(dnsserver.c_str(), &addr)) {
 
- 	    if (memcmp(dns_ip, &addr, sizeof addr))
 
- 		dns_setserver(0, &addr);
 
- 	}
 
-     }
 
-     {
 
- 	dns_ip = dns_getserver(0);
 
- 	const char *dns_server_str = inet_ntoa(*dns_ip);
 
- 	printf("[DNS]  DNS server: %s\n", dns_server_str);
 
- 	setenv_cond("status.net.dns.server", dns_server_str);
 
-     }
 
-     // If Arduino supported both of these at the same that would be
 
-     // awesome, but it requires ESP-IDF reconfiguration...
 
-     if (getenv_bool("sntp.enabled")) {
 
- 	if (!invalid_ip(sntp_getserver(0))) {
 
- 	    sntp_server_show();
 
- 	} else {
 
- 	    sntp_set_server(getenv("sntp.server"));
 
- 	}
 
-     }
 
-     /* Only run on first start */
 
-     if (!services_started) {
 
- 	services_started = true;
 
- 	my_httpd_start();
 
- 	esp_register_shutdown_handler(stop_services);
 
-     }
 
- }
 
- static const char *ip_str(const IPAddress &ip)
 
- {
 
-     static char ip_buf[4*4];
 
-     const IPAddress ip_none(0,0,0,0);
 
-     return strcpy(ip_buf, ip == ip_none ? "" : ip.toString().c_str());
 
- }
 
- static void setenv_ip(const char *var, const IPAddress &ip)
 
- {
 
-     setenv_config(var, ip_str(ip));
 
- }
 
- static bool force_conn_update;
 
- static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
 
- {
 
-     bool retry_sta  = false;
 
-     bool is_connect = false;
 
-     enum connected {
 
- 	CON_STA = 1,
 
- 	CON_ETH = 2,
 
- 	CON_AP  = 4
 
-     };
 
-     static unsigned int connected;
 
-     unsigned int prev_connected = connected;
 
-     static int ap_clients = 0;
 
-     int prev_ap_clients = ap_clients;
 
-     IPAddress wifi_local_ip = WiFi.localIP();
 
-     const char *local_ip = ip_str(wifi_local_ip);
 
-     switch (event) {
 
-     case ARDUINO_EVENT_WIFI_READY:
 
- 	printf("[WIFI] Interface ready\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_SCAN_DONE:
 
- 	printf("[WIFI] Completed scan for access points\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_START:
 
- 	printf("[WIFI] Client started\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_STOP:
 
- 	printf("[WIFI] Clients stopped\n");
 
- 	connected &= ~CON_STA;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_CONNECTED:
 
- 	printf("[WIFI] Connected to access point\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
 
- 	printf("[WIFI] Disconnected from WiFi access point\n");
 
- 	connected &= ~CON_STA;
 
- 	retry_sta = true;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE:
 
- 	printf("[WIFI] Authentication mode of access point has changed\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_GOT_IP:
 
-     {
 
- 	printf("[WIFI] Obtained IP address: %s\n", local_ip);
 
- 	connected |= CON_STA;
 
- 	is_connect = true;
 
- 	break;
 
-     }
 
-     case ARDUINO_EVENT_WIFI_STA_LOST_IP:
 
-     {
 
- 	printf("[WIFI] Lost IP address\n");
 
- 	connected &= ~CON_STA;
 
- 	retry_sta = true;
 
- 	break;
 
-     }
 
-     case ARDUINO_EVENT_WPS_ER_SUCCESS:
 
- 	printf("[WIFI] WiFi Protected Setup (WPS): succeeded in enrollee mode\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WPS_ER_FAILED:
 
- 	printf("[WIFI] WiFi Protected Setup (WPS): failed in enrollee mode\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WPS_ER_TIMEOUT:
 
- 	printf("[WIFI] WiFi Protected Setup (WPS): timeout in enrollee mode\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WPS_ER_PIN:
 
- 	printf("[WIFI] WiFi Protected Setup (WPS): pin code in enrollee mode\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_START:
 
- 	printf("[WIFI] Access point started\n");
 
- 	ap_clients  = 0;
 
- 	connected  |= CON_AP;
 
- 	is_connect  = true;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_STOP:
 
- 	printf("[WIFI] Access point stopped\n");
 
- 	connected  &= ~CON_AP;
 
- 	ap_clients  = 0;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
 
- 	printf("[WIFI] Client connected\n");
 
- 	ap_clients++;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
 
- 	printf("[WIFI] Client disconnected\n");
 
- 	ap_clients--;
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
 
- 	printf("[WIFI] Assigned IP address %s to client\n",
 
- 	       inet_ntoa(info.wifi_ap_staipassigned.ip));
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
 
- 	printf("[WIFI] Received probe request\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
 
- 	printf("[WIFI] AP IPv6 is preferred\n");
 
- 	break;
 
-     case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
 
- 	printf("[WIFI] STA IPv6 is preferred\n");
 
- 	is_connect = true;
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_GOT_IP6:
 
- 	printf("[ETH]  Ethernet IPv6 is preferred\n");
 
- 	is_connect = true;
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_START:
 
- 	printf("[ETH]  Ethernet started\n");
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_STOP:
 
- 	printf("[ETH]  Ethernet stopped\n");
 
- 	connected &= ~CON_ETH;
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_CONNECTED:
 
- 	printf("[ETH]  Ethernet connected\n");
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_DISCONNECTED:
 
- 	printf("[ETH]  Ethernet disconnected\n");
 
- 	connected &= ~CON_ETH;
 
- 	retry_sta = true;
 
- 	break;
 
-     case ARDUINO_EVENT_ETH_GOT_IP:
 
- 	printf("[ETH]  Obtained IP address: %s\n", local_ip);
 
- 	connected |= CON_ETH;
 
- 	is_connect = true;
 
- 	break;
 
-     default:
 
- 	break;
 
-     }
 
-     if (connected & ~CON_AP) {
 
- 	sta_timeout_disable();
 
- 	if (!ap_clients)
 
- 	    WiFi.enableAP(false);
 
-     } else if (ssid != "") {
 
- 	sta_timeout_enable();
 
-     }
 
-     unsigned int conn_change = force_conn_update ?
 
- 	-1U : (connected ^ prev_connected);
 
-     if (conn_change) {
 
- 	force_conn_update = false;
 
- 	if (conn_change & CON_STA) {
 
- 	    setenv_bool("status.net.sta.conn", connected & CON_STA);
 
- 	    setenv_config("status.net.sta.ip4",
 
- 			  connected & CON_STA ? local_ip : "");
 
- 	    setenv_ip("status.net.sta.ip4.mask", WiFi.subnetMask());
 
- 	    setenv_ip("status.net.sta.ip4.gw", WiFi.gatewayIP());
 
- 	}
 
- 	if (conn_change & CON_AP)
 
- 	    setenv_bool("status.net.ap.conn", connected & CON_AP);
 
- 	if (conn_change & CON_ETH) {
 
- 	    setenv_bool("status.net.eth.conn", connected & CON_ETH);
 
- 	    setenv_config("status.net.eth.ip4",
 
- 			  connected & CON_ETH ? local_ip : "");
 
- 	    setenv_ip("status.net.eth.ip4.mask", WiFi.subnetMask());
 
- 	    setenv_ip("status.net.eth.ip4.gw", WiFi.gatewayIP());
 
- 	}
 
- 	if (ssid == "") {
 
- 	    // No network configured
 
- 	    led_set(LED_GREEN, connected & CON_AP ? LED_FLASH_SLOW : LED_OFF);
 
- 	} else {
 
- 	    led_set(LED_GREEN, connected & CON_AP ? LED_FLASH_FAST : LED_ON);
 
- 	}
 
-     }
 
-     if (is_connect) {
 
- 	start_services();
 
-     }
 
-     if (ap_clients != prev_ap_clients)
 
- 	setenv_ul("status.net.ap.clients", ap_clients);
 
-     if (retry_sta) {
 
- 	WiFi.disconnect();
 
- 	WiFi.begin();
 
-     }
 
- }
 
- static void setenv_mac(const char *var, const uint8_t mac[6])
 
- {
 
-     char mac_str[3*6];
 
-     snprintf(mac_str, sizeof mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
 
- 	     mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 
-     setenv(var, mac_str, 1);
 
- }
 
- static void wifi_config_ap(void)
 
- {
 
-     /* No network configuration set */
 
-     IPAddress AP_IP      = IPAddress(192,168,0,1);
 
-     IPAddress AP_Netmask = IPAddress(255,255,255,0);
 
-     IPAddress AP_Gateway = IPAddress(0,0,0,0); // No gateway
 
-     unsigned int channel = time(NULL) % 11;	   // Pseudo-random
 
-     uint8_t mac[6];
 
-     char mac_str[6*3];
 
-     char ap_ssid[64];
 
-     WiFi.softAPmacAddress(mac);
 
-     setenv_mac("status.net.ap.mac", mac);
 
-     /* The last two bytes of the MAC */
 
-     snprintf(ap_ssid, sizeof ap_ssid, "MAX80_%02X%02X", mac[4], mac[5]);
 
-     printf("[WIFI] AP SSID %s IP %s netmask %s channel %u\n",
 
- 	       ap_ssid, AP_IP.toString(), AP_Netmask.toString(), channel+1);
 
-     setenv_cond("status.net.ap.ssid", ap_ssid);
 
-     setenv_ip("status.net.ap.ip4", AP_IP);
 
-     setenv_ip("status.net.ap.ip4.mask", AP_Netmask);
 
-     setenv_ul("status.net.ap.clients", 0);
 
-     WiFi.softAP(ap_ssid, NULL, channel+1, 0, 4, true);
 
-     WiFi.softAPConfig(AP_IP, AP_Gateway, AP_Netmask);
 
-     WiFi.softAPsetHostname(ap_ssid);
 
-     // Conservative setting: 20 MHz (single channel) only; this is for
 
-     // reliability, not performance.
 
-     esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_AP, WIFI_BW_HT20);
 
-     // Enable unconditionally if no SSID
 
-     WiFi.enableAP(ssid == "");
 
- }
 
- static void wifi_config_sta(void)
 
- {
 
-     uint8_t mac[6];
 
-     WiFi.macAddress(mac);
 
-     setenv_mac("status.net.sta.mac", mac);
 
-     setenv_cond("status.net.sta.ssid", ssid.c_str());
 
-     if (ssid == "") {
 
- 	WiFi.enableSTA(false);
 
- 	return;
 
-     }
 
-     sta_failure_timer = xTimerCreate("wifi_sta", configTICK_RATE_HZ*30,
 
- 				     pdFALSE, NULL,
 
- 				     (TimerCallbackFunction_t)sta_timeout);
 
-     sta_timeout_enable();
 
-     WiFi.begin(ssid.c_str(), password.c_str());
 
-     WiFi.setAutoConnect(true);
 
-     WiFi.setAutoReconnect(true);
 
-     WiFi.enableSTA(true);
 
- }
 
- static void wifi_config(void)
 
- {
 
-     ssid         = getenv("wifi.ssid");
 
-     password     = getenv("wifi.psk");
 
-     hostname     = getenv("hostname");
 
-     dnsserver    = getenv("ip4.dns");
 
-     force_conn_update = true;
 
-     WiFi.persistent(false);
 
-     WiFi.setSleep(false);
 
-     if (hostname != "")
 
- 	WiFi.hostname(hostname);
 
-     wifi_config_sta();
 
-     wifi_config_ap();
 
- }
 
- void SetupWiFi() {
 
-     services_started = false;
 
-     WiFi.onEvent(WiFiEvent);
 
-     my_sntp_start();
 
-     printf("[INFO] Setting up WiFi\n");
 
-     wifi_config();
 
- }
 
 
  |