Merge branch 'feature/mdns_again' into 'master'

New mDNS implementation

See merge request !1683
This commit is contained in:
Ivan Grokhotkov 2018-01-16 18:38:42 +08:00
commit 429371c182
11 changed files with 5954 additions and 1359 deletions

View file

@ -0,0 +1,2 @@
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := private_include

View file

@ -20,35 +20,69 @@ extern "C" {
#ifndef MDNS_TEST_MODE #ifndef MDNS_TEST_MODE
#include <tcpip_adapter.h> #include <tcpip_adapter.h>
#include "esp_event.h"
#else #else
#include "esp32_compat.h" #include "esp32_compat.h"
#endif #endif
struct mdns_server_s; #define MDNS_TYPE_A 0x0001
typedef struct mdns_server_s mdns_server_t; #define MDNS_TYPE_PTR 0x000C
#define MDNS_TYPE_TXT 0x0010
#define MDNS_TYPE_AAAA 0x001C
#define MDNS_TYPE_SRV 0x0021
#define MDNS_TYPE_OPT 0x0029
#define MDNS_TYPE_NSEC 0x002F
#define MDNS_TYPE_ANY 0x00FF
/** /**
* @brief mDNS query result structure * @brief mDNS enum to specify the ip_protocol type
* */
typedef enum {
MDNS_IP_PROTOCOL_V4,
MDNS_IP_PROTOCOL_V6,
MDNS_IP_PROTOCOL_MAX
} mdns_ip_protocol_t;
/**
* @brief mDNS basic text item structure
* Used in mdns_service_add()
*/
typedef struct {
char * key; /*!< item key name */
char * value; /*!< item value string */
} mdns_txt_item_t;
/**
* @brief mDNS query linked list IP item
*/
typedef struct mdns_ip_addr_s {
ip_addr_t addr; /*!< IP address */
struct mdns_ip_addr_s * next; /*!< next IP, or NULL for the last IP in the list */
} mdns_ip_addr_t;
/**
* @brief mDNS query result structure
*/ */
typedef struct mdns_result_s { typedef struct mdns_result_s {
const char * host; /*!< hostname */ struct mdns_result_s * next; /*!< next result, or NULL for the last result in the list */
const char * instance; /*!< instance */
const char * txt; /*!< txt data */ tcpip_adapter_if_t tcpip_if; /*!< interface on which the result came (AP/STA/ETH) */
uint16_t priority; /*!< service priority */ mdns_ip_protocol_t ip_protocol; /*!< ip_protocol type of the interface (v4/v6) */
uint16_t weight; /*!< service weight */ // PTR
uint16_t port; /*!< service port */ char * instance_name; /*!< instance name */
struct ip4_addr addr; /*!< ip4 address */ // SRV
struct ip6_addr addrv6; /*!< ip6 address */ char * hostname; /*!< hostname */
const struct mdns_result_s * next; /*!< next result, or NULL for the last result in the list */ uint16_t port; /*!< service port */
// TXT
mdns_txt_item_t * txt; /*!< txt record */
size_t txt_count; /*!< number of txt items */
// A and AAAA
mdns_ip_addr_t * addr; /*!< linked list of IP addreses found */
} mdns_result_t; } mdns_result_t;
/** /**
* @brief Initialize mDNS on given interface * @brief Initialize mDNS on given interface
* *
* @param tcpip_if Interface that the server will listen on
* @param server Server pointer to populate on success
*
* @return * @return
* - ESP_OK on success * - ESP_OK on success
* - ESP_ERR_INVALID_ARG when bad tcpip_if is given * - ESP_ERR_INVALID_ARG when bad tcpip_if is given
@ -56,20 +90,18 @@ typedef struct mdns_result_s {
* - ESP_ERR_NO_MEM on memory error * - ESP_ERR_NO_MEM on memory error
* - ESP_ERR_WIFI_NOT_INIT when WiFi is not initialized by eps_wifi_init * - ESP_ERR_WIFI_NOT_INIT when WiFi is not initialized by eps_wifi_init
*/ */
esp_err_t mdns_init(tcpip_adapter_if_t tcpip_if, mdns_server_t ** server); esp_err_t mdns_init();
/** /**
* @brief Stop and free mDNS server * @brief Stop and free mDNS server
* *
* @param server mDNS Server to free
*
*/ */
void mdns_free(mdns_server_t * server); void mdns_free();
/** /**
* @brief Set the hostname for mDNS server * @brief Set the hostname for mDNS server
* required if you want to advertise services
* *
* @param server mDNS Server
* @param hostname Hostname to set * @param hostname Hostname to set
* *
* @return * @return
@ -77,41 +109,42 @@ void mdns_free(mdns_server_t * server);
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error * - ESP_ERR_NO_MEM memory error
*/ */
esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname); esp_err_t mdns_hostname_set(const char * hostname);
/** /**
* @brief Set the default instance name for mDNS server * @brief Set the default instance name for mDNS server
* *
* @param server mDNS Server * @param instance_name Instance name to set
* @param instance Instance name to set
* *
* @return * @return
* - ESP_OK success * - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error * - ESP_ERR_NO_MEM memory error
*/ */
esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance); esp_err_t mdns_instance_name_set(const char * instance_name);
/** /**
* @brief Add service to mDNS server * @brief Add service to mDNS server
* *
* @param server mDNS Server * @param instance_name instance name to set. If NULL,
* @param service service type (_http, _ftp, etc) * global instance name or hostname will be used
* @param proto service protocol (_tcp, _udp) * @param service_type service type (_http, _ftp, etc)
* @param port service port * @param proto service protocol (_tcp, _udp)
* @param port service port
* @param num_items number of items in TXT data
* @param txt string array of TXT data (eg. {{"var","val"},{"other","2"}})
* *
* @return * @return
* - ESP_OK success * - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error * - ESP_ERR_NO_MEM memory error
*/ */
esp_err_t mdns_service_add(mdns_server_t * server, const char * service, const char * proto, uint16_t port); esp_err_t mdns_service_add(const char * instance_name, const char * service_type, const char * proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
/** /**
* @brief Remove service from mDNS server * @brief Remove service from mDNS server
* *
* @param server mDNS Server * @param service_type service type (_http, _ftp, etc)
* @param service service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* *
* @return * @return
@ -120,15 +153,14 @@ esp_err_t mdns_service_add(mdns_server_t * server, const char * service, const c
* - ESP_ERR_NOT_FOUND Service not found * - ESP_ERR_NOT_FOUND Service not found
* - ESP_FAIL unknown error * - ESP_FAIL unknown error
*/ */
esp_err_t mdns_service_remove(mdns_server_t * server, const char * service, const char * proto); esp_err_t mdns_service_remove(const char * service_type, const char * proto);
/** /**
* @brief Set instance name for service * @brief Set instance name for service
* *
* @param server mDNS Server * @param service_type service type (_http, _ftp, etc)
* @param service service type (_http, _ftp, etc) * @param proto service protocol (_tcp, _udp)
* @param proto service protocol (_tcp, _udp) * @param instance_name instance name to set
* @param instance instance name to set
* *
* @return * @return
* - ESP_OK success * - ESP_OK success
@ -136,30 +168,12 @@ esp_err_t mdns_service_remove(mdns_server_t * server, const char * service, cons
* - ESP_ERR_NOT_FOUND Service not found * - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error * - ESP_ERR_NO_MEM memory error
*/ */
esp_err_t mdns_service_instance_set(mdns_server_t * server, const char * service, const char * proto, const char * instance); esp_err_t mdns_service_instance_name_set(const char * service_type, const char * proto, const char * instance_name);
/**
* @brief Set TXT data for service
*
* @param server mDNS Server
* @param service service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param num_items number of items in TXT data
* @param txt string array of TXT data (eg. {"var=val","other=2"})
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_set(mdns_server_t * server, const char * service, const char * proto, uint8_t num_items, const char ** txt);
/** /**
* @brief Set service port * @brief Set service port
* *
* @param server mDNS Server * @param service_type service type (_http, _ftp, etc)
* @param service service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp) * @param proto service protocol (_tcp, _udp)
* @param port service port * @param port service port
* *
@ -168,69 +182,182 @@ esp_err_t mdns_service_txt_set(mdns_server_t * server, const char * service, con
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found * - ESP_ERR_NOT_FOUND Service not found
*/ */
esp_err_t mdns_service_port_set(mdns_server_t * server, const char * service, const char * proto, uint16_t port); esp_err_t mdns_service_port_set(const char * service_type, const char * proto, uint16_t port);
/**
* @brief Replace all TXT items for service
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param num_items number of items in TXT data
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, mdns_txt_item_t txt[], uint8_t num_items);
/**
* @brief Set/Add TXT item for service TXT record
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update
* @param value the new value of the key
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set(const char * service_type, const char * proto, const char * key, const char * value);
/**
* @brief Remove TXT item for service TXT record
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_remove(const char * service_type, const char * proto, const char * key);
/** /**
* @brief Remove and free all services from mDNS server * @brief Remove and free all services from mDNS server
* *
* @param server mDNS Server
*
* @return * @return
* - ESP_OK success * - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
*/ */
esp_err_t mdns_service_remove_all(mdns_server_t * server); esp_err_t mdns_service_remove_all();
/** /**
* @brief Query mDNS for host or service * @brief Query mDNS for host or service
* All following query methods are derived from this one
* *
* @param server mDNS Server * @param name service instance or host name (NULL for PTR queries)
* @param service service type or host name * @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries)
* @param proto service protocol or NULL if searching for host * @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries)
* @param timeout time to wait for answers. If 0, mdns_query_end MUST be called to end the search * @param type type of query (MDNS_TYPE_*)
* * @param timeout time in milliseconds to wait for answers.
* @return the number of results found * @param max_results maximum results to be collected
*/ * @param results pointer to the results of the query
size_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout); * results must be freed using mdns_query_results_free below
/**
* @brief Stop mDNS Query started with timeout = 0
*
* @param server mDNS Server
*
* @return the number of results found
*/
size_t mdns_query_end(mdns_server_t * server);
/**
* @brief get the number of results currently in memoty
*
* @param server mDNS Server
*
* @return the number of results
*/
size_t mdns_result_get_count(mdns_server_t * server);
/**
* @brief Get mDNS Search result with given index
*
* @param server mDNS Server
* @param num the index of the result
*
* @return the result or NULL if error
*/
const mdns_result_t * mdns_result_get(mdns_server_t * server, size_t num);
/**
* @brief Remove and free all search results from mDNS server
*
* @param server mDNS Server
* *
* @return * @return
* - ESP_OK success * - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG timeout was not given
*/ */
esp_err_t mdns_result_free(mdns_server_t * server); esp_err_t mdns_query(const char * name, const char * service_type, const char * proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t ** results);
/**
* @brief Free query results
*
* @param results linked list of results to be freed
*/
void mdns_query_results_free(mdns_result_t * results);
/**
* @brief Query mDNS for service
*
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param max_results maximum results to be collected
* @param results pointer to the results of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_ptr(const char * service_type, const char * proto, uint32_t timeout, size_t max_results, mdns_result_t ** results);
/**
* @brief Query mDNS for SRV record
*
* @param instance_name service instance name
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param result pointer to the result of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_srv(const char * instance_name, const char * service_type, const char * proto, uint32_t timeout, mdns_result_t ** result);
/**
* @brief Query mDNS for TXT record
*
* @param instance_name service instance name
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param result pointer to the result of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_txt(const char * instance_name, const char * service_type, const char * proto, uint32_t timeout, mdns_result_t ** result);
/**
* @brief Query mDNS for A record
*
* @param host_name host name to look for
* @param timeout time in milliseconds to wait for answer.
* @param addr pointer to the resulting IP4 address
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_a(const char * host_name, uint32_t timeout, ip4_addr_t * addr);
/**
* @brief Query mDNS for A record
*
* @param host_name host name to look for
* @param timeout time in milliseconds to wait for answer. If 0, max_results needs to be defined
* @param addr pointer to the resulting IP6 address
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_aaaa(const char * host_name, uint32_t timeout, ip6_addr_t * addr);
/**
* @brief System event handler
* This method controls the service state on all active interfaces and applications are required
* to call it from the system event handler for normal operation of mDNS service.
*
* @param ctx The system event context
* @param event The system event
*/
esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -0,0 +1,22 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _MDNS_CONSOLE_H_
#define _MDNS_CONSOLE_H_
/**
* @brief Register MDNS functions with the console component
*/
void mdns_console_register();
#endif /* _MDNS_CONSOLE_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,388 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MDNS_PRIVATE_H_
#define MDNS_PRIVATE_H_
//#define MDNS_ENABLE_DEBUG
#ifdef MDNS_ENABLE_DEBUG
#define _mdns_dbg_printf(...) printf(__VA_ARGS__)
#endif
#define MDNS_ANSWER_PTR_TTL 4500
#define MDNS_ANSWER_TXT_TTL 4500
#define MDNS_ANSWER_SRV_TTL 120
#define MDNS_ANSWER_A_TTL 120
#define MDNS_ANSWER_AAAA_TTL 120
#define MDNS_FLAGS_AUTHORITATIVE 0x8400
#define MDNS_FLAGS_DISTRIBUTED 0x0200
#define MDNS_NAME_REF 0xC000
//custom type! only used by this implementation
//to help manage service discovery handling
#define MDNS_TYPE_SDPTR 0x0032
#define MDNS_CLASS_IN 0x0001
#define MDNS_CLASS_ANY 0x00FF
#define MDNS_CLASS_IN_FLUSH_CACHE 0x8001
#define MDNS_ANSWER_ALL 0x3F
#define MDNS_ANSWER_PTR 0x08
#define MDNS_ANSWER_TXT 0x04
#define MDNS_ANSWER_SRV 0x02
#define MDNS_ANSWER_A 0x01
#define MDNS_ANSWER_AAAA 0x10
#define MDNS_ANSWER_NSEC 0x20
#define MDNS_ANSWER_SDPTR 0x80
#define MDNS_SERVICE_PORT 5353 // UDP port that the server runs on
#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_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_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
#define MDNS_HEAD_LEN 12
#define MDNS_HEAD_ID_OFFSET 0
#define MDNS_HEAD_FLAGS_OFFSET 2
#define MDNS_HEAD_QUESTIONS_OFFSET 4
#define MDNS_HEAD_ANSWERS_OFFSET 6
#define MDNS_HEAD_SERVERS_OFFSET 8
#define MDNS_HEAD_ADDITIONAL_OFFSET 10
#define MDNS_TYPE_OFFSET 0
#define MDNS_CLASS_OFFSET 2
#define MDNS_TTL_OFFSET 4
#define MDNS_LEN_OFFSET 8
#define MDNS_DATA_OFFSET 10
#define MDNS_SRV_PRIORITY_OFFSET 0
#define MDNS_SRV_WEIGHT_OFFSET 2
#define MDNS_SRV_PORT_OFFSET 4
#define MDNS_SRV_FQDN_OFFSET 6
#define MDNS_TIMER_PERIOD_US 100000
#define MDNS_SERVICE_LOCK() xSemaphoreTake(_mdns_service_semaphore, portMAX_DELAY)
#define MDNS_SERVICE_UNLOCK() xSemaphoreGive(_mdns_service_semaphore)
#define queueToEnd(type, queue, item) \
if (!queue) { \
queue = item; \
} else { \
type * _q = queue; \
while (_q->next) { _q = _q->next; } \
_q->next = item; \
}
#define queueDetach(type, queue, item) \
if (queue) { \
if (queue == item) { \
queue = queue->next; \
} else { \
type * _q = queue; \
while (_q->next && _q->next != item) { \
_q = _q->next; \
} \
if (_q->next == item) { \
_q->next = item->next; \
item->next = NULL; \
} \
} \
}
#define queueFree(type, queue) while (queue) { type * _q = queue; queue = queue->next; free(_q); }
#define PCB_STATE_IS_PROBING(s) (s->state > PCB_OFF && s->state < PCB_ANNOUNCE_1)
#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 MDNS_SEARCH_LOCK() xSemaphoreTake(_mdns_server->search.lock, portMAX_DELAY)
#define MDNS_SEARCH_UNLOCK() xSemaphoreGive(_mdns_server->search.lock)
typedef enum {
PCB_OFF, PCB_DUP, PCB_INIT,
PCB_PROBE_1, PCB_PROBE_2, PCB_PROBE_3,
PCB_ANNOUNCE_1, PCB_ANNOUNCE_2, PCB_ANNOUNCE_3,
PCB_RUNNING
} mdns_pcb_state_t;
typedef enum {
MDNS_ANSWER, MDNS_NS, MDNS_EXTRA
} mdns_parsed_recort_type_t;
typedef enum {
ACTION_SYSTEM_EVENT,
ACTION_HOSTNAME_SET,
ACTION_INSTANCE_SET,
ACTION_SERVICE_ADD,
ACTION_SERVICE_DEL,
ACTION_SERVICE_INSTANCE_SET,
ACTION_SERVICE_PORT_SET,
ACTION_SERVICE_TXT_REPLACE,
ACTION_SERVICE_TXT_SET,
ACTION_SERVICE_TXT_DEL,
ACTION_SERVICES_CLEAR,
ACTION_SEARCH_ADD,
ACTION_SEARCH_SEND,
ACTION_SEARCH_END,
ACTION_TX_HANDLE,
ACTION_RX_HANDLE,
ACTION_TASK_STOP,
ACTION_MAX
} mdns_action_type_t;
typedef struct {
uint16_t id;
union {
struct {
uint16_t qr :1;
uint16_t opCode :4;
uint16_t aa :1;
uint16_t tc :1;
uint16_t rd :1;
uint16_t ra :1;
uint16_t z :1;
uint16_t ad :1;
uint16_t cd :1;
uint16_t rCode :4;//response/error code
};
uint16_t value;
} flags;
uint16_t questions; //QDCOUNT
uint16_t answers; //ANCOUNT
uint16_t servers; //NSCOUNT
uint16_t additional;//ARCOUNT
} mdns_header_t;
typedef struct {
char host[MDNS_NAME_BUF_LEN];
char service[MDNS_NAME_BUF_LEN];
char proto[MDNS_NAME_BUF_LEN];
char domain[MDNS_NAME_BUF_LEN];
uint8_t parts;
uint8_t sub;
} mdns_name_t;
typedef struct mdns_parsed_question_s {
struct mdns_parsed_question_s * next;
uint16_t type;
bool unicast;
char * host;
char * service;
char * proto;
char * domain;
} mdns_parsed_question_t;
typedef struct mdns_parsed_record_s {
struct mdns_parsed_record_s * next;
mdns_parsed_recort_type_t record_type;
uint16_t type;
uint16_t clas;
uint8_t flush;
uint32_t ttl;
char * host;
char * service;
char * proto;
char * domain;
uint16_t data_len;
uint8_t *data;
} mdns_parsed_record_t;
typedef struct {
tcpip_adapter_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
//struct udp_pcb *pcb;
ip_addr_t src;
uint16_t src_port;
uint8_t multicast;
uint8_t authoritative;
uint8_t probe;
uint8_t discovery;
uint8_t distributed;
mdns_parsed_question_t * questions;
mdns_parsed_record_t * records;
} mdns_parsed_packet_t;
typedef struct {
tcpip_adapter_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
struct pbuf *pb;
ip_addr_t src;
ip_addr_t dest;
uint16_t src_port;
uint8_t multicast;
} mdns_rx_packet_t;
typedef struct mdns_txt_linked_item_s {
const char * key; /*!< item key name */
const char * value; /*!< item value string */
struct mdns_txt_linked_item_s * next; /*!< next result, or NULL for the last result in the list */
} mdns_txt_linked_item_t;
typedef struct {
const char * instance;
const char * service;
const char * proto;
uint16_t priority;
uint16_t weight;
uint16_t port;
mdns_txt_linked_item_t * txt;
} mdns_service_t;
typedef struct mdns_srv_item_s {
struct mdns_srv_item_s * next;
mdns_service_t * service;
} mdns_srv_item_t;
typedef struct mdns_out_question_s {
struct mdns_out_question_s * next;
uint16_t type;
uint8_t unicast;
const char * host;
const char * service;
const char * proto;
const char * domain;
} mdns_out_question_t;
typedef struct mdns_out_answer_s {
struct mdns_out_answer_s * next;
uint16_t type;
uint8_t bye;
uint8_t flush;
mdns_service_t * service;
const char * custom_instance;
const char * custom_service;
const char * custom_proto;
} mdns_out_answer_t;
typedef struct mdns_tx_packet_s {
struct mdns_tx_packet_s * next;
uint32_t send_at;
tcpip_adapter_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
ip_addr_t dst;
uint16_t port;
uint16_t flags;
uint8_t distributed;
mdns_out_question_t * questions;
mdns_out_answer_t * answers;
mdns_out_answer_t * servers;
mdns_out_answer_t * additional;
} mdns_tx_packet_t;
typedef struct {
mdns_pcb_state_t state;
struct udp_pcb * pcb;
mdns_srv_item_t ** probe_services;
uint8_t probe_services_len;
uint8_t probe_ip;
uint8_t probe_running;
uint16_t failed_probes;
} mdns_pcb_t;
typedef enum {
SEARCH_OFF,
SEARCH_INIT,
SEARCH_RUNNING,
SEARCH_MAX
} mdns_search_once_state_t;
typedef struct mdns_search_once_s {
struct mdns_search_once_s * next;
mdns_search_once_state_t state;
uint32_t started_at;
uint32_t sent_at;
uint32_t timeout;
SemaphoreHandle_t lock;
uint16_t type;
uint8_t max_results;
uint8_t num_results;
char * instance;
char * service;
char * proto;
mdns_result_t * result;
} mdns_search_once_t;
typedef struct mdns_server_s {
struct {
mdns_pcb_t pcbs[MDNS_IP_PROTOCOL_MAX];
} interfaces[TCPIP_ADAPTER_IF_MAX];
const char * hostname;
const char * instance;
mdns_srv_item_t * services;
SemaphoreHandle_t lock;
QueueHandle_t action_queue;
mdns_tx_packet_t * tx_queue_head;
mdns_search_once_t * search_once;
esp_timer_handle_t timer_handle;
} mdns_server_t;
typedef struct {
mdns_action_type_t type;
union {
char * hostname;
char * instance;
struct {
system_event_id_t event_id;
tcpip_adapter_if_t interface;
} sys_event;
struct {
mdns_srv_item_t * service;
} srv_add;
struct {
mdns_srv_item_t * service;
} srv_del;
struct {
mdns_srv_item_t * service;
char * instance;
} srv_instance;
struct {
mdns_srv_item_t * service;
uint16_t port;
} srv_port;
struct {
mdns_srv_item_t * service;
uint8_t num_items;
mdns_txt_item_t * txt;
} srv_txt_replace;
struct {
mdns_srv_item_t * service;
char * key;
char * value;
} srv_txt_set;
struct {
mdns_srv_item_t * service;
char * key;
} srv_txt_del;
struct {
mdns_search_once_t * search;
} search_add;
struct {
mdns_tx_packet_t * packet;
} tx_handle;
struct {
mdns_rx_packet_t * packet;
} rx_handle;
} data;
} mdns_action_t;
#endif /* MDNS_PRIVATE_H_ */

View file

@ -603,6 +603,18 @@ esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *ho
*/ */
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname); esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname);
/**
* @brief Get the LwIP netif* that is assigned to the interface
*
* @param[in] tcpip_if: the interface which we will get the hostname
* @param[out] void ** netif: pointer to fill the resulting interface
*
* @return ESP_OK:success
* ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error
* ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:parameter error
*/
esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -1181,4 +1181,18 @@ static esp_err_t tcpip_adapter_reset_ip_info(tcpip_adapter_if_t tcpip_if)
return ESP_OK; return ESP_OK;
} }
esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif)
{
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
}
*netif = esp_netif[tcpip_if];
if (*netif == NULL) {
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
}
return ESP_OK;
}
#endif /* CONFIG_TCPIP_LWIP */ #endif /* CONFIG_TCPIP_LWIP */

View file

@ -20,21 +20,19 @@ Example method to start mDNS for the STA interface and set ``hostname`` and ``de
:: ::
mdns_server_t * mdns = NULL;
void start_mdns_service() void start_mdns_service()
{ {
//initialize mDNS service on STA interface //initialize mDNS service
esp_err_t err = mdns_init(TCPIP_ADAPTER_IF_STA, &mdns); esp_err_t err = mdns_init();
if (err) { if (err) {
printf("MDNS Init failed: %d\n", err); printf("MDNS Init failed: %d\n", err);
return; return;
} }
//set hostname //set hostname
mdns_set_hostname(mdns, "my-esp32"); mdns_hostname_set("my-esp32");
//set default instance //set default instance
mdns_set_instance(mdns, "Jhon's ESP32 Thing"); mdns_instance_name_set("Jhon's ESP32 Thing");
} }
mDNS Services mDNS Services
@ -42,36 +40,35 @@ mDNS Services
mDNS can advertise information about network services that your device offers. Each service is defined by a few properties. mDNS can advertise information about network services that your device offers. Each service is defined by a few properties.
* ``service``: (required) service type, prepended with underscore. Some common types can be found `here <http://www.dns-sd.org/serviceTypes.html>`_. * ``instance_name``: friendly name for your service, like ``Jhon's ESP32 Web Server``. If not defined, ``default_instance`` will be used.
* ``service_type``: (required) service type, prepended with underscore. Some common types can be found `here <http://www.dns-sd.org/serviceTypes.html>`_.
* ``proto``: (required) protocol that the service runs on, prepended with underscore. Example: ``_tcp`` or ``_udp`` * ``proto``: (required) protocol that the service runs on, prepended with underscore. Example: ``_tcp`` or ``_udp``
* ``port``: (required) network port that the service runs on * ``port``: (required) network port that the service runs on
* ``instance``: friendly name for your service, like ``Jhon's ESP32 Web Server``. If not defined, ``default_instance`` will be used. * ``txt``: ``{var, val}`` array of strings, used to define properties for your service
* ``txt``: ``var=val`` array of strings, used to define properties for your service
Example method to add a few services and different properties:: Example method to add a few services and different properties::
void add_mdns_services() void add_mdns_services()
{ {
//add our services //add our services
mdns_service_add(mdns, "_http", "_tcp", 80); mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
mdns_service_add(mdns, "_arduino", "_tcp", 3232); mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
mdns_service_add(mdns, "_myservice", "_udp", 1234); mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
//NOTE: services must be added before their properties can be set //NOTE: services must be added before their properties can be set
//use custom instance for the web server //use custom instance for the web server
mdns_service_instance_set(mdns, "_http", "_tcp", "Jhon's ESP32 Web Server"); mdns_service_instance_name_set("_http", "_tcp", "Jhon's ESP32 Web Server");
const char * arduTxtData[4] = { mdns_txt_item_t serviceTxtData[3] = {
"board=esp32", {"board","esp32"},
"tcp_check=no", {"u","user"},
"ssh_upload=no", {"p","password"}
"auth_upload=no"
}; };
//set txt data for service (will free and replace current data) //set txt data for service (will free and replace current data)
mdns_service_txt_set(mdns, "_arduino", "_tcp", 4, arduTxtData); mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
//change service port //change service port
mdns_service_port_set(mdns, "_myservice", "_udp", 4321); mdns_service_port_set("_myservice", "_udp", 4321);
} }
mDNS Query mDNS Query
@ -79,60 +76,85 @@ mDNS Query
mDNS provides methods for browsing for services and resolving host's IP/IPv6 addresses. mDNS provides methods for browsing for services and resolving host's IP/IPv6 addresses.
Results are returned as a linked list of ``mdns_result_t`` objects. If the result is from host query, it will contain only ``addr`` and ``addrv6`` if found. Service queries will populate all fields in a result that were found. Results for services are returned as a linked list of ``mdns_result_t`` objects.
Example method to resolve host IPs:: Example method to resolve host IPs::
void resolve_mdns_host(const char * hostname) void resolve_mdns_host(const char * host_name)
{ {
printf("mDNS Host Lookup: %s.local\n", hostname); printf("Query A: %s.local", host_name);
//run search for 1000 ms
if (mdns_query(mdns, hostname, NULL, 1000)) { struct ip4_addr addr;
//results were found addr.addr = 0;
const mdns_result_t * results = mdns_result_get(mdns, 0);
//itterate through all results esp_err_t err = mdns_query_a(host_name, 2000, &addr);
size_t i = 1; if(err){
while(results) { if(err == ESP_ERR_NOT_FOUND){
//print result information printf("Host was not found!");
printf(" %u: IP:" IPSTR ", IPv6:" IPV6STR "\n", i++ return;
IP2STR(&results->addr), IPV62STR(results->addrv6));
//load next result. Will be NULL if this was the last one
results = results->next;
} }
//free the results from memory printf("Query Failed");
mdns_result_free(mdns); return;
} else {
//host was not found
printf(" Host Not Found\n");
} }
printf(IPSTR, IP2STR(&addr));
} }
Example method to resolve local services:: Example method to resolve local services::
void find_mdns_service(const char * service, const char * proto) static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
{ static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
printf("mDNS Service Lookup: %s.%s\n", service, proto);
//run search for 1000 ms void mdns_print_results(mdns_result_t * results){
if (mdns_query(mdns, service, proto, 1000)) { mdns_result_t * r = results;
//results were found mdns_ip_addr_t * a = NULL;
const mdns_result_t * results = mdns_result_get(mdns, 0); int i = 1, t;
//itterate through all results while(r){
size_t i = 1; printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
while(results) { if(r->instance_name){
//print result information printf(" PTR : %s\n", r->instance_name);
printf(" %u: hostname:%s, instance:\"%s\", IP:" IPSTR ", IPv6:" IPV6STR ", port:%u, txt:%s\n", i++,
(results->host)?results->host:"NULL", (results->instance)?results->instance:"NULL",
IP2STR(&results->addr), IPV62STR(results->addrv6),
results->port, (results->txt)?results->txt:"\r");
//load next result. Will be NULL if this was the last one
results = results->next;
} }
//free the results from memory if(r->hostname){
mdns_result_free(mdns); printf(" SRV : %s.local:%u\n", r->hostname, r->port);
} else { }
//service was not found if(r->txt_count){
printf(" Service Not Found\n"); 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);
}
printf("\n");
}
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)));
}
a = a->next;
}
r = r->next;
} }
}
void find_mdns_service(const char * service_name, const char * proto)
{
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){
ESP_LOGE(TAG, "Query Failed");
return;
}
if(!results){
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
} }
Example of using the methods above:: Example of using the methods above::

View file

@ -2,4 +2,20 @@
Shows how to use mDNS to advertise lookup services and hosts Shows how to use mDNS to advertise lookup services and hosts
## Example workflow
- mDNS is initialized with host name and instance name defined through `make menuconfig` and `_http._tcp` service is added to be advertised
- WiFi STA is started and trying to connect to the access point defined through `make menuconfig`
- The system event handler is used to pass the network events to mDNS so the service is aware when the interface comes up or down
- GPIO0 (BOOT Button) is initialized as pulled-up input that can be monitored for button press
- Example task is started to check if the button is pressed so it can execute the mDNS queries defined
## Running the example
- Run `make menuconfig` to configure the access point's SSID and Password and the default device mDNS host name and instance name
- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal
- Wait for WiFi to connec to your access point
- You can now ping the device at `[hostname].local` and browse for `_http._tcp` on the same network to find the advertised service
- Pressing the BOOT button will start quring the local network for the predefined in `check_button` hosts and services
See the README.md file in the upper level 'examples' directory for more information about examples. See the README.md file in the upper level 'examples' directory for more information about examples.

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

@ -16,6 +16,9 @@
#include "esp_log.h" #include "esp_log.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "mdns.h" #include "mdns.h"
#include "driver/gpio.h"
#include <sys/socket.h>
#include <netdb.h>
/* The examples use simple WiFi configuration that you can set via /* The examples use simple WiFi configuration that you can set via
'make menuconfig'. 'make menuconfig'.
@ -35,9 +38,11 @@ static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event, /* The event group allows multiple bits for each event,
but we only care about one event - are we connected but we only care about one event - are we connected
to the AP with an IP? */ to the AP with an IP? */
const int CONNECTED_BIT = BIT0; const int IP4_CONNECTED_BIT = BIT0;
const int IP6_CONNECTED_BIT = BIT1;
static const char *TAG = "mdns-test"; static const char *TAG = "mdns-test";
static bool auto_reconnect = true;
static esp_err_t event_handler(void *ctx, system_event_t *event) static esp_err_t event_handler(void *ctx, system_event_t *event)
{ {
@ -50,17 +55,23 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
break; break;
case SYSTEM_EVENT_STA_GOT_IP: case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); xEventGroupSetBits(wifi_event_group, IP4_CONNECTED_BIT);
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
xEventGroupSetBits(wifi_event_group, IP6_CONNECTED_BIT);
break; break;
case SYSTEM_EVENT_STA_DISCONNECTED: case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently /* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */ auto-reassociate. */
esp_wifi_connect(); if (auto_reconnect) {
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); esp_wifi_connect();
}
xEventGroupClearBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT);
break; break;
default: default:
break; break;
} }
mdns_handle_system_event(ctx, event);
return ESP_OK; return ESP_OK;
} }
@ -84,101 +95,150 @@ static void initialise_wifi(void)
ESP_ERROR_CHECK( esp_wifi_start() ); ESP_ERROR_CHECK( esp_wifi_start() );
} }
static void query_mdns_service(mdns_server_t * mdns, const char * service, const char * proto) static void initialise_mdns(void)
{ {
if(!mdns) { //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);
}
printf("\n");
}
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)));
}
a = a->next;
}
r = r->next;
}
}
static void query_mdns_service(const char * service_name, const char * proto)
{
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){
ESP_LOGE(TAG, "Query Failed");
return; return;
} }
uint32_t res; if(!results){
if (!proto) { ESP_LOGW(TAG, "No results found!");
ESP_LOGI(TAG, "Host Lookup: %s", service); return;
res = mdns_query(mdns, service, 0, 1000);
if (res) {
size_t i;
for(i=0; i<res; i++) {
const mdns_result_t * r = mdns_result_get(mdns, i);
if (r) {
ESP_LOGI(TAG, " %u: " IPSTR " " IPV6STR, i+1,
IP2STR(&r->addr), IPV62STR(r->addrv6));
}
}
mdns_result_free(mdns);
} else {
ESP_LOGI(TAG, " Not Found");
}
} else {
ESP_LOGI(TAG, "Service Lookup: %s.%s ", service, proto);
res = mdns_query(mdns, service, proto, 1000);
if (res) {
size_t i;
for(i=0; i<res; i++) {
const mdns_result_t * r = mdns_result_get(mdns, i);
if (r) {
ESP_LOGI(TAG, " %u: %s \"%s\" " IPSTR " " IPV6STR " %u %s", i+1,
(r->host)?r->host:"", (r->instance)?r->instance:"",
IP2STR(&r->addr), IPV62STR(r->addrv6),
r->port, (r->txt)?r->txt:"");
}
}
mdns_result_free(mdns);
}
} }
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){
ESP_LOGW(TAG, "Host was not found!");
return;
}
ESP_LOGE(TAG, "Query Failed");
return;
}
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) static void mdns_example_task(void *pvParameters)
{ {
mdns_server_t * mdns = NULL; /* 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) { while(1) {
/* Wait for the callback to set the CONNECTED_BIT in the check_button();
event group. vTaskDelay(50 / portTICK_PERIOD_MS);
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
if (!mdns) {
esp_err_t err = mdns_init(TCPIP_ADAPTER_IF_STA, &mdns);
if (err) {
ESP_LOGE(TAG, "Failed starting MDNS: %u", err);
continue;
}
ESP_ERROR_CHECK( mdns_set_hostname(mdns, EXAMPLE_MDNS_HOSTNAME) );
ESP_ERROR_CHECK( mdns_set_instance(mdns, EXAMPLE_MDNS_INSTANCE) );
const char * arduTxtData[4] = {
"board=esp32",
"tcp_check=no",
"ssh_upload=no",
"auth_upload=no"
};
ESP_ERROR_CHECK( mdns_service_add(mdns, "_arduino", "_tcp", 3232) );
ESP_ERROR_CHECK( mdns_service_txt_set(mdns, "_arduino", "_tcp", 4, arduTxtData) );
ESP_ERROR_CHECK( mdns_service_add(mdns, "_http", "_tcp", 80) );
ESP_ERROR_CHECK( mdns_service_instance_set(mdns, "_http", "_tcp", "ESP32 WebServer") );
ESP_ERROR_CHECK( mdns_service_add(mdns, "_smb", "_tcp", 445) );
} else {
query_mdns_service(mdns, "esp32", NULL);
query_mdns_service(mdns, "_arduino", "_tcp");
query_mdns_service(mdns, "_http", "_tcp");
query_mdns_service(mdns, "_printer", "_tcp");
query_mdns_service(mdns, "_ipp", "_tcp");
query_mdns_service(mdns, "_afpovertcp", "_tcp");
query_mdns_service(mdns, "_smb", "_tcp");
query_mdns_service(mdns, "_ftp", "_tcp");
query_mdns_service(mdns, "_nfs", "_tcp");
}
ESP_LOGI(TAG, "Restarting in 10 seconds!");
vTaskDelay(10000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Starting again!");
} }
} }
void app_main() void app_main()
{ {
ESP_ERROR_CHECK( nvs_flash_init() ); ESP_ERROR_CHECK( nvs_flash_init() );
initialise_mdns();
initialise_wifi(); initialise_wifi();
initialise_button();
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
} }