diff --git a/examples/basic_thread_border_router/main/idf_component.yml b/examples/basic_thread_border_router/main/idf_component.yml index 0c11903..f4b859a 100644 --- a/examples/basic_thread_border_router/main/idf_component.yml +++ b/examples/basic_thread_border_router/main/idf_component.yml @@ -1,5 +1,6 @@ ## IDF Component Manager Manifest File dependencies: + espressif/esp_websocket_client: "^1.2.3" espressif/mdns: "^1.0.0" espressif/esp_ot_cli_extension: version: "~1.2.0" diff --git a/examples/basic_thread_border_router/sdkconfig.defaults b/examples/basic_thread_border_router/sdkconfig.defaults index 32a2245..b902bc4 100644 --- a/examples/basic_thread_border_router/sdkconfig.defaults +++ b/examples/basic_thread_border_router/sdkconfig.defaults @@ -107,3 +107,12 @@ CONFIG_EXAMPLE_ETH_SPI_INT_GPIO=39 CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=40 CONFIG_EXAMPLE_ETH_PHY_ADDR=1 # end of Etherenet + +# +# Example of WebSocket Client Disconnect issue +CONFIG_OPENTHREAD_DNS64_CLIENT=y +CONFIG_OPENTHREAD_DNS_SERVER_ADDR="1.1.1.1" +CONFIG_OPENTHREAD_BR_AUTO_START=y +CONFIG_EXAMPLE_CONNECT_WIFI=n +CONFIG_EXAMPLE_CONNECT_ETHERNET=y +# End of Example of WebSocket Client Disconnect issue diff --git a/examples/common/thread_border_router/CMakeLists.txt b/examples/common/thread_border_router/CMakeLists.txt index 627cc4c..6bef125 100644 --- a/examples/common/thread_border_router/CMakeLists.txt +++ b/examples/common/thread_border_router/CMakeLists.txt @@ -1,4 +1,4 @@ -set(requires esp_ot_cli_extension openthread protocol_examples_common vfs esp_wifi esp_eth esp_rcp_update) +set(requires esp_ot_cli_extension openthread protocol_examples_common vfs esp_wifi esp_eth esp_rcp_update esp_websocket_client) if(CONFIG_OPENTHREAD_CLI_OTA) list(APPEND requires esp_http_client esp_br_http_ota) diff --git a/examples/common/thread_border_router/src/border_router_launch.c b/examples/common/thread_border_router/src/border_router_launch.c index 75a66ca..83771a2 100644 --- a/examples/common/thread_border_router/src/border_router_launch.c +++ b/examples/common/thread_border_router/src/border_router_launch.c @@ -37,6 +37,9 @@ #include "openthread/tasklet.h" #include "openthread/thread_ftd.h" +#include "esp_crt_bundle.h" +#include "esp_websocket_client.h" + #if CONFIG_OPENTHREAD_CLI_WIFI #include "esp_ot_wifi_cmd.h" #endif @@ -102,6 +105,105 @@ static void rcp_failure_handler(void) #endif } +static void log_error_if_nonzero(const char *message, int error_code) +{ + if (error_code != 0) { + ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code); + } +} + +static void websocket_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) { + esp_websocket_event_data_t *data = (esp_websocket_event_data_t *) event_data; + switch (event_id) { + case WEBSOCKET_EVENT_CONNECTED: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED"); + break; + case WEBSOCKET_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED"); + log_error_if_nonzero("HTTP status code", data->error_handle.esp_ws_handshake_status_code); + if (data->error_handle.error_type == WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT) { + log_error_if_nonzero("reported from esp-tls", data->error_handle.esp_tls_last_esp_err); + log_error_if_nonzero("reported from tls stack", data->error_handle.esp_tls_stack_err); + log_error_if_nonzero("captured as transport's socket errno", + data->error_handle.esp_transport_sock_errno); + } + break; + case WEBSOCKET_EVENT_DATA: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_DATA"); + ESP_LOGI(TAG, "Received opcode=%d", data->op_code); + if (data->op_code == 0x08 && data->data_len == 2) { + ESP_LOGW(TAG, "Received closed message with code=%d", 256 * data->data_ptr[0] + data->data_ptr[1]); + } else { + ESP_LOGW(TAG, "Received=%.*s", data->data_len, (char *) data->data_ptr); + } + + // If received data contains json structure it succeed to parse + ESP_LOGW(TAG, "Total payload length=%d, data_len=%d, current payload offset=%d\r\n", data->payload_len, + data->data_len, data->payload_offset); + + break; + case WEBSOCKET_EVENT_ERROR: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR"); + log_error_if_nonzero("HTTP status code", data->error_handle.esp_ws_handshake_status_code); + if (data->error_handle.error_type == WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT) { + log_error_if_nonzero("reported from esp-tls", data->error_handle.esp_tls_last_esp_err); + log_error_if_nonzero("reported from tls stack", data->error_handle.esp_tls_stack_err); + log_error_if_nonzero("captured as transport's socket errno", + data->error_handle.esp_transport_sock_errno); + } + break; + } +} + +static void websocket_client_example_worker(void *ctx) +{ + struct ifreq if_name = {0}; + esp_netif_get_netif_impl_name(get_example_netif(), if_name.ifr_name); + ESP_LOGI(TAG, "Network interface name: %s", if_name.ifr_name); + + esp_websocket_client_config_t websocket_cfg = {}; + + websocket_cfg.uri = "wss://echo.websocket.events"; + websocket_cfg.if_name = &if_name; + + // Using certificate bundle as default server certificate source + websocket_cfg.crt_bundle_attach = esp_crt_bundle_attach; + + ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri); + + esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg); + esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client); + + esp_websocket_client_start(client); + + while (1) { + if (esp_websocket_client_is_connected(client)) { + size_t buffer_len = 50; + uint8_t *buffer = malloc(buffer_len); + + if (buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate buffer"); + } else { + memset(buffer, 0, buffer_len); + + int bytes_sent = esp_websocket_client_send_bin(client, (const char *) buffer, buffer_len, portMAX_DELAY); + + if (bytes_sent == buffer_len) { + ESP_LOGI(TAG, "Successfully sent message"); + } else if (bytes_sent >= 0) { + ESP_LOGE(TAG, "Only sent %d of %d bytes of message", bytes_sent, buffer_len); + } else { + ESP_LOGE(TAG, "Failed to send message"); + } + + free(buffer); + } + } + + vTaskDelay(10000 / portTICK_PERIOD_MS); + } +} + static void ot_br_init(void *ctx) { #if CONFIG_OPENTHREAD_CLI_WIFI @@ -149,6 +251,9 @@ static void ot_br_init(void *ctx) ESP_LOGE(TAG, "Auto-start mode failed, please try to start manually"); } #endif // CONFIG_OPENTHREAD_BR_AUTO_START + + xTaskCreate(websocket_client_example_worker, "websocket_client_example_worker", 6144, NULL, 4, NULL); + vTaskDelete(NULL); }