ESP-IDF TCP Socket Serial Bridge.

lrsimpson
Posts: 2
Joined: Mon Feb 14, 2022 8:15 am

ESP-IDF TCP Socket Serial Bridge.

Postby lrsimpson » Mon Feb 14, 2022 8:28 am

I am trying to recreate the Arduino wi-fi Serial bridge using BSD sockets in ESP-IDF. If anyone has a working example that would be amazing as so far my google searches have led me nowhere.

Code: Select all

/*
  WiFiTelnetToSerial - Example Transparent UART to Telnet Server for ESP32

  Copyright (c) 2017 Hristo Gochkov. All rights reserved.
  This file is part of the ESP32 WiFi library for Arduino environment.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti wifiMulti;

//how many clients should be able to telnet to this ESP32
#define MAX_SRV_CLIENTS 1
const char* ssid = "**********";
const char* password = "**********";

WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];

void setup() {
  Serial.begin(115200);
  Serial.println("\nConnecting");

  wifiMulti.addAP(ssid, password);
  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");

  Serial.println("Connecting Wifi ");
  for (int loops = 10; loops > 0; loops--) {
    if (wifiMulti.run() == WL_CONNECTED) {
      Serial.println("");
      Serial.print("WiFi connected ");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
      break;
    }
    else {
      Serial.println(loops);
      delay(1000);
    }
  }
  if (wifiMulti.run() != WL_CONNECTED) {
    Serial.println("WiFi connect failed");
    delay(1000);
    ESP.restart();
  }

  //start UART and the server
  Serial2.begin(9600);
  server.begin();
  server.setNoDelay(true);

  Serial.print("Ready! Use 'telnet ");
  Serial.print(WiFi.localIP());
  Serial.println(" 23' to connect");
}

void loop() {
  uint8_t i;
  if (wifiMulti.run() == WL_CONNECTED) {
    //check if there are any new clients
    if (server.hasClient()){
      for(i = 0; i < MAX_SRV_CLIENTS; i++){
        //find free/disconnected spot
        if (!serverClients[i] || !serverClients[i].connected()){
          if(serverClients[i]) serverClients[i].stop();
          serverClients[i] = server.available();
          if (!serverClients[i]) Serial.println("available broken");
          Serial.print("New client: ");
          Serial.print(i); Serial.print(' ');
          Serial.println(serverClients[i].remoteIP());
          break;
        }
      }
      if (i >= MAX_SRV_CLIENTS) {
        //no free/disconnected spot so reject
        server.available().stop();
      }
    }
    //check clients for data
    for(i = 0; i < MAX_SRV_CLIENTS; i++){
      if (serverClients[i] && serverClients[i].connected()){
        if(serverClients[i].available()){
          //get data from the telnet client and push it to the UART
          while(serverClients[i].available()) Serial2.write(serverClients[i].read());
        }
      }
      else {
        if (serverClients[i]) {
          serverClients[i].stop();
        }
      }
    }
    //check UART for data
    if(Serial2.available()){
      size_t len = Serial2.available();
      uint8_t sbuf[len];
      Serial2.readBytes(sbuf, len);
      //push UART data to all connected telnet clients
      for(i = 0; i < MAX_SRV_CLIENTS; i++){
        if (serverClients[i] && serverClients[i].connected()){
          serverClients[i].write(sbuf, len);
          delay(1);
        }
      }
    }
  }
  else {
    Serial.println("WiFi not connected!");
    for(i = 0; i < MAX_SRV_CLIENTS; i++) {
      if (serverClients[i]) serverClients[i].stop();
    }
    delay(1000);
  }
}


I have cobbled together the following code from TCP server example.

The problem with this code is that the Data read from the UART only seems to appear after data has been received by the server (aka recv called).

If anyone has any suggestions as to how to make it so that the UART data it written to the server immediately, it would be appreciated.

Cheers Laurence.

Code is below.

Code: Select all

/* WiFi station 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 <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include <stdio.h>

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>

/* The examples use WiFi configuration that you can set via project configuration menu

   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_ESP_WIFI_SSID      "xxxxx"
#define EXAMPLE_ESP_WIFI_PASS      "xxxxx"
#define EXAMPLE_ESP_MAXIMUM_RETRY  2
#define BUF_SIZE (1024)
#define UART_NUM_1 1

/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;

/* The event group allows multiple bits for each event, but we only care about two events:
 * - we are connected to the AP with an IP
 * - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static const char *TAG = "wifi station";

static int s_retry_num = 0;

#define PORT                        23
#define KEEPALIVE_IDLE              6
#define KEEPALIVE_INTERVAL          6
#define KEEPALIVE_COUNT             3



static void init_UART1(void) { //This setups UART 1 and gives it a baud rate of 115200 
    const int uart_num1 = UART_NUM_1;
    uart_config_t uart_config1 = {  //writing down the conditions of the uart. 
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .rx_flow_ctrl_thresh = 122,
    };
    // We won't use a buffer for sending data.
    uart_driver_install(uart_num1, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0); //starting UART1 with a rx and tx buffer of 2048 with no queue and no interrupt function.
    uart_param_config(uart_num1, &uart_config1); //setting the conditions of the uart according to config1
    uart_set_pin(uart_num1, 22, 23, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //Setup UART1 according to the default pin arrangement of ESP32 
}


static void do_retransmit(const int sock) //TCP ECHO effectively.
{
    int len;
	int length = 0; 
    char rx_buffer[128];
	char tx_buffer[128];
	const int uart_num1 = UART_NUM_1;
	    u_long non_blocking=1;
    int sendcnt=0;
	
	        while (1) {
            //send out
			ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num1, (size_t*)&length));
			uart_read_bytes(uart_num1, tx_buffer, length,0);
			int to_write = length;
            while (to_write > 0) {
                int written = send(sock, rx_buffer + (length - to_write), to_write, 0);
                if (written < 0) {
                    ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
                }
                to_write -= written;
            }
			
			write(sock, tx_buffer, length);
            //len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
			//if(len > 0){
		//	uart_write_bytes(uart_num1, rx_buffer, len);
			
		//	ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num1, (size_t*)&length));
		//	uart_read_bytes(uart_num1, tx_buffer, length,0);
		//	write(sock, tx_buffer, length);
		//	}			
}
}


static void tcp_server_task(void *pvParameters)
{
    char addr_str[128];
    int addr_family = (int)pvParameters;
    int ip_protocol = 0;
    int keepAlive = 1;
    int keepIdle = KEEPALIVE_IDLE;
    int keepInterval = KEEPALIVE_INTERVAL;
    int keepCount = KEEPALIVE_COUNT;
    struct sockaddr_storage dest_addr;

    if (addr_family == AF_INET) {
        struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
        dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
        dest_addr_ip4->sin_family = AF_INET;
        dest_addr_ip4->sin_port = htons(PORT);
        ip_protocol = IPPROTO_IP;
    }

    int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
    if (listen_sock < 0) {
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
        vTaskDelete(NULL);
        return;
    }
    int opt = 1;
    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    ESP_LOGI(TAG, "Socket created");

    int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (err != 0) {
        ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
        ESP_LOGE(TAG, "IPPROTO: %d", addr_family);
        goto CLEAN_UP;
    }
    ESP_LOGI(TAG, "Socket bound, port %d", PORT);

    err = listen(listen_sock, 1);
    if (err != 0) {
        ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
        goto CLEAN_UP;
    }

    while (1) {

        ESP_LOGI(TAG, "Socket listening");

        struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
        socklen_t addr_len = sizeof(source_addr);
        int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
        if (sock < 0) {
            ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
            break;
        }

        // Set tcp keepalive option
    //    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(int));
     //   setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepIdle, sizeof(int));
     //   setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(int));
	   int nodelay = 1;
        setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(int));
     //   setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keepCount, sizeof(int));
        // Convert ip address to string
        if (source_addr.ss_family == PF_INET) {
            inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
        }
        ESP_LOGI(TAG, "Socket accepted ip address: %s", addr_str);

        do_retransmit(sock);

		if (sock != -1) {
            ESP_LOGI(TAG, "Shutting down socket and restarting...");
            shutdown(sock, 0);
            close(sock);
        }
    }

CLEAN_UP:
    close(listen_sock);
    vTaskDelete(NULL);
}

static void 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) {
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } 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));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

void wifi_init_sta(void)
{
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());

    esp_netif_t *my_sta = esp_netif_create_default_wifi_sta();

    esp_netif_dhcpc_stop(my_sta);

    esp_netif_ip_info_t ip_info;

    IP4_ADDR(&ip_info.ip, 192, 168, 2, 220);
   	IP4_ADDR(&ip_info.gw, 192, 168, 2, 1);
   	IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);

    esp_netif_set_ip_info(my_sta, &ip_info);

    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, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_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, "wifi_init_sta finished.");

    /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
     * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);

    /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
     * happened. */
    if (bits & WIFI_CONNECTED_BIT) {
        ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    } else if (bits & WIFI_FAIL_BIT) {
        ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    } else {
        ESP_LOGE(TAG, "UNEXPECTED EVENT");
    }

    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
    vEventGroupDelete(s_wifi_event_group);
}


void app_main(void)
{
    //Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
	init_UART1();
    xTaskCreate(tcp_server_task, "tcp_server", 4096, (void*)AF_INET, 5, NULL);
}
Last edited by lrsimpson on Fri Feb 18, 2022 12:03 pm, edited 1 time in total.

lrsimpson
Posts: 2
Joined: Mon Feb 14, 2022 8:15 am

Re: ESP-IDF TCP Socket Serial Bridge.

Postby lrsimpson » Fri Feb 18, 2022 12:03 pm

Problem was, a blocking code and the fact the message apparently waits for a receive or send depending on if you set it up as a server or client.

this was solved through making the sockets non-blocking sorta like this..

Code: Select all

fcntl(socket, F_SETFL, O_NONBLOCK); 

and using the MSG_DONTWAIT as follows.

Code: Select all

recv(socket, rx_buffer, sizeof(rx_buffer) - 1, MSG_DONTWAIT);
send(socket, tx_buffer, length, MSG_DONTWAIT);

Full Code if you should want it is down below.

The code setups up a wifi
This code setups up a UART on pins 22 and 23, reads bytes at the UART and write (or sends) this information to the server.
The code also reads bytes at the server and writes this to the UART.


Code: Select all

/* WiFi station 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 <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include <stdio.h>

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>

/* The examples use WiFi configuration that you can set via project configuration menu

   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_ESP_WIFI_SSID      "xxxxx"
#define EXAMPLE_ESP_WIFI_PASS      "xxxxxx"
#define EXAMPLE_ESP_MAXIMUM_RETRY  2
#define BUF_SIZE (1024)
//#define UART_NUM_1 1

/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;

/* The event group allows multiple bits for each event, but we only care about two events:
 * - we are connected to the AP with an IP
 * - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static const char *TAG = "wifi station";

static int s_retry_num = 0;

#define PORT                        23
#define KEEPALIVE_IDLE              6
#define KEEPALIVE_INTERVAL          6
#define KEEPALIVE_COUNT             3


//struct sockaddr_storage source_addr;
struct sockaddr_in clientAddress;
struct sockaddr_in serverAddress;
int serverSocket; 
int socketstatus;
int connectstatus;
int len;
int length = 0; 
int clientSocket; 
char addr_str[128];
char rx_buffer[128];
char tx_buffer[128];
  const int uart_num1 = UART_NUM_1;

static void init_UART1(void) { //This setups UART 1 and gives it a baud rate of 115200 
    uart_config_t uart_config1 = {  //writing down the conditions of the uart. 
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .rx_flow_ctrl_thresh = 122,
    };
    // We won't use a buffer for sending data.
    uart_driver_install(uart_num1, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0); //starting UART1 with a rx and tx buffer of 2048 with no queue and no interrupt function.
    uart_param_config(uart_num1, &uart_config1); //setting the conditions of the uart according to config1
    uart_set_pin(uart_num1, 22, 23, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //Setup UART1 according to the default pin arrangement of ESP32 
}

bool hasclient() //so now we can receive messages from this part...
{
if(socketstatus >=0) { // already have client
return true; 
}
socklen_t clientAddressLength = sizeof(clientAddress);
socketstatus = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressLength); //if we accept a client socketstatus will be greater than 0! 
fcntl(socketstatus, F_SETFL, O_NONBLOCK);
int opt = 1; 
setsockopt(socketstatus, SOL_SOCKET, TCP_NODELAY, &opt, sizeof(int));
if(socketstatus >= 0){ //we actually accepted a client
return true;
}
return false; 
}



static void port1(void)
{
if(hasclient() == 1){
			ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num1, (size_t*)&length));
			uart_read_bytes(uart_num1, tx_buffer, length,20 / portTICK_RATE_MS);
			if(length > 0){
			length = send(socketstatus, tx_buffer, length, MSG_DONTWAIT);
			}		
			len = recv(socketstatus, rx_buffer, sizeof(rx_buffer) - 1, MSG_DONTWAIT);
			if(len < 0){
			//error
			}
			else if(len == 0){
			//connection closed
			}
			else{
			rx_buffer[len] = 0;
			uart_write_bytes(uart_num1, rx_buffer, len);
			//ESP_LOGI(TAG, "Received %d bytes: %s", len, rx_buffer);
			//if(connected() == 1){
		//	int to_write = len;
		//	if (to_write > 0) {
         //       int written = send(socketstatus, rx_buffer + (len - to_write), to_write, MSG_DONTWAIT);
          //      if (written < 0) {
           //         ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
            //    }
             //   to_write -= written;
           // }
        }

}
else{
        shutdown(socketstatus, 0);
        close(socketstatus);
		socketstatus = -1; 
}
}


//connectstatus = close(clientSocket); 
//socketstatus = close(serverSocket);
//}



static void loop_task(void *pvParameters)
{

const TickType_t xDelay = 1 / portTICK_PERIOD_MS;

     for( ;; )
     {
         // Task code goes here.
		 port1(); 
		 vTaskDelay( xDelay );
     }

//vTaskDelete(NULL);
}

static void init_server(void)
{
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);		//Grabs connected ip address which is set by the wifi_init_sta
serverAddress.sin_port = htons(PORT);					//Sets port of tcp socket PORT is current set to 23.
	
serverSocket = socket(AF_INET, SOCK_STREAM, 0); //initialize tcp socket AF_INET refers to IPV4 addresses and SOCK_STREAM saids initiate socket as tcp socket. 
if(serverSocket < 0){
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
		close(serverSocket);
}
	int opt = 1;
	setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
	setsockopt(serverSocket, SOL_SOCKET, TCP_NODELAY, &opt, sizeof(int));
	ESP_LOGI(TAG, "Socket created");
	
	 int err = bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
    if (err != 0) {
        ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
        close(serverSocket);
    }
    ESP_LOGI(TAG, "Socket bound, port %d", PORT);

    err = listen(serverSocket, 1);
    if (err != 0) {
        ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
        close(serverSocket);		
    }
	  fcntl(serverSocket, F_SETFL, O_NONBLOCK);
	  socketstatus = -1;
	  connectstatus = -1;
}

static void 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) {
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } 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));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

void wifi_init_sta(void)
{
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());

    esp_netif_t *my_sta = esp_netif_create_default_wifi_sta();

    esp_netif_dhcpc_stop(my_sta);

    esp_netif_ip_info_t ip_info;

    IP4_ADDR(&ip_info.ip, 192, 168, 2, 220);
   	IP4_ADDR(&ip_info.gw, 192, 168, 2, 1);
   	IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);

    esp_netif_set_ip_info(my_sta, &ip_info);

    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, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_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, "wifi_init_sta finished.");

    /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
     * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);

    /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
     * happened. */
    if (bits & WIFI_CONNECTED_BIT) {
        ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    } else if (bits & WIFI_FAIL_BIT) {
        ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    } else {
        ESP_LOGE(TAG, "UNEXPECTED EVENT");
    }

    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
    vEventGroupDelete(s_wifi_event_group);
}


void app_main(void)
{
    //Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
	init_UART1();
    wifi_init_sta(); //wi-fi Configuration.
	init_server(); //Initial server configuration. 
    xTaskCreate(loop_task, "loop_task", 65535, (void*)AF_INET, 1, NULL);
}

mxAmir
Posts: 1
Joined: Tue Oct 25, 2022 4:38 pm

Re: ESP-IDF TCP Socket Serial Bridge.

Postby mxAmir » Tue Oct 25, 2022 4:54 pm

Nice! it works very cool :D , except, when I try to reconnect I can´t see info any more :| , added this to your code:
  1. ...
  2. static void port1(void)
  3. {
  4.    if(hasclient() == 1){
  5.    ...
  6.       else if(len == 0){
  7.             //connection closed, closing the socket and wating for new connection
  8.             shutdown(socketstatus, 0);
  9.             close(socketstatus);
  10.             socketstatus = -1;
  11.             }
  12.    ...
  13. }
  14. ...

The reason is I got 'socketstatus = 58' at connection and remains '58' when terminal on my device is closed, making it to cicle as if 'hasclient' was always true.

Who is online

Users browsing this forum: snutw_ and 117 guests