Wifi Task
The wifi task manages connecting and reconnecting to a wifi network, setting the mdns hostname and ip address of the device, and searching for the mqtt broker.
Configuration
WIFI_VERBOSE_LOGGING
if set to 1, the wifi task will log any wifi events to the console.
#define WIFI_VERBOSE_LOGGING 0
EXPONENTIAL_BACKOFF_START
the initial time to wait before reconnecting to a wifi network after a failure in ms.
#define EXPONENTIAL_BACKOFF_START (100)
EXPONENTIAL_BACKOFF_MAX
the maximum time to wait before reconnecting to a wifi network after a failure in ms.
#define EXPONENTIAL_BACKOFF_MAX (30000)
Public Variables
current_ip
the current ip address of the device as a string in format A.B.C.D . is empty string "" if not connected to a wifi network.
char current_ip[20] = {0};
server_ip
the ip address of the broker as a string in format A.B.C.D . is empty string "" if not found.
char server_ip[20] = {0};
hostname
the mdns hostname of the device as a string. in the form ReGen_XXXXXXXXXXXX where X is a hex digit.
char hostname[32] = {0};
Public Functions
find_broker
triggers a rescan for the mqtt broker, can block for up to 1 second.
void find_broker(void)
{
esp_ip4_addr_t ip;
esp_err_t res = mdns_query_a("egym_broker", 1000, &ip);
if (res == ESP_OK)
{
sprintf(server_ip, IPSTR, IP2STR(&ip));
WIFI_LOG_VERBOSE("found mqtt broker at %s\n", server_ip);
}
else
{
WIFI_LOG_VERBOSE("failed to find mqtt broker on local network\n");
}
}
wifi_is_connected
returns true if the device is currently connected to a wifi network.
bool wifi_is_connected(void)
{
return xEventGroupGetBits(s_wifi_event_group) & WIFI_CONNECTED_BIT;
}
wifi_init()
initializes the wifi task.
void wifi_init(void)
{
wifi_cient_init();
mdns_start();
// wifi_logging_init();
}
Private Variables
s_wifi_event_group
the event group for the wifi task. used for wifi_is_connected().
static EventGroupHandle_t s_wifi_event_group;
exponential_backoff
the current time to wait before reconnecting to a wifi network after a failure in ms doubles each failiure, until it reaches its maximum.
static int exponential_backoff = EXPONENTIAL_BACKOFF_START;
Private Functions
event_handler
handles wifi events from the ESP WiFi stack. tries to reconnect to the wifi network if disconnected. sets the current ip address if connected.
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
memset(current_ip, 0, sizeof(current_ip));
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
if (exponential_backoff < EXPONENTIAL_BACKOFF_MAX)
{
exponential_backoff *= 2;
}
WIFI_LOG_VERBOSE("failed to connect to the AP, wait %dms", exponential_backoff);
vTaskDelay(pdMS_TO_TICKS(exponential_backoff));
esp_wifi_connect();
WIFI_LOG_VERBOSE("retry to connect to the AP");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
memset(current_ip, 0, sizeof(current_ip));
sprintf(current_ip, IPSTR, IP2STR(&event->ip_info.ip));
exponential_backoff = EXPONENTIAL_BACKOFF_START;
WIFI_LOG_VERBOSE("got ip: %s", current_ip);
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
wifi_cient_init
initializes the ESP WiFi stack.
static esp_err_t wifi_cient_init(void)
{
esp_err_t res = ESP_OK;
s_wifi_event_group = xEventGroupCreate();
res |= esp_netif_init();
res |= esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
res |= esp_wifi_init(&cfg);
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
res |= esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id);
res |= esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip);
wifi_config_t wifi_config = {
.sta =
{
.ssid = "Energym_bikes",
.password = "[REDACTED]",
.threshold.authmode = WIFI_AUTH_OPEN,
.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED,
},
};
res |= esp_wifi_set_mode(WIFI_MODE_STA);
res |= esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
res |= esp_wifi_start();
return res;
}
mdns_start
starts the mdns service. registers the mdns hostname of the device. registers a .egym.tcp service for the device so zeroconf clients can find it.
static void mdns_start()
{
mdns_init();
uint8_t mac[8];
esp_read_mac(mac, ESP_MAC_BT);
sprintf(hostname, "ReGen_%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
mdns_hostname_set(hostname);
mdns_instance_name_set(hostname);
mdns_service_add(NULL, "_egym", "_tcp", 80, NULL, 0);
}