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.
This commit is contained in:
Jiacheng Guo 2021-12-21 16:53:20 +08:00
parent b886dc6998
commit d610282742
5 changed files with 80 additions and 12 deletions

View File

@ -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 <string.h>
#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);

View File

@ -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 <stdio.h>
#include <unistd.h>
#include <string.h>
#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"

View File

@ -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}
};

View File

@ -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");
}
}
}

View File

@ -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 <stdint.h>
#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.
*