12. Wi-Fi
TCP Server in AP Mode
Verification method: After downloading the code, use your phone to search and connect to the Wi-Fi: LCKFB-ESP32, password: 12345678 Open the TCP debugging APP, set it as a client, with IP 192.168.4.1 and port 9527. The connection will be successful.
c
/* WiFi softAP 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 <stdlib.h>
#include <stdio.h>
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_event_loop.h"
#include "esp_err.h"
// #include "lwip/err.h"
// #include "lwip/sys.h"
#include "lwip/sockets.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.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 "LCKFB-ESP32"
#define EXAMPLE_ESP_WIFI_PASS "12345678"
//#define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_ESP_WIFI_CHANNEL
#define EXAMPLE_MAX_STA_CONN 5 // Maximum number of connections
#define TCP_PORT 9527 // Client listening port
#define WIFI_CONNECTED_BIT BIT0
static const char *TAG = "wifi softAP";
//socket
static int server_socket = 0; // Server socket
static struct sockaddr_in server_addr; // Server address
static struct sockaddr_in client_addr; // Client address
static unsigned int socklen = sizeof(client_addr); // Address length
static int connect_socket = 0; // Connection socket
bool g_rxtx_need_restart = false; // Reconnection flag after exception
EventGroupHandle_t tcp_event_group; // Wi-Fi established successfully semaphore
// Wi-Fi event
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
switch (event_id){
case WIFI_EVENT_AP_STACONNECTED: // AP mode - a STA connected successfully
// As an AP, a sta connected
// ESP_LOGI(TAG, "station:" MACSTR " join,AID=%d\n",MAC2STR(event->event_info.sta_connected.mac),event->event_info.sta_connected.aid);
// Set the event bit
xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
break;
case WIFI_EVENT_AP_STADISCONNECTED:// AP mode - a STA disconnected
// ESP_LOGI(TAG, "station:" MACSTR "leave,AID=%d\n",MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
// Re-establish the server
g_rxtx_need_restart = true;
xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT);
break;
default:
break;
}
}
void wifi_init_softap(void)
{
tcp_event_group = xEventGroupCreate();
//tcpip_adapter_init();
// Initialize the underlying TCP/IP stack
ESP_ERROR_CHECK(esp_netif_init());
// Create the default event loop
ESP_ERROR_CHECK(esp_event_loop_create_default());
// Create the default Wi-Fi AP. This API aborts on any initialization error.
esp_netif_create_default_wifi_ap();
// Wi-Fi stack configuration parameters passed to the esp_wifi_init call.
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
// Allocate resources for the Wi-Fi task
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// Register an instance of the event handler to the default loop.
// This function does the same as esp_event_handler_instance_register_with,
// except that it registers the handler to the default event loop.
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL));
wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID, // Wi-Fi account
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),// Wi-Fi account length
//.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_PASS,// Wi-Fi password
.max_connection = EXAMPLE_MAX_STA_CONN,// Maximum number of client connections
#ifdef CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT
.authmode = WIFI_AUTH_WPA3_PSK,
.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
#else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */
.authmode = WIFI_AUTH_WPA2_PSK,
#endif
.pmf_cfg = {
.required = true,
},
},
};
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
// Set the Wi-Fi working mode to AP mode
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
// Set the AP mode configuration
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
// Start Wi-Fi
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s ",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}
// Get the socket error code
int get_socket_error_code(int socket)
{
int result;
u32_t optlen = sizeof(int);
int err = getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen);
if (err == -1){
//WSAGetLastError();
ESP_LOGE(TAG, "socket error code:%d", err);
ESP_LOGE(TAG, "socket error code:%s", strerror(err));
return -1;
}
return result;
}
// Get the socket error reason
int show_socket_error_reason(const char *str, int socket)
{
int err = get_socket_error_code(socket);
if (err != 0){
ESP_LOGW(TAG, "%s socket error reason %d %s", str, err, strerror(err));
}
return err;
}
// Close the socket
void close_socket()
{
close(connect_socket);
close(server_socket);
}
// Receive data task
void recv_data(void *pvParameters)
{
int len = 0;
char databuff[1024];
while (1){
memset(databuff, 0x00, sizeof(databuff));// Clear the buffer
len = recv(connect_socket, databuff, sizeof(databuff), 0);// Read received data
g_rxtx_need_restart = false;
if (len > 0){
ESP_LOGI(TAG, "recvData: %s", databuff);// Print the received array
send(connect_socket, databuff, strlen(databuff), 0);// Echo the received data
//sendto(connect_socket, databuff , sizeof(databuff), 0, (struct sockaddr *) &remote_addr,sizeof(remote_addr));
}else{
show_socket_error_reason("recv_data", connect_socket);// Print error information
g_rxtx_need_restart = true;// Server fault, mark for reconnection
vTaskDelete(NULL);
}
}
close_socket();
g_rxtx_need_restart = true;// Mark for reconnection
vTaskDelete(NULL);
}
// Create a tcp server
esp_err_t create_tcp_server(bool isCreatServer)
{
// First time creating the server
if (isCreatServer){
ESP_LOGI(TAG, "server socket....,port=%d", TCP_PORT);
server_socket = socket(AF_INET, SOCK_STREAM, 0);// Create a new socket
if (server_socket < 0){
show_socket_error_reason("create_server", server_socket);
close(server_socket);// Close the new socket after failure, waiting for the next creation
return ESP_FAIL;
}
// Configure the new server socket parameters
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// bind: address binding
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
show_socket_error_reason("bind_server", server_socket);
close(server_socket);// Close the new socket after bind failure, waiting for the next creation
return ESP_FAIL;
}
}
// listen, next time, listen directly
if (listen(server_socket, 5) < 0){
show_socket_error_reason("listen_server", server_socket);
close(server_socket);// Close the new socket after listen failure, waiting for the next creation
return ESP_FAIL;
}
// accept, search the full connection queue
connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen);
if (connect_socket < 0){
show_socket_error_reason("accept_server", connect_socket);
close(server_socket);// Close the new socket after accept failure, waiting for the next creation
return ESP_FAIL;
}
ESP_LOGI(TAG, "tcp connection established!");
return ESP_OK;
}
// Establish a TCP connection and receive data from TCP
static void tcp_connect(void *pvParameters)
{
while (1){
g_rxtx_need_restart = false;
// Wait for the Wi-Fi connection semaphore, wait indefinitely
// Block and wait for one or more bits to be set in the previously created event group.
xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
// Start the TCP connection
ESP_LOGI(TAG, "start tcp connected");
TaskHandle_t tx_rx_task = NULL;
vTaskDelay(3000 / portTICK_PERIOD_MS);// Delay 3 seconds to prepare for creating the server
ESP_LOGI(TAG, "create tcp server");
int socket_ret = create_tcp_server(true);// Create the server
if (socket_ret == ESP_FAIL){// Creation failed
ESP_LOGI(TAG, "create tcp socket error,stop...");
continue;
}else{// Created successfully
ESP_LOGI(TAG, "create tcp socket succeed...");
// Create a tcp receive data task
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
ESP_LOGI(TAG, "Recv task create fail!");
}else{
ESP_LOGI(TAG, "Recv task create succeed!");
}
}
while (1){
vTaskDelay(3000 / portTICK_PERIOD_MS);
if (g_rxtx_need_restart){// Re-establish the server, same process as above
ESP_LOGI(TAG, "tcp server error,some client leave,restart...");
// Re-establish the server
if (ESP_FAIL != create_tcp_server(false)){
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
ESP_LOGE(TAG, "tcp server Recv task create fail!");
}else{
ESP_LOGI(TAG, "tcp server Recv task create succeed!");
g_rxtx_need_restart = false;// Re-establishment completed, clear the flag
}
}
}
}
}
vTaskDelete(NULL);
}
void app_main(void)
{
// Initialize FLASH
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);
// Create an AP
ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
wifi_init_softap();
// Create a new tcp connection task
xTaskCreate(&tcp_connect, "tcp_connect", 4096, NULL, 5, NULL);
while(1)
{
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
TCP Client in AP Mode
Verification method: After downloading the code, use your phone to search and connect to the Wi-Fi: LCKFB-ESP32, password: 12345678 Open the TCP debugging APP, set it as a server, with port 9527. Press the BOOT button on the development board, and the connection to the server will be successful.
c
/* WiFi softAP 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 <stdlib.h>
#include <stdio.h>
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_event_loop.h"
#include "esp_err.h"
// #include "lwip/err.h"
// #include "lwip/sys.h"
#include "lwip/sockets.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "driver/gpio.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 "LCKFB-ESP32"
#define EXAMPLE_ESP_WIFI_PASS "12345678"
//#define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_ESP_WIFI_CHANNEL
#define EXAMPLE_MAX_STA_CONN 5 // Maximum number of connections
#define TCP_PORT 9527 // Client listening port
#define WIFI_CONNECTED_BIT BIT0
static const char *TAG = "wifi softAP";
#define TCP_SERVER_ADRESS "192.168.4.2"
//socket
static int server_socket = 0; // Server socket
static struct sockaddr_in server_addr; // Server address
static struct sockaddr_in client_addr; // Client address
static unsigned int socklen = sizeof(client_addr); // Address length
static int connect_socket = 0; // Connection socket
bool g_rxtx_need_restart = false; // Reconnection flag after exception
EventGroupHandle_t tcp_event_group; // Wi-Fi established successfully semaphore
// Wi-Fi event
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
switch (event_id){
case WIFI_EVENT_AP_STACONNECTED: // AP mode - a STA connected successfully
// As an AP, a sta connected
// ESP_LOGI(TAG, "station:" MACSTR " join,AID=%d\n",MAC2STR(event->event_info.sta_connected.mac),event->event_info.sta_connected.aid);
// Set the event bit
xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
break;
case WIFI_EVENT_AP_STADISCONNECTED:// AP mode - a STA disconnected
// ESP_LOGI(TAG, "station:" MACSTR "leave,AID=%d\n",MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
// Re-establish the server
g_rxtx_need_restart = true;
xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT);
break;
default:
break;
}
}
void wifi_init_softap(void)
{
tcp_event_group = xEventGroupCreate();
//tcpip_adapter_init();
// Initialize the underlying TCP/IP stack
ESP_ERROR_CHECK(esp_netif_init());
// Create the default event loop
ESP_ERROR_CHECK(esp_event_loop_create_default());
// Create the default Wi-Fi AP. This API aborts on any initialization error.
esp_netif_create_default_wifi_ap();
// Wi-Fi stack configuration parameters passed to the esp_wifi_init call.
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
// Allocate resources for the Wi-Fi task
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// Register an instance of the event handler to the default loop.
// This function does the same as esp_event_handler_instance_register_with,
// except that it registers the handler to the default event loop.
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL));
wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID, // Wi-Fi account
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),// Wi-Fi account length
//.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_PASS,// Wi-Fi password
.max_connection = EXAMPLE_MAX_STA_CONN,// Maximum number of client connections
#ifdef CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT
.authmode = WIFI_AUTH_WPA3_PSK,
.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
#else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */
.authmode = WIFI_AUTH_WPA2_PSK,
#endif
.pmf_cfg = {
.required = true,
},
},
};
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
// Set the Wi-Fi working mode to AP mode
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
// Set the AP mode configuration
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
// Start Wi-Fi
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}
// Get the socket error code
int get_socket_error_code(int socket)
{
int result;
u32_t optlen = sizeof(int);
int err = getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen);
if (err == -1){
//WSAGetLastError();
ESP_LOGE(TAG, "socket error code:%d", err);
ESP_LOGE(TAG, "socket error code:%s", strerror(err));
return -1;
}
return result;
}
// Get the socket error reason
int show_socket_error_reason(const char *str, int socket)
{
int err = get_socket_error_code(socket);
if (err != 0){
ESP_LOGW(TAG, "%s socket error reason %d %s", str, err, strerror(err));
}
return err;
}
// Close the socket
void close_socket()
{
close(connect_socket);
close(server_socket);
}
// Receive data task
void recv_data(void *pvParameters)
{
int len = 0;
char databuff[1024];
while (1){
memset(databuff, 0x00, sizeof(databuff));// Clear the buffer
len = recv(connect_socket, databuff, sizeof(databuff), 0);// Read received data
g_rxtx_need_restart = false;
if (len > 0){
ESP_LOGI(TAG, "recvData: %s", databuff);// Print the received array
send(connect_socket, databuff, strlen(databuff), 0);// Echo the received data
//sendto(connect_socket, databuff , sizeof(databuff), 0, (struct sockaddr *) &remote_addr,sizeof(remote_addr));
}else{
show_socket_error_reason("recv_data", connect_socket);// Print error information
g_rxtx_need_restart = true;// Server fault, mark for reconnection
vTaskDelete(NULL);
}
}
close_socket();
g_rxtx_need_restart = true;// Mark for reconnection
vTaskDelete(NULL);
}
// Create a tcp client
esp_err_t create_tcp_client(void)
{
ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d",TCP_SERVER_ADRESS, TCP_PORT);
// Create a new socket
connect_socket = socket(AF_INET, SOCK_STREAM, 0);
if (connect_socket < 0){
show_socket_error_reason("create client", connect_socket);// Print error information
close(connect_socket);// Close the new socket after failure, waiting for the next creation
return ESP_FAIL;
}
// Configure the connection server information
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_PORT);
server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_ADRESS);
ESP_LOGI(TAG, "connectting server...");
// Connect to the server
if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
show_socket_error_reason("client connect", connect_socket);// Print error information
ESP_LOGE(TAG, "connect failed!");
// After connection failure, close the previously created socket, waiting for the next creation
close(connect_socket);
return ESP_FAIL;
}
ESP_LOGI(TAG, "connect success!");
return ESP_OK;
/*
// First time creating the server
if (isCreatServer){
ESP_LOGI(TAG, "server socket....,port=%d", TCP_PORT);
server_socket = socket(AF_INET, SOCK_STREAM, 0);// Create a new socket
if (server_socket < 0){
show_socket_error_reason("create_server", server_socket);
close(server_socket);// Close the new socket after failure, waiting for the next creation
return ESP_FAIL;
}
// Configure the new server socket parameters
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// bind: address binding
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
show_socket_error_reason("bind_server", server_socket);
close(server_socket);// Close the new socket after bind failure, waiting for the next creation
return ESP_FAIL;
}
}
// listen, next time, listen directly
if (listen(server_socket, 5) < 0){
show_socket_error_reason("listen_server", server_socket);
close(server_socket);// Close the new socket after listen failure, waiting for the next creation
return ESP_FAIL;
}
// accept, search the full connection queue
connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen);
if (connect_socket < 0){
show_socket_error_reason("accept_server", connect_socket);
close(server_socket);// Close the new socket after accept failure, waiting for the next creation
return ESP_FAIL;
}
ESP_LOGI(TAG, "tcp connection established!");
return ESP_OK;
*/
}
// Establish a TCP connection and receive data from TCP
static void tcp_connect(void *pvParameters)
{
while (1){
g_rxtx_need_restart = false;
// Wait for the Wi-Fi connection semaphore, wait indefinitely
// Block and wait for one or more bits to be set in the previously created event group.
xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
// Start the TCP connection
ESP_LOGI(TAG, "start tcp connected");
TaskHandle_t tx_rx_task = NULL;
vTaskDelay(3000 / portTICK_PERIOD_MS);// Delay 3 seconds to prepare for creating the server
ESP_LOGI(TAG, "create tcp server");
// Create the client
int socket_ret = create_tcp_client();
if (socket_ret == ESP_FAIL){// Creation failed
ESP_LOGI(TAG, "create tcp socket error,stop...");
continue;
}else{// Created successfully
ESP_LOGI(TAG, "create tcp socket succeed...");
// Create a tcp receive data task
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
ESP_LOGI(TAG, "Recv task create fail!");
}else{
ESP_LOGI(TAG, "Recv task create succeed!");
}
}
while (1){
vTaskDelay(3000 / portTICK_PERIOD_MS);
if (g_rxtx_need_restart){// Re-establish the server, same process as above
ESP_LOGI(TAG, "tcp server error,some client leave,restart...");
// Re-establish the server
if (ESP_FAIL != create_tcp_client()){
if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)){
ESP_LOGE(TAG, "tcp client Recv task create fail!");
}else{
ESP_LOGI(TAG, "tcp client Recv task create succeed!");
g_rxtx_need_restart = false;// Re-establishment completed, clear the flag
}
}
}
}
}
vTaskDelete(NULL);
}
void app_main(void)
{
// Initialize FLASH
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);
// Create an AP
ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
wifi_init_softap();
// Create a new tcp connection task
xTaskCreate(&tcp_connect, "tcp_connect", 4096, NULL, 5, NULL);
// Configure the GPIO structure
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_ANYEDGE; // Falling and rising edge trigger interrupt
io_conf.pin_bit_mask = 1 << 0; // Set the GPIO number
io_conf.mode = GPIO_MODE_INPUT; // Input mode
io_conf.pull_up_en = GPIO_PULLUP_ENABLE; // Enable port pull-up
gpio_config(&io_conf);
while(1)
{
vTaskDelay(500/portTICK_PERIOD_MS);
if(gpio_get_level(0)==0){
// Create a new tcp connection task
xTaskCreate(&tcp_connect, "tcp_connect", 4096, NULL, 5, NULL);
break;
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343