| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | /* MDNS-SD Query and advertise Example
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This example code is in the Public Domain (or CC0 licensed, at your option.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Unless required by applicable law or agreed to in writing, this | 
					
						
							|  |  |  |    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | 
					
						
							|  |  |  |    CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/task.h"
 | 
					
						
							|  |  |  | #include "freertos/event_groups.h"
 | 
					
						
							|  |  |  | #include "esp_system.h"
 | 
					
						
							|  |  |  | #include "esp_wifi.h"
 | 
					
						
							|  |  |  | #include "esp_event_loop.h"
 | 
					
						
							|  |  |  | #include "esp_log.h"
 | 
					
						
							|  |  |  | #include "nvs_flash.h"
 | 
					
						
							|  |  |  | #include "mdns.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | #include "driver/gpio.h"
 | 
					
						
							|  |  |  | #include <sys/socket.h>
 | 
					
						
							|  |  |  | #include <netdb.h>
 | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* The examples use simple WiFi configuration that you can set via
 | 
					
						
							|  |  |  |    'make menuconfig'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    If you'd rather not, just change the below entries to strings with | 
					
						
							|  |  |  |    the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
 | 
					
						
							|  |  |  | #define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define EXAMPLE_MDNS_HOSTNAME CONFIG_MDNS_HOSTNAME
 | 
					
						
							|  |  |  | #define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* FreeRTOS event group to signal when we are connected & ready to make a request */ | 
					
						
							|  |  |  | static EventGroupHandle_t wifi_event_group; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The event group allows multiple bits for each event,
 | 
					
						
							|  |  |  |    but we only care about one event - are we connected | 
					
						
							|  |  |  |    to the AP with an IP? */ | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | const int IP4_CONNECTED_BIT = BIT0; | 
					
						
							|  |  |  | const int IP6_CONNECTED_BIT = BIT1; | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static const char *TAG = "mdns-test"; | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | static bool auto_reconnect = true; | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static esp_err_t event_handler(void *ctx, system_event_t *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch(event->event_id) { | 
					
						
							|  |  |  |     case SYSTEM_EVENT_STA_START: | 
					
						
							|  |  |  |         esp_wifi_connect(); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SYSTEM_EVENT_STA_CONNECTED: | 
					
						
							|  |  |  |         /* enable ipv6 */ | 
					
						
							|  |  |  |         tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SYSTEM_EVENT_STA_GOT_IP: | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         xEventGroupSetBits(wifi_event_group, IP4_CONNECTED_BIT); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SYSTEM_EVENT_AP_STA_GOT_IP6: | 
					
						
							|  |  |  |         xEventGroupSetBits(wifi_event_group, IP6_CONNECTED_BIT); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case SYSTEM_EVENT_STA_DISCONNECTED: | 
					
						
							|  |  |  |         /* This is a workaround as ESP32 WiFi libs don't currently
 | 
					
						
							|  |  |  |            auto-reassociate. */ | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         if (auto_reconnect) { | 
					
						
							|  |  |  |             esp_wifi_connect(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         xEventGroupClearBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     mdns_handle_system_event(ctx, event); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void initialise_wifi(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     tcpip_adapter_init(); | 
					
						
							|  |  |  |     wifi_event_group = xEventGroupCreate(); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); | 
					
						
							|  |  |  |     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); | 
					
						
							|  |  |  |     wifi_config_t wifi_config = { | 
					
						
							|  |  |  |         .sta = { | 
					
						
							|  |  |  |             .ssid = EXAMPLE_WIFI_SSID, | 
					
						
							|  |  |  |             .password = EXAMPLE_WIFI_PASS, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( esp_wifi_start() ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | static void initialise_mdns(void) | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     //initialize mDNS
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_init() ); | 
					
						
							|  |  |  |     //set mDNS hostname (required if you want to advertise services)
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_hostname_set(EXAMPLE_MDNS_HOSTNAME) ); | 
					
						
							|  |  |  |     //set default mDNS instance name
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //structure with TXT records
 | 
					
						
							|  |  |  |     mdns_txt_item_t serviceTxtData[3] = { | 
					
						
							|  |  |  |         {"board","esp32"}, | 
					
						
							|  |  |  |         {"u","user"}, | 
					
						
							|  |  |  |         {"p","password"} | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //initialize service
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3) ); | 
					
						
							|  |  |  |     //add another TXT item
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") ); | 
					
						
							|  |  |  |     //change TXT item value
 | 
					
						
							|  |  |  |     ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "u", "admin") ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char * if_str[] = {"STA", "AP", "ETH", "MAX"}; | 
					
						
							|  |  |  | static const char * ip_protocol_str[] = {"V4", "V6", "MAX"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void mdns_print_results(mdns_result_t * results){ | 
					
						
							|  |  |  |     mdns_result_t * r = results; | 
					
						
							|  |  |  |     mdns_ip_addr_t * a = NULL; | 
					
						
							|  |  |  |     int i = 1, t; | 
					
						
							|  |  |  |     while(r){ | 
					
						
							|  |  |  |         printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]); | 
					
						
							|  |  |  |         if(r->instance_name){ | 
					
						
							|  |  |  |             printf("  PTR : %s\n", r->instance_name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if(r->hostname){ | 
					
						
							|  |  |  |             printf("  SRV : %s.local:%u\n", r->hostname, r->port); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if(r->txt_count){ | 
					
						
							|  |  |  |             printf("  TXT : [%u] ", r->txt_count); | 
					
						
							|  |  |  |             for(t=0; t<r->txt_count; t++){ | 
					
						
							|  |  |  |                 printf("%s=%s; ", r->txt[t].key, r->txt[t].value); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |             printf("\n"); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         a = r->addr; | 
					
						
							|  |  |  |         while(a){ | 
					
						
							|  |  |  |             if(a->addr.type == MDNS_IP_PROTOCOL_V6){ | 
					
						
							|  |  |  |                 printf("  AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 printf("  A   : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |             a = a->next; | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         r = r->next; | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  | static void query_mdns_service(const char * service_name, const char * proto) | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mdns_result_t * results = NULL; | 
					
						
							|  |  |  |     esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20,  &results); | 
					
						
							|  |  |  |     if(err){ | 
					
						
							| 
									
										
										
										
											2018-02-22 14:48:53 +01:00
										 |  |  |         ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if(!results){ | 
					
						
							|  |  |  |         ESP_LOGW(TAG, "No results found!"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     mdns_print_results(results); | 
					
						
							|  |  |  |     mdns_query_results_free(results); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void query_mdns_host(const char * host_name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ESP_LOGI(TAG, "Query A: %s.local", host_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct ip4_addr addr; | 
					
						
							|  |  |  |     addr.addr = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     esp_err_t err = mdns_query_a(host_name, 2000,  &addr); | 
					
						
							|  |  |  |     if(err){ | 
					
						
							|  |  |  |         if(err == ESP_ERR_NOT_FOUND){ | 
					
						
							| 
									
										
										
										
											2018-02-22 14:48:53 +01:00
										 |  |  |             ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err)); | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |             return; | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-22 14:48:53 +01:00
										 |  |  |         ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err)); | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     ESP_LOGI(TAG, IPSTR, IP2STR(&addr)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void initialise_button(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     gpio_config_t io_conf; | 
					
						
							|  |  |  |     io_conf.intr_type = GPIO_PIN_INTR_DISABLE; | 
					
						
							|  |  |  |     io_conf.pin_bit_mask = 1; | 
					
						
							|  |  |  |     io_conf.mode = GPIO_MODE_INPUT; | 
					
						
							|  |  |  |     io_conf.pull_up_en = 1; | 
					
						
							|  |  |  |     io_conf.pull_down_en = 0; | 
					
						
							|  |  |  |     gpio_config(&io_conf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void check_button(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static bool old_level = true; | 
					
						
							|  |  |  |     bool new_level = gpio_get_level(GPIO_NUM_0); | 
					
						
							|  |  |  |     if (!new_level && old_level) { | 
					
						
							|  |  |  |         query_mdns_host("esp32"); | 
					
						
							|  |  |  |         query_mdns_service("_arduino", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_http", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_printer", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_ipp", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_afpovertcp", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_smb", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_ftp", "_tcp"); | 
					
						
							|  |  |  |         query_mdns_service("_nfs", "_tcp"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     old_level = new_level; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void mdns_example_task(void *pvParameters) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* Wait for the callback to set the CONNECTED_BIT in the event group. */ | 
					
						
							|  |  |  |     xEventGroupWaitBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT, | 
					
						
							|  |  |  |                      false, true, portMAX_DELAY); | 
					
						
							|  |  |  |     while(1) { | 
					
						
							|  |  |  |         check_button(); | 
					
						
							|  |  |  |         vTaskDelay(50 / portTICK_PERIOD_MS); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void app_main() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-14 21:39:44 +08:00
										 |  |  |     ESP_ERROR_CHECK( nvs_flash_init() ); | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     initialise_mdns(); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  |     initialise_wifi(); | 
					
						
							| 
									
										
										
										
											2017-12-07 14:21:40 +01:00
										 |  |  |     initialise_button(); | 
					
						
							| 
									
										
										
										
											2017-03-22 12:36:11 +08:00
										 |  |  |     xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); | 
					
						
							| 
									
										
										
										
											2017-01-16 23:08:35 +01:00
										 |  |  | } |