#include "nvs.h" #include "nvs-config.h" #include "network.h" #include #include #include #include #include #include #include #define TAG "network" #define ESP_WIFI_SSID "blackmagic" #define ESP_WIFI_PASS "iamwitcher" #define ESP_WIFI_CHANNEL 1 #define MDNS_HOST_NAME "blackmagic" #define MDNS_INSTANCE "blackmagic web server" #ifndef min #define min(a, b) \ ({ \ __typeof__(a) _a = (a); \ __typeof__(b) _b = (b); \ _a < _b ? _a : _b; \ }) #endif #define WIFI_MAXIMUM_RETRY 3 #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 static WiFiMode wifi_mode = WiFiModeSTA; uint32_t network_get_ip(void) { tcpip_adapter_ip_info_t ip_info; if(wifi_mode == WiFiModeSTA) { tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); } else { tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip_info); } return ip_info.ip.addr; } static void sta_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) { esp_wifi_connect(); } 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; ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); } } static void ap_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if(event_id == WIFI_EVENT_AP_STACONNECTED) { wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*)event_data; ESP_LOGI(TAG, "station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid); } else if(event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*)event_data; ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d", MAC2STR(event->mac), event->aid); } } static void network_start_ap(mstring_t* ap_ssid, mstring_t* ap_pass) { ESP_LOGI(TAG, "init access point mode"); esp_netif_create_default_wifi_ap(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_event_handler_instance_register( WIFI_EVENT, ESP_EVENT_ANY_ID, &ap_event_handler, NULL, NULL)); wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); wifi_config.ap.ssid_len = 0; wifi_config.ap.channel = ESP_WIFI_CHANNEL; wifi_config.ap.max_connection = 4; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; memcpy( &wifi_config.ap.ssid, mstring_get_cstr(ap_ssid), min(sizeof(wifi_config.ap.ssid), mstring_size(ap_ssid))); memcpy( &wifi_config.ap.password, mstring_get_cstr(ap_pass), min(sizeof(wifi_config.ap.password), mstring_size(ap_pass))); wifi_config.ap.ssid_len = mstring_size(ap_ssid); if(mstring_size(ap_pass) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI( TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d", mstring_get_cstr(ap_ssid), mstring_get_cstr(ap_pass), ESP_WIFI_CHANNEL); ESP_LOGI(TAG, "init access point mode done"); } static bool network_connect_ap(mstring_t* ap_ssid, mstring_t* ap_pass) { bool result = false; ESP_LOGI(TAG, "init connect to AP"); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &sta_event_handler, NULL)); ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &sta_event_handler, NULL)); wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); memcpy( &wifi_config.sta.ssid, mstring_get_cstr(ap_ssid), min(sizeof(wifi_config.sta.ssid), mstring_size(ap_ssid))); memcpy( &wifi_config.sta.password, mstring_get_cstr(ap_pass), min(sizeof(wifi_config.sta.password), mstring_size(ap_pass))); 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, "init connect to AP done. SSID:%s password:%s", mstring_get_cstr(ap_ssid), mstring_get_cstr(ap_pass)); return result; } void network_hostnames_init(void) { mstring_t* hostname = mstring_alloc(); ESP_LOGI(TAG, "init mdns"); mdns_init(); nvs_config_get_hostname(hostname); mdns_hostname_set(mstring_get_cstr(hostname)); mdns_instance_name_set(MDNS_INSTANCE); mdns_txt_item_t serviceTxtData[] = {{"board", "esp32"}, {"path", "/"}}; ESP_ERROR_CHECK(mdns_service_add( "ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, sizeof(serviceTxtData) / sizeof(serviceTxtData[0]))); ESP_LOGI(TAG, "init MDNS done"); ESP_LOGI(TAG, "init netbios"); netbiosns_init(); netbiosns_set_name(mstring_get_cstr(hostname)); ESP_LOGI(TAG, "init netbios done"); mstring_free(hostname); } WiFiMode network_init(void) { mstring_t* ssid = mstring_alloc(); mstring_t* pass = mstring_alloc(); ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_netif_init()); nvs_config_get_wifi_mode(&wifi_mode); network_hostnames_init(); switch(wifi_mode) { case WiFiModeAP: nvs_config_get_ap_ssid(ssid); nvs_config_get_ap_pass(pass); network_start_ap(ssid, pass); break; case WiFiModeSTA: nvs_config_get_sta_ssid(ssid); nvs_config_get_sta_pass(pass); network_connect_ap(ssid, pass); break; case WiFiModeDisabled: break; } mstring_free(ssid); mstring_free(pass); return wifi_mode; } WiFiMode network_get_mode(void) { return wifi_mode; }