34:
name_<"WiFi Manager">
35,
author_<"Edu Meneses (2022) and Travis J. West (2023)">
37,
license_<"SPDX-License-Identifier: MIT">
39,
description_<"An ESP-IDF WiFi API wrapper originally adapted from the Puara Module Manager">
43 ,
"Name of this device on the network."
44 "Must be less than 31 bytes long."
45 "Requires reboot to take effect."
48 text<
"access point SSID"
49 ,
"Name of the device-hosted network."
50 "Must be less than 31 bytes long."
51 "Requires reboot to take effect."
54 text<
"access point password"
55 ,
"Password of the device-hosted network."
56 "Must be greater than 8 and less than 63 bytes long."
57 "Requires reboot to take effect."
61 ,
"Name of the WiFi network to connect to."
62 "Must be less than 31 bytes long."
63 "Requires reboot to take effect."
67 ,
"Password of the WiFi network to connect to."
68 "Must be greater than 8 and less than 63 bytes long."
69 "Requires reboot to take effect."
72 toggle<
"enable access point"
73 ,
"Indicate whether to persistently enable the device-hosted network."
74 "When this toggle is disabled, the access point is only enabled if"
75 "the device fails to connect to WiFi in station mode."
82 toggle<
"WiFi connected",
"Indicates when WiFi is successfully connected"> wifi_connected;
83 toggle<
"AP running",
"Indicates when the device-hosted network is running"> ap_running;
84 text<
"WiFi MAC",
"MAC address of the device as a WiFi station on the main network"> wifi_mac;
85 text<
"AP MAC",
"MAC address of the device as a WiFi access point on the device-hosted network"> ap_mac;
86 text<
"IP address",
"IP address of the device as a WiFi station on the main network."
87 "Use this address to send network messages to the device when WiFi is connected."> ip_address;
91 EventGroupHandle_t event_group;
92 char connection_attempts;
93 sygup::CstdioLogger* log;
94 static constexpr int connected_bit = BIT0;
95 static constexpr int fail_bit = BIT1;
96 static constexpr int maximum_connection_attempts = 2;
99 void set_wifi_mode(wifi_mode_t mode)
101 log.print(
"wifi: setting WiFi mode to ");
104 case WIFI_MODE_STA: log.println(
"station");
break;
105 case WIFI_MODE_AP: log.println(
"access point");
break;
106 case WIFI_MODE_APSTA: log.println(
"access point / station");
break;
107 default: log.println(
"unsupported mode..?");
break;
110 ESP_ERROR_CHECK(esp_wifi_set_mode(mode));
112 if (mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA)
114 wifi_config_t sta_config{};
115 std::memcpy(sta_config.sta.ssid, inputs.wifi_ssid.value.c_str(), inputs.wifi_ssid.value.length()+1);
116 std::memcpy(sta_config.sta.password, inputs.wifi_password.value.c_str(), inputs.wifi_password.value.length()+1);
117 log.println(
"wifi: Enabling station");
118 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config));
121 if (mode == WIFI_MODE_AP || mode == WIFI_MODE_APSTA)
123 wifi_config_t ap_config{};
124 std::memcpy(ap_config.ap.ssid, inputs.ap_ssid.value.c_str(), inputs.ap_ssid.value.length()+1);
125 std::memcpy(ap_config.ap.password, inputs.ap_password.value.c_str(), inputs.ap_password.value.length()+1);
126 ap_config.ap.ssid_len = inputs.ap_ssid.value.length();
127 ap_config.ap.channel = 5;
128 ap_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
129 ap_config.ap.ssid_hidden = 0;
130 ap_config.ap.max_connection = 5;
132 log.println(
"wifi: Enabling access point");
133 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
137 [[no_unique_address]] sygup::CstdioLogger log;
141 if (inputs.hostname.value.empty() || inputs.hostname.value.length() > 31)
143 inputs.hostname =
"sygaldry_instrument";
144 log.println(
"wifi warning: initialized hostname................ '", inputs.hostname.value,
"'");
147 if (inputs.ap_ssid.value.empty() || inputs.ap_ssid.value.length() > 31)
149 inputs.ap_ssid =
"sygaldry_admin";
150 log.println(
"wifi warning: initialized access point SSID....... '", inputs.ap_ssid.value,
"'");
153 if ( inputs.ap_password.value.empty() || inputs.ap_password.value.length() < 8 || inputs.ap_password.value.length() > 63)
155 inputs.ap_password =
"sygaldry_admin";
156 log.println(
"wifi warning: initialized access point password... '", inputs.ap_password.value,
"'");
160 if ( inputs.wifi_ssid.value.empty() || inputs.wifi_ssid.value.length() > 31)
162 inputs.wifi_ssid =
"sygaldry_wifi";
163 log.println(
"wifi warning: initialized WiFi SSID............... '", inputs.wifi_ssid.value,
"'");
166 if ( inputs.wifi_password.value.empty() || inputs.wifi_password.value.length() < 8 || inputs.wifi_password.value.length() > 63)
168 inputs.wifi_password =
"sygaldry_admin";
169 log.println(
"wifi warning: initialized WiFi password........... '", inputs.wifi_password.value,
"'");
171 esp_err_t ret = nvs_flash_init();
172 if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
173 ESP_ERROR_CHECK(nvs_flash_erase());
174 ret = nvs_flash_init();
176 ESP_ERROR_CHECK(ret);
177 log.println(
"wifi: Initialized NVS");
179 ESP_ERROR_CHECK(esp_netif_init());
180 log.println(
"wifi: Initialized network interface");
182 ESP_ERROR_CHECK(esp_event_loop_create_default());
183 log.println(
"wifi: Created default event loop");
186 esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
187 esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
188 ESP_ERROR_CHECK(esp_netif_set_hostname( sta_netif
189 , inputs.hostname.value.c_str()
192 ESP_ERROR_CHECK(esp_netif_set_hostname( ap_netif
193 , inputs.hostname.value.c_str()
196 log.println(
"wifi: Set hostnames");
198 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
199 ESP_ERROR_CHECK(esp_wifi_init(&cfg));
200 log.println(
"wifi: Initialized WiFi with default configuration");
201 if (inputs.enable_ap) set_wifi_mode(WIFI_MODE_APSTA);
202 else set_wifi_mode(WIFI_MODE_STA);
203 auto sta_event_handler = +[](
void * arg, esp_event_base_t event_base,
long int event_id,
void * event_data)
205 handler_state_t& handler_state = *(handler_state_t*)arg;
206 auto& log = *handler_state.log;
207 if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
209 log.println(
"wifi: WiFi station started. Connecting to network...");
212 else if (event_base == WIFI_EVENT &&
213 event_id == WIFI_EVENT_STA_DISCONNECTED)
215 log.print(
"wifi: Station disconnected. ");
216 if (handler_state.connection_attempts < handler_state.maximum_connection_attempts)
218 log.println(
"Attempting to reconnect...");
220 handler_state.connection_attempts++;
222 log.println(
"Connection failed.");
223 xEventGroupSetBits(handler_state.event_group, handler_state.fail_bit);
225 }
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
226 log.println(
"Connection succeeded.");
227 handler_state.connection_attempts = 0;
228 xEventGroupSetBits(handler_state.event_group, handler_state.connected_bit);
231 handler_state_t handler_state{};
232 handler_state.event_group = xEventGroupCreate();
233 handler_state.connection_attempts = 0;
234 handler_state.log = &log;
236 esp_event_handler_instance_t instance_any_id;
237 esp_event_handler_instance_t instance_got_ip;
238 ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
241 (
void*)&handler_state,
244 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
247 (
void*)&handler_state,
250 log.println(
"wifi: Registered WiFi station event handler");
252 log.println(
"wifi: Starting WiFi...");
253 ESP_ERROR_CHECK(esp_wifi_start());
255 EventBits_t bits = xEventGroupWaitBits( handler_state.event_group
256 , handler_state.connected_bit | handler_state.fail_bit
257 , pdFALSE, pdFALSE, portMAX_DELAY
259 log.println(
"wifi: Finished waiting...");
260 if (bits & handler_state.connected_bit)
262 outputs.wifi_connected = 1;
263 outputs.ap_running = inputs.enable_ap;
267 set_wifi_mode(WIFI_MODE_AP);
268 outputs.ap_running = 1;
269 outputs.wifi_connected = 0;
284 char mac_string[18] = {0};
285 unsigned char mac[6] = {0};
287 auto mac_to_string = [&]()
290 for (
int i = 0; i < 6; ++i)
292 auto [one_past_written, ec] = std::to_chars(ptr, ptr+2, mac[i], 16);
293 if (one_past_written != ptr+2)
304 esp_wifi_get_mac(WIFI_IF_STA, mac);
306 outputs.wifi_mac.value = mac_string;
308 esp_wifi_get_mac(WIFI_IF_AP, mac);
310 outputs.ap_mac.value = mac_string;
313 esp_netif_ip_info_t ip_info;
314 esp_netif_get_ip_info(sta_netif, &ip_info);
316 auto [a,b] = std::to_chars(ptr, ptr+3, esp_ip4_addr1_16(&ip_info.ip), 10);
319 auto [c,d] = std::to_chars(ptr, ptr+3, esp_ip4_addr2_16(&ip_info.ip), 10);
322 auto [e,f] = std::to_chars(ptr, ptr+3, esp_ip4_addr3_16(&ip_info.ip), 10);
325 auto [g,h] = std::to_chars(ptr, ptr+3, esp_ip4_addr4_16(&ip_info.ip), 10);
328 outputs.ip_address = ip_string;
331 void main() {
return; }
A text string endpoint with persistent value semantics.
Definition sygah-endpoints.hpp:304