|
@@ -1,27 +1,23 @@
|
|
|
#include "common.h"
|
|
|
#include "WiFi.h"
|
|
|
#include "wifi.h"
|
|
|
-#include "storage.h"
|
|
|
+#include "config.h"
|
|
|
#include "httpd.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 = "";
|
|
|
-static String password = "";
|
|
|
-static String otaPassword = "";
|
|
|
-static String hostname = "max80";
|
|
|
-static String DNSServer = "";
|
|
|
-static String SNTPServer = "";
|
|
|
-static String TimeZone = "CET-1CEST,M3.5.0,M10.5.0/3"; // Sweden
|
|
|
+static wifi_mode_t mode;
|
|
|
+static String ssid, password, hostname, dnsserver, sntpserver;
|
|
|
|
|
|
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
|
|
@@ -72,25 +68,29 @@ static inline bool invalid_ip(const ip_addr_t *ip)
|
|
|
|
|
|
static void start_services(void)
|
|
|
{
|
|
|
- /* Always run after connect */
|
|
|
+ /* Always run after (re)connect */
|
|
|
const ip_addr_t *dns_ip = dns_getserver(0);
|
|
|
- if (invalid_ip(dns_ip)) {
|
|
|
- /* No DNS server from DHCP? */
|
|
|
+ if (invalid_ip(dns_ip) || mode == WIFI_AP ||
|
|
|
+ getenv_bool("ip4.dhcp.nodns")) {
|
|
|
+ /* Static DNS server configuration */
|
|
|
ip_addr_t addr;
|
|
|
- if (inet_aton(DNSServer.c_str(), &addr)) {
|
|
|
+ if (dnsserver != "" && inet_aton(dnsserver.c_str(), &addr)) {
|
|
|
dns_setserver(0, &addr);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
dns_ip = dns_getserver(0);
|
|
|
printf("[DNS] DNS server: %s\n", inet_ntoa(*dns_ip));
|
|
|
-
|
|
|
+
|
|
|
// If Arduino supported both of these at the same that would be
|
|
|
// awesome, but it requires ESP-IDF reconfiguration...
|
|
|
const ip_addr_t *sntp_ip = sntp_getserver(0);
|
|
|
|
|
|
- if (invalid_ip(sntp_ip) && !SNTPServer.isEmpty())
|
|
|
- sntp_setservername(0, SNTPServer.c_str());
|
|
|
+ if (invalid_ip(sntp_ip) || mode == WIFI_AP ||
|
|
|
+ getenv_bool("ip4.dhcp.nosntp")) {
|
|
|
+ if (sntpserver != "")
|
|
|
+ sntp_setservername(0, sntpserver.c_str());
|
|
|
+ }
|
|
|
|
|
|
sntp_ip = sntp_getserver(0);
|
|
|
printf("[SNTP] Time server: %s\n", inet_ntoa(*sntp_ip));
|
|
@@ -112,6 +112,7 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
|
|
{
|
|
|
bool retry = false;
|
|
|
bool connected = false;
|
|
|
+ static int ap_clients = 0;
|
|
|
|
|
|
switch (event) {
|
|
|
case ARDUINO_EVENT_WIFI_READY:
|
|
@@ -158,18 +159,25 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
|
|
break;
|
|
|
case ARDUINO_EVENT_WIFI_AP_START:
|
|
|
printf("[WIFI] Access point started\n");
|
|
|
+ ap_clients = 0;
|
|
|
+ connected = true;
|
|
|
break;
|
|
|
case ARDUINO_EVENT_WIFI_AP_STOP:
|
|
|
printf("[WIFI] Access point stopped\n");
|
|
|
+ ap_clients = 0;
|
|
|
+ connected = false;
|
|
|
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 to client\n");
|
|
|
+ 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");
|
|
@@ -218,38 +226,77 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void SetupWiFi() {
|
|
|
- services_started = false;
|
|
|
+static void wifi_config(void)
|
|
|
+{
|
|
|
+ ssid = getenv("wifi.ssid");
|
|
|
+ password = getenv("wifi.psk");
|
|
|
+ hostname = getenv("hostname");
|
|
|
+ sntpserver = getenv_bool("sntp") ? getenv("sntp.server") : "";
|
|
|
+ dnsserver = getenv("ip4.dns");
|
|
|
+
|
|
|
+ WiFi.persistent(false);
|
|
|
|
|
|
- ssid = GetWifiSSID();
|
|
|
- password = GetWifiPassword();
|
|
|
- hostname = GetHostname();
|
|
|
+ if (hostname != "")
|
|
|
+ WiFi.hostname(hostname);
|
|
|
|
|
|
- if (!TimeZone.isEmpty()) {
|
|
|
- printf("[INFO] Setting TZ = %s\n", TimeZone.c_str());
|
|
|
- setenv("TZ", TimeZone.c_str(), 1);
|
|
|
- tzset();
|
|
|
+ if (ssid == "") {
|
|
|
+ uint8_t mac[6];
|
|
|
+ char ssid_buf[64];
|
|
|
+
|
|
|
+ mode = WIFI_AP;
|
|
|
+ password = "";
|
|
|
+
|
|
|
+ WiFi.macAddress(mac);
|
|
|
+ /* Skip first 4 bytes of MAC */
|
|
|
+ snprintf(ssid_buf, sizeof ssid_buf, "MAX80_%02X%02X", mac[4], mac[5]);
|
|
|
+ ssid = String(ssid_buf);
|
|
|
+ } else {
|
|
|
+ mode = WIFI_STA;
|
|
|
}
|
|
|
- my_sntp_start();
|
|
|
-
|
|
|
- printf("[INFO] Setting up WiFi\n");
|
|
|
- printf("[INFO] SSID: %s\n", ssid.c_str());
|
|
|
|
|
|
- WiFi.onEvent(WiFiEvent);
|
|
|
+ printf("[WIFI] SSID [%s]: %s\n",
|
|
|
+ mode == WIFI_AP ? "AP" : "STA", ssid.c_str());
|
|
|
|
|
|
- if (WiFi.getMode() != WIFI_STA) {
|
|
|
- WiFi.mode(WIFI_STA);
|
|
|
+ if (WiFi.getMode() != mode) {
|
|
|
+ WiFi.mode(mode);
|
|
|
delay(10);
|
|
|
}
|
|
|
|
|
|
- if (WiFi.SSID() != ssid || WiFi.psk() != password) {
|
|
|
- printf("[INFO] WiFi config changed.\n");
|
|
|
- // ... Try to connect to WiFi station.
|
|
|
- WiFi.begin(ssid.c_str(), password.c_str());
|
|
|
+ if (mode == WIFI_AP) {
|
|
|
+ /* 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;
|
|
|
+
|
|
|
+ printf("[WIFI] AP IP %s netmask %s channel %u\n",
|
|
|
+ AP_IP.toString(), AP_Netmask.toString(), channel+1);
|
|
|
+
|
|
|
+ WiFi.softAP(ssid.c_str(), password.c_str(), channel+1, 0, 4, true);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Conservative settings: 20 MHz, maximum power; this is for
|
|
|
+ // reliability, not performance.
|
|
|
+ //
|
|
|
+ WiFi.setTxPower((wifi_power_t)0);
|
|
|
+ esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_AP, WIFI_BW_HT20);
|
|
|
+
|
|
|
+ WiFi.softAPsetHostname(ssid.c_str());
|
|
|
+ WiFi.softAPConfig(AP_IP, AP_Gateway, AP_Netmask);
|
|
|
} else {
|
|
|
- WiFi.begin();
|
|
|
+ WiFi.begin(ssid.c_str(), password.c_str());
|
|
|
+ WiFi.setAutoConnect(true);
|
|
|
+ WiFi.setAutoReconnect(true);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- WiFi.setAutoReconnect(true);
|
|
|
- WiFi.setHostname(hostname.c_str());
|
|
|
+void SetupWiFi() {
|
|
|
+ services_started = false;
|
|
|
+
|
|
|
+ WiFi.onEvent(WiFiEvent);
|
|
|
+
|
|
|
+ my_sntp_start();
|
|
|
+
|
|
|
+ printf("[INFO] Setting up WiFi\n");
|
|
|
+ wifi_config();
|
|
|
}
|