#include "network.h" #include #include #include #include #include #include #include #include #include ESP_EVENT_DEFINE_BASE(SNTP_EVENT); static const char *TAG = "network"; void time_sync_notification_cb(struct timeval *tv) { // NOLINT, it cant ESP_LOGI(TAG, "time synced, unix time is %llu", tv->tv_sec); esp_event_post(SNTP_EVENT, SNTP_EVENT_SYNCED, nullptr, 0, portMAX_DELAY); } // logs IP, starts sntp static void on_get_ip(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { const ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "ip getto: " IPSTR, IP2STR(&event->ip_info.ip)); sntp_set_time_sync_notification_cb(time_sync_notification_cb); sntp_set_sync_interval(SNTP_TIME_SYNC_INTERVAL_MINUTES * 60 * 1000); esp_sntp_setservername(0, SNTP_SERVER); setenv("TZ", POSIX_TIMEZONE_STRING, true); tzset(); esp_sntp_init(); } // we sometimes call this by hand to init scanning static void on_wifi_disconnect(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { ESP_LOGI(TAG, "Wi-Fi disconnected, scanning for networks..."); const wifi_scan_config_t scan_cfg = {.show_hidden = true}; esp_wifi_scan_start(&scan_cfg, false); } // when scanning done, match against known networks and try to connect to it static void on_scan_done(void *nets, esp_event_base_t event_base, int32_t event_id, void *event_data) { const struct wifi_networks_t *known_networks = (struct wifi_networks_t *)nets; uint16_t ap_count = 0; esp_wifi_scan_get_ap_num(&ap_count); wifi_ap_record_t *ap_list = malloc(ap_count * sizeof(wifi_ap_record_t)); esp_wifi_scan_get_ap_records(&ap_count, ap_list); int best_match = -1; int best_rssi = INT_MIN; for (int i = 0; i < ap_count; i++) { for (int k = 0; k < known_networks->num_nets; k++) { if (strcmp((char *)ap_list[i].ssid, known_networks->nets[k].ssid) == 0) { if (ap_list[i].rssi > best_rssi) { best_rssi = (uint8_t)ap_list[i].rssi; best_match = k; } } } } free(ap_list); if (best_match < 0) { ESP_LOGW(TAG, "no known networks found"); on_wifi_disconnect(nullptr, WIFI_EVENT, WIFI_EVENT_SCAN_DONE, nullptr); return; } wifi_config_t wifi_cfg = {}; strncpy((char *)wifi_cfg.sta.ssid, known_networks->nets[best_match].ssid, sizeof(known_networks->nets[0].ssid) - 1); strncpy((char *)wifi_cfg.sta.password, known_networks->nets[best_match].password, sizeof(known_networks->nets[0].password) - 1); wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); esp_wifi_connect(); } void init_ethernet(const char *hostname) { ESP_ERROR_CHECK(esp_netif_init()); uint8_t eth_port_cnt = 0; esp_eth_handle_t *eth_handles; // allow ethernet oscillator ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); // install eth chip driver ESP_ERROR_CHECK(ethernet_init_all(ð_handles, ð_port_cnt)); const esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); esp_netif_t *eth_netif = esp_netif_new(&cfg); esp_netif_set_hostname(eth_netif, hostname); ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[0]))); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_get_ip, nullptr)); ESP_ERROR_CHECK(esp_eth_start(eth_handles[0])); } void init_wifi(const struct wifi_networks_t *nets, const char *hostname) { nvs_flash_init(); esp_netif_init(); esp_netif_t *netif = esp_netif_create_default_wifi_sta(); esp_netif_set_hostname(netif, hostname); // create and register event handlers esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_SCAN_DONE, on_scan_done, (void *)nets); esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, nullptr); esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_get_ip, nullptr); const wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_start(); on_wifi_disconnect(nullptr, WIFI_EVENT, WIFI_EVENT_SCAN_DONE, nullptr); }