@@ -318,3 +318,311 @@ void mdns_browse_action(mdns_action_t *action, mdns_action_subtype_t type)
318318 }
319319
320320}
321+
322+ /**
323+ * @brief Add result to browse, only add when the result is a new one.
324+ */
325+ static esp_err_t _mdns_add_browse_result (mdns_browse_sync_t * sync_browse , mdns_result_t * r )
326+ {
327+ mdns_browse_result_sync_t * sync_r = sync_browse -> sync_result ;
328+ while (sync_r ) {
329+ if (sync_r -> result == r ) {
330+ break ;
331+ }
332+ sync_r = sync_r -> next ;
333+ }
334+ if (!sync_r ) {
335+ // Do not find, need to add the result to the list
336+ mdns_browse_result_sync_t * new = (mdns_browse_result_sync_t * )mdns_mem_malloc (sizeof (mdns_browse_result_sync_t ));
337+
338+ if (!new ) {
339+ HOOK_MALLOC_FAILED ;
340+ return ESP_ERR_NO_MEM ;
341+ }
342+ new -> result = r ;
343+ new -> next = sync_browse -> sync_result ;
344+ sync_browse -> sync_result = new ;
345+ }
346+ return ESP_OK ;
347+ }
348+
349+ /**
350+ * @brief Called from parser to add A/AAAA data to search result
351+ */
352+ void _mdns_browse_result_add_ip (mdns_browse_t * browse , const char * hostname , esp_ip_addr_t * ip ,
353+ mdns_if_t tcpip_if , mdns_ip_protocol_t ip_protocol , uint32_t ttl , mdns_browse_sync_t * out_sync_browse )
354+ {
355+ if (out_sync_browse -> browse == NULL ) {
356+ return ;
357+ } else {
358+ if (out_sync_browse -> browse != browse ) {
359+ return ;
360+ }
361+ }
362+ mdns_result_t * r = NULL ;
363+ mdns_ip_addr_t * r_a = NULL ;
364+ if (browse ) {
365+ r = browse -> result ;
366+ while (r ) {
367+ if (r -> ip_protocol == ip_protocol ) {
368+ // Find the target result in browse result.
369+ if (r -> esp_netif == _mdns_get_esp_netif (tcpip_if ) && !mdns_utils_str_null_or_empty (r -> hostname ) && !strcasecmp (hostname , r -> hostname )) {
370+ r_a = r -> addr ;
371+ // Check if the address has already added in result.
372+ while (r_a ) {
373+ #ifdef CONFIG_LWIP_IPV4
374+ if (r_a -> addr .type == ip -> type && r_a -> addr .type == ESP_IPADDR_TYPE_V4 && r_a -> addr .u_addr .ip4 .addr == ip -> u_addr .ip4 .addr ) {
375+ break ;
376+ }
377+ #endif
378+ #ifdef CONFIG_LWIP_IPV6
379+ if (r_a -> addr .type == ip -> type && r_a -> addr .type == ESP_IPADDR_TYPE_V6 && !memcmp (r_a -> addr .u_addr .ip6 .addr , ip -> u_addr .ip6 .addr , 16 )) {
380+ break ;
381+ }
382+ #endif
383+ r_a = r_a -> next ;
384+ }
385+ if (!r_a ) {
386+ // The current IP is a new one, add it to the link list.
387+ mdns_ip_addr_t * a = NULL ;
388+ a = _mdns_result_addr_create_ip (ip );
389+ if (!a ) {
390+ return ;
391+ }
392+ a -> next = r -> addr ;
393+ r -> addr = a ;
394+ if (r -> ttl != ttl ) {
395+ if (r -> ttl == 0 ) {
396+ r -> ttl = ttl ;
397+ } else {
398+ _mdns_result_update_ttl (r , ttl );
399+ }
400+ }
401+ if (_mdns_add_browse_result (out_sync_browse , r ) != ESP_OK ) {
402+ return ;
403+ }
404+ break ;
405+ }
406+ }
407+ }
408+ r = r -> next ;
409+ }
410+ }
411+ }
412+
413+ static bool is_txt_item_in_list (mdns_txt_item_t txt , uint8_t txt_value_len , mdns_txt_item_t * txt_list , uint8_t * txt_value_len_list , size_t txt_count )
414+ {
415+ for (size_t i = 0 ; i < txt_count ; i ++ ) {
416+ if (strcmp (txt .key , txt_list [i ].key ) == 0 ) {
417+ if (txt_value_len == txt_value_len_list [i ] && memcmp (txt .value , txt_list [i ].value , txt_value_len ) == 0 ) {
418+ return true;
419+ } else {
420+ // The key value is unique, so there is no need to continue searching.
421+ return false;
422+ }
423+ }
424+ }
425+ return false;
426+ }
427+
428+ /**
429+ * @brief Called from parser to add TXT data to search result
430+ */
431+ void _mdns_browse_result_add_txt (mdns_browse_t * browse , const char * instance , const char * service , const char * proto ,
432+ mdns_txt_item_t * txt , uint8_t * txt_value_len , size_t txt_count , mdns_if_t tcpip_if , mdns_ip_protocol_t ip_protocol ,
433+ uint32_t ttl , mdns_browse_sync_t * out_sync_browse )
434+ {
435+ if (out_sync_browse -> browse == NULL ) {
436+ return ;
437+ } else {
438+ if (out_sync_browse -> browse != browse ) {
439+ return ;
440+ }
441+ }
442+ mdns_result_t * r = browse -> result ;
443+ while (r ) {
444+ if (r -> esp_netif == _mdns_get_esp_netif (tcpip_if ) && r -> ip_protocol == ip_protocol &&
445+ !mdns_utils_str_null_or_empty (r -> instance_name ) && !strcasecmp (instance , r -> instance_name ) &&
446+ !mdns_utils_str_null_or_empty (r -> service_type ) && !strcasecmp (service , r -> service_type ) &&
447+ !mdns_utils_str_null_or_empty (r -> proto ) && !strcasecmp (proto , r -> proto )) {
448+ bool should_update = false;
449+ if (r -> txt ) {
450+ // Check if txt changed
451+ if (txt_count != r -> txt_count ) {
452+ should_update = true;
453+ } else {
454+ for (size_t txt_index = 0 ; txt_index < txt_count ; txt_index ++ ) {
455+ if (!is_txt_item_in_list (txt [txt_index ], txt_value_len [txt_index ], r -> txt , r -> txt_value_len , r -> txt_count )) {
456+ should_update = true;
457+ break ;
458+ }
459+ }
460+ }
461+ // If the result has a previous txt entry, we delete it and re-add.
462+ for (size_t i = 0 ; i < r -> txt_count ; i ++ ) {
463+ mdns_mem_free ((char * )(r -> txt [i ].key ));
464+ mdns_mem_free ((char * )(r -> txt [i ].value ));
465+ }
466+ mdns_mem_free (r -> txt );
467+ mdns_mem_free (r -> txt_value_len );
468+ }
469+ r -> txt = txt ;
470+ r -> txt_value_len = txt_value_len ;
471+ r -> txt_count = txt_count ;
472+ if (r -> ttl != ttl ) {
473+ uint32_t previous_ttl = r -> ttl ;
474+ if (r -> ttl == 0 ) {
475+ r -> ttl = ttl ;
476+ } else {
477+ _mdns_result_update_ttl (r , ttl );
478+ }
479+ if (previous_ttl != r -> ttl ) {
480+ should_update = true;
481+ }
482+ }
483+ if (should_update ) {
484+ if (_mdns_add_browse_result (out_sync_browse , r ) != ESP_OK ) {
485+ return ;
486+ }
487+ }
488+ return ;
489+ }
490+ r = r -> next ;
491+ }
492+ r = (mdns_result_t * )mdns_mem_malloc (sizeof (mdns_result_t ));
493+ if (!r ) {
494+ HOOK_MALLOC_FAILED ;
495+ goto free_txt ;
496+ }
497+ memset (r , 0 , sizeof (mdns_result_t ));
498+ r -> instance_name = mdns_mem_strdup (instance );
499+ r -> service_type = mdns_mem_strdup (service );
500+ r -> proto = mdns_mem_strdup (proto );
501+ if (!r -> instance_name || !r -> service_type || !r -> proto ) {
502+ mdns_mem_free (r -> instance_name );
503+ mdns_mem_free (r -> service_type );
504+ mdns_mem_free (r -> proto );
505+ mdns_mem_free (r );
506+ return ;
507+ }
508+ r -> txt = txt ;
509+ r -> txt_value_len = txt_value_len ;
510+ r -> txt_count = txt_count ;
511+ r -> esp_netif = _mdns_get_esp_netif (tcpip_if );
512+ r -> ip_protocol = ip_protocol ;
513+ r -> ttl = ttl ;
514+ r -> next = browse -> result ;
515+ browse -> result = r ;
516+ _mdns_add_browse_result (out_sync_browse , r );
517+ return ;
518+
519+ free_txt :
520+ for (size_t i = 0 ; i < txt_count ; i ++ ) {
521+ mdns_mem_free ((char * )(txt [i ].key ));
522+ mdns_mem_free ((char * )(txt [i ].value ));
523+ }
524+ mdns_mem_free (txt );
525+ mdns_mem_free (txt_value_len );
526+ return ;
527+ }
528+
529+ static esp_err_t _mdns_copy_address_in_previous_result (mdns_result_t * result_list , mdns_result_t * r )
530+ {
531+ while (result_list ) {
532+ if (!mdns_utils_str_null_or_empty (result_list -> hostname ) && !mdns_utils_str_null_or_empty (r -> hostname ) && !strcasecmp (result_list -> hostname , r -> hostname ) &&
533+ result_list -> ip_protocol == r -> ip_protocol && result_list -> addr && !r -> addr ) {
534+ // If there is a same hostname in previous result, we need to copy the address here.
535+ r -> addr = copy_address_list (result_list -> addr );
536+ if (!r -> addr ) {
537+ return ESP_ERR_NO_MEM ;
538+ }
539+ break ;
540+ } else {
541+ result_list = result_list -> next ;
542+ }
543+ }
544+ return ESP_OK ;
545+ }
546+
547+ /**
548+ * @brief Called from parser to add SRV data to search result
549+ */
550+ void _mdns_browse_result_add_srv (mdns_browse_t * browse , const char * hostname , const char * instance , const char * service , const char * proto ,
551+ uint16_t port , mdns_if_t tcpip_if , mdns_ip_protocol_t ip_protocol , uint32_t ttl , mdns_browse_sync_t * out_sync_browse )
552+ {
553+ if (out_sync_browse -> browse == NULL ) {
554+ return ;
555+ } else {
556+ if (out_sync_browse -> browse != browse ) {
557+ return ;
558+ }
559+ }
560+ mdns_result_t * r = browse -> result ;
561+ while (r ) {
562+ if (r -> esp_netif == _mdns_get_esp_netif (tcpip_if ) && r -> ip_protocol == ip_protocol &&
563+ !mdns_utils_str_null_or_empty (r -> instance_name ) && !strcasecmp (instance , r -> instance_name ) &&
564+ !mdns_utils_str_null_or_empty (r -> service_type ) && !strcasecmp (service , r -> service_type ) &&
565+ !mdns_utils_str_null_or_empty (r -> proto ) && !strcasecmp (proto , r -> proto )) {
566+ if (mdns_utils_str_null_or_empty (r -> hostname ) || strcasecmp (hostname , r -> hostname )) {
567+ r -> hostname = mdns_mem_strdup (hostname );
568+ r -> port = port ;
569+ if (!r -> hostname ) {
570+ HOOK_MALLOC_FAILED ;
571+ return ;
572+ }
573+ if (!r -> addr ) {
574+ esp_err_t err = _mdns_copy_address_in_previous_result (browse -> result , r );
575+ if (err == ESP_ERR_NO_MEM ) {
576+ return ;
577+ }
578+ }
579+ if (_mdns_add_browse_result (out_sync_browse , r ) != ESP_OK ) {
580+ return ;
581+ }
582+ }
583+ if (r -> ttl != ttl ) {
584+ uint32_t previous_ttl = r -> ttl ;
585+ if (r -> ttl == 0 ) {
586+ r -> ttl = ttl ;
587+ } else {
588+ _mdns_result_update_ttl (r , ttl );
589+ }
590+ if (previous_ttl != r -> ttl ) {
591+ if (_mdns_add_browse_result (out_sync_browse , r ) != ESP_OK ) {
592+ return ;
593+ }
594+ }
595+ }
596+ return ;
597+ }
598+ r = r -> next ;
599+ }
600+ r = (mdns_result_t * )mdns_mem_malloc (sizeof (mdns_result_t ));
601+ if (!r ) {
602+ HOOK_MALLOC_FAILED ;
603+ return ;
604+ }
605+
606+ memset (r , 0 , sizeof (mdns_result_t ));
607+ r -> hostname = mdns_mem_strdup (hostname );
608+ r -> instance_name = mdns_mem_strdup (instance );
609+ r -> service_type = mdns_mem_strdup (service );
610+ r -> proto = mdns_mem_strdup (proto );
611+ if (!r -> hostname || !r -> instance_name || !r -> service_type || !r -> proto ) {
612+ HOOK_MALLOC_FAILED ;
613+ mdns_mem_free (r -> hostname );
614+ mdns_mem_free (r -> instance_name );
615+ mdns_mem_free (r -> service_type );
616+ mdns_mem_free (r -> proto );
617+ mdns_mem_free (r );
618+ return ;
619+ }
620+ r -> port = port ;
621+ r -> esp_netif = _mdns_get_esp_netif (tcpip_if );
622+ r -> ip_protocol = ip_protocol ;
623+ r -> ttl = ttl ;
624+ r -> next = browse -> result ;
625+ browse -> result = r ;
626+ _mdns_add_browse_result (out_sync_browse , r );
627+ return ;
628+ }
0 commit comments