@@ -318,3 +318,311 @@ void mdns_browse_action(mdns_action_t *action, mdns_action_subtype_t type)
318
318
}
319
319
320
320
}
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