diff --git a/components/esp_ot_cli_extension/CMakeLists.txt b/components/esp_ot_cli_extension/CMakeLists.txt index fd54d3a..5eaee6e 100644 --- a/components/esp_ot_cli_extension/CMakeLists.txt +++ b/components/esp_ot_cli_extension/CMakeLists.txt @@ -4,12 +4,9 @@ if(CONFIG_OPENTHREAD_CLI_IPERF) list(APPEND srcs "src/esp_ot_iperf.c") endif() -if(CONFIG_OPENTHREAD_CLI_TCP_SOCKET) - list(APPEND srcs "src/esp_ot_tcp_socket.c") -endif() - -if(CONFIG_OPENTHREAD_CLI_UDP_SOCKET) - list(APPEND srcs "src/esp_ot_udp_socket.c") +if(CONFIG_OPENTHREAD_CLI_SOCKET) + list(APPEND srcs "src/esp_ot_tcp_socket.c" + "src/esp_ot_udp_socket.c") endif() if(CONFIG_OPENTHREAD_CLI_WIFI) @@ -23,4 +20,9 @@ endif() set(include "include") idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include}" - REQUIRES lwip openthread iperf esp_br_http_ota esp_netif esp_wifi) + REQUIRES lwip openthread iperf esp_netif esp_wifi) + +if (CONFIG_OPENTHREAD_CLI_OTA) + idf_component_optional_requires(PUBLIC esp_br_http_ota) +endif() + diff --git a/components/esp_ot_cli_extension/Kconfig b/components/esp_ot_cli_extension/Kconfig index e4740d6..bd7d999 100644 --- a/components/esp_ot_cli_extension/Kconfig +++ b/components/esp_ot_cli_extension/Kconfig @@ -12,27 +12,22 @@ menu "OpenThread Extension CLI" depends on OPENTHREAD_CLI_ESP_EXTENSION default y - config OPENTHREAD_CLI_TCP_SOCKET - bool "Enable TCP socket command" + config OPENTHREAD_CLI_SOCKET + bool "Enable socket command" depends on OPENTHREAD_CLI_ESP_EXTENSION default y config OPENTHREAD_CLI_TCP_SERVER_PORT - int "the port of TCP server" + int "the port of TCP socket server" default 12345 - depends on OPENTHREAD_CLI_TCP_SOCKET + depends on OPENTHREAD_CLI_SOCKET help Set the connect port of socket - config OPENTHREAD_CLI_UDP_SOCKET - bool "Enable UDP socket command" - depends on OPENTHREAD_CLI_ESP_EXTENSION - default y - config OPENTHREAD_CLI_UDP_SERVER_PORT int "the port of UDP server" - default 54321 - depends on OPENTHREAD_CLI_UDP_SOCKET + default 12346 + depends on OPENTHREAD_CLI_SOCKET help Set the connect port of socket @@ -44,6 +39,6 @@ menu "OpenThread Extension CLI" config OPENTHREAD_CLI_OTA bool "Enable OTA command" depends on OPENTHREAD_CLI_ESP_EXTENSION && OPENTHREAD_BORDER_ROUTER - default y + default n endmenu diff --git a/components/esp_ot_cli_extension/README.md b/components/esp_ot_cli_extension/README.md index 2c4c8b6..565170a 100644 --- a/components/esp_ot_cli_extension/README.md +++ b/components/esp_ot_cli_extension/README.md @@ -15,6 +15,7 @@ To enable OpenThread extension commands, the following Kconfig option needs to b * [udpsockclient](#udpsockclient) * [udpsockserver](#udpsockserver) * [wifi](#wifi) +* [ota](#ota) ### iperf @@ -126,3 +127,53 @@ ot_socket: Socket created, connecting to fdde:ad00:beef:0:a7c6:6311:9c8c:271b:12 ot_socket: Successfully connected ... ``` + +### wifi + +Used for connecting the border router to the Wi-Fi network. + +```bash +> wifi +--wifi parameter--- +connect +-s : wifi ssid +-p : wifi psk +---example--- +join a wifi: +ssid: threadcertAP +psk: threadcertAP : wifi connect -s threadcertAP -p threadcertAP +state : get wifi state, disconnect or connect +---example--- +get wifi state : wifi state +Done +``` + +To join a Wi-Fi network, please use the `wifi connect` command: + +```bash +> wifi connect -s threadcertAP -p threadcertAP +``` + +To get the state of the Wi-Fi network: + +```bash +> wifi state +connected +Done +``` + +### ota + +Used for downloading border router firmware and updating the border router or the RCP alone. + +``` +> ota download https://192.168.1.2:8070/br_ota_image +``` + +After downloading the device will restart and update itself with the new firmware. The RCP will also be updated if the firmware version changes. + +``` +> ota rcpudate +``` + +This command will enforce a RCP update regardless of the RCP version. diff --git a/components/esp_ot_cli_extension/idf_component.yml b/components/esp_ot_cli_extension/idf_component.yml index 46c7c5e..1b6d482 100644 --- a/components/esp_ot_cli_extension/idf_component.yml +++ b/components/esp_ot_cli_extension/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.1.0" +version: "0.1.1" description: Espressif OpenThread CLI Extension url: https://github.com/espressif/esp-thread-br/tree/main/components/esp_ot_cli_extension dependencies: diff --git a/components/esp_ot_cli_extension/include/esp_ot_tcp_socket.h b/components/esp_ot_cli_extension/include/esp_ot_tcp_socket.h index 395b656..0464ec4 100644 --- a/components/esp_ot_cli_extension/include/esp_ot_tcp_socket.h +++ b/components/esp_ot_cli_extension/include/esp_ot_tcp_socket.h @@ -10,10 +10,12 @@ * 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. -*/ + */ #pragma once +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_ot_cli_extension/src/esp_ot_cli_extension.c b/components/esp_ot_cli_extension/src/esp_ot_cli_extension.c index a22e2cf..fe1c2d9 100644 --- a/components/esp_ot_cli_extension/src/esp_ot_cli_extension.c +++ b/components/esp_ot_cli_extension/src/esp_ot_cli_extension.c @@ -25,15 +25,13 @@ #include "openthread/cli.h" static const otCliCommand kCommands[] = { -#if CONFIG_OPENTHREAD_CLI_TCP_SOCKET +#if CONFIG_OPENTHREAD_CLI_SOCKET {"tcpsockserver", esp_ot_process_tcp_server}, {"tcpsockclient", esp_ot_process_tcp_client}, -#endif // CONFIG_OPENTHREAD_CLI_TCP_SOCKET -#if CONFIG_OPENTHREAD_CLI_UDP_SOCKET {"udpsockserver", esp_ot_process_udp_server}, {"udpsockclient", esp_ot_process_udp_client}, {"mcast", esp_ot_process_mcast_group}, -#endif // CONFIG_OPENTHREAD_CLI_UDP_SOCKET +#endif // CONFIG_OPENTHREAD_CLI_SOCKET #if CONFIG_OPENTHREAD_CLI_IPERF {"iperf", esp_ot_process_iperf}, #endif // CONFIG_OPENTHREAD_CLI_IPERF diff --git a/components/esp_ot_cli_extension/src/esp_ot_tcp_socket.c b/components/esp_ot_cli_extension/src/esp_ot_tcp_socket.c index 480b7a7..9bb99d3 100644 --- a/components/esp_ot_cli_extension/src/esp_ot_tcp_socket.c +++ b/components/esp_ot_cli_extension/src/esp_ot_tcp_socket.c @@ -10,12 +10,15 @@ * 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 "esp_ot_tcp_socket.h" #include "esp_check.h" #include "esp_err.h" #include "esp_log.h" -#include "esp_ot_tcp_socket.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -32,9 +35,9 @@ static void tcp_socket_server_task(void *pvParameters) int opt = 1; int port = CONFIG_OPENTHREAD_CLI_TCP_SERVER_PORT; int client_sock = 0; - struct timeval timeout = { 0 }; + struct timeval timeout = {0}; struct sockaddr_storage source_addr; // Large enough for both IPv6 - struct sockaddr_in6 listen_addr = { 0 }; + struct sockaddr_in6 listen_addr = {0}; // The TCP server listen at the address "::", which means all addresses can be listened to. inet6_aton("::", &listen_addr.sin6_addr); listen_addr.sin6_family = AF_INET6; @@ -50,14 +53,14 @@ static void tcp_socket_server_task(void *pvParameters) ESP_LOGI(TAG, "Socket created"); - err = bind(listen_sock, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr_in6) ); + err = bind(listen_sock, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr_in6)); ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET6); ESP_LOGI(TAG, "Socket bound, port %d", port); err = listen(listen_sock, 1); ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno); - //blocking-mode accept, set timeout 30 seconds + // blocking-mode accept, set timeout 30 seconds timeout.tv_sec = 30; setsockopt(listen_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); @@ -69,7 +72,7 @@ static void tcp_socket_server_task(void *pvParameters) ESP_GOTO_ON_FALSE((err >= 0), ESP_FAIL, exit, TAG, "Error occurred during sending: errno %d", errno); - //blocking-mode receive, set timeout 30 seconds + // blocking-mode receive, set timeout 30 seconds timeout.tv_sec = 30; setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); @@ -107,7 +110,7 @@ static void tcp_socket_client_task(void *pvParameters) int err = 0; int len = 0; int port = CONFIG_OPENTHREAD_CLI_TCP_SERVER_PORT; - struct sockaddr_in6 dest_addr = { 0 }; + struct sockaddr_in6 dest_addr = {0}; inet6_aton(host_ip, &dest_addr.sin6_addr); dest_addr.sin6_family = AF_INET6; @@ -147,16 +150,20 @@ void esp_ot_process_tcp_server(void *aContext, uint8_t aArgsLength, char *aArgs[ (void)(aContext); (void)(aArgsLength); (void)(*aArgs); + xTaskCreate(tcp_socket_server_task, "ot_tcp_scoket_server", 4096, xTaskGetCurrentTaskHandle(), 4, NULL); } void esp_ot_process_tcp_client(void *aContext, uint8_t aArgsLength, char *aArgs[]) { (void)(aContext); - (void)(aArgsLength); + + static char s_target_addr_string[128]; + if (aArgsLength == 0) { ESP_LOGE(TAG, "Invalid arguments."); } else { - xTaskCreate(tcp_socket_client_task, "ot_tcp_socket_client", 4096, aArgs[0], 4, NULL); + strncpy(s_target_addr_string, aArgs[0], sizeof(s_target_addr_string)); + xTaskCreate(tcp_socket_client_task, "ot_tcp_socket_client", 4096, s_target_addr_string, 4, NULL); } } diff --git a/components/esp_ot_cli_extension/src/esp_ot_udp_socket.c b/components/esp_ot_cli_extension/src/esp_ot_udp_socket.c index 002b319..7f64746 100644 --- a/components/esp_ot_cli_extension/src/esp_ot_udp_socket.c +++ b/components/esp_ot_cli_extension/src/esp_ot_udp_socket.c @@ -10,14 +10,17 @@ * 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 "esp_ot_udp_socket.h" #include "esp_check.h" #include "esp_err.h" #include "esp_log.h" #include "esp_netif.h" #include "esp_openthread_lock.h" -#include "esp_ot_udp_socket.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "lwip/err.h" #include "lwip/mld6.h" #include "lwip/sockets.h" @@ -35,7 +38,7 @@ static void udp_socket_server_task(void *pvParameters) int listen_sock; int port = CONFIG_OPENTHREAD_CLI_UDP_SERVER_PORT; - struct timeval timeout = { 0 }; + struct timeval timeout = {0}; struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 struct sockaddr_in6 listen_addr; @@ -96,7 +99,7 @@ static void udp_socket_client_task(void *pvParameters) int len; esp_err_t ret = ESP_OK; struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 - struct sockaddr_in6 dest_addr = { 0 }; + struct sockaddr_in6 dest_addr = {0}; uint8_t netif_index = esp_netif_get_netif_impl_index(esp_netif_get_handle_from_ifkey("OT_DEF")); inet6_aton(host_ip, &dest_addr.sin6_addr); @@ -135,22 +138,27 @@ void esp_ot_process_udp_server(void *aContext, uint8_t aArgsLength, char *aArgs[ { (void)(aContext); (void)(aArgsLength); + xTaskCreate(udp_socket_server_task, "ot_udp_scoket_server", 4096, xTaskGetCurrentTaskHandle(), 4, NULL); } void esp_ot_process_udp_client(void *aContext, uint8_t aArgsLength, char *aArgs[]) { (void)(aContext); + + static char s_target_addr_string[128]; + if (aArgsLength == 0) { ESP_LOGE(TAG, "Invalid arguments."); } else { - xTaskCreate(udp_socket_client_task, "ot_udp_socket_client", 4096, aArgs[0], 4, NULL); + strncpy(s_target_addr_string, aArgs[0], sizeof(s_target_addr_string)); + xTaskCreate(udp_socket_client_task, "ot_udp_socket_client", 4096, s_target_addr_string, 4, NULL); } } void esp_ot_process_mcast_group(void *aContext, uint8_t aArgsLength, char *aArgs[]) { - if (aArgsLength != 2 || (strncmp(aArgs[0], "join", 4) != 0 && strncmp(aArgs[0], "leave", 5) != 0) ) { + if (aArgsLength != 2 || (strncmp(aArgs[0], "join", 4) != 0 && strncmp(aArgs[0], "leave", 5) != 0)) { ESP_LOGE(TAG, "Invalid arguments: mcast [join|leave] group_address"); return; } diff --git a/examples/basic_thread_border_router/main/idf_component.yml b/examples/basic_thread_border_router/main/idf_component.yml new file mode 100644 index 0000000..6571fdc --- /dev/null +++ b/examples/basic_thread_border_router/main/idf_component.yml @@ -0,0 +1,17 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/mdns: "*" + ## Required IDF version + idf: + version: ">=4.1.0" + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true diff --git a/examples/basic_thread_border_router/sdkconfig.defaults b/examples/basic_thread_border_router/sdkconfig.defaults index e3332e0..02d0d5e 100644 --- a/examples/basic_thread_border_router/sdkconfig.defaults +++ b/examples/basic_thread_border_router/sdkconfig.defaults @@ -38,6 +38,7 @@ CONFIG_MBEDTLS_ECJPAKE_C=y CONFIG_OPENTHREAD_ENABLED=y CONFIG_OPENTHREAD_BORDER_ROUTER=y CONFIG_OPENTHREAD_TREL=y +CONFIG_OPENTHREAD_CLI_OTA=y # end of OpenThread #