mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-03 21:56:40 +02:00
Compare commits
17 Commits
websocket-
...
mdns-v1.2.
Author | SHA1 | Date | |
---|---|---|---|
96f4ebd994 | |||
247ca41bb7 | |||
891384cc53 | |||
38ef603296 | |||
312982e4aa | |||
d9d377133e | |||
110536ebb2 | |||
5ba7cfab8e | |||
2f7c58259d | |||
f42c0adfc0 | |||
2782277f3f | |||
3225f40c22 | |||
68ce794098 | |||
1dc4299eb0 | |||
ce7daddc77 | |||
5000a9a20a | |||
2646dcd23a |
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(modem): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_modem
|
||||
tag_format: modem-v$version
|
||||
version: 1.0.5
|
||||
version: 1.1.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## [1.1.0](https://github.com/espressif/esp-protocols/commits/modem-v1.1.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Added support for at_raw() command ([ae38110](https://github.com/espressif/esp-protocols/commit/ae38110), [#471](https://github.com/espressif/esp-protocols/issues/471))
|
||||
- Added iperf test for PPP netifs ([976e98d](https://github.com/espressif/esp-protocols/commit/976e98d))
|
||||
- Added test that performs OTA to exercise modem layers ([f2223dd](https://github.com/espressif/esp-protocols/commit/f2223dd))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed OTA test to gracefully fail with no verification ([1dc4299](https://github.com/espressif/esp-protocols/commit/1dc4299))
|
||||
- Added C-API to configure APN ([ce7dadd](https://github.com/espressif/esp-protocols/commit/ce7dadd), [#485](https://github.com/espressif/esp-protocols/issues/485))
|
||||
- Fixed AT commands to copy strings to prevent overrides ([741d166](https://github.com/espressif/esp-protocols/commit/741d166), [#463](https://github.com/espressif/esp-protocols/issues/463))
|
||||
- Fixed incorrect dial command format ([0998f3d](https://github.com/espressif/esp-protocols/commit/0998f3d), [#433](https://github.com/espressif/esp-protocols/issues/433))
|
||||
- Fixed documentation and example on creating custom device ([577de67](https://github.com/espressif/esp-protocols/commit/577de67), [#452](https://github.com/espressif/esp-protocols/issues/452))
|
||||
- Removed CI jobs for IDF v4.2 ([d88cd61](https://github.com/espressif/esp-protocols/commit/d88cd61))
|
||||
- Fixed OAT test to verify server cert and CN ([edc3e72](https://github.com/espressif/esp-protocols/commit/edc3e72))
|
||||
- Fixed set_pdp_context() command timeout ([1d80cbc](https://github.com/espressif/esp-protocols/commit/1d80cbc), [#455](https://github.com/espressif/esp-protocols/issues/455))
|
||||
|
||||
### Updated
|
||||
|
||||
- docs(modem): Added description of manual test procedure ([68ce794](https://github.com/espressif/esp-protocols/commit/68ce794))
|
||||
|
||||
## [1.0.5](https://github.com/espressif/esp-protocols/commits/modem-v1.0.5)
|
||||
|
||||
### Major changes
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.0.5"
|
||||
version: "1.1.0"
|
||||
description: Library for communicating with cellular modems in command and data modes
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
|
||||
issues: https://github.com/espressif/esp-protocols/issues
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -119,8 +119,27 @@ esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce, esp_modem_terminal_error_
|
||||
*/
|
||||
esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce, esp_modem_dce_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Convenient function to run arbitrary commands from C-API
|
||||
*
|
||||
* @param dce Modem DCE handle
|
||||
* @param command Command to send
|
||||
* @param got_line_cb Callback function which is called whenever we receive a line
|
||||
* @param timeout_ms Command timeout
|
||||
* @return ESP_OK on success, ESP_FAIL on failure
|
||||
*/
|
||||
|
||||
esp_err_t esp_modem_command(esp_modem_dce_t *dce, const char *command, esp_err_t(*got_line_cb)(uint8_t *data, size_t len), uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Sets the APN and configures it into the modem's PDP context
|
||||
*
|
||||
* @param dce Modem DCE handle
|
||||
* @param apn Access Point Name
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_modem_set_apn(esp_modem_dce_t *dce, const char *apn);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -448,3 +448,10 @@ extern "C" esp_err_t esp_modem_set_baud(esp_modem_dce_t *dce_wrap, int baud)
|
||||
{
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_baud(baud));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_apn(esp_modem_dce_t *dce_wrap, const char *apn)
|
||||
{
|
||||
auto new_pdp = std::unique_ptr<PdpContext>(new PdpContext(apn));
|
||||
dce_wrap->dce->get_module()->configure_pdp_context(std::move(new_pdp));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
47
components/esp_modem/test/README.md
Normal file
47
components/esp_modem/test/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# ESP-Modem Testing
|
||||
|
||||
This folder contains automated and manual tests for esp-modem component. Beside these tests, some jobs are executed in CI to exercise standard examples (please refer to the CI definition and CI related sdkconfigs in examples).
|
||||
|
||||
List of test projects:
|
||||
|
||||
* `host_test` -- esp_modem is build on host (linux), modem's terminal in mocked using Loobpack class which creates simple responders to AT and CMUX mode. This test is executed in CI.
|
||||
* `target` -- test executed on target with no modem device, just a pppd running on the test runner. This test is executed in CI.
|
||||
* `target_ota` -- Manual test which perform OTA over PPP.
|
||||
* `target_iperf` -- Manual test to measure data throughput via PPP.
|
||||
|
||||
## Manual testing
|
||||
|
||||
Prior to every `esp_modem` release, these manual tests must be executed and pass
|
||||
(IDF-9074 to move the manual tests to CI)
|
||||
|
||||
### `target_ota`
|
||||
|
||||
Make sure that the UART ISR is not in IRAM, so the error messages are expected in the log, but the ESP32 should recover and continue with downloading the image.
|
||||
|
||||
Perform the test for these devices
|
||||
* SIM7600 (CMUX mode)
|
||||
* BG96 (CMUX mode)
|
||||
* SIM7000 (PPP mode)
|
||||
* A7672 (CMUX mode -- the only device with 2 byte CMUX payload), so the test is expected to fail more often if (`CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD=y` && `CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED=n` && dte_buffer < device max payload)
|
||||
* NetworkDCE -- no modem device, pppd (PPP mode)
|
||||
|
||||
Perform the test with these configurations:
|
||||
* CONFIG_TEST_USE_VFS_TERM (y/n)
|
||||
* CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT (y/n)
|
||||
* CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD (y/n)
|
||||
* CONFIG_ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED (y/n)
|
||||
|
||||
**Criteria for passing the test**
|
||||
|
||||
The test should complete the download with maximum 1 retry (50% of OTA failure)
|
||||
In case of CMUX mode, we're trying to exit CMUX at the end of the test. This step might also fail for some devices, as the CMUX-exit is not supported on certain devices (when the final error message appears that the device failed to exit CMUX, we just verify the new image by reseting the ESP32)
|
||||
|
||||
### `target_iperf`
|
||||
|
||||
Run these 4 `iperf` configurations (either manually or using `pytest`):
|
||||
* tcp_tx_throughput
|
||||
* tcp_rx_throughput
|
||||
* udp_tx_throughput
|
||||
* udp_rx_throughput
|
||||
|
||||
And verify in all four cases the value is about 0.70 Mbps
|
@ -35,6 +35,10 @@ bool manual_ota::begin()
|
||||
esp_transport_handle_t tcp = esp_transport_tcp_init();
|
||||
ssl_ = esp_transport_batch_tls_init(tcp, max_buffer_size_);
|
||||
http_.config_.transport = ssl_;
|
||||
if (http_.config_.cert_pem == nullptr || common_name_ == nullptr) {
|
||||
ESP_LOGE(TAG, "TLS with no verification is not supported");
|
||||
return fail();
|
||||
}
|
||||
if (!esp_transport_batch_set_ca_cert(ssl_, http_.config_.cert_pem, 0)) {
|
||||
return fail();
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
/**
|
||||
* @brief Set common name of the server to verify
|
||||
*/
|
||||
const char *common_name_;
|
||||
const char *common_name_{};
|
||||
/**
|
||||
* @brief Wrapper around the http client -- Please set the http config
|
||||
*/
|
||||
|
35
components/esp_websocket_client/examples/linux/README.md
Normal file
35
components/esp_websocket_client/examples/linux/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# ESP Websocket Client - Host Example
|
||||
|
||||
This example demonstrates the ESP websocket client using the `linux` target. It allows for compilation and execution of the example directly within a Linux environment.
|
||||
|
||||
## Compilation and Execution
|
||||
|
||||
To compile and execute this example on Linux need to set target `linux`
|
||||
|
||||
```
|
||||
idf.py --preview set-target linux
|
||||
idf.py build
|
||||
./websocket.elf
|
||||
```
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
I (164532) websocket: [APP] Startup..
|
||||
I (164532) websocket: [APP] Free memory: 4294967295 bytes
|
||||
I (164532) websocket: [APP] IDF version: v5.3-dev-1353-gb3f7e2c8a4
|
||||
I (164538) websocket: Connecting to ws://echo.websocket.events...
|
||||
W (164538) websocket_client: `reconnect_timeout_ms` is not set, or it is less than or equal to zero, using default time out 10000 (milliseconds)
|
||||
W (164538) websocket_client: `network_timeout_ms` is not set, or it is less than or equal to zero, using default time out 10000 (milliseconds)
|
||||
I (165103) websocket: WEBSOCKET_EVENT_CONNECTED
|
||||
I (165539) websocket: Sending hello 0000
|
||||
I (165627) websocket: WEBSOCKET_EVENT_DATA
|
||||
I (165627) websocket: Received opcode=1
|
||||
W (165627) websocket: Received=hello 0000
|
||||
W (165627) websocket: Total payload length=10, data_len=10, current payload offset=0
|
||||
|
||||
I (166539) websocket: Sending fragmented message
|
||||
```
|
||||
|
||||
## Coverage Reporting
|
||||
For generating a coverage report, it's necessary to enable `CONFIG_GCOV_ENABLED=y` option. Set the following configuration in your project's SDK configuration file (`sdkconfig.ci.coverage`, `sdkconfig.ci.linux` or via `menuconfig`):
|
@ -1,3 +1,4 @@
|
||||
dependencies:
|
||||
idf: ">5.2"
|
||||
protocol_examples_common:
|
||||
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
|
||||
|
@ -4,5 +4,3 @@ CONFIG_IDF_TARGET_LINUX=y
|
||||
CONFIG_ESP_EVENT_POST_FROM_ISR=n
|
||||
CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=n
|
||||
CONFIG_WEBSOCKET_URI="ws://echo.websocket.events"
|
||||
CONFIG_WEBSOCKET_URI_FROM_STRING=y
|
||||
CONFIG_WEBSOCKET_URI_FROM_STDIN=n
|
||||
|
@ -3,6 +3,3 @@ CONFIG_IDF_TARGET_LINUX=y
|
||||
CONFIG_ESP_EVENT_POST_FROM_ISR=n
|
||||
CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=n
|
||||
CONFIG_WEBSOCKET_URI="ws://echo.websocket.events"
|
||||
CONFIG_WEBSOCKET_URI_FROM_STRING=y
|
||||
CONFIG_WEBSOCKET_URI_FROM_STDIN=n
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
|
@ -0,0 +1,5 @@
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_IDF_TARGET_LINUX=y
|
||||
CONFIG_ESP_EVENT_POST_FROM_ISR=n
|
||||
CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=n
|
||||
CONFIG_WEBSOCKET_URI="ws://echo.websocket.events"
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(mdns): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py mdns
|
||||
tag_format: mdns-v$version
|
||||
version: 1.2.3
|
||||
version: 1.2.4
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## [1.2.4](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.4)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Correction on 6d2c475 MDNS_PREDEF_NETIF_ETH fix ([fc59f87c4e](https://github.com/espressif/esp-protocols/commit/fc59f87c4e))
|
||||
- fix the logic of creating pcb for networking socket ([5000a9a20a](https://github.com/espressif/esp-protocols/commit/5000a9a20a))
|
||||
- fix compiling issue when disabling IPv4 ([2646dcd23a](https://github.com/espressif/esp-protocols/commit/2646dcd23a))
|
||||
- Fix compile error when MDNS_PREDEF_NETIF_ETH is defined, but ETH_ENABLED is not (#459) ([6d2c475c20](https://github.com/espressif/esp-protocols/commit/6d2c475c20))
|
||||
|
||||
## [1.2.3](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.3)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -21,6 +21,12 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "netdb.h"
|
||||
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
/* CONFIG_LWIP_IPV4 was introduced in IDF v5.1, set CONFIG_LWIP_IPV4 to 1 by default for IDF v5.0 */
|
||||
#ifndef CONFIG_LWIP_IPV4
|
||||
#define CONFIG_LWIP_IPV4 1
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
|
||||
#define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE
|
||||
#define EXAMPLE_BUTTON_GPIO CONFIG_MDNS_BUTTON_GPIO
|
||||
@ -227,7 +233,7 @@ static void query_mdns_hosts_async(const char *host_name)
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
static void query_mdns_host(const char *host_name)
|
||||
{
|
||||
ESP_LOGI(TAG, "Query A: %s.local", host_name);
|
||||
@ -247,6 +253,7 @@ static void query_mdns_host(const char *host_name)
|
||||
|
||||
ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
|
||||
}
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
|
||||
static void initialise_button(void)
|
||||
{
|
||||
@ -265,7 +272,9 @@ static void check_button(void)
|
||||
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
|
||||
if (!new_level && old_level) {
|
||||
query_mdns_hosts_async("esp32-mdns");
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
query_mdns_host("esp32");
|
||||
#endif
|
||||
query_mdns_service("_arduino", "_tcp");
|
||||
query_mdns_service("_http", "_tcp");
|
||||
query_mdns_service("_printer", "_tcp");
|
||||
@ -286,7 +295,9 @@ static void mdns_example_task(void *pvParameters)
|
||||
{
|
||||
#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1
|
||||
/* Send initial queries that are started by CI tester */
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
query_mdns_host("tinytester");
|
||||
#endif
|
||||
query_mdns_host_with_gethostbyname("tinytester-lwip.local");
|
||||
query_mdns_host_with_getaddrinfo("tinytester-lwip.local");
|
||||
#endif
|
||||
@ -362,7 +373,16 @@ static void query_mdns_host_with_gethostbyname(char *host)
|
||||
if (res) {
|
||||
unsigned int i = 0;
|
||||
while (res->h_addr_list[i] != NULL) {
|
||||
ESP_LOGI(TAG, "gethostbyname: %s resolved to: %s", host, inet_ntoa(*(struct in_addr *) (res->h_addr_list[i])));
|
||||
ESP_LOGI(TAG, "gethostbyname: %s resolved to: %s", host,
|
||||
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4)
|
||||
res->h_addrtype == AF_INET ? inet_ntoa(*(struct in_addr *) (res->h_addr_list[i])) :
|
||||
inet6_ntoa(*(struct in6_addr *) (res->h_addr_list[i]))
|
||||
#elif defined(CONFIG_LWIP_IPV6)
|
||||
inet6_ntoa(*(struct in6_addr *) (res->h_addr_list[i]))
|
||||
#else
|
||||
inet_ntoa(*(struct in_addr *) (res->h_addr_list[i]))
|
||||
#endif
|
||||
);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -384,10 +404,12 @@ static void query_mdns_host_with_getaddrinfo(char *host)
|
||||
if (!getaddrinfo(host, NULL, &hints, &res)) {
|
||||
while (res) {
|
||||
char *resolved_addr;
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4)
|
||||
resolved_addr = res->ai_family == AF_INET ?
|
||||
inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr) :
|
||||
inet_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
|
||||
inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
|
||||
#elif defined(CONFIG_LWIP_IPV6)
|
||||
resolved_addr = inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
|
||||
#else
|
||||
resolved_addr = inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr);
|
||||
#endif // CONFIG_LWIP_IPV6
|
||||
|
@ -87,26 +87,30 @@ def mdns_server(esp_host, events):
|
||||
continue
|
||||
data, addr = sock.recvfrom(1024)
|
||||
dns = dpkt.dns.DNS(data)
|
||||
if len(dns.qd) > 0 and dns.qd[0].type == dpkt.dns.DNS_A:
|
||||
if dns.qd[0].name == TESTER_NAME:
|
||||
print('Received query: {} '.format(dns.__repr__()))
|
||||
sock.sendto(get_dns_answer_to_mdns(TESTER_NAME),
|
||||
(MCAST_GRP, UDP_PORT))
|
||||
elif dns.qd[0].name == TESTER_NAME_LWIP:
|
||||
print('Received query: {} '.format(dns.__repr__()))
|
||||
sock.sendto(
|
||||
get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id),
|
||||
addr)
|
||||
if len(dns.an) > 0 and dns.an[0].type == dpkt.dns.DNS_A:
|
||||
print('Received answer from {}'.format(dns.an[0].name))
|
||||
if dns.an[0].name == esp_host + u'.local':
|
||||
print('Received answer to esp32-mdns query: {}'.format(
|
||||
dns.__repr__()))
|
||||
events['esp_answered'].set()
|
||||
if dns.an[0].name == esp_host + u'-delegated.local':
|
||||
print('Received answer to esp32-mdns-delegate query: {}'.
|
||||
format(dns.__repr__()))
|
||||
events['esp_delegated_answered'].set()
|
||||
if len(dns.qd) > 0:
|
||||
for dns_query in dns.qd:
|
||||
if dns_query.type == dpkt.dns.DNS_A:
|
||||
if dns_query.name == TESTER_NAME:
|
||||
print('Received query: {} '.format(dns.__repr__()))
|
||||
sock.sendto(get_dns_answer_to_mdns(TESTER_NAME),
|
||||
(MCAST_GRP, UDP_PORT))
|
||||
elif dns_query.name == TESTER_NAME_LWIP:
|
||||
print('Received query: {} '.format(dns.__repr__()))
|
||||
sock.sendto(
|
||||
get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id),
|
||||
addr)
|
||||
if len(dns.an) > 0:
|
||||
for dns_answer in dns.an:
|
||||
if dns_answer.type == dpkt.dns.DNS_A:
|
||||
print('Received answer from {}'.format(dns_answer.name))
|
||||
if dns_answer.name == esp_host + u'.local':
|
||||
print('Received answer to esp32-mdns query: {}'.format(
|
||||
dns.__repr__()))
|
||||
events['esp_answered'].set()
|
||||
if dns_answer.name == esp_host + u'-delegated.local':
|
||||
print('Received answer to esp32-mdns-delegate query: {}'.format(
|
||||
dns.__repr__()))
|
||||
events['esp_delegated_answered'].set()
|
||||
except socket.timeout:
|
||||
break
|
||||
except dpkt.UnpackError:
|
||||
@ -133,62 +137,66 @@ def test_examples_protocol_mdns(dut):
|
||||
}
|
||||
mdns_responder = Thread(target=mdns_server,
|
||||
args=(str(specific_host), mdns_server_events))
|
||||
ipv4 = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]',
|
||||
timeout=30)[1].decode()
|
||||
ip_addresses = [ipv4]
|
||||
ip_addresses = []
|
||||
if dut.app.sdkconfig.get('LWIP_IPV4') is True:
|
||||
ipv4 = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]',
|
||||
timeout=30)[1].decode()
|
||||
ip_addresses.append(ipv4)
|
||||
if dut.app.sdkconfig.get('LWIP_IPV6') is True:
|
||||
ipv6_r = r':'.join((r'[0-9a-fA-F]{4}', ) * 8)
|
||||
ipv6 = dut.expect(ipv6_r, timeout=30)[0].decode()
|
||||
ip_addresses.append(ipv6)
|
||||
print('Connected with IP addresses: {}'.format(','.join(ip_addresses)))
|
||||
try:
|
||||
# 3. check the mdns name is accessible.
|
||||
# TODO: Add test for example disabling IPV4
|
||||
mdns_responder.start()
|
||||
if not mdns_server_events['esp_answered'].wait(timeout=30):
|
||||
raise ValueError(
|
||||
'Test has failed: did not receive mdns answer within timeout')
|
||||
if not mdns_server_events['esp_delegated_answered'].wait(timeout=30):
|
||||
raise ValueError(
|
||||
'Test has failed: did not receive mdns answer for delegated host within timeout'
|
||||
if dut.app.sdkconfig.get('LWIP_IPV4') is True:
|
||||
# 3. check the mdns name is accessible.
|
||||
if not mdns_server_events['esp_answered'].wait(timeout=30):
|
||||
raise ValueError(
|
||||
'Test has failed: did not receive mdns answer within timeout')
|
||||
if not mdns_server_events['esp_delegated_answered'].wait(timeout=30):
|
||||
raise ValueError(
|
||||
'Test has failed: did not receive mdns answer for delegated host within timeout'
|
||||
)
|
||||
# 4. check DUT output if mdns advertized host is resolved
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: Query A: tinytester.local resolved to: 127.0.0.1')
|
||||
)
|
||||
# 4. check DUT output if mdns advertized host is resolved
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: Query A: tinytester.local resolved to: 127.0.0.1')
|
||||
)
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1'
|
||||
))
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1'
|
||||
))
|
||||
# 5. check the DUT answers to `dig` command
|
||||
dig_output = subprocess.check_output([
|
||||
'dig', '+short', '-p', '5353', '@224.0.0.251',
|
||||
'{}.local'.format(specific_host)
|
||||
])
|
||||
print('Resolving {} using "dig" succeeded with:\n{}'.format(
|
||||
specific_host, dig_output))
|
||||
if not ipv4.encode('utf-8') in dig_output:
|
||||
raise ValueError(
|
||||
'Test has failed: Incorrectly resolved DUT hostname using dig'
|
||||
"Output should've contained DUT's IP address:{}".format(ipv4))
|
||||
# 6. check the DUT reverse lookup
|
||||
if dut.app.sdkconfig.get('MDNS_RESPOND_REVERSE_QUERIES') is True:
|
||||
for ip_address in ip_addresses:
|
||||
dig_output = subprocess.check_output([
|
||||
'dig', '+short', '-p', '5353', '@224.0.0.251', '-x',
|
||||
'{}'.format(ip_address)
|
||||
])
|
||||
print('Reverse lookup for {} using "dig" succeeded with:\n{}'.
|
||||
format(ip_address, dig_output))
|
||||
if specific_host not in dig_output.decode():
|
||||
raise ValueError(
|
||||
'Test has failed: Incorrectly resolved DUT IP address using dig'
|
||||
"Output should've contained DUT's name:{}".format(
|
||||
specific_host))
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1'
|
||||
))
|
||||
dut.expect(
|
||||
re.compile(
|
||||
b'mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1'
|
||||
))
|
||||
# 5. check the DUT answers to `dig` command
|
||||
dig_output = subprocess.check_output([
|
||||
'dig', '+short', '-p', '5353', '@224.0.0.251',
|
||||
'{}.local'.format(specific_host)
|
||||
])
|
||||
print('Resolving {} using "dig" succeeded with:\n{}'.format(
|
||||
specific_host, dig_output))
|
||||
if not ipv4.encode('utf-8') in dig_output:
|
||||
raise ValueError(
|
||||
'Test has failed: Incorrectly resolved DUT hostname using dig'
|
||||
"Output should've contained DUT's IP address:{}".format(ipv4))
|
||||
# 6. check the DUT reverse lookup
|
||||
if dut.app.sdkconfig.get('MDNS_RESPOND_REVERSE_QUERIES') is True:
|
||||
for ip_address in ip_addresses:
|
||||
dig_output = subprocess.check_output([
|
||||
'dig', '+short', '-p', '5353', '@224.0.0.251', '-x',
|
||||
'{}'.format(ip_address)
|
||||
])
|
||||
print('Reverse lookup for {} using "dig" succeeded with:\n{}'.
|
||||
format(ip_address, dig_output))
|
||||
if specific_host not in dig_output.decode():
|
||||
raise ValueError(
|
||||
'Test has failed: Incorrectly resolved DUT IP address using dig'
|
||||
"Output should've contained DUT's name:{}".format(
|
||||
specific_host))
|
||||
|
||||
finally:
|
||||
mdns_server_events['stop'].set()
|
||||
|
@ -0,0 +1,15 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
|
||||
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
|
||||
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
|
||||
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
|
||||
CONFIG_LWIP_IPV4=n
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||
CONFIG_MDNS_BUTTON_GPIO=32
|
@ -1,4 +1,4 @@
|
||||
version: "1.2.3"
|
||||
version: "1.2.4"
|
||||
description: mDNS
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
|
||||
dependencies:
|
||||
|
@ -184,6 +184,11 @@ static inline void _mdns_clean_netif_ptr(mdns_if_t tcpip_if)
|
||||
static mdns_if_t _mdns_get_if_from_esp_netif(esp_netif_t *esp_netif)
|
||||
{
|
||||
for (int i = 0; i < MDNS_MAX_INTERFACES; ++i) {
|
||||
// The predefined netifs in the static array are NULL when firstly calling this function
|
||||
// if IPv4 is disabled. Set these netifs here.
|
||||
if (s_esp_netifs[i].netif == NULL && s_esp_netifs[i].predefined) {
|
||||
s_esp_netifs[i].netif = esp_netif_from_preset_if(s_esp_netifs[i].predef_if);
|
||||
}
|
||||
if (esp_netif == s_esp_netifs[i].netif) {
|
||||
return i;
|
||||
}
|
||||
@ -1059,6 +1064,7 @@ static uint16_t _mdns_append_srv_record(uint8_t *packet, uint16_t *index, mdns_s
|
||||
return record_length;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
/**
|
||||
* @brief appends A record to a packet, incrementing the index
|
||||
*
|
||||
@ -1108,8 +1114,9 @@ static uint16_t _mdns_append_a_record(uint8_t *packet, uint16_t *index, const ch
|
||||
record_length += 4;
|
||||
return record_length;
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
/**
|
||||
* @brief appends AAAA record to a packet, incrementing the index
|
||||
*
|
||||
@ -1232,7 +1239,7 @@ static bool _mdns_if_is_dup(mdns_if_t tcpip_if)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
/**
|
||||
* @brief Check if IPv6 address is NULL
|
||||
*/
|
||||
@ -1247,7 +1254,7 @@ static bool _ipv6_address_is_zero(esp_ip6_addr_t ip6)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
|
||||
static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_host_item_t *host,
|
||||
uint8_t address_type, bool flush, bool bye)
|
||||
@ -1257,17 +1264,19 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h
|
||||
|
||||
while (addr != NULL) {
|
||||
if (addr->addr.type == address_type) {
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (address_type == ESP_IPADDR_TYPE_V4 &&
|
||||
_mdns_append_a_record(packet, index, host->hostname, addr->addr.u_addr.ip4.addr, flush, bye) <= 0) {
|
||||
break;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (address_type == ESP_IPADDR_TYPE_V6 &&
|
||||
_mdns_append_aaaa_record(packet, index, host->hostname, (uint8_t *)addr->addr.u_addr.ip6.addr, flush,
|
||||
bye) <= 0) {
|
||||
break;
|
||||
}
|
||||
#endif // CONFIG_LWIP_IPV6
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
num_records++;
|
||||
}
|
||||
addr = addr->next;
|
||||
@ -1360,7 +1369,9 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
||||
return _mdns_append_txt_record(packet, index, answer->service, answer->flush, answer->bye) > 0;
|
||||
} else if (answer->type == MDNS_TYPE_SDPTR) {
|
||||
return _mdns_append_sdptr_record(packet, index, answer->service, answer->flush, answer->bye) > 0;
|
||||
} else if (answer->type == MDNS_TYPE_A) {
|
||||
}
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
else if (answer->type == MDNS_TYPE_A) {
|
||||
if (answer->host == &_mdns_self_host) {
|
||||
esp_netif_ip_info_t if_ip_info;
|
||||
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V4) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
|
||||
@ -1387,7 +1398,8 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
||||
return _mdns_append_host_answer(packet, index, answer->host, ESP_IPADDR_TYPE_V4, answer->flush, answer->bye);
|
||||
}
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
else if (answer->type == MDNS_TYPE_AAAA) {
|
||||
if (answer->host == &_mdns_self_host) {
|
||||
struct esp_ip6_addr if_ip6s[NETIF_IPV6_MAX_NUMS];
|
||||
@ -1425,7 +1437,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
||||
answer->bye);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1713,12 +1725,14 @@ static mdns_tx_packet_t *_mdns_alloc_packet_default(mdns_if_t tcpip_if, mdns_ip_
|
||||
packet->tcpip_if = tcpip_if;
|
||||
packet->ip_protocol = ip_protocol;
|
||||
packet->port = MDNS_SERVICE_PORT;
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
|
||||
esp_ip_addr_t addr = ESP_IP4ADDR_INIT(224, 0, 0, 251);
|
||||
memcpy(&packet->dst, &addr, sizeof(esp_ip_addr_t));
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else {
|
||||
#endif
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V6) {
|
||||
esp_ip_addr_t addr = ESP_IP6ADDR_INIT(0x000002ff, 0, 0, 0xfb000000);
|
||||
memcpy(&packet->dst, &addr, sizeof(esp_ip_addr_t));
|
||||
}
|
||||
@ -2877,6 +2891,7 @@ static void _mdns_dup_interface(mdns_if_t tcpip_if)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
/**
|
||||
* @brief Detect IPv4 address collision
|
||||
*/
|
||||
@ -2890,7 +2905,6 @@ static int _mdns_check_a_collision(esp_ip4_addr_t *ip, mdns_if_t tcpip_if)
|
||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
|
||||
return 1;//they win
|
||||
}
|
||||
|
||||
int ret = memcmp((uint8_t *)&if_ip_info.ip.addr, (uint8_t *)&ip->addr, sizeof(esp_ip4_addr_t));
|
||||
if (ret > 0) {
|
||||
return -1;//we win
|
||||
@ -2911,8 +2925,9 @@ static int _mdns_check_a_collision(esp_ip4_addr_t *ip, mdns_if_t tcpip_if)
|
||||
}
|
||||
return 0;//same
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
/**
|
||||
* @brief Detect IPv6 address collision
|
||||
*/
|
||||
@ -2946,7 +2961,7 @@ static int _mdns_check_aaaa_collision(esp_ip6_addr_t *ip, mdns_if_t tcpip_if)
|
||||
}
|
||||
return 0;//same
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
|
||||
static bool _hostname_is_ours(const char *hostname)
|
||||
{
|
||||
@ -3509,22 +3524,25 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
|
||||
#ifndef CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES
|
||||
// Check if the packet wasn't sent by us
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (packet->ip_protocol == MDNS_IP_PROTOCOL_V4) {
|
||||
esp_netif_ip_info_t if_ip_info;
|
||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(packet->tcpip_if), &if_ip_info) == ESP_OK &&
|
||||
memcmp(&if_ip_info.ip.addr, &packet->src.u_addr.ip4.addr, sizeof(esp_ip4_addr_t)) == 0) {
|
||||
return;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
} else {
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (packet->ip_protocol == MDNS_IP_PROTOCOL_V6) {
|
||||
struct esp_ip6_addr if_ip6;
|
||||
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(packet->tcpip_if), &if_ip6) == ESP_OK &&
|
||||
memcmp(&if_ip6, &packet->src.u_addr.ip6, sizeof(esp_ip6_addr_t)) == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
#endif // CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES
|
||||
|
||||
// Check for the minimum size of mdns packet
|
||||
if (len <= MDNS_HEAD_ADDITIONAL_OFFSET) {
|
||||
@ -3887,7 +3905,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
}
|
||||
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
else if (type == MDNS_TYPE_AAAA) {//ipv6
|
||||
esp_ip_addr_t ip6;
|
||||
ip6.type = ESP_IPADDR_TYPE_V6;
|
||||
@ -3940,7 +3958,8 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
else if (type == MDNS_TYPE_A) {
|
||||
esp_ip_addr_t ip;
|
||||
ip.type = ESP_IPADDR_TYPE_V4;
|
||||
@ -3993,6 +4012,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
}
|
||||
//end while
|
||||
if (parsed_packet->authoritative) {
|
||||
@ -4094,6 +4114,7 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (action & MDNS_EVENT_IP4_REVERSE_LOOKUP) {
|
||||
esp_netif_ip_info_t if_ip_info;
|
||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(mdns_if), &if_ip_info) == ESP_OK) {
|
||||
@ -4107,7 +4128,7 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (action & MDNS_EVENT_IP6_REVERSE_LOOKUP) {
|
||||
esp_ip6_addr_t addr6;
|
||||
@ -5483,22 +5504,25 @@ esp_err_t mdns_init(void)
|
||||
#endif
|
||||
|
||||
uint8_t i;
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
esp_ip6_addr_t tmp_addr6;
|
||||
#endif
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
esp_netif_ip_info_t if_ip_info;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (!esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(i), &tmp_addr6) && !_ipv6_address_is_zero(tmp_addr6)) {
|
||||
_mdns_enable_pcb(i, MDNS_IP_PROTOCOL_V6);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (!esp_netif_get_ip_info(_mdns_get_esp_netif(i), &if_ip_info) && if_ip_info.ip.addr) {
|
||||
_mdns_enable_pcb(i, MDNS_IP_PROTOCOL_V4);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_mdns_service_task_start()) {
|
||||
//service start failed!
|
||||
err = ESP_FAIL;
|
||||
@ -6468,6 +6492,7 @@ esp_err_t mdns_lookup_selfhosted_service(const char *instance, const char *servi
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
esp_err_t mdns_query_a(const char *name, uint32_t timeout, esp_ip4_addr_t *addr)
|
||||
{
|
||||
mdns_result_t *result = NULL;
|
||||
@ -6504,8 +6529,9 @@ esp_err_t mdns_query_a(const char *name, uint32_t timeout, esp_ip4_addr_t *addr)
|
||||
mdns_query_results_free(result);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
esp_err_t mdns_query_aaaa(const char *name, uint32_t timeout, esp_ip6_addr_t *addr)
|
||||
{
|
||||
mdns_result_t *result = NULL;
|
||||
@ -6542,7 +6568,7 @@ esp_err_t mdns_query_aaaa(const char *name, uint32_t timeout, esp_ip6_addr_t *ad
|
||||
mdns_query_results_free(result);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
|
||||
#ifdef MDNS_ENABLE_DEBUG
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,6 +8,7 @@
|
||||
#include "esp_console.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "mdns.h"
|
||||
#include "mdns_private.h"
|
||||
|
||||
static const char *ip_protocol_str[] = {"V4", "V6", "MAX"};
|
||||
|
||||
@ -50,6 +51,7 @@ static struct {
|
||||
struct arg_end *end;
|
||||
} mdns_query_a_args;
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
static int cmd_mdns_query_a(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &mdns_query_a_args);
|
||||
@ -106,8 +108,9 @@ static void register_mdns_query_a(void)
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
|
||||
}
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
static int cmd_mdns_query_aaaa(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &mdns_query_a_args);
|
||||
@ -164,7 +167,7 @@ static void register_mdns_query_aaaa(void)
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_LWIP_IPV6 */
|
||||
|
||||
static struct {
|
||||
struct arg_str *instance;
|
||||
@ -1042,8 +1045,10 @@ void mdns_console_register(void)
|
||||
register_mdns_service_txt_remove();
|
||||
register_mdns_service_remove_all();
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
register_mdns_query_a();
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#endif
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
register_mdns_query_aaaa();
|
||||
#endif
|
||||
register_mdns_query_txt();
|
||||
|
@ -96,6 +96,7 @@ static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protoco
|
||||
netif = esp_netif_get_netif_impl(tcpip_if);
|
||||
assert(netif);
|
||||
|
||||
#if LWIP_IPV4
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
|
||||
ip4_addr_t multicast_addr;
|
||||
IP4_ADDR(&multicast_addr, 224, 0, 0, 251);
|
||||
@ -110,21 +111,22 @@ static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protoco
|
||||
}
|
||||
}
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else {
|
||||
#endif // LWIP_IPV4
|
||||
#if LWIP_IPV6
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V6) {
|
||||
ip_addr_t multicast_addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000);
|
||||
|
||||
if (join) {
|
||||
if (mld6_joingroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
|
||||
if (mld6_joingroup_netif(netif, ip_2_ip6(&multicast_addr))) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
} else {
|
||||
if (mld6_leavegroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
|
||||
if (mld6_leavegroup_netif(netif, ip_2_ip6(&multicast_addr))) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LWIP_IPV6
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -152,29 +154,34 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
|
||||
packet->tcpip_if = MDNS_MAX_INTERFACES;
|
||||
packet->pb = this_pb;
|
||||
packet->src_port = rport;
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
packet->src.type = raddr->type;
|
||||
memcpy(&packet->src.u_addr, &raddr->u_addr, sizeof(raddr->u_addr));
|
||||
#else
|
||||
#elif LWIP_IPV4
|
||||
packet->src.type = IPADDR_TYPE_V4;
|
||||
memcpy(&packet->src.u_addr.ip4, &raddr->addr, sizeof(ip_addr_t));
|
||||
packet->src.u_addr.ip4.addr = raddr->addr;
|
||||
#elif LWIP_IPV6
|
||||
packet->src.type = IPADDR_TYPE_V6;
|
||||
memcpy(&packet->src.u_addr.ip6, raddr, sizeof(ip_addr_t));
|
||||
#endif
|
||||
packet->dest.type = packet->src.type;
|
||||
|
||||
#if LWIP_IPV4
|
||||
if (packet->src.type == IPADDR_TYPE_V4) {
|
||||
packet->ip_protocol = MDNS_IP_PROTOCOL_V4;
|
||||
struct ip_hdr *iphdr = (struct ip_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP_HLEN);
|
||||
packet->dest.u_addr.ip4.addr = iphdr->dest.addr;
|
||||
packet->multicast = ip4_addr_ismulticast(&(packet->dest.u_addr.ip4));
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else {
|
||||
#endif // LWIP_IPV4
|
||||
#if LWIP_IPV6
|
||||
if (packet->src.type == IPADDR_TYPE_V6) {
|
||||
packet->ip_protocol = MDNS_IP_PROTOCOL_V6;
|
||||
struct ip6_hdr *ip6hdr = (struct ip6_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP6_HLEN);
|
||||
memcpy(&packet->dest.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
|
||||
packet->multicast = ip6_addr_ismulticast(&(packet->dest.u_addr.ip6));
|
||||
}
|
||||
#endif
|
||||
#endif // LWIP_IPV6
|
||||
|
||||
//lwip does not return the proper pcb if you have more than one for the same multicast address (but different interfaces)
|
||||
struct netif *netif = NULL;
|
||||
@ -182,15 +189,14 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
|
||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
|
||||
if (s_interfaces[i].proto && netif && netif == ip_current_input_netif ()) {
|
||||
#if LWIP_IPV4
|
||||
if (packet->src.type == IPADDR_TYPE_V4) {
|
||||
#if CONFIG_LWIP_IPV6
|
||||
if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) {
|
||||
#else
|
||||
if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
|
||||
#endif //packet source is not in the same subnet
|
||||
if ((packet->src.u_addr.ip4.addr & ip_2_ip4(&netif->netmask)->addr) != (ip_2_ip4(&netif->ip_addr)->addr & ip_2_ip4(&netif->netmask)->addr)) {
|
||||
//packet source is not in the same subnet
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // LWIP_IPV4
|
||||
packet->tcpip_if = i;
|
||||
found = true;
|
||||
break;
|
||||
@ -347,12 +353,17 @@ size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, c
|
||||
memcpy((uint8_t *)pbt->payload, data, len);
|
||||
|
||||
ip_addr_t ip_add_copy;
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#if LWIP_IPV6 && LWIP_IPV4
|
||||
ip_add_copy.type = ip->type;
|
||||
memcpy(&(ip_add_copy.u_addr), &(ip->u_addr), sizeof(ip_add_copy.u_addr));
|
||||
#else
|
||||
memcpy(&(ip_add_copy.addr), &(ip->u_addr), sizeof(ip_add_copy.addr));
|
||||
#endif // CONFIG_LWIP_IPV6
|
||||
#elif LWIP_IPV4
|
||||
ip_add_copy.addr = ip->u_addr.ip4.addr;
|
||||
#elif LWIP_IPV6
|
||||
#if LWIP_IPV6_SCOPES
|
||||
ip_add_copy.zone = ip->u_addr.ip6.zone;
|
||||
#endif // LWIP_IPV6_SCOPES
|
||||
memcpy(ip_add_copy.addr, ip->u_addr.ip6.addr, sizeof(ip_add_copy.addr));
|
||||
#endif
|
||||
|
||||
mdns_api_call_t msg = {
|
||||
.tcpip_if = tcpip_if,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -138,11 +138,13 @@ static inline char *get_string_address(struct sockaddr_storage *source_addr)
|
||||
static char address_str[40]; // 40=(8*4+7+term) is the max size of ascii IPv6 addr "XXXX:XX...XX:XXXX"
|
||||
char *res = NULL;
|
||||
// Convert ip address to string
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (source_addr->ss_family == PF_INET) {
|
||||
res = inet_ntoa_r(((struct sockaddr_in *)source_addr)->sin_addr, address_str, sizeof(address_str));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
else if (source_addr->ss_family == PF_INET6) {
|
||||
if (source_addr->ss_family == PF_INET6) {
|
||||
res = inet6_ntoa_r(((struct sockaddr_in6 *)source_addr)->sin6_addr, address_str, sizeof(address_str));
|
||||
}
|
||||
#endif
|
||||
@ -157,6 +159,7 @@ static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t p
|
||||
{
|
||||
size_t ss_addr_len = 0;
|
||||
memset(in_addr, 0, sizeof(struct sockaddr_storage));
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V4 && addr->type == ESP_IPADDR_TYPE_V4) {
|
||||
in_addr->ss_family = PF_INET;
|
||||
#if !defined(CONFIG_IDF_TARGET_LINUX)
|
||||
@ -167,8 +170,9 @@ static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t p
|
||||
in_addr_ip4->sin_port = port;
|
||||
in_addr_ip4->sin_addr.s_addr = addr->u_addr.ip4.addr;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else if (ip_protocol == MDNS_IP_PROTOCOL_V6 && addr->type == ESP_IPADDR_TYPE_V6) {
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V6 && addr->type == ESP_IPADDR_TYPE_V6) {
|
||||
memset(in_addr, 0, sizeof(struct sockaddr_storage));
|
||||
in_addr->ss_family = PF_INET6;
|
||||
#if !defined(CONFIG_IDF_TARGET_LINUX)
|
||||
@ -212,6 +216,7 @@ size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, c
|
||||
|
||||
static inline void inet_to_espaddr(const struct sockaddr_storage *in_addr, esp_ip_addr_t *addr, uint16_t *port)
|
||||
{
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (in_addr->ss_family == PF_INET) {
|
||||
struct sockaddr_in *in_addr_ip4 = (struct sockaddr_in *)in_addr;
|
||||
memset(addr, 0, sizeof(esp_ip_addr_t));
|
||||
@ -219,8 +224,9 @@ static inline void inet_to_espaddr(const struct sockaddr_storage *in_addr, esp_i
|
||||
addr->u_addr.ip4.addr = in_addr_ip4->sin_addr.s_addr;
|
||||
addr->type = ESP_IPADDR_TYPE_V4;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else if (in_addr->ss_family == PF_INET6) {
|
||||
#endif /* CONFIG_LWIP_IPV4 */
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (in_addr->ss_family == PF_INET6) {
|
||||
struct sockaddr_in6 *in_addr_ip6 = (struct sockaddr_in6 *)in_addr;
|
||||
memset(addr, 0, sizeof(esp_ip_addr_t));
|
||||
*port = in_addr_ip6->sin6_port;
|
||||
@ -346,17 +352,9 @@ static bool create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||
}
|
||||
int sock = s_interfaces[tcpip_if].sock;
|
||||
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
|
||||
if (sock >= 0) {
|
||||
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
|
||||
int err = join_mdns_multicast_group(sock, netif, other_ip_proto);
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
|
||||
return false;
|
||||
}
|
||||
s_interfaces[tcpip_if].proto |= (other_ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||
return true;
|
||||
if (sock < 0) {
|
||||
sock = create_socket(netif);
|
||||
}
|
||||
sock = create_socket(netif);
|
||||
if (sock < 0) {
|
||||
ESP_LOGE(TAG, "Failed to create the socket!");
|
||||
return false;
|
||||
@ -383,7 +381,7 @@ esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||
|
||||
static int create_socket(esp_netif_t *netif)
|
||||
{
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
int sock = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
#else
|
||||
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
@ -398,7 +396,7 @@ static int create_socket(esp_netif_t *netif)
|
||||
ESP_LOGE(TAG, "Failed setsockopt() to set SO_REUSEADDR. errno=%d: %s\n", errno, strerror(errno));
|
||||
}
|
||||
// Bind the socket to any address
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
struct sockaddr_in6 saddr = { INADDR_ANY };
|
||||
saddr.sin6_family = AF_INET6;
|
||||
saddr.sin6_port = htons(5353);
|
||||
@ -434,7 +432,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
static int socket_add_ipv6_multicast_group(int sock, esp_netif_t *netif)
|
||||
{
|
||||
int ifindex = esp_netif_get_netif_impl_index(netif);
|
||||
@ -457,6 +455,7 @@ static int socket_add_ipv6_multicast_group(int sock, esp_netif_t *netif)
|
||||
}
|
||||
#endif // CONFIG_LWIP_IPV6
|
||||
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
static int socket_add_ipv4_multicast_group(int sock, esp_netif_t *netif)
|
||||
{
|
||||
struct ip_mreq imreq = { 0 };
|
||||
@ -481,13 +480,16 @@ static int socket_add_ipv4_multicast_group(int sock, esp_netif_t *netif)
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
|
||||
static int join_mdns_multicast_group(int sock, esp_netif_t *netif, mdns_ip_protocol_t ip_protocol)
|
||||
{
|
||||
#ifdef CONFIG_LWIP_IPV4
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
|
||||
return socket_add_ipv4_multicast_group(sock, netif);
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
#ifdef CONFIG_LWIP_IPV6
|
||||
if (ip_protocol == MDNS_IP_PROTOCOL_V6) {
|
||||
return socket_add_ipv6_multicast_group(sock, netif);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -39,6 +39,14 @@
|
||||
#define NETIF_IPV6_MAX_NUMS 3
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
/* CONFIG_LWIP_IPV4 was introduced in IDF v5.1 */
|
||||
/* For IDF v5.0, set CONFIG_LWIP_IPV4 to 1 by default */
|
||||
#ifndef CONFIG_LWIP_IPV4
|
||||
#define CONFIG_LWIP_IPV4 1
|
||||
#endif // CONFIG_LWIP_IPV4
|
||||
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
|
||||
/** Number of configured interfaces */
|
||||
#if MDNS_MAX_PREDEF_INTERFACES > CONFIG_MDNS_MAX_INTERFACES
|
||||
#warning Number of configured interfaces is less then number of predefined interfaces. Please update CONFIG_MDNS_MAX_INTERFACES.
|
||||
|
@ -6,4 +6,10 @@ menu "LWIP-MOCK-CONFIG"
|
||||
help
|
||||
Enable/disable IPv6
|
||||
|
||||
config LWIP_IPV4
|
||||
bool "Enable IPv4"
|
||||
default y
|
||||
help
|
||||
Enable/disable IPv4
|
||||
|
||||
endmenu
|
||||
|
22
examples/README.md
Normal file
22
examples/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Examples
|
||||
|
||||
## Overview
|
||||
|
||||
This directory showcases a variety of examples, illustrating the use of different interfaces and functionalities. Navigate through these examples to understand how to implement and integrate various components and features in your projects.
|
||||
|
||||
## Detailed Examples
|
||||
|
||||
1. **Multiple Network Interfaces Example**: Demonstrates the integration and management of multiple network interfaces.
|
||||
Location: [multiple_netifs](esp_netif/multiple_netifs)
|
||||
|
||||
2. **SLIP Device Client**: Provides a detailed example of a SLIP (Serial Line Internet Protocol) device client implementation.
|
||||
Location: [slip_custom_netif](esp_netif/slip_custom_netif/)
|
||||
|
||||
3. **MQTT Demo on Linux**: A comprehensive demonstration of an MQTT (Message Queuing Telemetry Transport) application designed to run on a Linux environment.
|
||||
Location: [mqtt](mqtt)
|
||||
|
||||
## Additional Resources and Examples
|
||||
|
||||
For an extensive collection of additional examples, especially those related to specific components, please visit the upper layer directory and navigate to the respective component's example directory.
|
||||
|
||||
**Important**: To explore more, check the path: `components/*component_name/examples`
|
Reference in New Issue
Block a user