@@ -2389,6 +2389,53 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
2389
2389
}
2390
2390
}
2391
2391
2392
+ /**
2393
+ * @brief Send bye for particular subtypes
2394
+ */
2395
+ static void _mdns_send_bye_subtype (mdns_srv_item_t * service , const char * instance_name , mdns_subtype_t * remove_subtypes )
2396
+ {
2397
+ uint8_t i , j ;
2398
+ for (i = 0 ; i < MDNS_MAX_INTERFACES ; i ++ ) {
2399
+ for (j = 0 ; j < MDNS_IP_PROTOCOL_MAX ; j ++ ) {
2400
+ if (mdns_is_netif_ready (i , j )) {
2401
+ mdns_tx_packet_t * packet = _mdns_alloc_packet_default ((mdns_if_t )i , (mdns_ip_protocol_t )j );
2402
+ packet -> flags = MDNS_FLAGS_QR_AUTHORITATIVE ;
2403
+ if (!_mdns_alloc_answer (& packet -> answers , MDNS_TYPE_PTR , service -> service , NULL , true, true)) {
2404
+ _mdns_free_tx_packet (packet );
2405
+ return ;
2406
+ }
2407
+
2408
+ static uint8_t pkt [MDNS_MAX_PACKET_SIZE ];
2409
+ uint16_t index = MDNS_HEAD_LEN ;
2410
+ memset (pkt , 0 , MDNS_HEAD_LEN );
2411
+ mdns_out_answer_t * a ;
2412
+ uint8_t count ;
2413
+
2414
+ _mdns_set_u16 (pkt , MDNS_HEAD_FLAGS_OFFSET , packet -> flags );
2415
+ _mdns_set_u16 (pkt , MDNS_HEAD_ID_OFFSET , packet -> id );
2416
+
2417
+ count = 0 ;
2418
+ a = packet -> answers ;
2419
+ while (a ) {
2420
+ if (a -> type == MDNS_TYPE_PTR && a -> service ) {
2421
+ const mdns_subtype_t * current_subtype = remove_subtypes ;
2422
+ while (current_subtype ) {
2423
+ count += (_mdns_append_subtype_ptr_record (pkt , & index , instance_name , current_subtype -> subtype , a -> service -> service , a -> service -> proto , a -> flush , a -> bye ) > 0 );
2424
+ current_subtype = current_subtype -> next ;
2425
+ }
2426
+ }
2427
+ a = a -> next ;
2428
+ }
2429
+ _mdns_set_u16 (pkt , MDNS_HEAD_ANSWERS_OFFSET , count );
2430
+
2431
+ _mdns_udp_pcb_write (packet -> tcpip_if , packet -> ip_protocol , & packet -> dst , packet -> port , pkt , index );
2432
+
2433
+ _mdns_free_tx_packet (packet );
2434
+ }
2435
+ }
2436
+ }
2437
+ }
2438
+
2392
2439
/**
2393
2440
* @brief Send announcement on particular PCB
2394
2441
*/
@@ -2804,16 +2851,22 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
2804
2851
}
2805
2852
}
2806
2853
2807
- static void _mdns_free_service_subtype ( mdns_service_t * service )
2854
+ static void _mdns_free_subtype ( mdns_subtype_t * subtype )
2808
2855
{
2809
- while (service -> subtype ) {
2810
- mdns_subtype_t * next = service -> subtype -> next ;
2811
- free ((char * )service -> subtype -> subtype );
2812
- free (service -> subtype );
2813
- service -> subtype = next ;
2856
+ while (subtype ) {
2857
+ mdns_subtype_t * next = subtype -> next ;
2858
+ free ((char * )subtype -> subtype );
2859
+ free (subtype );
2860
+ subtype = next ;
2814
2861
}
2815
2862
}
2816
2863
2864
+ static void _mdns_free_service_subtype (mdns_service_t * service )
2865
+ {
2866
+ _mdns_free_subtype (service -> subtype );
2867
+ service -> subtype = NULL ;
2868
+ }
2869
+
2817
2870
/**
2818
2871
* @brief free service memory
2819
2872
*
@@ -6357,11 +6410,23 @@ esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const
6357
6410
ret = _mdns_service_subtype_remove_for_host (s , subtype );
6358
6411
ESP_GOTO_ON_ERROR (ret , err , TAG , "Failed to remove the subtype: %s" , subtype );
6359
6412
6360
- // TODO: Need to transmit a sendbye message for the removed subtype.
6361
- // TODO: Need to remove this subtype answer from the scheduled answer list.
6413
+ // Transmit a sendbye message for the removed subtype.
6414
+ mdns_subtype_t * remove_subtypes = (mdns_subtype_t * )malloc (sizeof (mdns_subtype_t ));
6415
+ ESP_GOTO_ON_FALSE (remove_subtypes , ESP_ERR_NO_MEM , out_of_mem , TAG , "Out of memory" );
6416
+ remove_subtypes -> subtype = strdup (subtype );
6417
+ ESP_GOTO_ON_FALSE (remove_subtypes -> subtype , ESP_ERR_NO_MEM , out_of_mem , TAG , "Out of memory" );
6418
+ remove_subtypes -> next = NULL ;
6419
+
6420
+ _mdns_send_bye_subtype (s , instance_name , remove_subtypes );
6421
+ _mdns_free_subtype (remove_subtypes );
6362
6422
err :
6363
6423
MDNS_SERVICE_UNLOCK ();
6364
6424
return ret ;
6425
+ out_of_mem :
6426
+ HOOK_MALLOC_FAILED ;
6427
+ free (remove_subtypes );
6428
+ MDNS_SERVICE_UNLOCK ();
6429
+ return ret ;
6365
6430
}
6366
6431
6367
6432
static esp_err_t _mdns_service_subtype_add_for_host (mdns_srv_item_t * service , const char * subtype )
@@ -6433,6 +6498,56 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
6433
6498
return mdns_service_subtype_add_multiple_items_for_host (instance_name , service_type , proto , hostname , _subtype , 1 );
6434
6499
}
6435
6500
6501
+ static mdns_subtype_t * _mdns_service_find_subtype_needed_sendbye (mdns_service_t * service , mdns_subtype_item_t subtype [],
6502
+ uint8_t num_items )
6503
+ {
6504
+ if (!service ) {
6505
+ return NULL ;
6506
+ }
6507
+
6508
+ mdns_subtype_t * current = service -> subtype ;
6509
+ mdns_subtype_t * prev = NULL ;
6510
+ mdns_subtype_t * prev_goodbye = NULL ;
6511
+ mdns_subtype_t * out_goodbye_subtype = NULL ;
6512
+
6513
+ while (current ) {
6514
+ bool subtype_in_update = false;
6515
+
6516
+ for (int i = 0 ; i < num_items ; i ++ ) {
6517
+ if (strcmp (subtype [i ].subtype , current -> subtype ) == 0 ) {
6518
+ subtype_in_update = true;
6519
+ break ;
6520
+ }
6521
+ }
6522
+
6523
+ if (!subtype_in_update ) {
6524
+ // Remove from original list
6525
+ if (prev ) {
6526
+ prev -> next = current -> next ;
6527
+ } else {
6528
+ service -> subtype = current -> next ;
6529
+ }
6530
+
6531
+ mdns_subtype_t * to_move = current ;
6532
+ current = current -> next ;
6533
+
6534
+ // Add to goodbye list
6535
+ to_move -> next = NULL ;
6536
+ if (prev_goodbye ) {
6537
+ prev_goodbye -> next = to_move ;
6538
+ } else {
6539
+ out_goodbye_subtype = to_move ;
6540
+ }
6541
+ prev_goodbye = to_move ;
6542
+ } else {
6543
+ prev = current ;
6544
+ current = current -> next ;
6545
+ }
6546
+ }
6547
+
6548
+ return out_goodbye_subtype ;
6549
+ }
6550
+
6436
6551
esp_err_t mdns_service_subtype_update_multiple_items_for_host (const char * instance_name , const char * service_type , const char * proto ,
6437
6552
const char * hostname , mdns_subtype_item_t subtype [], uint8_t num_items )
6438
6553
{
@@ -6445,7 +6560,13 @@ esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instan
6445
6560
mdns_srv_item_t * s = _mdns_get_service_item_instance (instance_name , service_type , proto , hostname );
6446
6561
ESP_GOTO_ON_FALSE (s , ESP_ERR_NOT_FOUND , err , TAG , "Service doesn't exist" );
6447
6562
6448
- // TODO: find subtype needs to say sendbye
6563
+ mdns_subtype_t * goodbye_subtype = _mdns_service_find_subtype_needed_sendbye (s -> service , subtype , num_items );
6564
+
6565
+ if (goodbye_subtype ) {
6566
+ _mdns_send_bye_subtype (s , instance_name , goodbye_subtype );
6567
+ }
6568
+
6569
+ _mdns_free_subtype (goodbye_subtype );
6449
6570
_mdns_free_service_subtype (s -> service );
6450
6571
6451
6572
for (; cur_index < num_items ; cur_index ++ ) {
0 commit comments