Merge branch 'feature/sync_mdns_from_espidf' into 'master'

mdns: sync code from esp-idf

See merge request sdk/ESP8266_RTOS_SDK!943
This commit is contained in:
Dong Heng
2019-07-09 15:50:36 +08:00
13 changed files with 288 additions and 89 deletions

View File

@ -23,6 +23,11 @@
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "tcpip_adapter.h" #include "tcpip_adapter.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -1,6 +1,5 @@
if(CONFIG_ENABLE_MDNS) if(CONFIG_ENABLE_MDNS)
set(COMPONENT_SRCS "src/mdns.c" set(COMPONENT_SRCS "src/mdns.c"
"src/mdns_console.c"
"src/mdns_networking.c") "src/mdns_networking.c")
set(COMPONENT_PRIV_INCLUDEDIRS "private_include") set(COMPONENT_PRIV_INCLUDEDIRS "private_include")
@ -9,5 +8,12 @@ endif()
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_REQUIRES "lwip" "ssl" "tcpip_adapter") set(COMPONENT_REQUIRES "lwip" "ssl" "tcpip_adapter")
if(CONFIG_ENABLE_MDNS_CONSOLE)
set(COMPONENT_SRCS "${COMPONENT_SRCS}"
"src/mdns_console.c")
endif()
set(COMPONENT_REQUIRES "console" "tcpip_adapter" "newlib")
register_component() register_component()

View File

@ -7,6 +7,14 @@ config ENABLE_MDNS
help help
Enable this option and then mDNS is to be used. Enable this option and then mDNS is to be used.
config ENABLE_MDNS_CONSOLE
bool "Enable mDNS console"
default n
depends on ENABLE_MDNS
select USING_ESP_CONSOLE
help
Enable this option and then mDNS console is to be used.
config MDNS_MAX_SERVICES config MDNS_MAX_SERVICES
int "Max number of services" int "Max number of services"
range 1 64 range 1 64

View File

@ -4,3 +4,7 @@ COMPONENT_PRIV_INCLUDEDIRS := private_include
ifdef CONFIG_ENABLE_MDNS ifdef CONFIG_ENABLE_MDNS
COMPONENT_SRCDIRS := src COMPONENT_SRCDIRS := src
endif endif
ifndef CONFIG_ENABLE_MDNS_CONSOLE
COMPONENT_OBJEXCLUDE := src/mdns_console.o
endif

View File

@ -5,6 +5,8 @@
* MDNS Server Networking -- private include * MDNS Server Networking -- private include
* *
*/ */
#include "mdns.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/queue.h" #include "freertos/queue.h"
@ -19,8 +21,7 @@
#include "esp_system.h" #include "esp_system.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "mdns.h"
#include "mdns_private.h"
/** /**
* @brief Queue RX packet action * @brief Queue RX packet action

View File

@ -14,6 +14,12 @@
#ifndef MDNS_PRIVATE_H_ #ifndef MDNS_PRIVATE_H_
#define MDNS_PRIVATE_H_ #define MDNS_PRIVATE_H_
#include <stdint.h>
#include <stdbool.h>
#include "tcpip_adapter.h"
#include "esp_timer.h"
#include "mdns.h"
//#define MDNS_ENABLE_DEBUG //#define MDNS_ENABLE_DEBUG
#ifdef MDNS_ENABLE_DEBUG #ifdef MDNS_ENABLE_DEBUG
@ -52,7 +58,7 @@
#define MDNS_ANSWER_SDPTR 0x80 #define MDNS_ANSWER_SDPTR 0x80
#define MDNS_SERVICE_PORT 5353 // UDP port that the server runs on #define MDNS_SERVICE_PORT 5353 // UDP port that the server runs on
#define MDNS_SERVICE_STACK_DEPTH CONFIG_MDNS_STACKSIZE // Stack size for the service thread #define MDNS_SERVICE_STACK_DEPTH 4096 // Stack size for the service thread
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing #define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
#define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server #define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record #define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
@ -115,9 +121,9 @@
#define PCB_STATE_IS_ANNOUNCING(s) (s->state > PCB_PROBE_3 && s->state < PCB_RUNNING) #define PCB_STATE_IS_ANNOUNCING(s) (s->state > PCB_PROBE_3 && s->state < PCB_RUNNING)
#define PCB_STATE_IS_RUNNING(s) (s->state == PCB_RUNNING) #define PCB_STATE_IS_RUNNING(s) (s->state == PCB_RUNNING)
#define MDNS_SEARCH_LOCK() xSemaphoreTake(_mdns_server->search.lock, portMAX_DELAY) #ifndef HOOK_MALLOC_FAILED
#define MDNS_SEARCH_UNLOCK() xSemaphoreGive(_mdns_server->search.lock) #define HOOK_MALLOC_FAILED ESP_LOGE(TAG, "Cannot allocate memory (line: %d, free heap: %d bytes)", __LINE__, esp_get_free_heap_size());
#endif
typedef enum { typedef enum {
PCB_OFF, PCB_DUP, PCB_INIT, PCB_OFF, PCB_DUP, PCB_INIT,
@ -289,6 +295,7 @@ typedef struct mdns_tx_packet_s {
mdns_out_answer_t * answers; mdns_out_answer_t * answers;
mdns_out_answer_t * servers; mdns_out_answer_t * servers;
mdns_out_answer_t * additional; mdns_out_answer_t * additional;
bool queued;
} mdns_tx_packet_t; } mdns_tx_packet_t;
typedef struct { typedef struct {
@ -315,7 +322,7 @@ typedef struct mdns_search_once_s {
uint32_t started_at; uint32_t started_at;
uint32_t sent_at; uint32_t sent_at;
uint32_t timeout; uint32_t timeout;
SemaphoreHandle_t lock; SemaphoreHandle_t done_semaphore;
uint16_t type; uint16_t type;
uint8_t max_results; uint8_t max_results;
uint8_t num_results; uint8_t num_results;

View File

@ -13,11 +13,10 @@
// limitations under the License. // limitations under the License.
#include "mdns.h" #include "mdns.h"
#include "mdns_networking.h"
#include "mdns_private.h" #include "mdns_private.h"
#include "mdns_networking.h"
#include "esp_log.h"
#include <string.h> #include <string.h>
#include <stdlib.h>
#ifdef MDNS_ENABLE_DEBUG #ifdef MDNS_ENABLE_DEBUG
void mdns_debug_packet(const uint8_t * data, size_t len); void mdns_debug_packet(const uint8_t * data, size_t len);
@ -28,6 +27,8 @@ static const char * MDNS_SUB_STR = "_sub";
mdns_server_t * _mdns_server = NULL; mdns_server_t * _mdns_server = NULL;
static const char *TAG = "MDNS";
static volatile TaskHandle_t _mdns_service_task_handle = NULL; static volatile TaskHandle_t _mdns_service_task_handle = NULL;
static SemaphoreHandle_t _mdns_service_semaphore = NULL; static SemaphoreHandle_t _mdns_service_semaphore = NULL;
@ -65,11 +66,16 @@ static char * _mdns_mangle_name(char* in) {
//need to add -2 to string //need to add -2 to string
ret = malloc(strlen(in) + 3); ret = malloc(strlen(in) + 3);
if (ret == NULL) { if (ret == NULL) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
sprintf(ret, "%s-2", in); sprintf(ret, "%s-2", in);
} else { } else {
ret = malloc(strlen(in) + 2); //one extra byte in case 9-10 or 99-100 etc ret = malloc(strlen(in) + 2); //one extra byte in case 9-10 or 99-100 etc
if (ret == NULL) {
HOOK_MALLOC_FAILED;
return NULL;
}
strcpy(ret, in); strcpy(ret, in);
int baseLen = p - in; //length of 'bla' in 'bla-123' int baseLen = p - in; //length of 'bla' in 'bla-123'
//overwrite suffix with new suffix //overwrite suffix with new suffix
@ -119,6 +125,7 @@ esp_err_t _mdns_send_rx_action(mdns_rx_packet_t * packet)
action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -559,6 +566,9 @@ static uint16_t _mdns_append_txt_record(uint8_t * packet, uint16_t * index, mdns
return 0; return 0;
} }
data_len += l; data_len += l;
} else {
HOOK_MALLOC_FAILED;
// continue
} }
txt = txt->next; txt = txt->next;
} }
@ -1132,6 +1142,7 @@ static bool _mdns_alloc_answer(mdns_out_answer_t ** destnation, uint16_t type, m
mdns_out_answer_t * a = (mdns_out_answer_t *)malloc(sizeof(mdns_out_answer_t)); mdns_out_answer_t * a = (mdns_out_answer_t *)malloc(sizeof(mdns_out_answer_t));
if (!a) { if (!a) {
HOOK_MALLOC_FAILED;
return false; return false;
} }
a->type = type; a->type = type;
@ -1150,6 +1161,7 @@ static mdns_tx_packet_t * _mdns_alloc_packet_default(tcpip_adapter_if_t tcpip_if
{ {
mdns_tx_packet_t * packet = (mdns_tx_packet_t*)malloc(sizeof(mdns_tx_packet_t)); mdns_tx_packet_t * packet = (mdns_tx_packet_t*)malloc(sizeof(mdns_tx_packet_t));
if (!packet) { if (!packet) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
memset((uint8_t*)packet, 0, sizeof(mdns_tx_packet_t)); memset((uint8_t*)packet, 0, sizeof(mdns_tx_packet_t));
@ -1287,6 +1299,7 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(tcpip_adapter_if_t tcpip_if,
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t)); mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t));
if (!q) { if (!q) {
HOOK_MALLOC_FAILED;
_mdns_free_tx_packet(packet); _mdns_free_tx_packet(packet);
return NULL; return NULL;
} }
@ -1312,6 +1325,7 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(tcpip_adapter_if_t tcpip_if,
if (include_ip && !_str_null_or_empty(_mdns_server->hostname)) { if (include_ip && !_str_null_or_empty(_mdns_server->hostname)) {
mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t)); mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t));
if (!q) { if (!q) {
HOOK_MALLOC_FAILED;
_mdns_free_tx_packet(packet); _mdns_free_tx_packet(packet);
return NULL; return NULL;
} }
@ -1438,20 +1452,13 @@ static void _mdns_pcb_send_bye(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
} }
/** /**
* @brief Send probe for particular services on particular PCB * @brief Send probe for additional services on particular PCB
*/ */
static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip) static void _mdns_init_pcb_probe_new_service(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
{ {
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol]; mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
size_t services_final_len = len; size_t services_final_len = len;
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
if (_str_null_or_empty(_mdns_server->hostname)) {
pcb->state = PCB_RUNNING;
return;
}
if (PCB_STATE_IS_PROBING(pcb)) { if (PCB_STATE_IS_PROBING(pcb)) {
services_final_len += pcb->probe_services_len; services_final_len += pcb->probe_services_len;
} }
@ -1459,6 +1466,7 @@ static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t
if (services_final_len) { if (services_final_len) {
_services = (mdns_srv_item_t **)malloc(sizeof(mdns_srv_item_t *) * services_final_len); _services = (mdns_srv_item_t **)malloc(sizeof(mdns_srv_item_t *) * services_final_len);
if (!_services) { if (!_services) {
HOOK_MALLOC_FAILED;
return; return;
} }
@ -1495,6 +1503,50 @@ static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t
pcb->state = PCB_PROBE_1; pcb->state = PCB_PROBE_1;
} }
/**
* @brief Send probe for particular services on particular PCB
*
* Tests possible duplication on probing service structure and probes only for new entries.
* - If pcb probing then add only non-probing services and restarts probing
* - If pcb not probing, run probing for all specified services
*/
static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
{
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
if (_str_null_or_empty(_mdns_server->hostname)) {
pcb->state = PCB_RUNNING;
return;
}
if (PCB_STATE_IS_PROBING(pcb)) {
// Looking for already probing services to resolve duplications
mdns_srv_item_t * new_probe_services[len];
int new_probe_service_len = 0;
bool found;
for (int j=0; j < len; ++j) {
found = false;
for (int i=0; i < pcb->probe_services_len; ++i) {
if (pcb->probe_services[i] == services[j]) {
found = true;
break;
}
}
if (!found) {
new_probe_services[new_probe_service_len++] = services[j];
}
}
// init probing for newly added services
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol,
new_probe_service_len?new_probe_services:NULL, new_probe_service_len, probe_ip);
} else {
// not probing, so init for all services
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol, services, len, probe_ip);
}
}
/** /**
* @brief Restart the responder on particular PCB * @brief Restart the responder on particular PCB
*/ */
@ -1739,6 +1791,7 @@ static mdns_txt_linked_item_t * _mdns_allocate_txt(size_t num_items, mdns_txt_it
for (i=0; i<num_items; i++) { for (i=0; i<num_items; i++) {
mdns_txt_linked_item_t * new_item = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t)); mdns_txt_linked_item_t * new_item = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
if (!new_item) { if (!new_item) {
HOOK_MALLOC_FAILED;
break; break;
} }
new_item->key = strdup(txt[i].key); new_item->key = strdup(txt[i].key);
@ -1785,6 +1838,7 @@ static mdns_service_t * _mdns_create_service(const char * service, const char *
{ {
mdns_service_t * s = (mdns_service_t *)malloc(sizeof(mdns_service_t)); mdns_service_t * s = (mdns_service_t *)malloc(sizeof(mdns_service_t));
if (!s) { if (!s) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
@ -1846,6 +1900,9 @@ static void _mdns_dealloc_scheduled_service_answers(mdns_out_answer_t ** destina
*/ */
static void _mdns_remove_scheduled_service_packets(mdns_service_t * service) static void _mdns_remove_scheduled_service_packets(mdns_service_t * service)
{ {
if (!service) {
return;
}
mdns_tx_packet_t * p = NULL; mdns_tx_packet_t * p = NULL;
mdns_tx_packet_t * q = _mdns_server->tx_queue_head; mdns_tx_packet_t * q = _mdns_server->tx_queue_head;
while (q) { while (q) {
@ -1934,7 +1991,6 @@ static void _mdns_free_service(mdns_service_t * service)
if (!service) { if (!service) {
return; return;
} }
_mdns_remove_scheduled_service_packets(service);
free((char *)service->instance); free((char *)service->instance);
free((char *)service->service); free((char *)service->service);
free((char *)service->proto); free((char *)service->proto);
@ -2048,6 +2104,9 @@ static int _mdns_check_txt_collision(mdns_service_t * service, const uint8_t * d
sprintf(tmp, "%s=%s", txt->key, txt->value); sprintf(tmp, "%s=%s", txt->key, txt->value);
_mdns_append_string(ours, &index, tmp); _mdns_append_string(ours, &index, tmp);
free(tmp); free(tmp);
} else {
HOOK_MALLOC_FAILED;
// continue
} }
txt = txt->next; txt = txt->next;
} }
@ -2404,6 +2463,10 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
} }
mdns_txt_item_t * txt = (mdns_txt_item_t *)malloc(sizeof(mdns_txt_item_t) * num_items); mdns_txt_item_t * txt = (mdns_txt_item_t *)malloc(sizeof(mdns_txt_item_t) * num_items);
if (!txt) {
HOOK_MALLOC_FAILED;
return;
}
memset(txt, 0, sizeof(mdns_txt_item_t) * num_items); memset(txt, 0, sizeof(mdns_txt_item_t) * num_items);
size_t txt_num = 0; size_t txt_num = 0;
@ -2424,6 +2487,7 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
} }
char * key = (char *)malloc(name_len + 1); char * key = (char *)malloc(name_len + 1);
if (!key) { if (!key) {
HOOK_MALLOC_FAILED;
goto handle_error;//error goto handle_error;//error
} }
@ -2437,6 +2501,10 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
int value_len = partLen - name_len - 1; int value_len = partLen - name_len - 1;
if (value_len > 0) { if (value_len > 0) {
char * value = (char *)malloc(value_len + 1); char * value = (char *)malloc(value_len + 1);
if (!value) {
HOOK_MALLOC_FAILED;
goto handle_error;//error
}
memcpy(value, data + i, value_len); memcpy(value, data + i, value_len);
value[value_len] = 0; value[value_len] = 0;
i += value_len; i += value_len;
@ -2500,6 +2568,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
mdns_parsed_packet_t * parsed_packet = (mdns_parsed_packet_t *)malloc(sizeof(mdns_parsed_packet_t)); mdns_parsed_packet_t * parsed_packet = (mdns_parsed_packet_t *)malloc(sizeof(mdns_parsed_packet_t));
if (!parsed_packet) { if (!parsed_packet) {
HOOK_MALLOC_FAILED;
return; return;
} }
memset(parsed_packet, 0, sizeof(mdns_parsed_packet_t)); memset(parsed_packet, 0, sizeof(mdns_parsed_packet_t));
@ -2560,8 +2629,9 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
parsed_packet->discovery = true; parsed_packet->discovery = true;
mdns_srv_item_t * a = _mdns_server->services; mdns_srv_item_t * a = _mdns_server->services;
while (a) { while (a) {
mdns_parsed_question_t * question = (mdns_parsed_question_t *)malloc(sizeof(mdns_parsed_question_t)); mdns_parsed_question_t * question = (mdns_parsed_question_t *)calloc(1, sizeof(mdns_parsed_question_t));
if (!question) { if (!question) {
HOOK_MALLOC_FAILED;
goto clear_rx_packet; goto clear_rx_packet;
} }
question->next = parsed_packet->questions; question->next = parsed_packet->questions;
@ -2587,8 +2657,9 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
parsed_packet->probe = true; parsed_packet->probe = true;
} }
mdns_parsed_question_t * question = (mdns_parsed_question_t *)malloc(sizeof(mdns_parsed_question_t)); mdns_parsed_question_t * question = (mdns_parsed_question_t *)calloc(1, sizeof(mdns_parsed_question_t));
if (!question) { if (!question) {
HOOK_MALLOC_FAILED;
goto clear_rx_packet; goto clear_rx_packet;
} }
question->next = parsed_packet->questions; question->next = parsed_packet->questions;
@ -2709,8 +2780,10 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
if (search_result) { if (search_result) {
if (search_result->type == MDNS_TYPE_PTR) { if (search_result->type == MDNS_TYPE_PTR) {
if (!result->hostname) { // assign host/port for this entry only if not previously set
result->port = port; result->port = port;
result->hostname = strdup(name->host); result->hostname = strdup(name->host);
}
} else { } else {
_mdns_search_result_add_srv(search_result, name->host, port, packet->tcpip_if, packet->ip_protocol); _mdns_search_result_add_srv(search_result, name->host, port, packet->tcpip_if, packet->ip_protocol);
} }
@ -2771,10 +2844,6 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
if (search_result) { if (search_result) {
mdns_txt_item_t * txt = NULL; mdns_txt_item_t * txt = NULL;
size_t txt_count = 0; size_t txt_count = 0;
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
if (!txt_count) {
continue;
}
mdns_result_t * result = NULL; mdns_result_t * result = NULL;
if (search_result->type == MDNS_TYPE_PTR) { if (search_result->type == MDNS_TYPE_PTR) {
@ -2794,12 +2863,18 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
} }
} }
if (!result->txt) { if (!result->txt) {
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
if (txt_count) {
result->txt = txt; result->txt = txt;
result->txt_count = txt_count; result->txt_count = txt_count;
} }
}
} else { } else {
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
if (txt_count) {
_mdns_search_result_add_txt(search_result, txt, txt_count, packet->tcpip_if, packet->ip_protocol); _mdns_search_result_add_txt(search_result, txt, txt_count, packet->tcpip_if, packet->ip_protocol);
} }
}
} else if (ours) { } else if (ours) {
if (parsed_packet->questions && !parsed_packet->probe) { if (parsed_packet->questions && !parsed_packet->probe) {
_mdns_remove_parsed_question(parsed_packet, type, service); _mdns_remove_parsed_question(parsed_packet, type, service);
@ -3038,7 +3113,7 @@ static void _mdns_search_free(mdns_search_once_t * search)
free(search->instance); free(search->instance);
free(search->service); free(search->service);
free(search->proto); free(search->proto);
vSemaphoreDelete(search->lock); vSemaphoreDelete(search->done_semaphore);
free(search); free(search);
} }
@ -3049,12 +3124,13 @@ static mdns_search_once_t * _mdns_search_init(const char * name, const char * se
{ {
mdns_search_once_t * search = (mdns_search_once_t *)malloc(sizeof(mdns_search_once_t)); mdns_search_once_t * search = (mdns_search_once_t *)malloc(sizeof(mdns_search_once_t));
if (!search) { if (!search) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
memset(search, 0, sizeof(mdns_search_once_t)); memset(search, 0, sizeof(mdns_search_once_t));
search->lock = xSemaphoreCreateMutex(); search->done_semaphore = xSemaphoreCreateBinary();
if (!search->lock) { if (!search->done_semaphore) {
free(search); free(search);
return NULL; return NULL;
} }
@ -3093,8 +3169,6 @@ static mdns_search_once_t * _mdns_search_init(const char * name, const char * se
search->started_at = xTaskGetTickCount() * portTICK_PERIOD_MS; search->started_at = xTaskGetTickCount() * portTICK_PERIOD_MS;
search->next = NULL; search->next = NULL;
xSemaphoreTake(search->lock, 0);
return search; return search;
} }
@ -3105,7 +3179,7 @@ static void _mdns_search_finish(mdns_search_once_t * search)
{ {
search->state = SEARCH_OFF; search->state = SEARCH_OFF;
queueDetach(mdns_search_once_t, _mdns_server->search_once, search); queueDetach(mdns_search_once_t, _mdns_server->search_once, search);
xSemaphoreGive(search->lock); xSemaphoreGive(search->done_semaphore);
} }
/** /**
@ -3140,6 +3214,7 @@ static mdns_ip_addr_t * _mdns_result_addr_create_ip(ip_addr_t * ip)
{ {
mdns_ip_addr_t * a = (mdns_ip_addr_t *)malloc(sizeof(mdns_ip_addr_t)); mdns_ip_addr_t * a = (mdns_ip_addr_t *)malloc(sizeof(mdns_ip_addr_t));
if (!a) { if (!a) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
memset(a, 0 , sizeof(mdns_ip_addr_t)); memset(a, 0 , sizeof(mdns_ip_addr_t));
@ -3199,6 +3274,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
if (!search->max_results || search->num_results < search->max_results) { if (!search->max_results || search->num_results < search->max_results) {
r = (mdns_result_t *)malloc(sizeof(mdns_result_t)); r = (mdns_result_t *)malloc(sizeof(mdns_result_t));
if (!r) { if (!r) {
HOOK_MALLOC_FAILED;
return; return;
} }
@ -3244,6 +3320,7 @@ static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search,
if (!search->max_results || search->num_results < search->max_results) { if (!search->max_results || search->num_results < search->max_results) {
r = (mdns_result_t *)malloc(sizeof(mdns_result_t)); r = (mdns_result_t *)malloc(sizeof(mdns_result_t));
if (!r) { if (!r) {
HOOK_MALLOC_FAILED;
return NULL; return NULL;
} }
@ -3279,6 +3356,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char
if (!search->max_results || search->num_results < search->max_results) { if (!search->max_results || search->num_results < search->max_results) {
r = (mdns_result_t *)malloc(sizeof(mdns_result_t)); r = (mdns_result_t *)malloc(sizeof(mdns_result_t));
if (!r) { if (!r) {
HOOK_MALLOC_FAILED;
return; return;
} }
@ -3307,7 +3385,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
while (r) { while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol) { if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol) {
if (r->txt) { if (r->txt) {
return; goto free_txt;
} }
r->txt = txt; r->txt = txt;
r->txt_count = txt_count; r->txt_count = txt_count;
@ -3318,12 +3396,8 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
if (!search->max_results || search->num_results < search->max_results) { if (!search->max_results || search->num_results < search->max_results) {
r = (mdns_result_t *)malloc(sizeof(mdns_result_t)); r = (mdns_result_t *)malloc(sizeof(mdns_result_t));
if (!r) { if (!r) {
for (i=0; i<txt_count; i++) { HOOK_MALLOC_FAILED;
free((char *)(txt[i].key)); goto free_txt;
free((char *)(txt[i].value));
}
free(txt);
return;
} }
memset(r, 0 , sizeof(mdns_result_t)); memset(r, 0 , sizeof(mdns_result_t));
@ -3335,6 +3409,14 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
search->result = r; search->result = r;
search->num_results++; search->num_results++;
} }
return;
free_txt:
for (i=0; i<txt_count; i++) {
free((char *)(txt[i].key));
free((char *)(txt[i].value));
}
free(txt);
} }
/** /**
@ -3420,6 +3502,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t)); mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t));
if (!q) { if (!q) {
HOOK_MALLOC_FAILED;
_mdns_free_tx_packet(packet); _mdns_free_tx_packet(packet);
return NULL; return NULL;
} }
@ -3442,6 +3525,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
} }
mdns_out_answer_t * a = (mdns_out_answer_t *)malloc(sizeof(mdns_out_answer_t)); mdns_out_answer_t * a = (mdns_out_answer_t *)malloc(sizeof(mdns_out_answer_t));
if (!a) { if (!a) {
HOOK_MALLOC_FAILED;
_mdns_free_tx_packet(packet); _mdns_free_tx_packet(packet);
return NULL; return NULL;
} }
@ -3467,7 +3551,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
static void _mdns_search_send_pcb(mdns_search_once_t * search, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) static void _mdns_search_send_pcb(mdns_search_once_t * search, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{ {
mdns_tx_packet_t * packet = NULL; mdns_tx_packet_t * packet = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state == PCB_RUNNING) { if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol); packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol);
if (!packet) { if (!packet) {
return; return;
@ -3482,6 +3566,22 @@ static void _mdns_search_send_pcb(mdns_search_once_t * search, tcpip_adapter_if_
*/ */
static void _mdns_search_send(mdns_search_once_t * search) static void _mdns_search_send(mdns_search_once_t * search)
{ {
mdns_search_once_t* queue = _mdns_server->search_once;
bool found = false;
// looking for this search in active searches
while (queue) {
if (queue == search) {
found = true;
break;
}
queue = queue->next;
}
if (!found) {
// no longer active -> skip sending this search
return;
}
uint8_t i, j; uint8_t i, j;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) { for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) { for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
@ -3671,6 +3771,7 @@ static void _mdns_execute_action(mdns_action_t * action)
if (!txt) { if (!txt) {
txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t)); txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
if (!txt) { if (!txt) {
HOOK_MALLOC_FAILED;
_mdns_free_action(action); _mdns_free_action(action);
return; return;
} }
@ -3719,6 +3820,7 @@ static void _mdns_execute_action(mdns_action_t * action)
if (_mdns_server->services == action->data.srv_del.service) { if (_mdns_server->services == action->data.srv_del.service) {
_mdns_server->services = a->next; _mdns_server->services = a->next;
_mdns_send_bye(&a, 1, false); _mdns_send_bye(&a, 1, false);
_mdns_remove_scheduled_service_packets(a->service);
_mdns_free_service(a->service); _mdns_free_service(a->service);
free(a); free(a);
} else { } else {
@ -3729,6 +3831,7 @@ static void _mdns_execute_action(mdns_action_t * action)
mdns_srv_item_t * b = a->next; mdns_srv_item_t * b = a->next;
a->next = a->next->next; a->next = a->next->next;
_mdns_send_bye(&b, 1, false); _mdns_send_bye(&b, 1, false);
_mdns_remove_scheduled_service_packets(b->service);
_mdns_free_service(b->service); _mdns_free_service(b->service);
free(b); free(b);
} }
@ -3742,6 +3845,7 @@ static void _mdns_execute_action(mdns_action_t * action)
while (a) { while (a) {
mdns_srv_item_t * s = a; mdns_srv_item_t * s = a;
a = a->next; a = a->next;
_mdns_remove_scheduled_service_packets(s->service);
_mdns_free_service(s->service); _mdns_free_service(s->service);
free(s); free(s);
} }
@ -3757,7 +3861,17 @@ static void _mdns_execute_action(mdns_action_t * action)
_mdns_search_finish(action->data.search_add.search); _mdns_search_finish(action->data.search_add.search);
break; break;
case ACTION_TX_HANDLE: case ACTION_TX_HANDLE:
_mdns_tx_handle_packet(action->data.tx_handle.packet); {
mdns_tx_packet_t * p = _mdns_server->tx_queue_head;
// packet to be handled should be at tx head, but must be consistent with the one pushed to action queue
if (p && p==action->data.tx_handle.packet && p->queued) {
p->queued = false; // clearing, as the packet might be reused (pushed and transmitted again)
_mdns_server->tx_queue_head = p->next;
_mdns_tx_handle_packet(p);
} else {
ESP_LOGD(TAG, "Skipping transmit of an unexpected packet!");
}
}
break; break;
case ACTION_RX_HANDLE: case ACTION_RX_HANDLE:
mdns_parse_packet(action->data.rx_handle.packet); mdns_parse_packet(action->data.rx_handle.packet);
@ -3779,6 +3893,7 @@ static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_o
action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -3793,26 +3908,38 @@ static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_o
/** /**
* @brief Called from timer task to run mDNS responder * @brief Called from timer task to run mDNS responder
*
* periodically checks first unqueued packet (from tx head).
* if it is scheduled to be transmitted, then pushes the packet to action queue to be handled.
*
*/ */
static void _mdns_scheduler_run() static void _mdns_scheduler_run()
{ {
MDNS_SERVICE_LOCK();
mdns_tx_packet_t * p = _mdns_server->tx_queue_head; mdns_tx_packet_t * p = _mdns_server->tx_queue_head;
mdns_action_t * action = NULL; mdns_action_t * action = NULL;
// find first unqueued packet
while (p && p->queued) {
p = p->next;
}
if (!p) { if (!p) {
MDNS_SERVICE_UNLOCK();
return; return;
} }
MDNS_SERVICE_LOCK();
if ((int32_t)(p->send_at - (xTaskGetTickCount() * portTICK_PERIOD_MS)) < 0) { if ((int32_t)(p->send_at - (xTaskGetTickCount() * portTICK_PERIOD_MS)) < 0) {
action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (action) { if (action) {
_mdns_server->tx_queue_head = p->next;
action->type = ACTION_TX_HANDLE; action->type = ACTION_TX_HANDLE;
action->data.tx_handle.packet = p; action->data.tx_handle.packet = p;
p->queued = true;
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) { if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
free(action); free(action);
_mdns_server->tx_queue_head = p; p->queued = false;
} }
} else {
HOOK_MALLOC_FAILED;
// continue
} }
} }
MDNS_SERVICE_UNLOCK(); MDNS_SERVICE_UNLOCK();
@ -3826,7 +3953,6 @@ static void _mdns_search_run()
MDNS_SERVICE_LOCK(); MDNS_SERVICE_LOCK();
mdns_search_once_t * s = _mdns_server->search_once; mdns_search_once_t * s = _mdns_server->search_once;
uint32_t now = xTaskGetTickCount() * portTICK_PERIOD_MS; uint32_t now = xTaskGetTickCount() * portTICK_PERIOD_MS;
if (!s) { if (!s) {
MDNS_SERVICE_UNLOCK(); MDNS_SERVICE_UNLOCK();
return; return;
@ -3930,7 +4056,10 @@ static esp_err_t _mdns_service_task_start()
if (!_mdns_service_task_handle) { if (!_mdns_service_task_handle) {
xTaskCreatePinnedToCore(_mdns_service_task, "mdns", MDNS_SERVICE_STACK_DEPTH, NULL, 1, (TaskHandle_t * const)(&_mdns_service_task_handle), 0); xTaskCreatePinnedToCore(_mdns_service_task, "mdns", MDNS_SERVICE_STACK_DEPTH, NULL, 1, (TaskHandle_t * const)(&_mdns_service_task_handle), 0);
if (!_mdns_service_task_handle) { if (!_mdns_service_task_handle) {
_mdns_stop_timer();
MDNS_SERVICE_UNLOCK(); MDNS_SERVICE_UNLOCK();
vSemaphoreDelete(_mdns_service_semaphore);
_mdns_service_semaphore = NULL;
return ESP_FAIL; return ESP_FAIL;
} }
} }
@ -3946,7 +4075,6 @@ static esp_err_t _mdns_service_task_start()
*/ */
static esp_err_t _mdns_service_task_stop() static esp_err_t _mdns_service_task_stop()
{ {
MDNS_SERVICE_LOCK();
_mdns_stop_timer(); _mdns_stop_timer();
if (_mdns_service_task_handle) { if (_mdns_service_task_handle) {
mdns_action_t action; mdns_action_t action;
@ -3960,7 +4088,8 @@ static esp_err_t _mdns_service_task_stop()
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
} }
} }
MDNS_SERVICE_UNLOCK(); vSemaphoreDelete(_mdns_service_semaphore);
_mdns_service_semaphore = NULL;
return ESP_OK; return ESP_OK;
} }
@ -3976,6 +4105,7 @@ esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event)
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_OK; return ESP_OK;
} }
action->type = ACTION_SYSTEM_EVENT; action->type = ACTION_SYSTEM_EVENT;
@ -3997,6 +4127,7 @@ esp_err_t mdns_init()
_mdns_server = (mdns_server_t *)malloc(sizeof(mdns_server_t)); _mdns_server = (mdns_server_t *)malloc(sizeof(mdns_server_t));
if (!_mdns_server) { if (!_mdns_server) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset((uint8_t*)_mdns_server, 0, sizeof(mdns_server_t)); memset((uint8_t*)_mdns_server, 0, sizeof(mdns_server_t));
@ -4013,12 +4144,6 @@ esp_err_t mdns_init()
goto free_lock; goto free_lock;
} }
if (_mdns_service_task_start()) {
//service start failed!
err = ESP_FAIL;
goto free_all;
}
uint8_t i; uint8_t i;
ip6_addr_t tmp_addr6; ip6_addr_t tmp_addr6;
tcpip_adapter_ip_info_t if_ip_info; tcpip_adapter_ip_info_t if_ip_info;
@ -4032,9 +4157,19 @@ esp_err_t mdns_init()
} }
} }
if (_mdns_service_task_start()) {
//service start failed!
err = ESP_FAIL;
goto free_all_and_disable_pcbs;
}
return ESP_OK; return ESP_OK;
free_all: free_all_and_disable_pcbs:
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V4);
}
vQueueDelete(_mdns_server->action_queue); vQueueDelete(_mdns_server->action_queue);
free_lock: free_lock:
vSemaphoreDelete(_mdns_server->lock); vSemaphoreDelete(_mdns_server->lock);
@ -4050,8 +4185,8 @@ void mdns_free()
if (!_mdns_server) { if (!_mdns_server) {
return; return;
} }
_mdns_service_task_stop();
mdns_service_remove_all(_mdns_server); mdns_service_remove_all(_mdns_server);
_mdns_service_task_stop();
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) { for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) { for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_pcb_deinit(i, j); _mdns_pcb_deinit(i, j);
@ -4073,7 +4208,7 @@ void mdns_free()
free(h->instance); free(h->instance);
free(h->service); free(h->service);
free(h->proto); free(h->proto);
vSemaphoreDelete(h->lock); vSemaphoreDelete(h->done_semaphore);
if (h->result) { if (h->result) {
mdns_query_results_free(h->result); mdns_query_results_free(h->result);
} }
@ -4099,6 +4234,7 @@ esp_err_t mdns_hostname_set(const char * hostname)
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
free(new_hostname); free(new_hostname);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4127,6 +4263,7 @@ esp_err_t mdns_instance_name_set(const char * instance)
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
free(new_instance); free(new_instance);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4166,6 +4303,7 @@ esp_err_t mdns_service_add(const char * instance, const char * service, const ch
item = (mdns_srv_item_t *)malloc(sizeof(mdns_srv_item_t)); item = (mdns_srv_item_t *)malloc(sizeof(mdns_srv_item_t));
if (!item) { if (!item) {
HOOK_MALLOC_FAILED;
_mdns_free_service(s); _mdns_free_service(s);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4175,6 +4313,7 @@ esp_err_t mdns_service_add(const char * instance, const char * service, const ch
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
_mdns_free_service(s); _mdns_free_service(s);
free(item); free(item);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
@ -4211,6 +4350,7 @@ esp_err_t mdns_service_port_set(const char * service, const char * proto, uint16
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
action->type = ACTION_SERVICE_PORT_SET; action->type = ACTION_SERVICE_PORT_SET;
@ -4243,6 +4383,7 @@ esp_err_t mdns_service_txt_set(const char * service, const char * proto, mdns_tx
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
_mdns_free_linked_txt(new_txt); _mdns_free_linked_txt(new_txt);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4270,6 +4411,7 @@ esp_err_t mdns_service_txt_item_set(const char * service, const char * proto, co
} }
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4306,6 +4448,7 @@ esp_err_t mdns_service_txt_item_remove(const char * service, const char * proto,
} }
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4343,6 +4486,7 @@ esp_err_t mdns_service_instance_name_set(const char * service, const char * prot
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
free(new_instance); free(new_instance);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
@ -4369,6 +4513,7 @@ esp_err_t mdns_service_remove(const char * service, const char * proto)
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
action->type = ACTION_SERVICE_DEL; action->type = ACTION_SERVICE_DEL;
@ -4391,6 +4536,7 @@ esp_err_t mdns_service_remove_all()
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) { if (!action) {
HOOK_MALLOC_FAILED;
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
action->type = ACTION_SERVICES_CLEAR; action->type = ACTION_SERVICES_CLEAR;
@ -4457,7 +4603,7 @@ esp_err_t mdns_query(const char * name, const char * service, const char * proto
_mdns_search_free(search); _mdns_search_free(search);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
xSemaphoreTake(search->lock, portMAX_DELAY); xSemaphoreTake(search->done_semaphore, portMAX_DELAY);
*results = search->result; *results = search->result;
_mdns_search_free(search); _mdns_search_free(search);

View File

@ -11,7 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifdef MDNS_ENABLE_CONSOLE
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "esp_console.h" #include "esp_console.h"
@ -1058,4 +1057,4 @@ void mdns_console_register()
register_mdns_query_ip(); register_mdns_query_ip();
register_mdns_query_svc(); register_mdns_query_svc();
} }
#endif

View File

@ -4,8 +4,9 @@
* *
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h> #include "mdns_private.h"
#include "mdns_networking.h" #include "mdns_networking.h"
#include "esp_log.h"
extern mdns_server_t * _mdns_server; extern mdns_server_t * _mdns_server;
@ -14,6 +15,7 @@ extern mdns_server_t * _mdns_server;
* MDNS Server Networking * MDNS Server Networking
* *
*/ */
static const char *TAG = "MDNS_Networking";
static struct udp_pcb * _pcb_main = NULL; static struct udp_pcb * _pcb_main = NULL;
@ -119,6 +121,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
mdns_rx_packet_t * packet = (mdns_rx_packet_t *)malloc(sizeof(mdns_rx_packet_t)); mdns_rx_packet_t * packet = (mdns_rx_packet_t *)malloc(sizeof(mdns_rx_packet_t));
if (!packet) { if (!packet) {
HOOK_MALLOC_FAILED;
//missed packet - no memory //missed packet - no memory
pbuf_free(this_pb); pbuf_free(this_pb);
continue; continue;
@ -240,6 +243,9 @@ typedef struct {
struct tcpip_api_call_data call; struct tcpip_api_call_data call;
tcpip_adapter_if_t tcpip_if; tcpip_adapter_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol; mdns_ip_protocol_t ip_protocol;
struct pbuf *pbt;
const ip_addr_t *ip;
uint16_t port;
esp_err_t err; esp_err_t err;
} mdns_api_call_t; } mdns_api_call_t;
@ -275,7 +281,7 @@ esp_err_t _mdns_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_prot
.tcpip_if = tcpip_if, .tcpip_if = tcpip_if,
.ip_protocol = ip_protocol .ip_protocol = ip_protocol
}; };
tcpip_api_call(_mdns_pcb_init_api, (struct tcpip_api_call_data*)&msg); tcpip_api_call(_mdns_pcb_init_api, &msg.call);
return msg.err; return msg.err;
} }
@ -285,29 +291,45 @@ esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_pr
.tcpip_if = tcpip_if, .tcpip_if = tcpip_if,
.ip_protocol = ip_protocol .ip_protocol = ip_protocol
}; };
tcpip_api_call(_mdns_pcb_deinit_api, (struct tcpip_api_call_data*)&msg); tcpip_api_call(_mdns_pcb_deinit_api, &msg.call);
return msg.err; return msg.err;
} }
static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
{
void * nif = NULL;
mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
mdns_pcb_t * _pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol];
esp_err_t err = tcpip_adapter_get_netif(msg->tcpip_if, &nif);
if (err) {
pbuf_free(msg->pbt);
msg->err = err;
return err;
}
err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
pbuf_free(msg->pbt);
msg->err = err;
return err;
}
size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len) size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
{ {
struct netif * netif = NULL;
void * nif = NULL;
esp_err_t err = tcpip_adapter_get_netif(tcpip_if, &nif);
netif = (struct netif *)nif;
if (err) {
return 0;
}
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (pbt == NULL) { if (pbt == NULL) {
return 0; return 0;
} }
memcpy((uint8_t *)pbt->payload, data, len); memcpy((uint8_t *)pbt->payload, data, len);
err = udp_sendto_if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb, pbt, ip, port, netif); mdns_api_call_t msg = {
pbuf_free(pbt); .tcpip_if = tcpip_if,
if (err) { .ip_protocol = ip_protocol,
.pbt = pbt,
.ip = ip,
.port = port
};
tcpip_api_call(_mdns_udp_pcb_write_api, &msg.call);
if (msg.err) {
return 0; return 0;
} }
return len; return len;

View File

@ -1,6 +1,6 @@
# The following five lines of boilerplate have to be in your project's # The following lines of boilerplate have to be in your project's CMakeLists
# CMakeLists in this exact order for cmake to work correctly # in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mdns) project(mdns-test)

View File

@ -1,3 +1,4 @@
set(COMPONENT_SRCS "mdns_example_main.c") set(COMPONENT_SRCS "mdns_example_main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component() register_component()

View File

@ -8,7 +8,7 @@ config WIFI_SSID
config WIFI_PASSWORD config WIFI_PASSWORD
string "WiFi Password" string "WiFi Password"
default "myssid" default "mypassword"
help help
WiFi password (WPA or WPA2) for the example to use. WiFi password (WPA or WPA2) for the example to use.

10
examples/protocols/mdns/main/mdns_example_main.c Executable file → Normal file
View File

@ -145,13 +145,13 @@ static void mdns_print_results(mdns_result_t * results){
if(r->txt_count){ if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count); printf(" TXT : [%u] ", r->txt_count);
for(t=0; t<r->txt_count; t++){ for(t=0; t<r->txt_count; t++){
printf("%s=%s; ", r->txt[t].key, r->txt[t].value); printf("%s=%s; ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL");
} }
printf("\n"); printf("\n");
} }
a = r->addr; a = r->addr;
while(a){ while(a){
if(a->addr.type == MDNS_IP_PROTOCOL_V6){ if(a->addr.type == IPADDR_TYPE_V6){
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
} else { } else {
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
@ -170,7 +170,7 @@ static void query_mdns_service(const char * service_name, const char * proto)
mdns_result_t * results = NULL; mdns_result_t * results = NULL;
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results); esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
if(err){ if(err){
ESP_LOGE(TAG, "Query Failed"); ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
return; return;
} }
if(!results){ if(!results){
@ -192,10 +192,10 @@ static void query_mdns_host(const char * host_name)
esp_err_t err = mdns_query_a(host_name, 2000, &addr); esp_err_t err = mdns_query_a(host_name, 2000, &addr);
if(err){ if(err){
if(err == ESP_ERR_NOT_FOUND){ if(err == ESP_ERR_NOT_FOUND){
ESP_LOGW(TAG, "Host was not found!"); ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err));
return; return;
} }
ESP_LOGE(TAG, "Query Failed"); ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
return; return;
} }