@@ -2383,6 +2383,53 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
2383
2383
}
2384
2384
}
2385
2385
2386
+ /**
2387
+ * @brief Send bye for particular subtypes
2388
+ */
2389
+ static void _mdns_send_bye_subtype (mdns_srv_item_t * service , const char * instance_name , mdns_subtype_t * remove_subtypes )
2390
+ {
2391
+ uint8_t i , j ;
2392
+ for (i = 0 ; i < MDNS_MAX_INTERFACES ; i ++ ) {
2393
+ for (j = 0 ; j < MDNS_IP_PROTOCOL_MAX ; j ++ ) {
2394
+ if (mdns_is_netif_ready (i , j )) {
2395
+ mdns_tx_packet_t * packet = _mdns_alloc_packet_default ((mdns_if_t )i , (mdns_ip_protocol_t )j );
2396
+ packet -> flags = MDNS_FLAGS_QR_AUTHORITATIVE ;
2397
+ if (!_mdns_alloc_answer (& packet -> answers , MDNS_TYPE_PTR , service -> service , NULL , true, true)) {
2398
+ _mdns_free_tx_packet (packet );
2399
+ return ;
2400
+ }
2401
+
2402
+ static uint8_t pkt [MDNS_MAX_PACKET_SIZE ];
2403
+ uint16_t index = MDNS_HEAD_LEN ;
2404
+ memset (pkt , 0 , MDNS_HEAD_LEN );
2405
+ mdns_out_answer_t * a ;
2406
+ uint8_t count ;
2407
+
2408
+ _mdns_set_u16 (pkt , MDNS_HEAD_FLAGS_OFFSET , packet -> flags );
2409
+ _mdns_set_u16 (pkt , MDNS_HEAD_ID_OFFSET , packet -> id );
2410
+
2411
+ count = 0 ;
2412
+ a = packet -> answers ;
2413
+ while (a ) {
2414
+ if (a -> type == MDNS_TYPE_PTR && a -> service ) {
2415
+ const mdns_subtype_t * current_subtype = remove_subtypes ;
2416
+ while (current_subtype ) {
2417
+ count += (_mdns_append_subtype_ptr_record (pkt , & index , instance_name , current_subtype -> subtype , a -> service -> service , a -> service -> proto , a -> flush , a -> bye ) > 0 );
2418
+ current_subtype = current_subtype -> next ;
2419
+ }
2420
+ }
2421
+ a = a -> next ;
2422
+ }
2423
+ _mdns_set_u16 (pkt , MDNS_HEAD_ANSWERS_OFFSET , count );
2424
+
2425
+ _mdns_udp_pcb_write (packet -> tcpip_if , packet -> ip_protocol , & packet -> dst , packet -> port , pkt , index );
2426
+
2427
+ _mdns_free_tx_packet (packet );
2428
+ }
2429
+ }
2430
+ }
2431
+ }
2432
+
2386
2433
/**
2387
2434
* @brief Send announcement on particular PCB
2388
2435
*/
@@ -2794,16 +2841,22 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
2794
2841
}
2795
2842
}
2796
2843
2797
- static void _mdns_free_service_subtype ( mdns_service_t * service )
2844
+ static void _mdns_free_subtype ( mdns_subtype_t * subtype )
2798
2845
{
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 ;
2846
+ while (subtype ) {
2847
+ mdns_subtype_t * next = subtype -> next ;
2848
+ free ((char * )subtype -> subtype );
2849
+ free (subtype );
2850
+ subtype = next ;
2804
2851
}
2805
2852
}
2806
2853
2854
+ static void _mdns_free_service_subtype (mdns_service_t * service )
2855
+ {
2856
+ _mdns_free_subtype (service -> subtype );
2857
+ service -> subtype = NULL ;
2858
+ }
2859
+
2807
2860
/**
2808
2861
* @brief free service memory
2809
2862
*
@@ -6347,11 +6400,23 @@ esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const
6347
6400
ret = _mdns_service_subtype_remove_for_host (s , subtype );
6348
6401
ESP_GOTO_ON_ERROR (ret , err , TAG , "Failed to remove the subtype: %s" , subtype );
6349
6402
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.
6403
+ // Transmit a sendbye message for the removed subtype.
6404
+ mdns_subtype_t * remove_subtypes = (mdns_subtype_t * )malloc (sizeof (mdns_subtype_t ));
6405
+ ESP_GOTO_ON_FALSE (remove_subtypes , ESP_ERR_NO_MEM , out_of_mem , TAG , "Out of memory" );
6406
+ remove_subtypes -> subtype = strdup (subtype );
6407
+ ESP_GOTO_ON_FALSE (remove_subtypes -> subtype , ESP_ERR_NO_MEM , out_of_mem , TAG , "Out of memory" );
6408
+ remove_subtypes -> next = NULL ;
6409
+
6410
+ _mdns_send_bye_subtype (s , instance_name , remove_subtypes );
6411
+ _mdns_free_subtype (remove_subtypes );
6352
6412
err :
6353
6413
MDNS_SERVICE_UNLOCK ();
6354
6414
return ret ;
6415
+ out_of_mem :
6416
+ HOOK_MALLOC_FAILED ;
6417
+ free (remove_subtypes );
6418
+ MDNS_SERVICE_UNLOCK ();
6419
+ return ret ;
6355
6420
}
6356
6421
6357
6422
static esp_err_t _mdns_service_subtype_add_for_host (mdns_srv_item_t * service , const char * subtype )
@@ -6423,6 +6488,56 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
6423
6488
return mdns_service_subtype_add_multiple_items_for_host (instance_name , service_type , proto , hostname , _subtype , 1 );
6424
6489
}
6425
6490
6491
+ static mdns_subtype_t * _mdns_service_find_subtype_needed_sendbye (mdns_service_t * service , mdns_subtype_item_t subtype [],
6492
+ uint8_t num_items )
6493
+ {
6494
+ if (!service ) {
6495
+ return NULL ;
6496
+ }
6497
+
6498
+ mdns_subtype_t * current = service -> subtype ;
6499
+ mdns_subtype_t * prev = NULL ;
6500
+ mdns_subtype_t * prev_goodbye = NULL ;
6501
+ mdns_subtype_t * out_goodbye_subtype = NULL ;
6502
+
6503
+ while (current ) {
6504
+ bool subtype_in_update = false;
6505
+
6506
+ for (int i = 0 ; i < num_items ; i ++ ) {
6507
+ if (strcmp (subtype [i ].subtype , current -> subtype ) == 0 ) {
6508
+ subtype_in_update = true;
6509
+ break ;
6510
+ }
6511
+ }
6512
+
6513
+ if (!subtype_in_update ) {
6514
+ // Remove from original list
6515
+ if (prev ) {
6516
+ prev -> next = current -> next ;
6517
+ } else {
6518
+ service -> subtype = current -> next ;
6519
+ }
6520
+
6521
+ mdns_subtype_t * to_move = current ;
6522
+ current = current -> next ;
6523
+
6524
+ // Add to goodbye list
6525
+ to_move -> next = NULL ;
6526
+ if (prev_goodbye ) {
6527
+ prev_goodbye -> next = to_move ;
6528
+ } else {
6529
+ out_goodbye_subtype = to_move ;
6530
+ }
6531
+ prev_goodbye = to_move ;
6532
+ } else {
6533
+ prev = current ;
6534
+ current = current -> next ;
6535
+ }
6536
+ }
6537
+
6538
+ return out_goodbye_subtype ;
6539
+ }
6540
+
6426
6541
esp_err_t mdns_service_subtype_update_multiple_items_for_host (const char * instance_name , const char * service_type , const char * proto ,
6427
6542
const char * hostname , mdns_subtype_item_t subtype [], uint8_t num_items )
6428
6543
{
@@ -6435,7 +6550,13 @@ esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instan
6435
6550
mdns_srv_item_t * s = _mdns_get_service_item_instance (instance_name , service_type , proto , hostname );
6436
6551
ESP_GOTO_ON_FALSE (s , ESP_ERR_NOT_FOUND , err , TAG , "Service doesn't exist" );
6437
6552
6438
- // TODO: find subtype needs to say sendbye
6553
+ mdns_subtype_t * goodbye_subtype = _mdns_service_find_subtype_needed_sendbye (s -> service , subtype , num_items );
6554
+
6555
+ if (goodbye_subtype ) {
6556
+ _mdns_send_bye_subtype (s , instance_name , goodbye_subtype );
6557
+ }
6558
+
6559
+ _mdns_free_subtype (goodbye_subtype );
6439
6560
_mdns_free_service_subtype (s -> service );
6440
6561
6441
6562
for (; cur_index < num_items ; cur_index ++ ) {
0 commit comments