/* BSD Socket API Example This example code is in the Public Domain (or CC0 licensed, at your option.) Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include /* The examples use simple WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ #define EXAMPLE_WIFI_SSID "DAP" #define EXAMPLE_WIFI_PASS "12345678" #define PORT 22350 /* FreeRTOS event group to signal when we are connected & ready to make a request */ static EventGroupHandle_t wifi_event_group; const int IPV4_GOTIP_BIT = BIT0; #ifdef CONFIG_EXAMPLE_IPV6 const int IPV6_GOTIP_BIT = BIT1; #endif static const char *TAG = "example"; static esp_err_t event_handler(void *ctx, system_event_t *event) { /* For accessing reason codes in case of disconnection */ system_event_info_t *info = &event->event_info; switch (event->event_id) { case SYSTEM_EVENT_STA_START: esp_wifi_connect(); os_printf("SYSTEM_EVENT_STA_START\r\n"); break; case SYSTEM_EVENT_STA_CONNECTED: #ifdef CONFIG_EXAMPLE_IPV6 /* enable ipv6 */ tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); #endif break; case SYSTEM_EVENT_STA_GOT_IP: xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); os_printf("SYSTEM_EVENT_STA_GOT_IP\r\n"); break; case SYSTEM_EVENT_STA_DISCONNECTED: os_printf("Disconnect reason : %d\r\n", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); #ifdef CONFIG_EXAMPLE_IPV6 xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); #endif break; case SYSTEM_EVENT_AP_STA_GOT_IP6: #ifdef CONFIG_EXAMPLE_IPV6 xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n"); char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); os_printf("IPv6: %s\r\n", ip6); #endif default: break; } return ESP_OK; } static void initialise_wifi(void) { tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); wifi_config_t wifi_config = { .sta = { .ssid = EXAMPLE_WIFI_SSID, .password = EXAMPLE_WIFI_PASS, }, }; os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid); 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()); } static void wait_for_ip() { #ifdef CONFIG_EXAMPLE_IPV6 uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT; #else uint32_t bits = IPV4_GOTIP_BIT; #endif os_printf("Waiting for AP connection...\r\n"); xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); os_printf("Connected to AP"); } static void tcp_server_task(void *pvParameters) { char rx_buffer[2048]; char addr_str[128]; int addr_family; int ip_protocol; while (1) { #ifdef CONFIG_EXAMPLE_IPV4 struct sockaddr_in destAddr; destAddr.sin_addr.s_addr = htonl(INADDR_ANY); destAddr.sin_family = AF_INET; destAddr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 struct sockaddr_in6 destAddr; bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); destAddr.sin6_family = AF_INET6; destAddr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); if (listen_sock < 0) { os_printf("Unable to create socket: errno %d\r\n", errno); break; } os_printf("Socket created"); int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); if (err != 0) { os_printf("Socket unable to bind: errno %d\r\n", errno); break; } os_printf("Socket binded"); err = listen(listen_sock, 1); if (err != 0) { os_printf("Error occured during listen: errno %d\r\n", errno); break; } os_printf("Socket listening"); #ifdef CONFIG_EXAMPLE_IPV6 struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 #else struct sockaddr_in sourceAddr; #endif uint addrLen = sizeof(sourceAddr); int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); if (sock < 0) { os_printf("Unable to accept connection: errno %d\r\n", errno); break; } os_printf("Socket accepted"); while (1) { int len = recv(sock, rx_buffer, 2047, 0); // Error occured during receiving if (len < 0) { os_printf("recv failed: errno %d\r\n", errno); break; } // Connection closed else if (len == 0) { os_printf("Connection closed\r\n"); break; } // Data received else { #ifdef CONFIG_EXAMPLE_IPV6 // Get the sender's ip address as string if (sourceAddr.sin6_family == PF_INET) { inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); } else if (sourceAddr.sin6_family == PF_INET6) { inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); } #else inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); #endif rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string //os_printf("Received %d bytes from %s:\r\n", len, addr_str); // os_printf("%s", rx_buffer); int err = send(sock, rx_buffer, len, 0); if (err < 0) { os_printf("Error occured during sending: errno %d\r\n", errno); break; } } } if (sock != -1) { os_printf("Shutting down socket and restarting...\r\n"); shutdown(sock, 0); close(sock); shutdown(listen_sock, 0); close(listen_sock); vTaskDelay(5); } } vTaskDelete(NULL); } void app_main() { ESP_ERROR_CHECK(nvs_flash_init()); initialise_wifi(); wait_for_ip(); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); }