diff --git a/examples/performance/tcp_perf/main/Kconfig.projbuild b/examples/performance/tcp_perf/main/Kconfig.projbuild index 92bf8387f..7c95b49bc 100644 --- a/examples/performance/tcp_perf/main/Kconfig.projbuild +++ b/examples/performance/tcp_perf/main/Kconfig.projbuild @@ -103,6 +103,7 @@ config TCP_PERF_SERVER_PORT config TCP_PERF_SERVER_IP string "TCP server ip" + depends on TCP_PERF_ESP_IS_CLIENT default "192.168.4.1" help IP of TCP server. diff --git a/examples/performance/tcp_perf/main/tcp_main.c b/examples/performance/tcp_perf/main/tcp_main.c index fbb65c0f0..bb86700a7 100644 --- a/examples/performance/tcp_perf/main/tcp_main.c +++ b/examples/performance/tcp_perf/main/tcp_main.c @@ -1,3 +1,11 @@ +/* tcp_perf 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. +*/ /* @@ -22,6 +30,7 @@ step3: #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_err.h" @@ -32,63 +41,62 @@ step3: //this task establish a TCP connection and receive data from TCP static void tcp_conn(void *pvParameters) { - ESP_LOGI(TAG, "task tcp_conn start."); + ESP_LOGI(TAG, "task tcp_conn."); /*wating for connecting to AP*/ - do - { - vTaskDelay(100); - } - while (!connectedflag); + xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT,false, true, portMAX_DELAY); + ESP_LOGI(TAG, "sta has connected to ap."); /*create tcp socket*/ int socket_ret; -#if ESP_TCP_MODE_SERVER +#if EXAMPLE_ESP_TCP_MODE_SERVER + ESP_LOGI(TAG, "tcp_server will start after 3s..."); vTaskDelay(3000 / portTICK_RATE_MS); ESP_LOGI(TAG, "create_tcp_server."); socket_ret=create_tcp_server(); -#else /*ESP_TCP_MODE_SERVER*/ +#else /*EXAMPLE_ESP_TCP_MODE_SERVER*/ + ESP_LOGI(TAG, "tcp_client will start after 20s..."); vTaskDelay(20000 / portTICK_RATE_MS); ESP_LOGI(TAG, "create_tcp_client."); socket_ret = create_tcp_client(); #endif - if(ESP_FAIL == socket_ret) { + if(socket_ret == ESP_FAIL) { ESP_LOGI(TAG, "create tcp socket error,stop."); vTaskDelete(NULL); } /*create a task to tx/rx data*/ TaskHandle_t tx_rx_task; -#if ESP_TCP_PERF_TX +#if EXAMPLE_ESP_TCP_PERF_TX xTaskCreate(&send_data, "send_data", 4096, NULL, 4, &tx_rx_task); -#else /*ESP_TCP_PERF_TX*/ +#else /*EXAMPLE_ESP_TCP_PERF_TX*/ xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task); #endif - int pps; + int bps; while (1) { total_data = 0; vTaskDelay(3000 / portTICK_RATE_MS);//every 3s - pps = total_data / 3; + bps = total_data / 3; if (total_data <= 0) { - int err_ret = check_socket_error_code(); - if (err_ret == ECONNRESET) { - ESP_LOGI(TAG, "disconnected... stop."); + int err_ret = check_working_socket(); + if (err_ret == ECONNRESET || ECONNABORTED) { + ESP_LOGW(TAG, "tcp disconnected... stop.\n"); break; } } -#if ESP_TCP_PERF_TX - ESP_LOGI(TAG, "tcp send %d byte per sec!", pps); -#if ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX + ESP_LOGI(TAG, "tcp send %d byte per sec!", bps); +#if EXAMPLE_ESP_TCP_DELAY_INFO ESP_LOGI(TAG, "tcp send packet total:%d succeed:%d failed:%d\n" "time(ms):0-30:%d 30-100:%d 100-300:%d 300-1000:%d 1000+:%d\n", total_pack, send_success, send_fail, delay_classify[0], delay_classify[1], delay_classify[2], delay_classify[3], delay_classify[4]); -#endif /*ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_DELAY_INFO*/ #else - ESP_LOGI(TAG, "tcp recv %d byte per sec!\n", pps); -#endif /*ESP_TCP_PERF_TX*/ + ESP_LOGI(TAG, "tcp recv %d byte per sec!\n", bps); +#endif /*EXAMPLE_ESP_TCP_PERF_TX*/ } close_socket(); vTaskDelete(tx_rx_task); @@ -99,12 +107,12 @@ static void tcp_conn(void *pvParameters) void app_main(void) { -#if ESP_WIFI_MODE_AP - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP\n"); +#if EXAMPLE_ESP_WIFI_MODE_AP + ESP_LOGI(TAG, "EXAMPLE_ESP_WIFI_MODE_AP"); wifi_init_softap(); -#else /*ESP_WIFI_MODE_AP*/ - ESP_LOGI(TAG, "ESP_WIFI_MODE_STA\n"); +#else + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); -#endif +#endif /*EXAMPLE_ESP_WIFI_MODE_AP*/ xTaskCreate(&tcp_conn, "tcp_conn", 4096, NULL, 5, NULL); } diff --git a/examples/performance/tcp_perf/main/tcp_perf.c b/examples/performance/tcp_perf/main/tcp_perf.c index 0b8447ee9..d0c817147 100644 --- a/examples/performance/tcp_perf/main/tcp_perf.c +++ b/examples/performance/tcp_perf/main/tcp_perf.c @@ -1,21 +1,17 @@ -// Copyright 2013-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* tcp_perf 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_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" @@ -23,6 +19,10 @@ #include "tcp_perf.h" + +/* FreeRTOS event group to signal when we are connected to wifi */ +EventGroupHandle_t tcp_event_group; + /*socket*/ static int server_socket = 0; static struct sockaddr_in server_addr; @@ -30,17 +30,18 @@ static struct sockaddr_in client_addr; static unsigned int socklen = sizeof(client_addr); static int connect_socket = 0; -int connectedflag = 0; int total_data = 0; -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO int total_pack = 0; int send_success = 0; int send_fail = 0; int delay_classify[5] = { 0 }; -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ + + static esp_err_t event_handler(void *ctx, system_event_t *event) @@ -51,26 +52,26 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) break; case SYSTEM_EVENT_STA_DISCONNECTED: esp_wifi_connect(); + xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_STA_CONNECTED: break; case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "event_handler:SYSTEM_EVENT_STA_GOT_IP!"); ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - connectedflag = 1; + xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_AP_STACONNECTED: ESP_LOGI(TAG, "station:"MACSTR" join,AID=%d\n", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid); - connectedflag = 1; + xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_AP_STADISCONNECTED: ESP_LOGI(TAG, "station:"MACSTR"leave,AID=%d\n", MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid); - connectedflag = 0; + xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT); break; default: break; @@ -82,33 +83,33 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) void send_data(void *pvParameters) { int len = 0; - char databuff[DEFAULT_PKTSIZE]; - memset(databuff, PACK_BYTE_IS, DEFAULT_PKTSIZE); + char databuff[EXAMPLE_DEFAULT_PKTSIZE]; + memset(databuff, EXAMPLE_PACK_BYTE_IS, EXAMPLE_DEFAULT_PKTSIZE); vTaskDelay(100/portTICK_RATE_MS); ESP_LOGI(TAG, "start sending..."); -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO //delaytime struct timeval tv_start; struct timeval tv_finish; unsigned long send_delay_ms; -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ while(1) { -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO total_pack++; gettimeofday(&tv_start, NULL); -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ //send function - len = send(connect_socket, databuff, DEFAULT_PKTSIZE, 0); + len = send(connect_socket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0); -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO gettimeofday(&tv_finish, NULL); -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ if(len > 0) { total_data += len; -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO send_success++; send_delay_ms = (tv_finish.tv_sec - tv_start.tv_sec) * 1000 + (tv_finish.tv_usec - tv_start.tv_usec) / 1000; @@ -122,37 +123,34 @@ void send_data(void *pvParameters) delay_classify[3]++; else delay_classify[4]++; -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ - }/*if(len > 0)*/ - else { + } else { -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO send_fail++; -#endif /*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ - - /*Most of the error code will be send window full. - *So, for faster sending,don't show error code. - *if it can't work as expectations,unnote the two lines here. - **/ - //show_socket_error_code(connect_socket); - //vTaskDelay(500/portTICK_RATE_MS); - } +#endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ + + if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { + show_socket_error_reason(connect_socket); + } + } /*if(len > 0)*/ } } //receive data void recv_data(void *pvParameters) { int len = 0; - char databuff[DEFAULT_PKTSIZE]; + char databuff[EXAMPLE_DEFAULT_PKTSIZE]; while (1) { - len = recv(connect_socket, databuff, DEFAULT_PKTSIZE, 0); + len = recv(connect_socket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0); if (len > 0) { total_data += len; - } - else { - show_socket_error_code(connect_socket); - vTaskDelay(500 / portTICK_RATE_MS); + } else { + if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { + show_socket_error_reason(connect_socket); + } + vTaskDelay(100 / portTICK_RATE_MS); } } } @@ -161,28 +159,28 @@ void recv_data(void *pvParameters) //use this esp32 as a tcp server. return ESP_OK:success ESP_FAIL:error esp_err_t create_tcp_server() { - ESP_LOGI(TAG, "server socket....port=%d\n", DEFAULT_PORT); + ESP_LOGI(TAG, "server socket....port=%d\n", EXAMPLE_DEFAULT_PORT); server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket < 0) { - show_socket_error_code(server_socket); + show_socket_error_reason(server_socket); return ESP_FAIL; } server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(DEFAULT_PORT); + server_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { - show_socket_error_code(server_socket); + show_socket_error_reason(server_socket); close(server_socket); return ESP_FAIL; } if (listen(server_socket, 5) < 0) { - show_socket_error_code(server_socket); + show_socket_error_reason(server_socket); close(server_socket); return ESP_FAIL; } connect_socket = accept(server_socket, (struct sockaddr*)&client_addr, &socklen); if (connect_socket<0) { - show_socket_error_code(connect_socket); + show_socket_error_reason(connect_socket); close(server_socket); return ESP_FAIL; } @@ -194,18 +192,18 @@ esp_err_t create_tcp_server() esp_err_t create_tcp_client() { ESP_LOGI(TAG, "client socket....serverip:port=%s:%d\n", - DEFAULT_SERVER_IP, DEFAULT_PORT); + EXAMPLE_DEFAULT_SERVER_IP, EXAMPLE_DEFAULT_PORT); connect_socket = socket(AF_INET, SOCK_STREAM, 0); if (connect_socket < 0) { - show_socket_error_code(connect_socket); + show_socket_error_reason(connect_socket); return ESP_FAIL; } server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(DEFAULT_PORT); - server_addr.sin_addr.s_addr = inet_addr(DEFAULT_SERVER_IP); + server_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT); + server_addr.sin_addr.s_addr = inet_addr(EXAMPLE_DEFAULT_SERVER_IP); ESP_LOGI(TAG, "connecting to server..."); if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - show_socket_error_code(connect_socket); + show_socket_error_reason(connect_socket); return ESP_FAIL; } ESP_LOGI(TAG, "connect to server success!"); @@ -215,6 +213,8 @@ esp_err_t create_tcp_client() //wifi_init_sta void wifi_init_sta() { + tcp_event_group = xEventGroupCreate(); + tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); @@ -222,8 +222,8 @@ void wifi_init_sta() ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .sta = { - .ssid = DEFAULT_SSID, - .password = DEFAULT_PWD + .ssid = EXAMPLE_DEFAULT_SSID, + .password = EXAMPLE_DEFAULT_PWD }, }; @@ -233,11 +233,13 @@ void wifi_init_sta() ESP_LOGI(TAG, "wifi_init_sta finished."); ESP_LOGI(TAG, "connect to ap SSID:%s password:%s \n", - DEFAULT_SSID,DEFAULT_PWD); + EXAMPLE_DEFAULT_SSID,EXAMPLE_DEFAULT_PWD); } //wifi_init_softap void wifi_init_softap() { + tcp_event_group = xEventGroupCreate(); + tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); @@ -245,14 +247,14 @@ void wifi_init_softap() ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .ap = { - .ssid = DEFAULT_SSID, + .ssid = EXAMPLE_DEFAULT_SSID, .ssid_len = 0, - .max_connection=MAX_STA_CONN, - .password = DEFAULT_PWD, + .max_connection=EXAMPLE_MAX_STA_CONN, + .password = EXAMPLE_DEFAULT_PWD, .authmode = WIFI_AUTH_WPA_WPA2_PSK }, }; - if (strlen(DEFAULT_PWD) ==0) { + if (strlen(EXAMPLE_DEFAULT_PWD) ==0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } @@ -261,71 +263,48 @@ void wifi_init_softap() ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s \n", - DEFAULT_SSID, DEFAULT_PWD); + EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD); } -char* tcpip_get_reason(int err) -{ - switch (err) { - case 0: - return "reason: other reason"; - case ENOMEM: - return "reason: out of memory"; - case ENOBUFS: - return "reason: buffer error"; - case EWOULDBLOCK: - return "reason: timeout, try again"; - case EHOSTUNREACH: - return "reason: routing problem"; - case EINPROGRESS: - return "reason: operation in progress"; - case EINVAL: - return "reason: invalid value"; - case EADDRINUSE: - return "reason: address in use"; - case EALREADY: - return "reason: conn already connected"; - case EISCONN: - return "reason: conn already established"; - case ECONNABORTED: - return "reason: connection aborted"; - case ECONNRESET: - return "reason: connection is reset"; - case ENOTCONN: - return "reason: connection closed"; - case EIO: - return "reason: invalid argument"; - case -1: - return "reason: low level netif error"; - default: - return "reason not found"; - } -} - -int show_socket_error_code(int socket) +int get_socket_error_code(int socket) { int result; u32_t optlen = sizeof(int); - getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen); - ESP_LOGI(TAG, "socket error %d reason: %s", result, tcpip_get_reason(result)); + if(getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen) == -1) { + ESP_LOGE(TAG, "getsockopt failed"); + return -1; + } return result; } -int check_socket_error_code() +int show_socket_error_reason(int socket) +{ + int err = get_socket_error_code(socket); + ESP_LOGW(TAG, "socket error %d %s", err, strerror(err)); + return err; +} + +int check_working_socket() { int ret; -#if ESP_TCP_MODE_SERVER - ESP_LOGI(TAG, "check server_socket"); - ret = show_socket_error_code(server_socket); +#if EXAMPLE_ESP_TCP_MODE_SERVER + ESP_LOGD(TAG, "check server_socket"); + ret = get_socket_error_code(server_socket); + if(ret != 0) { + ESP_LOGW(TAG, "server socket error %d %s", ret, strerror(ret)); + } if(ret == ECONNRESET) return ret; #endif - ESP_LOGI(TAG, "check connect_socket"); - ret = show_socket_error_code(connect_socket); - if(ret == ECONNRESET) + ESP_LOGD(TAG, "check connect_socket"); + ret = get_socket_error_code(connect_socket); + if(ret != 0) { + ESP_LOGW(TAG, "connect socket error %d %s", ret, strerror(ret)); + } + if(ret != 0) return ret; return 0; } diff --git a/examples/performance/tcp_perf/main/tcp_perf.h b/examples/performance/tcp_perf/main/tcp_perf.h index e29215b5b..2280dc8f4 100644 --- a/examples/performance/tcp_perf/main/tcp_perf.h +++ b/examples/performance/tcp_perf/main/tcp_perf.h @@ -1,3 +1,13 @@ +/* tcp_perf 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. +*/ + + #ifndef __TCP_PERF_H__ #define __TCP_PERF_H__ @@ -7,33 +17,43 @@ extern "C" { #endif -/*AP info and tcp_server info*/ -#define DEFAULT_SSID CONFIG_TCP_PERF_WIFI_SSID -#define DEFAULT_PWD CONFIG_TCP_PERF_WIFI_PASSWORD -#define DEFAULT_PORT CONFIG_TCP_PERF_SERVER_PORT -#define DEFAULT_SERVER_IP CONFIG_TCP_PERF_SERVER_IP -#define DEFAULT_PKTSIZE CONFIG_TCP_PERF_PKT_SIZE -#define MAX_STA_CONN 1 //how many sta can be connected(AP mode) + /*test options*/ -#define ESP_WIFI_MODE_AP CONFIG_TCP_PERF_WIFI_MODE_AP //TRUE:AP FALSE:STA -#define ESP_TCP_MODE_SERVER CONFIG_TCP_PERF_SERVER //TRUE:server FALSE:client -#define ESP_TCP_PERF_TX CONFIG_TCP_PERF_TX //TRUE:send FALSE:receive -#define ESP_TCP_DELAY_INFO CONFIG_TCP_PERF_DELAY_DEBUG //TRUE:show delay time info +#define EXAMPLE_ESP_WIFI_MODE_AP CONFIG_TCP_PERF_WIFI_MODE_AP //TRUE:AP FALSE:STA +#define EXAMPLE_ESP_TCP_MODE_SERVER CONFIG_TCP_PERF_SERVER //TRUE:server FALSE:client +#define EXAMPLE_ESP_TCP_PERF_TX CONFIG_TCP_PERF_TX //TRUE:send FALSE:receive +#define EXAMPLE_ESP_TCP_DELAY_INFO CONFIG_TCP_PERF_DELAY_DEBUG //TRUE:show delay time info + +/*AP info and tcp_server info*/ +#define EXAMPLE_DEFAULT_SSID CONFIG_TCP_PERF_WIFI_SSID +#define EXAMPLE_DEFAULT_PWD CONFIG_TCP_PERF_WIFI_PASSWORD +#define EXAMPLE_DEFAULT_PORT CONFIG_TCP_PERF_SERVER_PORT +#define EXAMPLE_DEFAULT_PKTSIZE CONFIG_TCP_PERF_PKT_SIZE +#define EXAMPLE_MAX_STA_CONN 1 //how many sta can be connected(AP mode) + +#ifdef CONFIG_TCP_PERF_SERVER_IP +#define EXAMPLE_DEFAULT_SERVER_IP CONFIG_TCP_PERF_SERVER_IP +#else +#define EXAMPLE_DEFAULT_SERVER_IP "192.168.4.1" +#endif /*CONFIG_TCP_PERF_SERVER_IP*/ -#define PACK_BYTE_IS 97 //'a' + +#define EXAMPLE_PACK_BYTE_IS 97 //'a' #define TAG "tcp_perf:" +/* FreeRTOS event group to signal when we are connected to wifi*/ +extern EventGroupHandle_t tcp_event_group; +#define WIFI_CONNECTED_BIT BIT0 -extern int connectedflag; extern int total_data; -#if ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO +#if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO extern int total_pack; extern int send_success; extern int send_fail; extern int delay_classify[5]; -#endif/*ESP_TCP_PERF_TX && ESP_TCP_DELAY_INFO*/ +#endif/*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/ //using esp as station @@ -54,11 +74,14 @@ void recv_data(void *pvParameters); //close all socket void close_socket(); +//get socket error code. return: error code +int get_socket_error_code(int socket); + //show socket error code. return: error code -int show_socket_error_code(int socket); +int show_socket_error_reason(int socket); //check working socket -int check_socket_error_code(); +int check_working_socket(); #ifdef __cplusplus diff --git a/examples/performance/udp_perf/main/Kconfig.projbuild b/examples/performance/udp_perf/main/Kconfig.projbuild index 72d40cb98..81ab39589 100644 --- a/examples/performance/udp_perf/main/Kconfig.projbuild +++ b/examples/performance/udp_perf/main/Kconfig.projbuild @@ -78,34 +78,35 @@ config UDP_PERF_TX config UDP_PERF_WIFI_SSID string "WiFi SSID" - default "esp_wifi_test1" - help - SSID (network name) for the example to connect to. + default "esp_wifi_test1" + help + SSID (network name) for the example to connect to. config UDP_PERF_WIFI_PASSWORD string "WiFi Password" - default "1234567890" - help - WiFi password (WPA or WPA2) for the example to use. + default "1234567890" + help + WiFi password (WPA or WPA2) for the example to use. config UDP_PERF_SERVER_PORT int "UDP server port" - default 4567 - help - Which will the udp server use. + default 4567 + help + Which will the udp server use. config UDP_PERF_SERVER_IP string "UDP server ip" - default "192.168.4.1" - help - IP of UDP server. + depends on UDP_PERF_ESP_IS_CLIENT + default "192.168.4.1" + help + IP of UDP server. - Ignore in UDP server. + Ignore in UDP server. config UDP_PERF_PKT_SIZE int "Size of UDP packet" - default 1460 - help - the data send&recv packet size. + default 1460 + help + the data send&recv packet size. endmenu diff --git a/examples/performance/udp_perf/main/udp_main.c b/examples/performance/udp_perf/main/udp_main.c index 60f59e9b3..d4d8b1fa9 100644 --- a/examples/performance/udp_perf/main/udp_main.c +++ b/examples/performance/udp_perf/main/udp_main.c @@ -1,3 +1,13 @@ +/* udp_perf 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. +*/ + + /* @@ -20,8 +30,10 @@ step3: */ +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_err.h" @@ -33,26 +45,24 @@ static void udp_conn(void *pvParameters) { ESP_LOGI(TAG, "task udp_conn start."); /*wating for connecting to AP*/ - do - { - vTaskDelay(100); - } - while (!connectedflag); + xEventGroupWaitBits(udp_event_group, WIFI_CONNECTED_BIT,false, true, portMAX_DELAY); ESP_LOGI(TAG, "sta has connected to ap."); /*create udp socket*/ int socket_ret; -#if ESP_UDP_MODE_SERVER +#if EXAMPLE_ESP_UDP_MODE_SERVER + ESP_LOGI(TAG, "create udp server after 3s..."); vTaskDelay(3000 / portTICK_RATE_MS); ESP_LOGI(TAG, "create_udp_server."); socket_ret=create_udp_server(); -#else /*ESP_UDP_MODE_SERVER*/ +#else /*EXAMPLE_ESP_UDP_MODE_SERVER*/ + ESP_LOGI(TAG, "create udp client after 20s..."); vTaskDelay(20000 / portTICK_RATE_MS); ESP_LOGI(TAG, "create_udp_client."); socket_ret = create_udp_client(); #endif - if(ESP_FAIL == socket_ret) { + if(socket_ret == ESP_FAIL) { ESP_LOGI(TAG, "create udp socket error,stop."); vTaskDelete(NULL); } @@ -61,17 +71,27 @@ static void udp_conn(void *pvParameters) TaskHandle_t tx_rx_task; xTaskCreate(&send_recv_data, "send_recv_data", 4096, NULL, 4, &tx_rx_task); - int pps; + /*waiting udp connected success*/ + xEventGroupWaitBits(udp_event_group, UDP_CONNCETED_SUCCESS,false, true, portMAX_DELAY); + int bps; while (1) { total_data = 0; vTaskDelay(3000 / portTICK_RATE_MS);//every 3s - pps = total_data / 3; + bps = total_data / 3; -#if ESP_UDP_PERF_TX - ESP_LOGI(TAG, "udp send %d byte per sec! total pack: %d \n", pps, success_pack); + if (total_data <= 0) { + int err_ret = check_connected_socket(); + if (err_ret == -1) { //-1 reason: low level netif error + ESP_LOGW(TAG, "udp send & recv stop.\n"); + break; + } + } + +#if EXAMPLE_ESP_UDP_PERF_TX + ESP_LOGI(TAG, "udp send %d byte per sec! total pack: %d \n", bps, success_pack); #else - ESP_LOGI(TAG, "udp recv %d byte per sec! total pack: %d \n", pps, success_pack); -#endif /*ESP_UDP_PERF_TX*/ + ESP_LOGI(TAG, "udp recv %d byte per sec! total pack: %d \n", bps, success_pack); +#endif /*EXAMPLE_ESP_UDP_PERF_TX*/ } close_socket(); vTaskDelete(tx_rx_task); @@ -82,11 +102,11 @@ static void udp_conn(void *pvParameters) void app_main(void) { -#if ESP_WIFI_MODE_AP - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP\n"); +#if EXAMPLE_ESP_WIFI_MODE_AP + ESP_LOGI(TAG, "EXAMPLE_ESP_WIFI_MODE_AP"); wifi_init_softap(); -#else /*ESP_WIFI_MODE_AP*/ - ESP_LOGI(TAG, "ESP_WIFI_MODE_STA\n"); +#else /*EXAMPLE_ESP_WIFI_MODE_AP*/ + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); #endif xTaskCreate(&udp_conn, "udp_conn", 4096, NULL, 5, NULL); diff --git a/examples/performance/udp_perf/main/udp_perf.c b/examples/performance/udp_perf/main/udp_perf.c index 22a55ad90..694494624 100644 --- a/examples/performance/udp_perf/main/udp_perf.c +++ b/examples/performance/udp_perf/main/udp_perf.c @@ -1,21 +1,17 @@ -// Copyright 2013-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* udp_perf 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_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" @@ -24,13 +20,15 @@ #include "udp_perf.h" +/* FreeRTOS event group to signal when we are connected to WiFi and ready to start UDP test*/ +EventGroupHandle_t udp_event_group; + static int mysocket; static struct sockaddr_in remote_addr; static unsigned int socklen; -int connectedflag = 0; int total_data = 0; int success_pack = 0; @@ -43,6 +41,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) break; case SYSTEM_EVENT_STA_DISCONNECTED: esp_wifi_connect(); + xEventGroupClearBits(udp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_STA_CONNECTED: break; @@ -50,18 +49,19 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGI(TAG, "event_handler:SYSTEM_EVENT_STA_GOT_IP!"); ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - connectedflag=1; + xEventGroupSetBits(udp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_AP_STACONNECTED: ESP_LOGI(TAG, "station:"MACSTR" join,AID=%d\n", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid); - connectedflag=1; + xEventGroupSetBits(udp_event_group, WIFI_CONNECTED_BIT); break; case SYSTEM_EVENT_AP_STADISCONNECTED: ESP_LOGI(TAG, "station:"MACSTR"leave,AID=%d\n", MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid); + xEventGroupClearBits(udp_event_group, WIFI_CONNECTED_BIT); break; default: break; @@ -73,6 +73,8 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) //wifi_init_sta void wifi_init_sta() { + udp_event_group = xEventGroupCreate(); + tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); @@ -80,8 +82,8 @@ void wifi_init_sta() ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .sta = { - .ssid = DEFAULT_SSID, - .password = DEFAULT_PWD + .ssid = EXAMPLE_DEFAULT_SSID, + .password = EXAMPLE_DEFAULT_PWD }, }; @@ -91,11 +93,13 @@ void wifi_init_sta() ESP_LOGI(TAG, "wifi_init_sta finished."); ESP_LOGI(TAG, "connect to ap SSID:%s password:%s \n", - DEFAULT_SSID,DEFAULT_PWD); + EXAMPLE_DEFAULT_SSID,EXAMPLE_DEFAULT_PWD); } //wifi_init_softap void wifi_init_softap() { + udp_event_group = xEventGroupCreate(); + tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); @@ -103,14 +107,14 @@ void wifi_init_softap() ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .ap = { - .ssid = DEFAULT_SSID, + .ssid = EXAMPLE_DEFAULT_SSID, .ssid_len=0, - .max_connection=MAX_STA_CONN, - .password = DEFAULT_PWD, + .max_connection=EXAMPLE_MAX_STA_CONN, + .password = EXAMPLE_DEFAULT_PWD, .authmode=WIFI_AUTH_WPA_WPA2_PSK }, }; - if (strlen(DEFAULT_PWD) ==0) { + if (strlen(EXAMPLE_DEFAULT_PWD) ==0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } @@ -119,24 +123,24 @@ void wifi_init_softap() ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s \n", - DEFAULT_SSID, DEFAULT_PWD); + EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD); } //create a udp server socket. return ESP_OK:success ESP_FAIL:error esp_err_t create_udp_server() { - ESP_LOGI(TAG, "create_udp_server()"); + ESP_LOGI(TAG, "create_udp_server() port:%d", EXAMPLE_DEFAULT_PORT); mysocket = socket(AF_INET, SOCK_DGRAM, 0); if (mysocket < 0) { - show_socket_error_code(mysocket); + show_socket_error_reason(mysocket); return ESP_FAIL; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(DEFAULT_PORT); + server_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(mysocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - show_socket_error_code(mysocket); + show_socket_error_reason(mysocket); close(mysocket); return ESP_FAIL; } @@ -147,15 +151,17 @@ esp_err_t create_udp_server() esp_err_t create_udp_client() { ESP_LOGI(TAG, "create_udp_client()"); + ESP_LOGI(TAG, "connecting to %s:%d", + EXAMPLE_DEFAULT_SERVER_IP, EXAMPLE_DEFAULT_PORT); mysocket = socket(AF_INET, SOCK_DGRAM, 0); if (mysocket < 0) { - show_socket_error_code(mysocket); + show_socket_error_reason(mysocket); return ESP_FAIL; } /*for client remote_addr is also server_addr*/ remote_addr.sin_family = AF_INET; - remote_addr.sin_port = htons(DEFAULT_PORT); - remote_addr.sin_addr.s_addr = inet_addr(DEFAULT_SERVER_IP); + remote_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT); + remote_addr.sin_addr.s_addr = inet_addr(EXAMPLE_DEFAULT_SERVER_IP); return ESP_OK; } @@ -167,102 +173,79 @@ void send_recv_data(void *pvParameters) ESP_LOGI(TAG, "task send_recv_data start!\n"); int len; - char databuff[DEFAULT_PKTSIZE]; + char databuff[EXAMPLE_DEFAULT_PKTSIZE]; /*send&receive first packet*/ socklen = sizeof(remote_addr); - memset(databuff, PACK_BYTE_IS, DEFAULT_PKTSIZE); -#if ESP_UDP_MODE_SERVER + memset(databuff, EXAMPLE_PACK_BYTE_IS, EXAMPLE_DEFAULT_PKTSIZE); +#if EXAMPLE_ESP_UDP_MODE_SERVER ESP_LOGI(TAG, "first recvfrom:"); - len = recvfrom(mysocket, databuff, DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, &socklen); + len = recvfrom(mysocket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, &socklen); #else ESP_LOGI(TAG, "first sendto:"); - len = sendto(mysocket, databuff, DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); + len = sendto(mysocket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); #endif if (len > 0) { ESP_LOGI(TAG, "transfer data with %s:%u\n", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port)); + xEventGroupSetBits(udp_event_group, UDP_CONNCETED_SUCCESS); } else { - show_socket_error_code(mysocket); + show_socket_error_reason(mysocket); close(mysocket); vTaskDelete(NULL); - } + } /*if (len > 0)*/ -#if ESP_UDP_PERF_TX +#if EXAMPLE_ESP_UDP_PERF_TX vTaskDelay(500 / portTICK_RATE_MS); #endif ESP_LOGI(TAG, "start count!\n"); - while(1) - { - /*you can add delay time for fixed-frequency*/ - //vTaskDelay(5 / portTICK_RATE_MS); -#if ESP_UDP_PERF_TX - len = sendto(mysocket, databuff, DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); + while(1) { +#if EXAMPLE_ESP_UDP_PERF_TX + len = sendto(mysocket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); #else - len = recvfrom(mysocket, databuff, DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, &socklen); + len = recvfrom(mysocket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0, (struct sockaddr *)&remote_addr, &socklen); #endif if (len > 0) { total_data += len; success_pack++; } else { - //show_socket_error_code(mysocket); - /*you'd better turn off watch dog in menuconfig - *Component config->ESP32-specific->Task watchdog. - **/ - //vTaskDelay(1/portTICK_RATE_MS); - } - } + if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { + show_socket_error_reason(mysocket); + } + } /*if (len > 0)*/ + } /*while(1)*/ } -char* tcpip_get_reason(int err) -{ - switch (err) { - case 0: - return "reason: other reason"; - case ENOMEM: - return "reason: out of memory"; - case ENOBUFS: - return "reason: buffer error"; - case EWOULDBLOCK: - return "reason: timeout, try again"; - case EHOSTUNREACH: - return "reason: routing problem"; - case EINPROGRESS: - return "reason: operation in progress"; - case EINVAL: - return "reason: invalid value"; - case EADDRINUSE: - return "reason: address in use"; - case EALREADY: - return "reason: conn already connected"; - case EISCONN: - return "reason: conn already established"; - case ECONNABORTED: - return "reason: connection aborted"; - case ECONNRESET: - return "reason: connection is reset"; - case ENOTCONN: - return "reason: connection closed"; - case EIO: - return "reason: invalid argument"; - case -1: - return "reason: low level netif error"; - default: - return "reason not found"; - } -} - -int show_socket_error_code(int socket) +int get_socket_error_code(int socket) { int result; u32_t optlen = sizeof(int); - getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen); - ESP_LOGI(TAG, "socket error %d reason: %s", result, tcpip_get_reason(result)); + if(getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen) == -1) { + ESP_LOGE(TAG, "getsockopt failed"); + return -1; + } return result; } +int show_socket_error_reason(int socket) +{ + int err = get_socket_error_code(socket); + ESP_LOGW(TAG, "socket error %d %s", err, strerror(err)); + return err; +} + +int check_connected_socket() +{ + int ret; + ESP_LOGD(TAG, "check connect_socket"); + ret = get_socket_error_code(mysocket); + if(ret != 0) { + ESP_LOGW(TAG, "socket error %d %s", ret, strerror(ret)); + } + return ret; +} void close_socket() { diff --git a/examples/performance/udp_perf/main/udp_perf.h b/examples/performance/udp_perf/main/udp_perf.h index 0f8221559..11c1c512d 100644 --- a/examples/performance/udp_perf/main/udp_perf.h +++ b/examples/performance/udp_perf/main/udp_perf.h @@ -1,3 +1,13 @@ +/* udp_perf 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. +*/ + + #ifndef __UDP_PERF_H__ #define __UDP_PERF_H__ @@ -7,23 +17,33 @@ extern "C" { #endif -/*AP info and tcp_server info*/ -#define DEFAULT_SSID CONFIG_UDP_PERF_WIFI_SSID -#define DEFAULT_PWD CONFIG_UDP_PERF_WIFI_PASSWORD -#define DEFAULT_PORT CONFIG_UDP_PERF_SERVER_PORT -#define DEFAULT_SERVER_IP CONFIG_UDP_PERF_SERVER_IP -#define DEFAULT_PKTSIZE CONFIG_UDP_PERF_PKT_SIZE -#define MAX_STA_CONN 1 //how many sta can be connected(AP mode) + /*test options*/ -#define ESP_WIFI_MODE_AP CONFIG_UDP_PERF_WIFI_MODE_AP //TRUE:AP FALSE:STA -#define ESP_UDP_MODE_SERVER CONFIG_UDP_PERF_SERVER //TRUE:server FALSE:client -#define ESP_UDP_PERF_TX CONFIG_UDP_PERF_TX //TRUE:send FALSE:receive -#define PACK_BYTE_IS 97 //'a' +#define EXAMPLE_ESP_WIFI_MODE_AP CONFIG_UDP_PERF_WIFI_MODE_AP //TRUE:AP FALSE:STA +#define EXAMPLE_ESP_UDP_MODE_SERVER CONFIG_UDP_PERF_SERVER //TRUE:server FALSE:client +#define EXAMPLE_ESP_UDP_PERF_TX CONFIG_UDP_PERF_TX //TRUE:send FALSE:receive +#define EXAMPLE_PACK_BYTE_IS 97 //'a' +/*AP info and tcp_server info*/ +#define EXAMPLE_DEFAULT_SSID CONFIG_UDP_PERF_WIFI_SSID +#define EXAMPLE_DEFAULT_PWD CONFIG_UDP_PERF_WIFI_PASSWORD +#define EXAMPLE_DEFAULT_PORT CONFIG_UDP_PERF_SERVER_PORT +#define EXAMPLE_DEFAULT_PKTSIZE CONFIG_UDP_PERF_PKT_SIZE +#define EXAMPLE_MAX_STA_CONN 1 //how many sta can be connected(AP mode) + +#ifdef CONFIG_UDP_PERF_SERVER_IP +#define EXAMPLE_DEFAULT_SERVER_IP CONFIG_UDP_PERF_SERVER_IP +#else +#define EXAMPLE_DEFAULT_SERVER_IP "192.168.4.1" +#endif /*CONFIG_UDP_PERF_SERVER_IP*/ + #define TAG "udp_perf:" +/* FreeRTOS event group to signal when we are connected to WiFi and ready to start UDP test*/ +extern EventGroupHandle_t udp_event_group; +#define WIFI_CONNECTED_BIT BIT0 +#define UDP_CONNCETED_SUCCESS BIT1 -extern int connectedflag; extern int total_data; extern int success_pack; @@ -41,8 +61,14 @@ esp_err_t create_udp_client(); //send or recv data task void send_recv_data(void *pvParameters); +//get socket error code. return: error code +int get_socket_error_code(int socket); + //show socket error code. return: error code -int show_socket_error_code(int socket); +int show_socket_error_reason(int socket); + +//check connected socket. return: error code +int check_connected_socket(); //close all socket void close_socket();