diff --git a/components/lwip/port/esp32/netif/openthreadif.c b/components/lwip/port/esp32/netif/openthreadif.c index 06c7bfe480..b71940948b 100644 --- a/components/lwip/port/esp32/netif/openthreadif.c +++ b/components/lwip/port/esp32/netif/openthreadif.c @@ -1,15 +1,19 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "freertos/FreeRTOS.h" #include "esp_netif.h" #include "esp_netif_net_stack.h" +#include "lwip/err.h" #include "lwip/netif.h" #include "lwip/pbuf.h" #include "netif/openthreadif.h" +#include "esp_openthread.h" +#include "esp_openthread_lock.h" #include "openthread/error.h" #include "openthread/ip6.h" #include "openthread/link.h" @@ -47,7 +51,7 @@ static err_t openthread_output_ip6(struct netif *netif, struct pbuf *p, const st pbuf_free(q); } /* Check error */ - switch(ret) { + switch (ret) { case ESP_ERR_NO_MEM: return ERR_MEM; @@ -92,6 +96,34 @@ void openthread_netif_input(void *h, void *buffer, size_t len, void *eb) /* the pbuf will be free in upper layer, eg: tcpip_input */ } +static err_t openthread_netif_multicast_handler(struct netif *netif, + const ip6_addr_t *group, enum netif_mac_filter_action action) +{ + otError error = OT_ERROR_NONE; + otIp6Address multicast_addr; + + memcpy(multicast_addr.mFields.m8, group->addr, sizeof(group->addr)); + esp_openthread_lock_acquire(portMAX_DELAY); + if (action == NETIF_ADD_MAC_FILTER) { + error = otIp6SubscribeMulticastAddress(esp_openthread_get_instance(), &multicast_addr); + } else { + error = otIp6UnsubscribeMulticastAddress(esp_openthread_get_instance(), &multicast_addr); + } + esp_openthread_lock_release(); + switch (error) { + case OT_ERROR_NONE: + case OT_ERROR_ALREADY: + return ERR_OK; + case OT_ERROR_NO_BUFS: + return ERR_MEM; + case OT_ERROR_INVALID_ARGS: + return ERR_ARG; + default: + return ERR_IF; + } +} + + err_t openthread_netif_init(struct netif *netif) { netif->name[0] = 'o'; @@ -102,6 +134,7 @@ err_t openthread_netif_init(struct netif *netif) netif->flags = NETIF_FLAG_BROADCAST; netif->output = NULL; netif->output_ip6 = openthread_output_ip6; + netif->mld_mac_filter = openthread_netif_multicast_handler; netif->l2_buffer_free_notify = NULL; netif_set_link_up(netif); diff --git a/examples/openthread/ot_cli/main/esp_ot_cli.c b/examples/openthread/ot_cli/main/esp_ot_cli.c index 0d5e321dbe..863664a585 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0 + * SPDX-License-Identifier: CC0-1.0 * * OpenThread Command Line Example * @@ -14,6 +14,7 @@ #include #include +#include #include "esp_err.h" #include "esp_event.h" @@ -29,7 +30,6 @@ #include "esp_vfs_eventfd.h" #include "driver/uart.h" #include "freertos/FreeRTOS.h" -#include "freertos/portmacro.h" #include "freertos/task.h" #include "hal/uart_types.h" #include "openthread/cli.h" diff --git a/examples/openthread/ot_cli/main/esp_ot_cli_extension.c b/examples/openthread/ot_cli/main/esp_ot_cli_extension.c index f218535851..384e35ae50 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli_extension.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli_extension.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0 + * SPDX-License-Identifier: CC0-1.0 * * OpenThread Command Line Example * @@ -27,6 +27,7 @@ static const otCliCommand kCommands[] = { {"tcpsockclient", esp_ot_process_tcp_client}, {"udpsockserver", esp_ot_process_udp_server}, {"udpsockclient", esp_ot_process_udp_client}, + {"mcast", esp_ot_process_mcast_group}, {"iperf", esp_ot_process_iperf} }; diff --git a/examples/openthread/ot_cli/main/esp_ot_udp_socket.c b/examples/openthread/ot_cli/main/esp_ot_udp_socket.c index 39b167f817..002b319760 100644 --- a/examples/openthread/ot_cli/main/esp_ot_udp_socket.c +++ b/examples/openthread/ot_cli/main/esp_ot_udp_socket.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0 + * SPDX-License-Identifier: CC0-1.0 * * OpenThread Command Line Example * @@ -15,8 +15,11 @@ #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 "lwip/err.h" +#include "lwip/mld6.h" #include "lwip/sockets.h" #define TAG "ot_socket" @@ -94,6 +97,7 @@ static void udp_socket_client_task(void *pvParameters) esp_err_t ret = ESP_OK; struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 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); dest_addr.sin6_family = AF_INET6; @@ -103,6 +107,8 @@ static void udp_socket_client_task(void *pvParameters) 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); + setsockopt(client_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &netif_index, sizeof(netif_index)); + 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"); @@ -135,10 +141,30 @@ void esp_ot_process_udp_server(void *aContext, uint8_t aArgsLength, char *aArgs[ void esp_ot_process_udp_client(void *aContext, uint8_t aArgsLength, char *aArgs[]) { (void)(aContext); - (void)(aArgsLength); if (aArgsLength == 0) { ESP_LOGE(TAG, "Invalid arguments."); } else { xTaskCreate(udp_socket_client_task, "ot_udp_socket_client", 4096, aArgs[0], 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) ) { + ESP_LOGE(TAG, "Invalid arguments: mcast [join|leave] group_address"); + return; + } + + ip6_addr_t group; + inet6_aton(aArgs[1], &group); + struct netif *netif = netif_get_by_index(esp_netif_get_netif_impl_index(esp_netif_get_handle_from_ifkey("OT_DEF"))); + if (strncmp(aArgs[0], "join", 4) == 0) { + if (mld6_joingroup_netif(netif, &group) != ERR_OK) { + ESP_LOGE(TAG, "Failed to join group"); + } + } else { + if (mld6_leavegroup_netif(netif, &group) != ERR_OK) { + ESP_LOGE(TAG, "Failed to leave group"); + } + } +} diff --git a/examples/openthread/ot_cli/main/esp_ot_udp_socket.h b/examples/openthread/ot_cli/main/esp_ot_udp_socket.h index 97f9945dfd..4678102799 100644 --- a/examples/openthread/ot_cli/main/esp_ot_udp_socket.h +++ b/examples/openthread/ot_cli/main/esp_ot_udp_socket.h @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0 + * SPDX-License-Identifier: CC0-1.0 * * OpenThread Command Line Example * @@ -14,10 +14,18 @@ #pragma once +#include + #ifdef __cplusplus extern "C" { #endif +/** + * @brief User command "mcast" process. + * + */ +void esp_ot_process_mcast_group(void *aContext, uint8_t aArgsLength, char *aArgs[]); + /** * @brief User command "udpsockserver" process. *