2017-01-04 16:54:07 +00: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 13:21:40 +00:00
# include "driver/gpio.h"
# include <sys/socket.h>
# include <netdb.h>
2017-01-04 16:54:07 +00: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_INSTANCE CONFIG_MDNS_INSTANCE
2018-10-12 14:45:52 +00:00
2017-01-04 16:54:07 +00:00
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group ;
2018-10-12 14:45:52 +00:00
static const char c_config_hostname [ ] = CONFIG_MDNS_HOSTNAME ;
2017-01-04 16:54:07 +00:00
/* 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 13:21:40 +00:00
const int IP4_CONNECTED_BIT = BIT0 ;
const int IP6_CONNECTED_BIT = BIT1 ;
2017-01-04 16:54:07 +00:00
static const char * TAG = " mdns-test " ;
2017-12-07 13:21:40 +00:00
static bool auto_reconnect = true ;
2017-01-04 16:54:07 +00: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 13:21:40 +00: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-04 16:54:07 +00:00
break ;
case SYSTEM_EVENT_STA_DISCONNECTED :
/* This is a workaround as ESP32 WiFi libs don't currently
auto - reassociate . */
2017-12-07 13:21:40 +00:00
if ( auto_reconnect ) {
esp_wifi_connect ( ) ;
}
xEventGroupClearBits ( wifi_event_group , IP4_CONNECTED_BIT | IP6_CONNECTED_BIT ) ;
2017-01-04 16:54:07 +00:00
break ;
default :
break ;
}
2017-12-07 13:21:40 +00:00
mdns_handle_system_event ( ctx , event ) ;
2017-01-04 16:54:07 +00: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 13:21:40 +00:00
static void initialise_mdns ( void )
2017-01-04 16:54:07 +00:00
{
2018-10-12 14:45:52 +00:00
_Static_assert ( sizeof ( c_config_hostname ) < CONFIG_MAIN_TASK_STACK_SIZE / 2 , " Configured mDNS name consumes more than half of the stack. Please select a shorter host name or extend the main stack size please. " ) ;
const size_t config_hostname_len = sizeof ( c_config_hostname ) - 1 ; // without term char
char hostname [ config_hostname_len + 1 + 3 * 2 + 1 ] ; // adding underscore + 3 digits + term char
uint8_t mac [ 6 ] ;
// adding 3 LSBs from mac addr to setup a board specific name
esp_read_mac ( mac , ESP_MAC_WIFI_STA ) ;
snprintf ( hostname , sizeof ( hostname ) , " %s_%02x%02X%02X " , c_config_hostname , mac [ 3 ] , mac [ 4 ] , mac [ 5 ] ) ;
2017-12-07 13:21:40 +00:00
//initialize mDNS
ESP_ERROR_CHECK ( mdns_init ( ) ) ;
//set mDNS hostname (required if you want to advertise services)
2018-10-12 14:45:52 +00:00
ESP_ERROR_CHECK ( mdns_hostname_set ( hostname ) ) ;
ESP_LOGI ( TAG , " mdns hostname set to: [%s] " , hostname ) ;
2017-12-07 13:21:40 +00:00
//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 + + ) {
2018-04-30 07:03:35 +00:00
printf ( " %s=%s; " , r - > txt [ t ] . key , r - > txt [ t ] . value ? r - > txt [ t ] . value : " NULL " ) ;
2017-01-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00:00
printf ( " \n " ) ;
2017-01-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00: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-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00:00
a = a - > next ;
2017-01-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00:00
r = r - > next ;
2017-01-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00:00
2017-01-04 16:54:07 +00:00
}
2017-12-07 13:21:40 +00:00
static void query_mdns_service ( const char * service_name , const char * proto )
2017-01-04 16:54:07 +00:00
{
2017-12-07 13:21:40 +00: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 13:48:53 +00:00
ESP_LOGE ( TAG , " Query Failed: %s " , esp_err_to_name ( err ) ) ;
2017-12-07 13:21:40 +00:00
return ;
}
if ( ! results ) {
ESP_LOGW ( TAG , " No results found! " ) ;
return ;
}
2017-01-04 16:54:07 +00:00
2017-12-07 13:21:40 +00: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 13:48:53 +00:00
ESP_LOGW ( TAG , " %s: Host was not found! " , esp_err_to_name ( err ) ) ;
2017-12-07 13:21:40 +00:00
return ;
2017-01-04 16:54:07 +00:00
}
2018-02-22 13:48:53 +00:00
ESP_LOGE ( TAG , " Query Failed: %s " , esp_err_to_name ( err ) ) ;
2017-12-07 13:21:40 +00:00
return ;
}
2017-01-04 16:54:07 +00:00
2018-10-12 14:45:52 +00:00
ESP_LOGI ( TAG , " Query A: %s.local resolved to: " IPSTR , host_name , IP2STR ( & addr ) ) ;
2017-12-07 13:21:40 +00:00
}
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 ) ;
2018-10-12 14:45:52 +00:00
# if CONFIG_RESOLVE_TEST_SERVICES == 1
/* Send initial queries that are started by CI tester */
query_mdns_host ( " tinytester " ) ;
# endif
2017-12-07 13:21:40 +00:00
while ( 1 ) {
check_button ( ) ;
vTaskDelay ( 50 / portTICK_PERIOD_MS ) ;
2017-01-04 16:54:07 +00:00
}
}
void app_main ( )
{
2017-03-14 13:39:44 +00:00
ESP_ERROR_CHECK ( nvs_flash_init ( ) ) ;
2017-12-07 13:21:40 +00:00
initialise_mdns ( ) ;
2017-01-04 16:54:07 +00:00
initialise_wifi ( ) ;
2017-12-07 13:21:40 +00:00
initialise_button ( ) ;
2017-03-22 04:36:11 +00:00
xTaskCreate ( & mdns_example_task , " mdns_example_task " , 2048 , NULL , 5 , NULL ) ;
2017-01-04 16:54:07 +00:00
}