Skip to content

Commit 6c61dd3

Browse files
authored
Merge pull request #693 from zwx1995esp/feat/support_add_remove_subtype
feat(mdns): support update subtype (IDFGH-14068)
2 parents 8821ea3 + 062b8dc commit 6c61dd3

File tree

2 files changed

+206
-15
lines changed

2 files changed

+206
-15
lines changed

components/mdns/include/mdns.h

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ typedef struct {
6060
const char *value; /*!< item value string */
6161
} mdns_txt_item_t;
6262

63+
/**
64+
* @brief mDNS basic subtype item structure
65+
* Used in mdns_service_subtype_xxx() APIs
66+
*/
67+
typedef struct {
68+
const char *subtype; /*!< subtype name */
69+
} mdns_subtype_item_t;
70+
6371
/**
6472
* @brief mDNS query linked list IP item
6573
*/
@@ -544,7 +552,7 @@ esp_err_t mdns_service_txt_item_remove_for_host(const char *instance, const char
544552
const char *key);
545553

546554
/**
547-
* @brief Add subtype for service.
555+
* @brief Add a subtype for service.
548556
*
549557
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
550558
* @param service_type service type (_http, _ftp, etc)
@@ -561,6 +569,60 @@ esp_err_t mdns_service_txt_item_remove_for_host(const char *instance, const char
561569
esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto,
562570
const char *hostname, const char *subtype);
563571

572+
/**
573+
* @brief Remove a subtype for service.
574+
*
575+
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
576+
* @param service_type service type (_http, _ftp, etc)
577+
* @param proto service protocol (_tcp, _udp)
578+
* @param hostname service hostname. If NULL, local hostname will be used.
579+
* @param subtype The subtype to remove.
580+
*
581+
* @return
582+
* - ESP_OK success
583+
* - ESP_ERR_INVALID_ARG Parameter error
584+
* - ESP_ERR_NOT_FOUND Service not found
585+
*/
586+
esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const char *service_type, const char *proto,
587+
const char *hostname, const char *subtype);
588+
589+
/**
590+
* @brief Add multiple subtypes for service at once.
591+
*
592+
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
593+
* @param service_type service type (_http, _ftp, etc)
594+
* @param proto service protocol (_tcp, _udp)
595+
* @param hostname service hostname. If NULL, local hostname will be used.
596+
* @param subtype the pointer of subtype array to add.
597+
* @param num_items number of items in subtype array
598+
*
599+
* @return
600+
* - ESP_OK success
601+
* - ESP_ERR_INVALID_ARG Parameter error
602+
* - ESP_ERR_NOT_FOUND Service not found
603+
* - ESP_ERR_NO_MEM memory error
604+
*/
605+
esp_err_t mdns_service_subtype_add_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto,
606+
const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items);
607+
608+
/**
609+
* @brief Update subtype for service.
610+
*
611+
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
612+
* @param service_type service type (_http, _ftp, etc)
613+
* @param proto service protocol (_tcp, _udp)
614+
* @param hostname service hostname. If NULL, local hostname will be used.
615+
* @param subtype the pointer of subtype array to add.
616+
* @param num_items number of items in subtype array
617+
*
618+
* @return
619+
* - ESP_OK success
620+
* - ESP_ERR_INVALID_ARG Parameter error
621+
* - ESP_ERR_NOT_FOUND Service not found
622+
* - ESP_ERR_NO_MEM memory error
623+
*/
624+
esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto,
625+
const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items);
564626
/**
565627
* @brief Remove and free all services from mDNS server
566628
*

components/mdns/mdns.c

Lines changed: 143 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,6 +2794,16 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
27942794
}
27952795
}
27962796

2797+
static void _mdns_free_service_subtype(mdns_service_t *service)
2798+
{
2799+
while (service->subtype) {
2800+
mdns_subtype_t *next = service->subtype->next;
2801+
free((char *)service->subtype->subtype);
2802+
free(service->subtype);
2803+
service->subtype = next;
2804+
}
2805+
}
2806+
27972807
/**
27982808
* @brief free service memory
27992809
*
@@ -2815,12 +2825,7 @@ static void _mdns_free_service(mdns_service_t *service)
28152825
free((char *)s->value);
28162826
free(s);
28172827
}
2818-
while (service->subtype) {
2819-
mdns_subtype_t *next = service->subtype->next;
2820-
free((char *)service->subtype->subtype);
2821-
free(service->subtype);
2822-
service->subtype = next;
2823-
}
2828+
_mdns_free_service_subtype(service);
28242829
free(service);
28252830
}
28262831

@@ -6299,7 +6304,36 @@ esp_err_t mdns_service_txt_item_remove(const char *service, const char *proto, c
62996304
return mdns_service_txt_item_remove_for_host(NULL, service, proto, NULL, key);
63006305
}
63016306

6302-
esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service, const char *proto,
6307+
static esp_err_t _mdns_service_subtype_remove_for_host(mdns_srv_item_t *service, const char *subtype)
6308+
{
6309+
esp_err_t ret = ESP_ERR_NOT_FOUND;
6310+
mdns_subtype_t *srv_subtype = service->service->subtype;
6311+
mdns_subtype_t *pre = service->service->subtype;
6312+
while (srv_subtype) {
6313+
if (strcmp(srv_subtype->subtype, subtype) == 0) {
6314+
// Target subtype is found.
6315+
if (srv_subtype == service->service->subtype) {
6316+
// The first node needs to be removed
6317+
service->service->subtype = service->service->subtype->next;
6318+
} else {
6319+
pre->next = srv_subtype->next;
6320+
}
6321+
free((char *)srv_subtype->subtype);
6322+
free(srv_subtype);
6323+
ret = ESP_OK;
6324+
break;
6325+
}
6326+
pre = srv_subtype;
6327+
srv_subtype = srv_subtype->next;
6328+
}
6329+
if (ret == ESP_ERR_NOT_FOUND) {
6330+
ESP_LOGE(TAG, "Subtype : %s doesn't exist", subtype);
6331+
}
6332+
6333+
return ret;
6334+
}
6335+
6336+
esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const char *service, const char *proto,
63036337
const char *hostname, const char *subtype)
63046338
{
63056339
MDNS_SERVICE_LOCK();
@@ -6310,30 +6344,125 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
63106344
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance_name, service, proto, hostname);
63116345
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
63126346

6313-
mdns_subtype_t *srv_subtype = s->service->subtype;
6347+
ret = _mdns_service_subtype_remove_for_host(s, subtype);
6348+
ESP_GOTO_ON_ERROR(ret, err, TAG, "Failed to remove the subtype: %s", subtype);
6349+
6350+
// TODO: Need to transmit a sendbye message for the removed subtype.
6351+
// TODO: Need to remove this subtype answer from the scheduled answer list.
6352+
err:
6353+
MDNS_SERVICE_UNLOCK();
6354+
return ret;
6355+
}
6356+
6357+
static esp_err_t _mdns_service_subtype_add_for_host(mdns_srv_item_t *service, const char *subtype)
6358+
{
6359+
esp_err_t ret = ESP_OK;
6360+
mdns_subtype_t *srv_subtype = service->service->subtype;
63146361
while (srv_subtype) {
6315-
ESP_GOTO_ON_FALSE(strcmp(srv_subtype->subtype, subtype) != 0, ESP_ERR_INVALID_ARG, err, TAG, "The same subtype has already been added");
6362+
ESP_GOTO_ON_FALSE(strcmp(srv_subtype->subtype, subtype) != 0, ESP_ERR_INVALID_ARG, err, TAG, "Subtype: %s has already been added", subtype);
63166363
srv_subtype = srv_subtype->next;
63176364
}
63186365

6319-
mdns_service_t *srv = s->service;
63206366
mdns_subtype_t *subtype_item = (mdns_subtype_t *)malloc(sizeof(mdns_subtype_t));
63216367
ESP_GOTO_ON_FALSE(subtype_item, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
63226368
subtype_item->subtype = strdup(subtype);
63236369
ESP_GOTO_ON_FALSE(subtype_item->subtype, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
6324-
subtype_item->next = srv->subtype;
6325-
srv->subtype = subtype_item;
6370+
subtype_item->next = service->service->subtype;
6371+
service->service->subtype = subtype_item;
63266372

63276373
err:
6328-
MDNS_SERVICE_UNLOCK();
63296374
return ret;
63306375
out_of_mem:
6331-
MDNS_SERVICE_UNLOCK();
63326376
HOOK_MALLOC_FAILED;
63336377
free(subtype_item);
63346378
return ret;
63356379
}
63366380

6381+
esp_err_t mdns_service_subtype_add_multiple_items_for_host(const char *instance_name, const char *service, const char *proto,
6382+
const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items)
6383+
{
6384+
MDNS_SERVICE_LOCK();
6385+
esp_err_t ret = ESP_OK;
6386+
int cur_index = 0;
6387+
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service) && !_str_null_or_empty(proto) &&
6388+
(num_items > 0), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
6389+
6390+
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance_name, service, proto, hostname);
6391+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
6392+
6393+
for (; cur_index < num_items; cur_index++) {
6394+
ret = _mdns_service_subtype_add_for_host(s, subtype[cur_index].subtype);
6395+
if (ret == ESP_OK) {
6396+
continue;
6397+
} else if (ret == ESP_ERR_NO_MEM) {
6398+
ESP_LOGE(TAG, "Out of memory");
6399+
goto err;
6400+
} else {
6401+
ESP_LOGE(TAG, "Failed to add subtype: %s", subtype[cur_index].subtype);
6402+
goto exit;
6403+
}
6404+
}
6405+
6406+
_mdns_announce_all_pcbs(&s, 1, false);
6407+
err:
6408+
if (ret == ESP_ERR_NO_MEM) {
6409+
for (int idx = 0; idx < cur_index; idx++) {
6410+
_mdns_service_subtype_remove_for_host(s, subtype[idx].subtype);
6411+
}
6412+
}
6413+
exit:
6414+
MDNS_SERVICE_UNLOCK();
6415+
return ret;
6416+
}
6417+
6418+
esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto,
6419+
const char *hostname, const char *subtype)
6420+
{
6421+
mdns_subtype_item_t _subtype[1];
6422+
_subtype[0].subtype = subtype;
6423+
return mdns_service_subtype_add_multiple_items_for_host(instance_name, service_type, proto, hostname, _subtype, 1);
6424+
}
6425+
6426+
esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto,
6427+
const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items)
6428+
{
6429+
MDNS_SERVICE_LOCK();
6430+
esp_err_t ret = ESP_OK;
6431+
int cur_index = 0;
6432+
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service_type) && !_str_null_or_empty(proto) &&
6433+
(num_items > 0), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
6434+
6435+
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance_name, service_type, proto, hostname);
6436+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
6437+
6438+
// TODO: find subtype needs to say sendbye
6439+
_mdns_free_service_subtype(s->service);
6440+
6441+
for (; cur_index < num_items; cur_index++) {
6442+
ret = _mdns_service_subtype_add_for_host(s, subtype[cur_index].subtype);
6443+
if (ret == ESP_OK) {
6444+
continue;
6445+
} else if (ret == ESP_ERR_NO_MEM) {
6446+
ESP_LOGE(TAG, "Out of memory");
6447+
goto err;
6448+
} else {
6449+
ESP_LOGE(TAG, "Failed to add subtype: %s", subtype[cur_index].subtype);
6450+
goto exit;
6451+
}
6452+
}
6453+
6454+
_mdns_announce_all_pcbs(&s, 1, false);
6455+
err:
6456+
if (ret == ESP_ERR_NO_MEM) {
6457+
for (int idx = 0; idx < cur_index; idx++) {
6458+
_mdns_service_subtype_remove_for_host(s, subtype[idx].subtype);
6459+
}
6460+
}
6461+
exit:
6462+
MDNS_SERVICE_UNLOCK();
6463+
return ret;
6464+
}
6465+
63376466
esp_err_t mdns_service_instance_name_set_for_host(const char *instance_old, const char *service, const char *proto, const char *host,
63386467
const char *instance)
63396468
{

0 commit comments

Comments
 (0)