#include "network.h" #include "esp_log.h" #include "esp_log_level.h" #include "esp_netif.h" #include "esp_netif_ip_addr.h" #include "esp_netif_types.h" #include "esp_wifi_default.h" #include "esp_wifi_types_generic.h" #include "config.h" #include "freertos/idf_additions.h" #include "freertos/projdefs.h" #include #include #include #include #define TAG "sprayduck" static EventGroupHandle_t s_wifi_event_group; static esp_netif_ip_info_t* ip_address = NULL; void wifi_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* event_data) { if (base != WIFI_EVENT) { return; } if (id == WIFI_EVENT_STA_START) { // If station mode has started successfully, attempt a connection ESP_LOGI(TAG, "Connecting..."); ESP_ERROR_CHECK(esp_wifi_connect()); ESP_LOGI(TAG, "CONNECTED..."); } else if (id == WIFI_EVENT_STA_DISCONNECTED) { // If we disconnected, attempt a reconnect ESP_LOGI(TAG, "Attempting reconnection..."); ESP_ERROR_CHECK(esp_wifi_connect()); // Mark connection as not ready xEventGroupClearBits(s_wifi_event_group, BIT0); ip_address = NULL; } } void ip_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* event_data) { if (base != IP_EVENT) { return; } if (id == IP_EVENT_STA_GOT_IP) { // 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)); // Mark connection as ready xEventGroupSetBits(s_wifi_event_group, BIT0); ip_address = &event->ip_info; } } void setup_network() { // Event group to be notified when ready to connect s_wifi_event_group = xEventGroupCreate(); xEventGroupClearBits(s_wifi_event_group, BIT0); // Set logging level to verbose esp_log_level_set("sprayduck", ESP_LOG_VERBOSE); // Setup TCP/IP stack - create event loop which registers events from TC/IP // stack esp_netif_init(); // We must create the event loop before anything because the drivers need to // register system handlers, which require the event loop esp_event_loop_create_default(); // Setup Wi-fi driver, configured in Station (client) mode This step involves // attaching system handlers to the above created default event loop. This // must be done before attaching any user event handlers because this has // higer priority esp_netif_create_default_wifi_sta(); // Configuration for how the wifi will be setup wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); // Disable nvs memory, not needed config.nvs_enable = 0; // Initalize above declared wifi configuration This initalizes the wifi // driver, and starts the driver task ESP_ERROR_CHECK(esp_wifi_init(&config)); //Set to station mode ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); // Connect to AP with provided SSID and PASSWORD wifi_sta_config_t sta_config = { .ssid = SSID, .password = PASSWORD, }; // Apply above define configuration ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t*) &sta_config)); esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; // All Wifi related events are handled here ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id)); // All IP related events are handled here ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL, &instance_got_ip)); // Start the client ESP_ERROR_CHECK(esp_wifi_start()); } void send_packet(char* data) { ESP_LOGI(TAG, "Sending packet"); EventBits_t bits = xEventGroupGetBits(s_wifi_event_group); // We are connected and have a valid ip_address if (bits & BIT0 && ip_address != NULL) { ESP_LOGI(TAG, "Have IP, Sending packet"); // char ip[20]; // sprintf(ip, IPSTR, IP2STR(&ip_address->ip)); int sock; struct addrinfo hints, *p, *res; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(SERVER_IP, SERVER_PORT, &hints, &res) != 0) { return; } if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { fprintf(stderr, "%s: socket (%d): %s\n", TAG, errno, strerror(errno)); return ; } if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) { fprintf(stderr, "%s: connect (%d): %s\n", TAG, errno, strerror(errno)); return ; } int len = strlen(data); int bytes_sent = 0; int total_bytes_sent = 0; while (1) { if ((bytes_sent = send(sock, data, len, 0)) == -1) { fprintf(stderr, "%s: send (%d): %s\n", TAG, errno, strerror(errno)); return ; } total_bytes_sent += bytes_sent; if (bytes_sent == len) { break; } } close(sock); freeaddrinfo(res); return ; } }