wifi_ap.cpp
1 #include "wifi_internal.h" 2 3 #include <identity.h> 4 5 #include <Arduino.h> 6 #include <ESPmDNS.h> 7 #include <Preferences.h> 8 #include <WiFi.h> 9 10 namespace { 11 12 void configure_ap(const char *ssid, const char *password) { 13 Preferences prefs; 14 if (!networking::wifi::internal::openPreferences(false, &prefs)) return; 15 prefs.putString("ap_ssid", ssid); 16 prefs.putString("ap_pass", password); 17 prefs.end(); 18 Serial.printf("[wifi] AP config saved: ssid=%s\n", ssid); 19 } 20 21 } 22 23 void networking::wifi::ap::accessConfig(APConfig *config) { 24 Preferences prefs; 25 bool prefs_ok = networking::wifi::internal::openPreferences(true, &prefs); 26 if (!prefs_ok || prefs.getString("ap_ssid", config->ssid, sizeof(config->ssid)) == 0) { 27 strncpy(config->ssid, config::wifi::ap::SSID, sizeof(config->ssid) - 1); 28 config->ssid[sizeof(config->ssid) - 1] = '\0'; 29 } 30 if (!prefs_ok || prefs.getString("ap_pass", config->password, sizeof(config->password)) == 0) { 31 strncpy(config->password, config::wifi::ap::PASSWORD, sizeof(config->password) - 1); 32 config->password[sizeof(config->password) - 1] = '\0'; 33 } 34 if (prefs_ok) prefs.end(); 35 } 36 37 bool networking::wifi::ap::accessSnapshot(APSnapshot *snapshot) { 38 if (!snapshot) return false; 39 memset(snapshot, 0, sizeof(*snapshot)); 40 snapshot->active = networking::wifi::internal::ap_active; 41 APConfig config = {}; 42 networking::wifi::ap::accessConfig(&config); 43 strncpy(snapshot->ssid, config.ssid, sizeof(snapshot->ssid) - 1); 44 strncpy(snapshot->password, config.password, sizeof(snapshot->password) - 1); 45 strncpy(snapshot->ip, WiFi.softAPIP().toString().c_str(), sizeof(snapshot->ip) - 1); 46 snapshot->clients = WiFi.softAPgetStationNum(); 47 strncpy(snapshot->hostname, services::identity::access_hostname(), sizeof(snapshot->hostname) - 1); 48 strncpy(snapshot->mac, WiFi.softAPmacAddress().c_str(), sizeof(snapshot->mac) - 1); 49 return true; 50 } 51 52 bool networking::wifi::ap::applyConfig(APConfigureCommand *command) { 53 if (!command) return false; 54 configure_ap(command->config.ssid, command->config.password); 55 if (networking::wifi::ap::isActive()) { 56 networking::wifi::ap::disable(); 57 networking::wifi::ap::enable(); 58 } 59 networking::wifi::ap::accessSnapshot(&command->snapshot); 60 return true; 61 } 62 63 void networking::wifi::ap::enable() { 64 { 65 Preferences prefs; 66 if (networking::wifi::internal::openPreferences(false, &prefs)) { 67 prefs.putBool("ap_on", true); 68 prefs.end(); 69 } 70 } 71 72 if (networking::wifi::internal::ap_active) return; 73 74 APConfig cfg = {}; 75 networking::wifi::ap::accessConfig(&cfg); 76 77 WiFi.mode(WIFI_AP_STA); 78 79 IPAddress ap_ip(192, 168, 4, 1); 80 IPAddress gateway(192, 168, 4, 1); 81 IPAddress subnet(255, 255, 255, 0); 82 WiFi.softAPConfig(ap_ip, gateway, subnet); 83 WiFi.softAP(cfg.ssid, cfg.password, config::wifi::ap::CHANNEL); 84 85 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2) 86 WiFi.AP.enableDhcpCaptivePortal(); 87 #endif 88 89 networking::wifi::internal::ap_active = true; 90 91 if (!networking::wifi::internal::mdns_started && MDNS.begin(services::identity::access_hostname())) { 92 networking::wifi::internal::configureMdnsServices(services::identity::access_hostname()); 93 networking::wifi::internal::mdns_started = true; 94 Serial.printf("[mdns] %s.local\n", services::identity::access_hostname()); 95 } 96 97 Serial.printf("[wifi] AP started: %s (%s)\n", 98 cfg.ssid, ap_ip.toString().c_str()); 99 } 100 101 bool networking::wifi::ap::setEnabled(APEnabledCommand *command) { 102 if (!command) return false; 103 if (command->enabled) networking::wifi::ap::enable(); 104 else networking::wifi::ap::disable(); 105 networking::wifi::ap::accessSnapshot(&command->snapshot); 106 return true; 107 } 108 109 void networking::wifi::ap::disable() { 110 { 111 Preferences prefs; 112 if (networking::wifi::internal::openPreferences(false, &prefs)) { 113 prefs.putBool("ap_on", false); 114 prefs.end(); 115 } 116 } 117 118 if (!networking::wifi::internal::ap_active) return; 119 120 WiFi.softAPdisconnect(true); 121 122 if (WiFi.isConnected()) { 123 WiFi.mode(WIFI_MODE_STA); 124 } 125 126 networking::wifi::internal::ap_active = false; 127 Serial.println(F("[wifi] AP stopped")); 128 } 129 130 bool networking::wifi::ap::isActive() { 131 return networking::wifi::internal::ap_active; 132 }