mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-03 13:46:33 +02:00
Compare commits
16 Commits
wifi_remot
...
test_clang
Author | SHA1 | Date | |
---|---|---|---|
ec6fe22688 | |||
84fd3261c3 | |||
6deb731bda | |||
58efb58f5c | |||
5d69d3f0ac | |||
39d59032a2 | |||
e3418b5527 | |||
21d1540b76 | |||
186e258798 | |||
139166c2c5 | |||
7437d31368 | |||
d20255a40c | |||
6af6ca52a2 | |||
042533af90 | |||
732b1d5084 | |||
9e13870ad4 |
2
.github/workflows/clang-tidy.yml
vendored
2
.github/workflows/clang-tidy.yml
vendored
@ -4,7 +4,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- test_clang_tidy
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
6
.github/workflows/run-host-tests.yml
vendored
6
.github/workflows/run-host-tests.yml
vendored
@ -87,8 +87,10 @@ jobs:
|
||||
shell: bash
|
||||
if: ${{ inputs.run_coverage }}
|
||||
run: |
|
||||
apt-get update && apt-get install -y python3-pip rsync
|
||||
python -m pip install gcovr
|
||||
apt-get update && apt-get install -y rsync
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python3 -m pip install gcovr
|
||||
cd $GITHUB_WORKSPACE/${{inputs.component_path}}
|
||||
component=$(basename ${{ inputs.component_path }})
|
||||
gcov `find . -name "$component*gcda"`
|
||||
|
@ -142,7 +142,6 @@ private:
|
||||
size_t frame_header_offset;
|
||||
uint8_t *payload_start;
|
||||
size_t total_payload_size;
|
||||
int instance;
|
||||
int sabm_ack;
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,6 @@ private:
|
||||
static void on_ppp_changed(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
std::shared_ptr<DTE> ppp_dte;
|
||||
esp_netif_t *netif;
|
||||
struct ppp_netif_driver driver {};
|
||||
SignalGroup signal;
|
||||
static const size_t PPP_STARTED = SignalGroup::bit0;
|
||||
|
@ -150,7 +150,7 @@ bool CMux::data_available(uint8_t *data, size_t len)
|
||||
return false;
|
||||
}
|
||||
} else if ((type & FT_UIH) == FT_UIH && dlci == 0) { // notify the internal DISC command
|
||||
if ((len > 0 && (data[0] & 0xE1) == 0xE1) || (data == nullptr)) {
|
||||
if ((data == nullptr) || (len > 0 && (data[0] & 0xE1) == 0xE1)) {
|
||||
// Not a DISC, ignore (MSC frame)
|
||||
return true;
|
||||
}
|
||||
@ -346,6 +346,9 @@ bool CMux::on_cmux_data(uint8_t *data, size_t actual_len)
|
||||
actual_len = term->read(data, buffer.size);
|
||||
#endif
|
||||
}
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP("CMUX Received", data, actual_len, ESP_LOG_VERBOSE);
|
||||
CMuxFrame frame = { .ptr = data, .len = actual_len };
|
||||
while (frame.len > 0) {
|
||||
|
@ -69,7 +69,7 @@ void Netif::receive(uint8_t *data, size_t len)
|
||||
}
|
||||
|
||||
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
|
||||
ppp_dte(std::move(e)), netif(ppp_netif)
|
||||
ppp_dte(std::move(e))
|
||||
{
|
||||
driver.base.netif = ppp_netif;
|
||||
driver.ppp = this;
|
||||
|
@ -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
|
||||
*/
|
||||
@ -29,11 +29,15 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
|
||||
|
||||
void Netif::receive(uint8_t *data, size_t len)
|
||||
{
|
||||
esp_netif_receive(netif, data, len);
|
||||
esp_netif_receive(driver.base.netif, data, len);
|
||||
}
|
||||
|
||||
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
|
||||
ppp_dte(std::move(e)), netif(ppp_netif) {}
|
||||
ppp_dte(std::move(e))
|
||||
{
|
||||
driver.base.netif = ppp_netif;
|
||||
driver.ppp = this;
|
||||
}
|
||||
|
||||
void Netif::start()
|
||||
{
|
||||
@ -41,8 +45,8 @@ void Netif::start()
|
||||
receive(data, len);
|
||||
return true;
|
||||
});
|
||||
netif->transmit = esp_modem_dte_transmit;
|
||||
netif->ctx = (void *)this;
|
||||
driver.base.netif->transmit = esp_modem_dte_transmit;
|
||||
driver.base.netif->ctx = (void *)this;
|
||||
signal.set(PPP_STARTED);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ int FdTerminal::write(uint8_t *data, size_t len)
|
||||
|
||||
FdTerminal::~FdTerminal()
|
||||
{
|
||||
stop();
|
||||
FdTerminal::stop();
|
||||
}
|
||||
|
||||
} // namespace esp_modem
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "uart_resource.hpp"
|
||||
#include "vfs_resource/vfs_create.hpp"
|
||||
|
||||
constexpr const char *TAG = "vfs_uart_creator";
|
||||
[[maybe_unused]] constexpr const char *TAG = "vfs_uart_creator";
|
||||
|
||||
|
||||
struct esp_modem_vfs_resource {
|
||||
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(wifi_remote): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_wifi_remote
|
||||
tag_format: wifi_remote-v$version
|
||||
version: 0.2.2
|
||||
version: 0.2.3
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [0.2.3](https://github.com/espressif/esp-protocols/commits/wifi_remote-v0.2.3)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix server event/command race condtion using eventfd ([732b1d5](https://github.com/espressif/esp-protocols/commit/732b1d5))
|
||||
- Lock server before marshalling events ([9e13870](https://github.com/espressif/esp-protocols/commit/9e13870))
|
||||
|
||||
## [0.2.2](https://github.com/espressif/esp-protocols/commits/wifi_remote-v0.2.2)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -14,7 +14,7 @@ idf_component_register(INCLUDE_DIRS include
|
||||
${src_wifi_is_remote}
|
||||
PRIV_INCLUDE_DIRS eppp
|
||||
REQUIRES esp_event esp_netif
|
||||
PRIV_REQUIRES esp_wifi esp-tls)
|
||||
PRIV_REQUIRES esp_wifi esp-tls vfs)
|
||||
|
||||
idf_component_get_property(wifi esp_wifi COMPONENT_LIB)
|
||||
target_link_libraries(${wifi} PUBLIC ${COMPONENT_LIB})
|
||||
|
@ -129,6 +129,15 @@ public:
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int get_socket_fd()
|
||||
{
|
||||
int sock;
|
||||
if (esp_tls_get_conn_sockfd(tls_, &sock) != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
RpcHeader get_header()
|
||||
{
|
||||
RpcHeader header{};
|
||||
|
@ -16,7 +16,7 @@ struct esp_wifi_remote_mac_t {
|
||||
};
|
||||
|
||||
struct esp_wifi_remote_eppp_ip_event {
|
||||
uint32_t id;
|
||||
int32_t id;
|
||||
esp_netif_ip_info_t wifi_ip;
|
||||
esp_netif_ip_info_t ppp_ip;
|
||||
esp_netif_dns_info_t dns;
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "eppp_link.h"
|
||||
#include "wifi_remote_rpc_params.h"
|
||||
#include "lwip/apps/snmp.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_vfs_eventfd.h"
|
||||
|
||||
extern "C" esp_netif_t *wifi_remote_eppp_init(eppp_type_t role);
|
||||
|
||||
@ -32,7 +34,74 @@ const unsigned char key[] = "-----BEGIN PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMO
|
||||
|
||||
using namespace server;
|
||||
|
||||
struct Events {
|
||||
api_id type;
|
||||
int32_t id;
|
||||
esp_wifi_remote_eppp_ip_event *ip_data{nullptr};
|
||||
bool clean_ip_data{true};
|
||||
esp_err_t create_ip_data()
|
||||
{
|
||||
ip_data = new (std::nothrow) esp_wifi_remote_eppp_ip_event;
|
||||
return ip_data ? ESP_OK : ESP_ERR_NO_MEM;
|
||||
}
|
||||
~Events()
|
||||
{
|
||||
if (clean_ip_data) {
|
||||
delete ip_data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Sync {
|
||||
friend class RpcInstance;
|
||||
public:
|
||||
esp_err_t put(Events &ev)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(xQueueSend(queue, &ev, pdMS_TO_TICKS(queue_timeout)), ESP_FAIL, TAG, "Failed to queue event %" PRIi32, ev.id);
|
||||
ev.clean_ip_data = false; // IP data were successfully sent to the queue, will free manually after receiving from it
|
||||
uint64_t event_queued = 1;
|
||||
write(fd, &event_queued, sizeof(event_queued)); // trigger the wait loop that
|
||||
return ESP_OK;
|
||||
}
|
||||
Events get()
|
||||
{
|
||||
Events ev{};
|
||||
if (!xQueueReceive(queue, &ev, 0)) {
|
||||
ev.type = api_id::ERROR;
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
esp_err_t init()
|
||||
{
|
||||
queue = xQueueCreate(max_items, sizeof(Events));
|
||||
esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
|
||||
esp_vfs_eventfd_register(&config);
|
||||
fd = eventfd(0, EFD_SUPPORT_ISR);
|
||||
return queue == nullptr || fd < 0 ? ESP_ERR_NO_MEM : ESP_OK;
|
||||
}
|
||||
~Sync()
|
||||
{
|
||||
if (queue) {
|
||||
vQueueDelete(queue);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
int fd{-1};
|
||||
// Used to trigger task by either an internal event or rpc command
|
||||
static const int NONE = 0;
|
||||
static const int ERROR = 1;
|
||||
static const int EVENT = 2;
|
||||
static const int RPC = 4;
|
||||
private:
|
||||
QueueHandle_t queue{nullptr};
|
||||
const int max_items = 15;
|
||||
const int queue_timeout = 200;
|
||||
};
|
||||
|
||||
class RpcInstance {
|
||||
friend class Sync;
|
||||
public:
|
||||
RpcEngine rpc{role::SERVER};
|
||||
int sock{-1};
|
||||
@ -43,11 +112,12 @@ public:
|
||||
ESP_RETURN_ON_ERROR(start_server(), TAG, "Failed to start RPC server");
|
||||
ESP_RETURN_ON_ERROR(rpc.init(), TAG, "Failed to init RPC engine");
|
||||
ESP_RETURN_ON_ERROR(esp_netif_napt_enable(netif), TAG, "Failed to enable NAPT");
|
||||
ESP_RETURN_ON_ERROR(sync.init(), TAG, "Failed to init event queue");
|
||||
ESP_RETURN_ON_ERROR(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event");
|
||||
ESP_RETURN_ON_ERROR(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event");
|
||||
return xTaskCreate(task, "server", 8192, this, 5, nullptr) == pdTRUE ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
Sync sync;
|
||||
private:
|
||||
esp_netif_t *netif{nullptr};
|
||||
static void task(void *ctx)
|
||||
@ -81,23 +151,24 @@ private:
|
||||
esp_err_t wifi_event(int32_t id)
|
||||
{
|
||||
ESP_LOGI(TAG, "Received WIFI event %" PRIi32, id);
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::WIFI_EVENT, &id), TAG, "Failed to marshall WiFi event");
|
||||
Events ev{api_id::WIFI_EVENT, id, nullptr};
|
||||
ESP_RETURN_ON_ERROR(sync.put(ev), TAG, "Failed to queue WiFi event");
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t ip_event(int32_t id, ip_event_got_ip_t *ip_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Received IP event %" PRIi32, id);
|
||||
esp_wifi_remote_eppp_ip_event ip_event{};
|
||||
ip_event.id = id;
|
||||
Events ev{api_id::IP_EVENT, id, nullptr};
|
||||
if (ip_data->esp_netif) {
|
||||
// marshall additional data, only if netif available
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(ip_data->esp_netif, ESP_NETIF_DNS_MAIN, &ip_event.dns), TAG, "Failed to get DNS info");
|
||||
ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&ip_event.dns.ip.u_addr.ip4));
|
||||
memcpy(&ip_event.wifi_ip, &ip_data->ip_info, sizeof(ip_event.wifi_ip));
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_ip_info(netif, &ip_event.ppp_ip), TAG, "Failed to get IP info");
|
||||
ESP_RETURN_ON_ERROR(ev.create_ip_data(), TAG, "Failed to allocate event data");
|
||||
ev.ip_data->id = id;
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(ip_data->esp_netif, ESP_NETIF_DNS_MAIN, &ev.ip_data->dns), TAG, "Failed to get DNS info");
|
||||
ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&ev.ip_data->dns.ip.u_addr.ip4));
|
||||
memcpy(&ev.ip_data->wifi_ip, &ip_data->ip_info, sizeof(ev.ip_data->wifi_ip));
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_ip_info(netif, &ev.ip_data->ppp_ip), TAG, "Failed to get IP info");
|
||||
ESP_LOGI(TAG, "IP address:" IPSTR, IP2STR(&ip_data->ip_info.ip));
|
||||
}
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::IP_EVENT, &ip_event), TAG, "Failed to marshal IP event");
|
||||
ESP_RETURN_ON_ERROR(sync.put(ev), TAG, "Failed to queue IP event");
|
||||
return ESP_OK;
|
||||
}
|
||||
static void handler(void *ctx, esp_event_base_t base, int32_t id, void *data)
|
||||
@ -110,11 +181,83 @@ private:
|
||||
instance->ip_event(id, ip_data);
|
||||
}
|
||||
}
|
||||
int select()
|
||||
{
|
||||
struct timeval timeout = { .tv_sec = 1, .tv_usec = 0};
|
||||
int rpc_sock = rpc.get_socket_fd();
|
||||
|
||||
ESP_RETURN_ON_FALSE(rpc_sock != -1, Sync::ERROR, TAG, "failed ot get rpc socket");
|
||||
fd_set readset;
|
||||
fd_set errset;
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&errset);
|
||||
FD_SET(rpc_sock, &readset);
|
||||
FD_SET(sync.fd, &readset);
|
||||
FD_SET(rpc_sock, &errset);
|
||||
int ret = ::select(std::max(rpc_sock, 5) + 1, &readset, nullptr, &errset, &timeout);
|
||||
if (ret == 0) {
|
||||
ESP_LOGV(TAG, "poll_read: select - Timeout before any socket was ready!");
|
||||
return Sync::NONE;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "select error: %d", errno);
|
||||
return Sync::ERROR;
|
||||
}
|
||||
if (FD_ISSET(rpc_sock, &errset)) {
|
||||
int sock_errno = 0;
|
||||
uint32_t optlen = sizeof(sock_errno);
|
||||
getsockopt(rpc_sock, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
||||
ESP_LOGE(TAG, "select failed, socket errno = %d", sock_errno);
|
||||
return Sync::ERROR;
|
||||
}
|
||||
int result = Sync::NONE;
|
||||
if (FD_ISSET(rpc_sock, &readset)) {
|
||||
result |= Sync::RPC;
|
||||
}
|
||||
if (FD_ISSET(sync.fd, &readset)) {
|
||||
result |= Sync::EVENT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
esp_err_t marshall_events()
|
||||
{
|
||||
api_id type;
|
||||
do {
|
||||
Events ev = sync.get();
|
||||
type = ev.type;
|
||||
if (ev.type == api_id::WIFI_EVENT) {
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::WIFI_EVENT, &ev.id), TAG, "Failed to marshall WiFi event");
|
||||
} else if (ev.type == api_id::IP_EVENT && ev.ip_data) {
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::IP_EVENT, ev.ip_data), TAG, "Failed to marshal IP event");
|
||||
}
|
||||
} while (type != api_id::ERROR);
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t perform()
|
||||
{
|
||||
auto res = select();
|
||||
if (res == Sync::ERROR) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (res & Sync::EVENT) {
|
||||
uint64_t data;
|
||||
read(sync.fd, &data, sizeof(data));
|
||||
if (marshall_events() != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
if (res & Sync::RPC) {
|
||||
if (handle_commands() != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t handle_commands()
|
||||
{
|
||||
auto header = rpc.get_header();
|
||||
ESP_LOGI(TAG, "Received header id %d", (int) header.id);
|
||||
|
||||
switch (header.id) {
|
||||
case api_id::SET_MODE: {
|
||||
auto req = rpc.get_payload<wifi_mode_t>(api_id::SET_MODE, header);
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 0.2.2
|
||||
version: 0.2.3
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_wifi_remote
|
||||
description: Utility wrapper for esp_wifi functionality on remote targets
|
||||
dependencies:
|
||||
|
@ -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.3.1
|
||||
version: 1.3.2
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.2)
|
||||
|
||||
### Features
|
||||
|
||||
- add check of instance when handling PTR query ([6af6ca5](https://github.com/espressif/esp-protocols/commit/6af6ca5))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix of mdns afl tests ([139166c](https://github.com/espressif/esp-protocols/commit/139166c))
|
||||
- remove same protocol services with different instances ([042533a](https://github.com/espressif/esp-protocols/commit/042533a))
|
||||
|
||||
## [1.3.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.1)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.3.1"
|
||||
version: "1.3.2"
|
||||
description: mDNS
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
|
||||
dependencies:
|
||||
|
@ -1871,6 +1871,7 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
packet->id = parsed_packet->id;
|
||||
|
||||
mdns_parsed_question_t *q = parsed_packet->questions;
|
||||
uint32_t out_record_nums = 0;
|
||||
while (q) {
|
||||
shared = q->type == MDNS_TYPE_PTR || q->type == MDNS_TYPE_SDPTR || !parsed_packet->probe;
|
||||
if (q->type == MDNS_TYPE_SRV || q->type == MDNS_TYPE_TXT) {
|
||||
@ -1878,14 +1879,36 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
if (service == NULL || !_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
} else if (q->service && q->proto) {
|
||||
mdns_srv_item_t *service = _mdns_server->services;
|
||||
while (service) {
|
||||
if (_mdns_service_match_ptr_question(service->service, q)) {
|
||||
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
mdns_parsed_record_t *r = parsed_packet->records;
|
||||
bool is_record_exist = false;
|
||||
while (r) {
|
||||
if (service->service->instance && r->host) {
|
||||
if (_mdns_service_match_instance(service->service, r->host, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
|
||||
is_record_exist = true;
|
||||
break;
|
||||
}
|
||||
} else if (!service->service->instance && !r->host) {
|
||||
if (_mdns_service_match(service->service, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
|
||||
is_record_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
if (!is_record_exist) {
|
||||
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
}
|
||||
}
|
||||
service = service->next;
|
||||
@ -1894,22 +1917,31 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
if (!_mdns_create_answer_from_hostname(packet, q->host, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_ANY) {
|
||||
if (!_mdns_append_host_list(&packet->answers, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||
} else if (q->type == MDNS_TYPE_PTR) {
|
||||
mdns_host_item_t *host = mdns_get_host_item(q->host);
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
||||
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
|
||||
if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries"
|
||||
@ -1943,6 +1975,10 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
}
|
||||
q = q->next;
|
||||
}
|
||||
if (out_record_nums == 0) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
if (unicast || !send_flush) {
|
||||
memcpy(&packet->dst, &parsed_packet->src, sizeof(esp_ip_addr_t));
|
||||
packet->port = parsed_packet->src_port;
|
||||
@ -3336,7 +3372,11 @@ static bool _mdns_question_matches(mdns_parsed_question_t *question, uint16_t ty
|
||||
&& !strcasecmp(service->service->service, question->service)
|
||||
&& !strcasecmp(service->service->proto, question->proto)
|
||||
&& !strcasecmp(MDNS_DEFAULT_DOMAIN, question->domain)) {
|
||||
return true;
|
||||
if (!service->service->instance) {
|
||||
return true;
|
||||
} else if (service->service->instance && question->host && !strcasecmp(service->service->instance, question->host)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (service && (type == MDNS_TYPE_SRV || type == MDNS_TYPE_TXT)) {
|
||||
const char *name = _mdns_get_service_instance_name(service->service);
|
||||
@ -3635,6 +3675,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
parsed_packet->id = header.id;
|
||||
esp_netif_ip_addr_copy(&parsed_packet->src, &packet->src);
|
||||
parsed_packet->src_port = packet->src_port;
|
||||
parsed_packet->records = NULL;
|
||||
|
||||
if (header.questions) {
|
||||
uint8_t qs = header.questions;
|
||||
@ -3821,7 +3862,12 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
_mdns_search_result_add_ptr(search_result, name->host, name->service, name->proto,
|
||||
packet->tcpip_if, packet->ip_protocol, ttl);
|
||||
} else if ((discovery || ours) && !name->sub && _mdns_name_is_ours(name)) {
|
||||
if (discovery && (service = _mdns_get_service_item(name->service, name->proto, NULL))) {
|
||||
if (name->host[0]) {
|
||||
service = _mdns_get_service_item_instance(name->host, name->service, name->proto, NULL);
|
||||
} else {
|
||||
service = _mdns_get_service_item(name->service, name->proto, NULL);
|
||||
}
|
||||
if (discovery && service) {
|
||||
_mdns_remove_parsed_question(parsed_packet, MDNS_TYPE_SDPTR, service);
|
||||
} else if (service && parsed_packet->questions && !parsed_packet->probe) {
|
||||
_mdns_remove_parsed_question(parsed_packet, type, service);
|
||||
@ -3831,6 +3877,45 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
_mdns_remove_scheduled_answer(packet->tcpip_if, packet->ip_protocol, type, service);
|
||||
}
|
||||
}
|
||||
if (service) {
|
||||
mdns_parsed_record_t *record = malloc(sizeof(mdns_parsed_record_t));
|
||||
if (!record) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
record->next = parsed_packet->records;
|
||||
parsed_packet->records = record;
|
||||
record->type = MDNS_TYPE_PTR;
|
||||
record->record_type = MDNS_ANSWER;
|
||||
record->ttl = ttl;
|
||||
record->host = NULL;
|
||||
record->service = NULL;
|
||||
record->proto = NULL;
|
||||
if (name->host[0]) {
|
||||
record->host = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->host) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->host, name->host, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
if (name->service[0]) {
|
||||
record->service = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->service) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->service, name->service, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
if (name->proto[0]) {
|
||||
record->proto = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->proto) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->proto, name->proto, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type == MDNS_TYPE_SRV) {
|
||||
mdns_result_t *result = NULL;
|
||||
@ -4161,6 +4246,21 @@ clear_rx_packet:
|
||||
}
|
||||
free(question);
|
||||
}
|
||||
while (parsed_packet->records) {
|
||||
mdns_parsed_record_t *record = parsed_packet->records;
|
||||
parsed_packet->records = parsed_packet->records->next;
|
||||
if (record->host) {
|
||||
free(record->host);
|
||||
}
|
||||
if (record->service) {
|
||||
free(record->service);
|
||||
}
|
||||
if (record->proto) {
|
||||
free(record->proto);
|
||||
}
|
||||
record->next = NULL;
|
||||
free(record);
|
||||
}
|
||||
free(parsed_packet);
|
||||
if (browse_result_instance) {
|
||||
free(browse_result_instance);
|
||||
@ -5200,28 +5300,57 @@ static void _mdns_execute_action(mdns_action_t *action)
|
||||
break;
|
||||
case ACTION_SERVICE_DEL:
|
||||
a = _mdns_server->services;
|
||||
if (action->data.srv_del.service) {
|
||||
if (_mdns_server->services == action->data.srv_del.service) {
|
||||
_mdns_server->services = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
} else {
|
||||
while (a->next && a->next != action->data.srv_del.service) {
|
||||
a = a->next;
|
||||
mdns_srv_item_t *b = a;
|
||||
if (action->data.srv_del.instance) {
|
||||
while (a) {
|
||||
if (_mdns_service_match_instance(a->service, action->data.srv_del.instance,
|
||||
action->data.srv_del.service, action->data.srv_del.proto,
|
||||
action->data.srv_del.hostname)) {
|
||||
if (_mdns_server->services != a) {
|
||||
b->next = a->next;
|
||||
} else {
|
||||
_mdns_server->services = a->next;
|
||||
}
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
break;
|
||||
}
|
||||
if (a->next == action->data.srv_del.service) {
|
||||
mdns_srv_item_t *b = a->next;
|
||||
a->next = a->next->next;
|
||||
_mdns_send_bye(&b, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(b->service);
|
||||
_mdns_free_service(b->service);
|
||||
free(b);
|
||||
b = a;
|
||||
a = a->next;
|
||||
}
|
||||
} else {
|
||||
while (a) {
|
||||
if (_mdns_service_match(a->service, action->data.srv_del.service, action->data.srv_del.proto,
|
||||
action->data.srv_del.hostname)) {
|
||||
if (_mdns_server->services != a) {
|
||||
b->next = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
a = b->next;
|
||||
continue;
|
||||
} else {
|
||||
_mdns_server->services = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
a = _mdns_server->services;
|
||||
b = a;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
b = a;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
free((char *)action->data.srv_del.instance);
|
||||
free((char *)action->data.srv_del.service);
|
||||
free((char *)action->data.srv_del.proto);
|
||||
free((char *)action->data.srv_del.hostname);
|
||||
break;
|
||||
case ACTION_SERVICES_CLEAR:
|
||||
_mdns_send_final_bye(false);
|
||||
@ -6401,6 +6530,16 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
mdns_subtype_t *srv_subtype = s->service->subtype;
|
||||
while (srv_subtype) {
|
||||
if (strcmp(srv_subtype->subtype, subtype) == 0) {
|
||||
// The same subtype has already been added
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
srv_subtype = srv_subtype->next;
|
||||
}
|
||||
|
||||
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
|
||||
if (!action) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
@ -6489,12 +6628,40 @@ esp_err_t mdns_service_remove_for_host(const char *instance, const char *service
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
action->type = ACTION_SERVICE_DEL;
|
||||
action->data.srv_del.service = s;
|
||||
action->data.srv_del.instance = NULL;
|
||||
action->data.srv_del.hostname = NULL;
|
||||
if (!_str_null_or_empty(instance)) {
|
||||
action->data.srv_del.instance = strndup(instance, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.instance) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_str_null_or_empty(hostname)) {
|
||||
action->data.srv_del.hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.hostname) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
action->data.srv_del.service = strndup(service, MDNS_NAME_BUF_LEN - 1);
|
||||
action->data.srv_del.proto = strndup(proto, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.service || !action->data.srv_del.proto) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
fail:
|
||||
free((char *)action->data.srv_del.instance);
|
||||
free((char *)action->data.srv_del.service);
|
||||
free((char *)action->data.srv_del.proto);
|
||||
free((char *)action->data.srv_del.hostname);
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove(const char *service_type, const char *proto)
|
||||
|
@ -450,7 +450,10 @@ typedef struct {
|
||||
mdns_srv_item_t *service;
|
||||
} srv_add;
|
||||
struct {
|
||||
mdns_srv_item_t *service;
|
||||
char *instance;
|
||||
char *service;
|
||||
char *proto;
|
||||
char *hostname;
|
||||
} srv_del;
|
||||
struct {
|
||||
mdns_srv_item_t *service;
|
||||
|
@ -195,6 +195,7 @@
|
||||
#define CONFIG_HEAP_TRACING_OFF 1
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL 3
|
||||
#define CONFIG_LOG_MAXIMUM_LEVEL 3
|
||||
#define CONFIG_LOG_COLORS 1
|
||||
#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1
|
||||
#define CONFIG_LWIP_LOCAL_HOSTNAME "espressif"
|
||||
|
Reference in New Issue
Block a user