diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index ffd461169b..ac195606a3 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -179,6 +179,13 @@ menu "OpenThread" help Select this option to acquire NAT64 address from dns servers. + config OPENTHREAD_DNS_SERVER_ADDR + string "DNS server address (IPv4)" + depends on OPENTHREAD_DNS64_CLIENT + default "8.8.8.8" + help + Set the DNS server IPv4 address. + config OPENTHREAD_UART_BUFFER_SIZE int "The uart received buffer size of openthread" depends on OPENTHREAD_ENABLED diff --git a/components/openthread/include/esp_openthread_dns64.h b/components/openthread/include/esp_openthread_dns64.h index fafa7b4af2..8c8bb15795 100644 --- a/components/openthread/include/esp_openthread_dns64.h +++ b/components/openthread/include/esp_openthread_dns64.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,28 @@ extern "C" { #endif +/** + * @brief This function initiizes the dns64 client. + * + * @return + * - ESP_OK on success + * - ESP_FAIL if OpenThread state changed callback fails to be registered + * + */ +esp_err_t esp_openthread_dns64_client_init(void); + +/** + * @brief This function acquires the DNS server address. + * + * @param[out] dnsserver_addr The dns server address. + * + * @return + * - ESP_OK on sussess + * - ESP_ERR_INVALID_ARG if dnsserver_addr is NULL + * - ESP_ERR_INVALID_STATE if dns sever address not available + */ +esp_err_t esp_openthread_get_dnsserver_addr(ip6_addr_t *dnsserver_addr); + /** * @brief This function acquires the NAT64 prefix in the Thread network. * diff --git a/components/openthread/include/esp_openthread_types.h b/components/openthread/include/esp_openthread_types.h index a6903280ab..5923814fb4 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -37,6 +37,7 @@ typedef enum { OPENTHREAD_EVENT_TREL_ADD_IP6, /*!< OpenThread stack added TREL IPv6 address */ OPENTHREAD_EVENT_TREL_REMOVE_IP6, /*!< OpenThread stack removed TREL IPv6 address */ OPENTHREAD_EVENT_TREL_MULTICAST_GROUP_JOIN, /*!< OpenThread stack joined TREL IPv6 multicast group */ + OPENTHREAD_EVENT_SET_DNS_SERVER, /*!< OpenThread stack set DNS server >*/ } esp_openthread_event_t; /** diff --git a/components/openthread/port/esp_openthread.cpp b/components/openthread/port/esp_openthread.cpp index c4b1f00405..5c0b34c4a8 100644 --- a/components/openthread/port/esp_openthread.cpp +++ b/components/openthread/port/esp_openthread.cpp @@ -8,6 +8,7 @@ #include "esp_check.h" #include "esp_openthread_border_router.h" #include "esp_openthread_common_macro.h" +#include "esp_openthread_dns64.h" #include "esp_openthread_lock.h" #include "esp_openthread_platform.h" #include "esp_openthread_task_queue.h" @@ -25,6 +26,10 @@ esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) esp_openthread_lock_acquire(portMAX_DELAY); ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to initialize OpenThread instance"); +#if CONFIG_OPENTHREAD_DNS64_CLIENT + ESP_RETURN_ON_ERROR(esp_openthread_dns64_client_init(), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread dns64 client"); +#endif esp_openthread_lock_release(); return ESP_OK; diff --git a/components/openthread/port/esp_openthread_dns64.c b/components/openthread/port/esp_openthread_dns64.c index ed767234fa..cdece8334a 100644 --- a/components/openthread/port/esp_openthread_dns64.c +++ b/components/openthread/port/esp_openthread_dns64.c @@ -1,18 +1,62 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_openthread_dns64.h" +#include "esp_check.h" +#include "esp_event.h" #include "esp_log.h" #include "openthread/instance.h" #include "openthread/netdata.h" #include "lwip_default_hooks.h" #include "lwip/api.h" +#include "lwip/dns.h" #define TAG "OT_DNS64" +// The network data change callback sets the dns server address of index 0, while the CLI sets the dns server address of index 1. +#define OPENTHREAD_DNS_SERVER_INDEX 0 + +static void esp_openthread_netdata_change_callback(otChangedFlags changed_flags, void *ctx) +{ + if (OT_CHANGED_THREAD_NETDATA & changed_flags) { + ip_addr_t dns_server_addr = *IP_ADDR_ANY; + if (esp_openthread_get_nat64_prefix(&dns_server_addr.u_addr.ip6) == ESP_OK) { + dns_server_addr.type = IPADDR_TYPE_V6; + dns_server_addr.u_addr.ip6.addr[3] = ipaddr_addr(CONFIG_OPENTHREAD_DNS_SERVER_ADDR); + const ip_addr_t *dnsserver = dns_getserver(OPENTHREAD_DNS_SERVER_INDEX); + if (memcmp(dnsserver, &dns_server_addr, sizeof(ip_addr_t)) != 0) { + ESP_LOGI(TAG, "Set dns server address: %s", ipaddr_ntoa(&dns_server_addr)); + dns_setserver(OPENTHREAD_DNS_SERVER_INDEX, &dns_server_addr); + if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_SET_DNS_SERVER, NULL, 0, 0) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post OpenThread set DNS server event"); + } + } + } + } +} + +esp_err_t esp_openthread_dns64_client_init(void) +{ + otInstance *instance = esp_openthread_get_instance(); + ESP_RETURN_ON_FALSE(otSetStateChangedCallback(instance, esp_openthread_netdata_change_callback, NULL) == + OT_ERROR_NONE, + ESP_FAIL, TAG, "Failed to install network data change callback"); + dns_setserver(OPENTHREAD_DNS_SERVER_INDEX, NULL); + return ESP_OK; +} + +esp_err_t esp_openthread_get_dnsserver_addr(ip6_addr_t *dnsserver_addr) +{ + const ip_addr_t *dnsserver = dns_getserver(OPENTHREAD_DNS_SERVER_INDEX); + ESP_RETURN_ON_FALSE(dnsserver_addr, ESP_ERR_INVALID_ARG, TAG, "dnsserver_addr cannot be NULL"); + ESP_RETURN_ON_FALSE(!ip_addr_isany(dnsserver), ESP_ERR_INVALID_STATE, TAG, + "DNS server address is not set"); + memcpy(dnsserver_addr, &dnsserver->u_addr.ip6, sizeof(ip6_addr_t)); + return ESP_OK; +} esp_err_t esp_openthread_get_nat64_prefix(ip6_addr_t *nat64_prefix) {