2018-09-02 20:10:41 -04:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
#include "freertos/task.h"
|
2018-09-03 18:35:15 -04:00
|
|
|
#include "freertos/event_groups.h"
|
2018-09-02 20:10:41 -04:00
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
#include "esp_event_loop.h"
|
2018-09-02 20:10:41 -04:00
|
|
|
#include "esp_heap_caps.h"
|
2018-09-03 18:35:15 -04:00
|
|
|
#include "esp_log.h"
|
|
|
|
#include "esp_wifi.h"
|
|
|
|
#include "nvs_flash.h"
|
2018-09-02 20:10:41 -04:00
|
|
|
|
|
|
|
#include "driver/gpio.h"
|
2018-09-03 18:35:15 -04:00
|
|
|
#include "driver/uart.h"
|
2018-09-02 20:10:41 -04:00
|
|
|
#include "driver/spi_common.h"
|
|
|
|
#include "driver/spi_master.h"
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
#include "lwip/err.h"
|
|
|
|
#include "lwip/sys.h"
|
|
|
|
|
|
|
|
#include "esp32-wifi-manager.h"
|
|
|
|
|
|
|
|
#define MAX_ESSID (32)
|
|
|
|
#define MAX_PASSWORD (64)
|
2018-09-02 20:10:41 -04:00
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
static const char *TAG = "WM";
|
|
|
|
nvs_handle nvs;
|
2018-09-02 20:10:41 -04:00
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
typedef struct wifi_manager_ap_info {
|
|
|
|
char ssid[MAX_ESSID];
|
|
|
|
char password[MAX_PASSWORD];
|
|
|
|
} wifi_manager_ap_info_t;
|
|
|
|
|
|
|
|
typedef struct ap_store_base {
|
|
|
|
int8_t last;
|
2018-09-02 20:10:41 -04:00
|
|
|
uint8_t count;
|
2018-09-03 18:35:15 -04:00
|
|
|
uint32_t magic;
|
|
|
|
|
|
|
|
wifi_manager_ap_info_t aps[CONFIG_WIFI_MANAGER_MAX_AP];
|
|
|
|
} ap_store_t;
|
|
|
|
|
|
|
|
ap_store_t ap_store;
|
|
|
|
static EventGroupHandle_t wm_event_group;
|
2018-09-02 20:10:41 -04:00
|
|
|
|
2018-09-22 00:31:37 -04:00
|
|
|
void wifi_manager_connect();
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
uint8_t wifi_manager_ap_count() {
|
|
|
|
return ap_store.count;
|
|
|
|
};
|
|
|
|
|
|
|
|
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) {
|
|
|
|
ESP_LOGI(TAG, "wifi event: %d", event->event_id);
|
|
|
|
|
|
|
|
switch (event->event_id) {
|
|
|
|
case SYSTEM_EVENT_STA_START:
|
|
|
|
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_connect());
|
|
|
|
break;
|
|
|
|
case SYSTEM_EVENT_STA_GOT_IP:
|
|
|
|
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
|
|
|
|
ESP_LOGI(TAG, "Got IP: %s\n",
|
|
|
|
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
|
|
|
|
|
|
|
|
xEventGroupSetBits(wm_event_group, WIFI_CONNECTED);
|
|
|
|
break;
|
|
|
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
|
|
|
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
|
2018-09-22 01:12:17 -04:00
|
|
|
xEventGroupClearBits(wm_event_group, WIFI_CONNECTED);
|
2018-09-22 00:38:36 -04:00
|
|
|
|
2018-09-22 01:12:17 -04:00
|
|
|
vTaskDelay(CONFIG_WIFI_MANAGER_CONNECTION_DELAY / portTICK_PERIOD_MS);
|
2018-09-22 00:38:36 -04:00
|
|
|
|
|
|
|
ap_store.last++;
|
2018-09-22 01:12:17 -04:00
|
|
|
if(ap_store.count == ap_store.last) {
|
|
|
|
ap_store.last = 0;
|
|
|
|
}
|
2018-09-22 00:38:36 -04:00
|
|
|
|
|
|
|
wifi_manager_connect();
|
2018-09-03 18:35:15 -04:00
|
|
|
ESP_ERROR_CHECK(esp_wifi_connect());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ESP_OK;
|
|
|
|
|
|
|
|
return ESP_OK;
|
2018-09-02 20:10:41 -04:00
|
|
|
}
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
uint8_t wifi_manager_add_ap(char *ssid, char *password) {
|
|
|
|
strcpy(ap_store.aps[ap_store.count].ssid, (char *)ssid);
|
|
|
|
strcpy(ap_store.aps[ap_store.count].password, (char *)password);
|
|
|
|
|
|
|
|
++ap_store.count;
|
|
|
|
|
2018-09-22 00:32:23 -04:00
|
|
|
if(ap_store.last == -1)
|
|
|
|
ap_store.last = 0;
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
wifi_manager_save_config();
|
|
|
|
|
|
|
|
return ap_store.count;
|
|
|
|
};
|
|
|
|
|
|
|
|
void wifi_manager_connect() {
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
wifi_config_t wifi_config = {
|
|
|
|
.sta = {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-09-22 00:35:34 -04:00
|
|
|
ESP_LOGI(TAG, "connecting to AP %d of %d", ap_store.last, ap_store.count);
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
memcpy((char *)&wifi_config.sta.ssid, ap_store.aps[ap_store.last].ssid, strlen(ap_store.aps[ap_store.last].ssid) + 1);
|
|
|
|
memcpy((char *)&wifi_config.sta.password, ap_store.aps[ap_store.last].password, strlen(ap_store.aps[ap_store.last].password) + 1);
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
|
|
|
ESP_LOGI(TAG, "connect to ap SSID:%s password:%s",
|
|
|
|
wifi_config.sta.ssid, wifi_config.sta.password);
|
|
|
|
};
|
|
|
|
|
|
|
|
void wifi_manager_main_loop() {
|
2018-09-22 00:34:52 -04:00
|
|
|
ap_store.last = 0;
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
while(true) {
|
|
|
|
EventBits_t ev_bits = xEventGroupGetBits(wm_event_group);
|
|
|
|
|
|
|
|
if(ev_bits & AP_AVAILABLE && (ev_bits & WIFI_CONNECTING) == 0) {
|
|
|
|
ESP_LOGI(TAG, "AP Available, starting WiFi connect");
|
|
|
|
|
|
|
|
xEventGroupSetBits(wm_event_group, WIFI_CONNECTING);
|
|
|
|
|
|
|
|
wifi_manager_connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void wifi_manager_save_config() {
|
|
|
|
ESP_LOGI(TAG, "writing %d byte config", sizeof(ap_store));
|
|
|
|
ESP_LOGI(TAG, "ap_store.magic = 0x%4X", ap_store.magic);
|
|
|
|
ESP_LOGI(TAG, "ap_store.count = %d", ap_store.count);
|
|
|
|
ESP_LOGI(TAG, "ap_store.last = %d", ap_store.last);
|
|
|
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
|
|
for(; i < ap_store.count; i++) {
|
|
|
|
ESP_LOGI(TAG, "AP: %s", ap_store.aps[i].ssid);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ap_store.count > 0) {
|
|
|
|
ESP_LOGI(TAG, "setting AP_AVAILABLE");
|
|
|
|
|
|
|
|
xEventGroupSetBits(wm_event_group, AP_AVAILABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(nvs_set_blob(nvs, "config", &ap_store, (size_t)sizeof(ap_store)));
|
|
|
|
nvs_commit(nvs);
|
|
|
|
};
|
|
|
|
|
|
|
|
void wifi_manager_reset_store() {
|
2018-09-22 00:35:34 -04:00
|
|
|
ESP_LOGW(TAG, "resetting store");
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
memset(&ap_store, 0, sizeof(ap_store));
|
|
|
|
|
|
|
|
ap_store.magic = WIFI_MANAGER_MAGIC;
|
|
|
|
ap_store.last = -1;
|
|
|
|
|
|
|
|
wifi_manager_save_config();
|
|
|
|
};
|
|
|
|
|
|
|
|
void wifi_manager_load_config() {
|
|
|
|
size_t store_size = 0;
|
|
|
|
esp_err_t err;
|
|
|
|
|
|
|
|
err = nvs_get_blob(nvs, "config", NULL, &store_size);
|
|
|
|
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) ESP_ERROR_CHECK(err);
|
|
|
|
|
|
|
|
err = nvs_get_blob(nvs, "config", &ap_store, &store_size);
|
|
|
|
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) ESP_ERROR_CHECK(err);
|
|
|
|
|
|
|
|
if(ap_store.magic != WIFI_MANAGER_MAGIC) {
|
|
|
|
ESP_LOGI(TAG, "load_config got bad magic: 0x%8X", ap_store.magic);
|
|
|
|
|
|
|
|
wifi_manager_reset_store();
|
|
|
|
|
|
|
|
return wifi_manager_save_config();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ap_store.count > 0) {
|
|
|
|
xEventGroupSetBits(wm_event_group, AP_AVAILABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
for(; i < ap_store.count; i++)
|
|
|
|
ESP_LOGI(TAG, "AP: %s", ap_store.aps[i].ssid);
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "load_config found %d APs", ap_store.count);
|
|
|
|
};
|
|
|
|
|
2018-09-03 22:52:07 -04:00
|
|
|
EventGroupHandle_t wifi_manager_start() {
|
2018-09-03 18:35:15 -04:00
|
|
|
ESP_ERROR_CHECK(nvs_open("wm-config", NVS_READWRITE, &nvs));
|
|
|
|
|
|
|
|
wm_event_group = xEventGroupCreate();
|
|
|
|
|
|
|
|
wifi_manager_load_config();
|
2018-09-02 20:10:41 -04:00
|
|
|
|
2018-09-22 00:33:36 -04:00
|
|
|
tcpip_adapter_init();
|
|
|
|
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL) );
|
|
|
|
|
2018-09-03 18:35:15 -04:00
|
|
|
xTaskCreate(&wifi_manager_main_loop, "wm_main_loop", 4096, NULL, 6, NULL);
|
2018-09-03 22:52:07 -04:00
|
|
|
|
|
|
|
return wm_event_group;
|
2018-09-02 20:10:41 -04:00
|
|
|
};
|