mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-29 10:17:30 +02:00
mdns: Add asynchronous query API
Closes https://github.com/espressif/esp-idf/issues/7090 * Original commit: espressif/esp-idf@d81482d699
This commit is contained in:
committed by
suren-gabrielyan-espressif
parent
40da0d29be
commit
47c7266103
@ -30,6 +30,11 @@ extern "C" {
|
|||||||
#define MDNS_TYPE_NSEC 0x002F
|
#define MDNS_TYPE_NSEC 0x002F
|
||||||
#define MDNS_TYPE_ANY 0x00FF
|
#define MDNS_TYPE_ANY 0x00FF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Asynchronous query handle
|
||||||
|
*/
|
||||||
|
typedef struct mdns_search_once_s mdns_search_once_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief mDNS enum to specify the ip_protocol type
|
* @brief mDNS enum to specify the ip_protocol type
|
||||||
*/
|
*/
|
||||||
@ -477,6 +482,49 @@ esp_err_t mdns_service_txt_item_remove_for_host(const char * service_type, const
|
|||||||
*/
|
*/
|
||||||
esp_err_t mdns_service_remove_all(void);
|
esp_err_t mdns_service_remove_all(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deletes the finished query. Call this only after the search has ended!
|
||||||
|
*
|
||||||
|
* @param search pointer to search object
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK success
|
||||||
|
* - ESP_ERR_INVALID_STATE search has not finished
|
||||||
|
* - ESP_ERR_INVALID_ARG pointer to search object is NULL
|
||||||
|
*/
|
||||||
|
esp_err_t mdns_query_async_delete(mdns_search_once_t* search);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get results from search pointer. Results available as a pointer to the output parameter.
|
||||||
|
* Pointer to search object has to be deleted via `mdns_query_async_delete` once the query has finished.
|
||||||
|
* The results although have to be freed manually.
|
||||||
|
*
|
||||||
|
* @param search pointer to search object
|
||||||
|
* @param timeout time in milliseconds to wait for answers
|
||||||
|
* @param results pointer to the results of the query
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* True if search has finished before or at timeout
|
||||||
|
* False if search timeout is over
|
||||||
|
*/
|
||||||
|
bool mdns_query_async_get_results(mdns_search_once_t* search, uint32_t timeout, mdns_result_t ** results);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Query mDNS for host or service asynchronousely.
|
||||||
|
* Search has to be tested for progress and deleted manually!
|
||||||
|
*
|
||||||
|
* @param name service instance or host name (NULL for PTR queries)
|
||||||
|
* @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries)
|
||||||
|
* @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries)
|
||||||
|
* @param type type of query (MDNS_TYPE_*)
|
||||||
|
* @param timeout time in milliseconds during which mDNS query is active
|
||||||
|
* @param max_results maximum results to be collected
|
||||||
|
*
|
||||||
|
* @return mdns_search_once_s pointer to new search object if query initiated successfully.
|
||||||
|
* NULL otherwise.
|
||||||
|
*/
|
||||||
|
mdns_search_once_t* mdns_query_async_new(const char * name, const char * service_type, const char * proto, uint16_t type, uint32_t timeout, size_t max_results);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Query mDNS for host or service
|
* @brief Query mDNS for host or service
|
||||||
* All following query methods are derived from this one
|
* All following query methods are derived from this one
|
||||||
|
@ -5292,6 +5292,52 @@ void mdns_query_results_free(mdns_result_t * results)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t mdns_query_async_delete(mdns_search_once_t* search)
|
||||||
|
{
|
||||||
|
if (!search) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
if (search->state != SEARCH_OFF) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDNS_SERVICE_LOCK();
|
||||||
|
_mdns_search_free(search);
|
||||||
|
MDNS_SERVICE_UNLOCK();
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mdns_query_async_get_results(mdns_search_once_t* search, uint32_t timeout, mdns_result_t ** results)
|
||||||
|
{
|
||||||
|
if (xSemaphoreTake(search->done_semaphore, pdMS_TO_TICKS(timeout)) == pdTRUE) {
|
||||||
|
*results = search->result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdns_search_once_t* mdns_query_async_new(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, size_t max_results)
|
||||||
|
{
|
||||||
|
mdns_search_once_t *search = NULL;
|
||||||
|
|
||||||
|
if (!_mdns_server || !timeout || _str_null_or_empty(service) != _str_null_or_empty(proto)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
search = _mdns_search_init(name, service, proto, type, timeout, max_results);
|
||||||
|
if (!search) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mdns_send_search_action(ACTION_SEARCH_ADD, search)) {
|
||||||
|
_mdns_search_free(search);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t mdns_query(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t ** results)
|
esp_err_t mdns_query(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t ** results)
|
||||||
{
|
{
|
||||||
mdns_search_once_t * search = NULL;
|
mdns_search_once_t * search = NULL;
|
||||||
|
@ -63,10 +63,10 @@
|
|||||||
|
|
||||||
#define pdMS_TO_TICKS(a) a
|
#define pdMS_TO_TICKS(a) a
|
||||||
#define portTICK_RATE_MS 10
|
#define portTICK_RATE_MS 10
|
||||||
#define xSemaphoreTake(s,d)
|
|
||||||
#define xTaskDelete(a)
|
#define xTaskDelete(a)
|
||||||
#define vTaskDelete(a) free(a)
|
#define vTaskDelete(a) free(a)
|
||||||
#define xSemaphoreGive(s)
|
#define xSemaphoreGive(s)
|
||||||
|
#define xSemaphoreTake(s,d) true
|
||||||
#define xQueueCreateMutex(s)
|
#define xQueueCreateMutex(s)
|
||||||
#define _mdns_pcb_init(a,b) true
|
#define _mdns_pcb_init(a,b) true
|
||||||
#define _mdns_pcb_deinit(a,b) true
|
#define _mdns_pcb_deinit(a,b) true
|
||||||
|
@ -138,6 +138,54 @@ static void query_mdns_service(const char * service_name, const char * proto)
|
|||||||
mdns_query_results_free(results);
|
mdns_query_results_free(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_and_print_result(mdns_search_once_t *search)
|
||||||
|
{
|
||||||
|
// Check if any result is available
|
||||||
|
mdns_result_t * result = NULL;
|
||||||
|
if (!mdns_query_async_get_results(search, 0, &result)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) { // search timeout, but no result
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If yes, print the result
|
||||||
|
mdns_ip_addr_t * a = result->addr;
|
||||||
|
while (a) {
|
||||||
|
if(a->addr.type == ESP_IPADDR_TYPE_V6){
|
||||||
|
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
|
||||||
|
} else {
|
||||||
|
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
|
||||||
|
}
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
// and free the result
|
||||||
|
mdns_query_results_free(result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void query_mdns_hosts_async(const char * host_name)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Query both A and AAA: %s.local", host_name);
|
||||||
|
|
||||||
|
mdns_search_once_t *s_a = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_A, 1000, 1);
|
||||||
|
mdns_query_async_delete(s_a);
|
||||||
|
mdns_search_once_t *s_aaaa = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_AAAA, 1000, 1);
|
||||||
|
while (s_a || s_aaaa) {
|
||||||
|
if (s_a && check_and_print_result(s_a)) {
|
||||||
|
ESP_LOGI(TAG, "Query A %s.local finished", host_name);
|
||||||
|
mdns_query_async_delete(s_a);
|
||||||
|
s_a = NULL;
|
||||||
|
}
|
||||||
|
if (s_aaaa && check_and_print_result(s_aaaa)) {
|
||||||
|
ESP_LOGI(TAG, "Query AAAA %s.local finished", host_name);
|
||||||
|
mdns_query_async_delete(s_aaaa);
|
||||||
|
s_aaaa = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void query_mdns_host(const char * host_name)
|
static void query_mdns_host(const char * host_name)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Query A: %s.local", host_name);
|
ESP_LOGI(TAG, "Query A: %s.local", host_name);
|
||||||
@ -174,6 +222,7 @@ static void check_button(void)
|
|||||||
static bool old_level = true;
|
static bool old_level = true;
|
||||||
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
|
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
|
||||||
if (!new_level && old_level) {
|
if (!new_level && old_level) {
|
||||||
|
query_mdns_hosts_async("esp32-mdns");
|
||||||
query_mdns_host("esp32");
|
query_mdns_host("esp32");
|
||||||
query_mdns_service("_arduino", "_tcp");
|
query_mdns_service("_arduino", "_tcp");
|
||||||
query_mdns_service("_http", "_tcp");
|
query_mdns_service("_http", "_tcp");
|
||||||
|
Reference in New Issue
Block a user