mdns_test.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <string.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "mdns.h"
  10. #include "esp_log.h"
  11. #include "esp_netif.h"
  12. static const char *TAG = "mdns_test_app";
  13. static const int RETRY_COUNT = 10;
  14. static void mdns_print_results(mdns_result_t *results)
  15. {
  16. mdns_result_t *r = results;
  17. mdns_ip_addr_t *a = NULL;
  18. int t;
  19. while (r) {
  20. if (r->instance_name) {
  21. printf("PTR:%s.%s.%s\n", r->instance_name, r->service_type, r->proto);
  22. }
  23. if (r->hostname) {
  24. printf("SRV:%s.local:%u\n", r->hostname, r->port);
  25. }
  26. if (r->txt_count) {
  27. printf("TXT:[%zu] ", r->txt_count);
  28. for (t = 0; t < r->txt_count; t++) {
  29. printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL", r->txt_value_len[t]);
  30. }
  31. printf("\n");
  32. }
  33. a = r->addr;
  34. while (a) {
  35. if (a->addr.type == ESP_IPADDR_TYPE_V6) {
  36. printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
  37. } else {
  38. printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
  39. }
  40. a = a->next;
  41. }
  42. r = r->next;
  43. }
  44. }
  45. static bool check_and_print_result(mdns_search_once_t *search)
  46. {
  47. // Check if any result is available
  48. mdns_result_t *result = NULL;
  49. if (!mdns_query_async_get_results(search, 0, &result, NULL)) {
  50. return false;
  51. }
  52. if (!result) { // search timeout, but no result
  53. return false;
  54. }
  55. // If yes, print the result
  56. mdns_ip_addr_t *a = result->addr;
  57. while (a) {
  58. if (a->addr.type == ESP_IPADDR_TYPE_V6) {
  59. printf("Async query resolved to AAAA:" IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
  60. } else {
  61. printf("Async query resolved to A:" IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
  62. }
  63. a = a->next;
  64. }
  65. // and free the result
  66. mdns_query_results_free(result);
  67. return true;
  68. }
  69. static bool query_mdns_hosts_async(const char *host_name)
  70. {
  71. ESP_LOGI(TAG, "Query both A and AAA: %s.local", host_name);
  72. bool res = false;
  73. mdns_search_once_t *s_a = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_A, 1000, 1, NULL);
  74. mdns_query_async_delete(s_a);
  75. mdns_search_once_t *s_aaaa = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_AAAA, 1000, 1, NULL);
  76. while (s_a || s_aaaa) {
  77. if (s_a && check_and_print_result(s_a)) {
  78. ESP_LOGI(TAG, "Query A %s.local finished", host_name);
  79. mdns_query_async_delete(s_a);
  80. s_a = NULL;
  81. res = true;
  82. }
  83. if (s_aaaa && check_and_print_result(s_aaaa)) {
  84. ESP_LOGI(TAG, "Query AAAA %s.local finished", host_name);
  85. mdns_query_async_delete(s_aaaa);
  86. s_aaaa = NULL;
  87. res = true;
  88. }
  89. }
  90. return res;
  91. }
  92. static esp_err_t query_mdns_host(const char *host_name)
  93. {
  94. ESP_LOGI(TAG, "Query A: %s.local", host_name);
  95. struct esp_ip4_addr addr;
  96. addr.addr = 0;
  97. esp_err_t err = mdns_query_a(host_name, 2000, &addr);
  98. if (err) {
  99. if (err == ESP_ERR_NOT_FOUND) {
  100. ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err));
  101. }
  102. ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
  103. return err;
  104. }
  105. ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
  106. return ESP_OK;
  107. }
  108. static esp_err_t query_mdns_service(const char *instance, const char *service_name, const char *proto)
  109. {
  110. ESP_LOGI(TAG, "Query SRV: %s.%s.local", service_name, proto);
  111. mdns_result_t *results = NULL;
  112. esp_err_t err = mdns_query_srv(instance, service_name, proto, 3000, &results);
  113. if (err) {
  114. ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
  115. return err;
  116. }
  117. if (!results) {
  118. ESP_LOGW(TAG, "No results found!");
  119. }
  120. mdns_print_results(results);
  121. mdns_query_results_free(results);
  122. return ESP_OK;
  123. }
  124. void query_mdns_service_sub_type(const char *subtype, const char *service_name, const char *proto)
  125. {
  126. ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
  127. mdns_result_t *results = NULL;
  128. esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
  129. if (err) {
  130. ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
  131. }
  132. if (!results) {
  133. ESP_LOGW(TAG, "No results found!");
  134. }
  135. mdns_print_results(results);
  136. mdns_query_results_free(results);
  137. }
  138. void mdns_test(const char *line)
  139. {
  140. char test_case[32];
  141. int i = 0;
  142. const TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
  143. sscanf(line, "%s", test_case);
  144. ESP_LOGI(TAG, "test case = %s", test_case);
  145. if (strcmp(test_case, "CONFIG_TEST_QUERY_HOST") == 0) {
  146. i = 0;
  147. while (query_mdns_host("tinytester") != ESP_OK && i != RETRY_COUNT) {
  148. query_mdns_host("tinytester");
  149. i++;
  150. vTaskDelay(xDelay);
  151. }
  152. } else if (strcmp(test_case, "CONFIG_TEST_QUERY_HOST_ASYNC") == 0) {
  153. i = 0;
  154. while (query_mdns_hosts_async("tinytester") == false && i != RETRY_COUNT) {
  155. query_mdns_hosts_async("tinytester");
  156. i++;
  157. vTaskDelay(xDelay);
  158. }
  159. } else if (strcmp(test_case, "CONFIG_TEST_QUERY_SERVICE") == 0) {
  160. i = 0;
  161. while (query_mdns_service("ESP32", "_http", "_tcp") != ESP_OK && i != RETRY_COUNT) {
  162. query_mdns_service("ESP32", "_http", "_tcp");
  163. i++;
  164. vTaskDelay(xDelay);
  165. }
  166. } else {
  167. ESP_LOGE(TAG, "%s: No such test case", test_case);
  168. }
  169. }