openthread: add ot tcp and udp socket example

This commit is contained in:
zhangwenxu 2021-05-25 21:13:41 +08:00
parent 2aa48c9558
commit 7bc44ad5aa
11 changed files with 650 additions and 2 deletions

View File

@ -3,4 +3,4 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ot_esp_cli)
project(esp_ot_cli)

View File

@ -84,3 +84,162 @@ leader
Done
```
## Example1: TCP/UDP server and client
### Step 1 Configure the project
```bash
idf.py menuconfig
```
Enable the operation: Example Configuration -> Enable custom command in ot-cli -> Enable openthread tcp/udp socket
### Step 2 Build, Flash, and Run
You need to prepare two ESP devices each connected to a 15.4 RCP and flashed with this example.
```
idf.py -p PORT flash monitor
```
### Step 3 Set up network
On the first device, run:
```bash
> extaddr 166e0a0000000001
Done
> dataset channel 17
Done
> dataset panid 0xface
Done
> dataset extpanid 000db80000000000
Done
> dataset networkname GRL
Done
> dataset masterkey 00112233445566778899aabbccddeeff
Done
> dataset meshlocalprefix FD00:0DB8:0000:0000::
Done
> dataset pskc 00000000000000000000000000000000
Done
> dataset activetimestamp 1
Done
> dataset commit active
Done
> ifconfig up
Done
> thread start
Done
# After some seconds
> state
leader
Done
```
Now the first device has formed a Thread network, on the second device run:
```bash
> extaddr 166e0a0000000002
Done
> dataset channel 17
Done
> dataset panid 0xface
Done
> dataset extpanid 000db80000000000
Done
> dataset networkname GRL
Done
> dataset masterkey 00112233445566778899aabbccddeeff
Done
> dataset meshlocalprefix FD00:0DB8:0000:0000::
Done
> dataset pskc 00000000000000000000000000000000
Done
> dataset activetimestamp 1
Done
> dataset commit active
Done
> ifconfig up
Done
> thread start
Done
# After some seconds
> state
router # child is also a valid state
Done
```
Now the second device has joined the Thread network and acting as a router (or a child).
### Step 4 Set up tcp/udp socket server and client
In leader device, run this command in command line shell.
```bash
# for setup a tcp server
> tcpsockserver
# for setup an udp server
> udpsockserver
```
Then run this command to get the leader IPv6 address.
```bash
> ipaddr
fd00:db8:0:0:0:ff:fe00:fc00
fd00:db8:0:0:0:ff:fe00:ac00
fd00:db8:0:0:284a:cb4a:cb3b:2a42
fe80:0:0:0:146e:a00:0:1
```
In router device, run this command to set up a socket client in command line shell.
```bash
# for setup a tcp client
> tcpsockclient fd00:db8:0:0:284a:cb4a:cb3b:2a42
# for setup an udp client
> udpsockclient fd00:db8:0:0:284a:cb4a:cb3b:2a42
```
You will get
```bash
# in leader device
> tcpsockserver
I(173437) OPENTHREAD:[INFO]-CLI-----: execute command: tcpsockserver
> I (173437) ot_secket: Socket created
I (173437) ot_secket: Socket bound, port 12345
I (173457) ot_secket: Socket listening, timeout is 30 seconds
I(175007) OPENTHREAD:[INFO]-MLE-----: Send Advertisement (ff02:0:0:0:0:0:0:1)
......
I (182187) ot_secket: Received 28 bytes from client:
I (182187) ot_secket: This message is from client
I (182187) ot_secket: Socket accepted ip address: FD00:DB8::498:DDB:EC7:49DC
I (182189) ot_secket: Socket server is closed.
# in router device
> tcpsockclient fd00:db8:0:0:284a:cb4a:cb3b:2a42
I(37731) OPENTHREAD:[INFO]-CLI-----: execute command: tcpsockclient fd00:db8:0:0:284a:cb4a:cb3b:2a42
> I (37741) ot_secket: Socket created, connecting to b80d00fd:0:4acb4a28:422a3bcb:12345
I(37751) OPENTHREAD:[INFO]-ARP-----: Sending address query for fd00:db8:0:0:284a:cb4a:cb3b:2a42
......
I (38171) ot_secket: Successfully connected
......
I (38321) ot_secket: Received 28 bytes from fd00:db8:0:0:284a:cb4a:cb3b:2a42
I (38321) ot_secket: This message is from server
I (38323) ot_secket: Socket client is closed.
```

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "ot_esp_cli.c"
idf_component_register(SRCS "esp_ot_udp_socket.c" "esp_ot_tcp_socket.c" "esp_ot_cli_extension.c" "esp_ot_cli.c"
INCLUDE_DIRS ".")

View File

@ -0,0 +1,31 @@
menu "Openthread"
menuconfig OPENTHREAD_CUSTOM_COMMAND
bool "Enable custom command in ot-cli"
default n
config OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
bool "Enable openthread tcp socket"
depends on OPENTHREAD_CUSTOM_COMMAND
default n
config OPENTHEAD_EXAMPLE_TCP_SERVER_PORT
int "the port of TCP server"
default 12345
depends on OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
help
Set the connect port of socket
config OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
bool "Enable openthread udp socket"
depends on OPENTHREAD_CUSTOM_COMMAND
default n
config OPENTHEAD_EXAMPLE_UDP_SERVER_PORT
int "the port of UDP server"
default 54321
depends on OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
help
Set the connect port of socket
endmenu

View File

@ -33,6 +33,10 @@
#include "openthread/instance.h"
#include "openthread/tasklet.h"
#if CONFIG_OPENTHREAD_CUSTOM_COMMAND
#include "esp_ot_cli_extension.h"
#endif // CONFIG_OPENTHREAD_CUSTOM_COMMAND
#define TAG "ot_esp_cli"
extern void otAppCliInit(otInstance *instance);
@ -100,6 +104,9 @@ static void ot_task_worker(void *aContext)
esp_openthread_lock_acquire(portMAX_DELAY);
otAppCliInit(instance);
esp_openthread_lock_release();
#if CONFIG_OPENTHREAD_CUSTOM_COMMAND
esp_cli_custom_command_init();
#endif // CONFIG_OPENTHREAD_CUSTOM_COMMAND
while (true) {
FD_ZERO(&mainloop.read_fds);

View File

@ -0,0 +1,39 @@
// Copyright 2021 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.
#include "esp_openthread.h"
#include "esp_ot_cli_extension.h"
#include "esp_ot_tcp_socket.h"
#include "esp_ot_udp_socket.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
#include "openthread/cli.h"
static const otCliCommand kCommands[] = {
#if CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
{"tcpsockserver", esp_ot_process_tcp_server},
{"tcpsockclient", esp_ot_process_tcp_client},
#endif // CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
#if CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
{"udpsockserver", esp_ot_process_udp_server},
{"udpsockclient", esp_ot_process_udp_client},
#endif // CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
};
void esp_cli_custom_command_init()
{
otInstance *instance = esp_openthread_get_instance();
otCliSetUserCommands(kCommands, (sizeof(kCommands) / sizeof(kCommands[0])), instance);
}

View File

@ -0,0 +1,28 @@
// Copyright 2021 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Init the custom command.
*
*/
void esp_cli_custom_command_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,165 @@
// Copyright 2021 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.
#include "esp_check.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_ot_tcp_socket.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#if CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
#define TAG "ot_socket"
static void tcp_socket_server_task(void *pvParameters)
{
char addr_str[128];
char payload[] = "This message is from server\n";
char rx_buffer[128];
esp_err_t ret = ESP_OK;
int err = 0;
int len = 0;
int listen_sock;
int opt = 1;
int port = CONFIG_OPENTHEAD_EXAMPLE_TCP_SERVER_PORT;
int client_sock = 0;
struct timeval timeout;
struct sockaddr_storage source_addr; // Large enough for both IPv6
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;
listen_addr.sin6_port = htons(port);
listen_sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((listen_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// Note that by default IPV6 binds to both protocols, it is must be disabled
// if both protocols used at the same time (used in CI)
setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
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
timeout.tv_sec = 30;
setsockopt(listen_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
ESP_LOGI(TAG, "Socket listening, timeout is 30 seconds");
socklen_t addr_len = sizeof(source_addr);
client_sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
ESP_GOTO_ON_FALSE((client_sock >= 0), ESP_FAIL, exit, TAG, "Unable to accept connection: errno %d", errno);
ESP_GOTO_ON_FALSE((err >= 0), ESP_FAIL, exit, TAG, "Error occurred during sending: errno %d", errno);
//blocking-mode receive, set timeout 30 seconds
timeout.tv_sec = 30;
setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
len = recv(client_sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
// Error occurred during receiving
ESP_GOTO_ON_FALSE((len >= 0), ESP_FAIL, exit, TAG, "recv failed: errno %d", errno);
// Data received
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
ESP_LOGI(TAG, "Received %d bytes from client:", len);
ESP_LOGI(TAG, "%s", rx_buffer);
// Convert ip address to string
inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
ESP_LOGI(TAG, "Socket accepted ip address: %s", addr_str);
exit:
if (ret != ESP_OK || listen_sock != -1) {
shutdown(listen_sock, 0);
close(listen_sock);
}
if (client_sock != -1) {
shutdown(client_sock, 0);
close(client_sock);
}
ESP_LOGI(TAG, "Socket server is closed.");
vTaskDelete(NULL);
}
static void tcp_socket_client_task(void *pvParameters)
{
char *host_ip = (char *)pvParameters;
char *payload = "This message is from client\n";
char rx_buffer[128];
esp_err_t ret = ESP_OK;
int client_sock;
int err = 0;
int len = 0;
int port = CONFIG_OPENTHEAD_EXAMPLE_TCP_SERVER_PORT;
struct sockaddr_in6 dest_addr = { 0 };
inet6_aton(host_ip, &dest_addr.sin6_addr);
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(port);
client_sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((client_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created, connecting to %x:%x:%x:%x:%d", dest_addr.sin6_addr.un.u32_addr[0], dest_addr.sin6_addr.un.u32_addr[1], dest_addr.sin6_addr.un.u32_addr[2], dest_addr.sin6_addr.un.u32_addr[3], port);
err = connect(client_sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
ESP_LOGI(TAG, "Successfully connected");
len = send(client_sock, payload, strlen(payload), 0);
ESP_GOTO_ON_FALSE((len >= 0), ESP_FAIL, exit, TAG, "Error occurred during sending: errno %d", errno);
len = recv(client_sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
// Error occurred during receiving
ESP_GOTO_ON_FALSE((len >= 0), ESP_FAIL, exit, TAG, "recv failed: errno %d", errno);
// Data received
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
ESP_LOGI(TAG, "Received %d bytes from %s", len, host_ip);
ESP_LOGI(TAG, "%s", rx_buffer);
exit:
if (ret != ESP_OK || client_sock != -1) {
shutdown(client_sock, 0);
close(client_sock);
}
ESP_LOGI(TAG, "Socket client is closed.");
vTaskDelete(NULL);
}
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);
if (aArgs[0] == NULL) {
ESP_LOGE(TAG, "Invalid arguments.");
} else {
xTaskCreate(tcp_socket_client_task, "ot_tcp_socket_client", 4096, aArgs[0], 4, NULL);
}
}
#endif // CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE

View File

@ -0,0 +1,37 @@
// Copyright 2021 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
/**
* @brief User command "tcpsockserver" process.
*
*/
void esp_ot_process_tcp_server(void *aContext, uint8_t aArgsLength, char *aArgs[]);
/**
* @brief User command "tcpsockclient" process.
*
*/
void esp_ot_process_tcp_client(void *aContext, uint8_t aArgsLength, char *aArgs[]);
#endif // CONFIG_OPENTHREAD_ENABLE_TCP_SOCKET_EXAMPLE
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,145 @@
// Copyright 2020 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.
#include "esp_check.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_ot_udp_socket.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#if CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
#define TAG "ot_socket"
static void udp_socket_server_task(void *pvParameters)
{
char addr_str[128];
char *payload = "This message is from server\n";
char rx_buffer[128];
esp_err_t ret = ESP_OK;
int err = 0;
int len;
int listen_sock;
int port = CONFIG_OPENTHEAD_EXAMPLE_UDP_SERVER_PORT;
struct timeval timeout;
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
struct sockaddr_in6 listen_addr;
inet6_aton("::", &listen_addr.sin6_addr);
listen_addr.sin6_family = AF_INET6;
listen_addr.sin6_port = htons(port);
listen_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((listen_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created");
// Note that by default IPV6 binds to both protocols, it is must be disabled
// if both protocols used at the same time (used in CI)
int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
err = bind(listen_sock, (struct sockaddr *)&listen_addr, sizeof(listen_addr));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d", errno);
ESP_LOGI(TAG, "Socket bound, port %d", port);
timeout.tv_sec = 30;
setsockopt(listen_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
ESP_LOGI(TAG, "Waiting for data, timeout is 30 seconds");
socklen_t socklen = sizeof(source_addr);
len = recvfrom(listen_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
// Error occurred during receiving
ESP_GOTO_ON_FALSE((len >= 0), ESP_FAIL, exit, TAG, "recvfrom failed: errno %d", errno);
// Data received
// Get the sender's ip address as string
inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string...
ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
ESP_LOGI(TAG, "%s", rx_buffer);
err = sendto(listen_sock, payload, strlen(payload), 0, (struct sockaddr *)&source_addr, sizeof(source_addr));
ESP_GOTO_ON_FALSE((err >= 0), ESP_FAIL, exit, TAG, "Error occurred during sending: errno %d", errno);
exit:
if (ret != ESP_OK || listen_sock != -1) {
shutdown(listen_sock, 0);
close(listen_sock);
}
ESP_LOGI(TAG, "Socket server is closed.");
vTaskDelete(NULL);
}
static void udp_socket_client_task(void *pvParameters)
{
char rx_buffer[128];
char *host_ip = (char *)pvParameters;
char *payload = "This message is from client\n";
int client_sock;
int port = CONFIG_OPENTHEAD_EXAMPLE_UDP_SERVER_PORT;
int err = 0;
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 };
inet6_aton(host_ip, &dest_addr.sin6_addr);
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(port);
client_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((client_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created, sending to %s:%d", host_ip, port);
err = sendto(client_sock, payload, strlen(payload), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
ESP_GOTO_ON_FALSE((err >= 0), ESP_FAIL, exit, TAG, "Error occurred during sending: errno %d", errno);
ESP_LOGI(TAG, "Message sent");
socklen_t socklen = sizeof(source_addr);
len = recvfrom(client_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
// Error occurred during receiving
ESP_GOTO_ON_FALSE((len >= 0), ESP_FAIL, exit, TAG, "recvfrom failed: errno %d", errno);
// Data received
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
ESP_LOGI(TAG, "Received %d bytes from %s:", len, host_ip);
ESP_LOGI(TAG, "%s", rx_buffer);
exit:
if (ret != ESP_OK || client_sock != -1) {
shutdown(client_sock, 0);
close(client_sock);
}
ESP_LOGI(TAG, "Socket client is closed");
vTaskDelete(NULL);
}
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);
(void)(aArgsLength);
if (aArgs[0] == NULL) {
ESP_LOGE(TAG, "Invalid arguments.");
} else {
xTaskCreate(udp_socket_client_task, "ot_udp_socket_client", 4096, aArgs[0], 4, NULL);
}
}
#endif // CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE

View File

@ -0,0 +1,37 @@
// Copyright 2021 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
/**
* @brief User command "udpsockserver" process.
*
*/
void esp_ot_process_udp_server(void *aContext, uint8_t aArgsLength, char *aArgs[]);
/**
* @brief Yser command "udpsockserver" process.
*
*/
void esp_ot_process_udp_client(void *aContext, uint8_t aArgsLength, char *aArgs[]);
#endif // CONFIG_OPENTHREAD_ENABLE_UDP_SOCKET_EXAMPLE
#ifdef __cplusplus
}
#endif