From d610282742ad3333054141872c44914dd54fab52 Mon Sep 17 00:00:00 2001 From: Jiacheng Guo Date: Tue, 21 Dec 2021 16:53:20 +0800 Subject: [PATCH] openthread: sync lwip multicast groups to Thread stack This MR synchornizes the lwIP multicast groups to the Thread stack. This will fix sockets failing to receive messages sent to multicast groups issue. --- .../lwip/port/esp32/netif/openthreadif.c | 37 ++++++++++++++++++- examples/openthread/ot_cli/main/esp_ot_cli.c | 6 +-- .../ot_cli/main/esp_ot_cli_extension.c | 5 ++- .../ot_cli/main/esp_ot_udp_socket.c | 32 ++++++++++++++-- .../ot_cli/main/esp_ot_udp_socket.h | 12 +++++- 5 files changed, 80 insertions(+), 12 deletions(-) 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. *