Compare commits

...

6 Commits

7 changed files with 82 additions and 8 deletions

View File

@ -2513,12 +2513,14 @@ mdns_resp_netif_active(struct netif *netif)
* @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to
* allow dynamic replies.
* @param txt_data Userdata pointer for txt_fn
* @param subTypes table contanins all subtypes of the service
* param subtypes_nbr the number of the subtypes linked to that service, it should be <=MDNS_MAX_SERVICES_SUBTYPES
* @return service_id if the service was added to the netif, an err_t otherwise
*/
s8_t
mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_data)
mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_data, char **subTypes, u8_t subtypes_nbr )
{
u8_t slot;
u8_t slot,i;
struct mdns_service *srv;
struct mdns_host *mdns;
@ -2543,10 +2545,13 @@ mdns_resp_add_service(struct netif *netif, const char *name, const char *service
MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name)));
MEMCPY(&srv->service, service, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(service)));
for(i=0;i<LWIP_MIN(subtypes_nbr,MDNS_MAX_SERVICES_SUBTYPES);i++)
MEMCPY(&srv->subTypes[i], subTypes[i], LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(subTypes[i])));
srv->txt_fn = txt_fn;
srv->txt_userdata = txt_data;
srv->proto = (u16_t)proto;
srv->port = port;
srv->subtypes_nbr = subtypes_nbr;
mdns->services[slot] = srv;

View File

@ -632,4 +632,30 @@ mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain)
return ERR_OK;
}
/**
* Build domain name for a subtype service
* @param domain Where to write the domain name
* @param service The service struct, containing service name, type and protocol
* @param include_name Whether to include the service name in the domain
* @return ERR_OK if domain was written. If service name is included,
* \<subType\>.\<_sub\>.\<type\>.\<proto\>.local. will be written, otherwise \<type\>.\<proto\>.local.
* An err_t is returned on error.
*/
err_t
mdns_build_subtype_service_domain(struct mdns_domain *domain, struct mdns_service *service, int subTypes_index)
{
err_t res;
LWIP_UNUSED_ARG(res);
memset(domain, 0, sizeof(struct mdns_domain));
res = mdns_domain_add_label(domain, service->subTypes[subTypes_index], strlen(service->subTypes[subTypes_index]));
LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
res = mdns_domain_add_label(domain, "_sub", 4);
LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
res = mdns_domain_add_label(domain, service->service, (u8_t)strlen(service->service));
LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
res = mdns_domain_add_label(domain, dnssd_protos[service->proto], (u8_t)strlen(dnssd_protos[service->proto]));
LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res);
return mdns_add_dotlocal(domain);
}
#endif /* LWIP_MDNS_RESPONDER */

View File

@ -54,7 +54,7 @@
/* Function prototypes */
static void mdns_clear_outmsg(struct mdns_outmsg *outmsg);
static err_t mdns_add_service_subtype_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg, struct mdns_service *service);
/**
* Call user supplied function to setup TXT data
* @param service The service to build TXT record for
@ -660,6 +660,8 @@ mdns_create_outpacket(struct netif *netif, struct mdns_outmsg *msg,
if (msg->serv_replies[i] & REPLY_SERVICE_NAME_PTR) {
res = mdns_add_servicename_ptr_answer(outpkt, msg, service);
/*if a subtype is used, that following function write answer of the subtype service PTR RR to outpacket*/
res = mdns_add_service_subtype_ptr_answer(outpkt, msg, service);
if (res != ERR_OK) {
return res;
}
@ -1160,4 +1162,39 @@ mdns_send_request(struct mdns_request *req, struct netif *netif, const ip_addr_t
}
#endif
/** Write an all subtype services -> PTR RR to outpacket */
static err_t
mdns_add_service_subtype_ptr_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
struct mdns_service *service)
{
err_t res = ERR_OK;
u8_t subtyes_index;
u32_t ttl = MDNS_TTL_4500;
struct mdns_domain service_type, sub_service;
for(subtyes_index=0;subtyes_index < LWIP_MIN(service->subtypes_nbr,MDNS_MAX_SERVICES_SUBTYPES); subtyes_index++)
{
res =mdns_build_subtype_service_domain(&sub_service, service,subtyes_index);
res =mdns_build_service_domain(&service_type, service, 1);
/* When answering to a legacy querier, we need to repeat the question and
* limit the ttl to the short legacy ttl */
if(msg->legacy_query) {
/* Repeating the question only needs to be done for the question asked
* (max one question), not for the additional records. */
if(reply->questions < 1) {
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Add question for legacy query\n"));
res = mdns_add_question(reply, &sub_service, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0);
if (res != ERR_OK) {
return res;
}
reply->questions = 1;
}
/* ttl of legacy answer may not be greater then 10 seconds */
ttl = MDNS_TTL_10;
}
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n"));
res =mdns_add_answer(reply, &sub_service, DNS_RRTYPE_PTR, DNS_RRCLASS_IN,
0, ttl, NULL, 0, &service_type);
}
return res;
}
#endif /* LWIP_MDNS_RESPONDER */

View File

@ -112,7 +112,7 @@ err_t mdns_resp_remove_netif(struct netif *netif);
err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
int mdns_resp_netif_active(struct netif *netif);
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_userdata);
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, service_get_txt_fn_t txt_fn, void *txt_data, char **subTypes, u8_t subtypes_nbr );
err_t mdns_resp_del_service(struct netif *netif, u8_t slot);
err_t mdns_resp_rename_service(struct netif *netif, u8_t slot, const char *name);

View File

@ -70,7 +70,7 @@ err_t mdns_build_request_domain(struct mdns_domain *domain, struct mdns_request
#endif
u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
err_t mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain);
err_t mdns_build_subtype_service_domain(struct mdns_domain *domain, struct mdns_service *service, int subTypes_index);
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus

View File

@ -52,12 +52,14 @@
* transport. IGMP is needed for IPv4 multicast.
*/
#ifndef LWIP_MDNS_RESPONDER
#define LWIP_MDNS_RESPONDER 0
#define LWIP_MDNS_RESPONDER 1
#endif /* LWIP_MDNS_RESPONDER */
/** The maximum number of services per netif */
#ifndef MDNS_MAX_SERVICES
#define MDNS_MAX_SERVICES 1
/** The maximum number of subtypes per service */
#define MDNS_MAX_SERVICES_SUBTYPES 4
#endif
/** The minimum delay between probes in ms. RFC 6762 require 250ms.

View File

@ -98,14 +98,18 @@ struct mdns_service {
char name[MDNS_LABEL_MAXLEN + 1];
/** Type of service, like '_http' */
char service[MDNS_LABEL_MAXLEN + 1];
/** Callback function and userdata
* to update txtdata buffer */
/** SubType of service, like '_printer' */
char subTypes[MDNS_MAX_SERVICES_SUBTYPES][MDNS_LABEL_MAXLEN + 1];
/** Callback function and userdata/*
/* to update txtdata buffer */
service_get_txt_fn_t txt_fn;
void *txt_userdata;
/** Protocol, TCP or UDP */
u16_t proto;
/** Port of the service */
u16_t port;
/** Number of the subtypes of a service */
u16_t subtypes_nbr;
};
/** mDNS output packet */