@@ -2383,6 +2383,53 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
23832383 }
23842384}
23852385
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+
23862433/**
23872434 * @brief Send announcement on particular PCB
23882435 */
@@ -2794,16 +2841,22 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
27942841 }
27952842}
27962843
2797- static void _mdns_free_service_subtype ( mdns_service_t * service )
2844+ static void _mdns_free_subtype ( mdns_subtype_t * subtype )
27982845{
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 ;
28042851 }
28052852}
28062853
2854+ static void _mdns_free_service_subtype (mdns_service_t * service )
2855+ {
2856+ _mdns_free_subtype (service -> subtype );
2857+ service -> subtype = NULL ;
2858+ }
2859+
28072860/**
28082861 * @brief free service memory
28092862 *
@@ -6347,11 +6400,23 @@ esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const
63476400 ret = _mdns_service_subtype_remove_for_host (s , subtype );
63486401 ESP_GOTO_ON_ERROR (ret , err , TAG , "Failed to remove the subtype: %s" , subtype );
63496402
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 );
63526412err :
63536413 MDNS_SERVICE_UNLOCK ();
63546414 return ret ;
6415+ out_of_mem :
6416+ HOOK_MALLOC_FAILED ;
6417+ free (remove_subtypes );
6418+ MDNS_SERVICE_UNLOCK ();
6419+ return ret ;
63556420}
63566421
63576422static 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
64236488 return mdns_service_subtype_add_multiple_items_for_host (instance_name , service_type , proto , hostname , _subtype , 1 );
64246489}
64256490
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+
64266541esp_err_t mdns_service_subtype_update_multiple_items_for_host (const char * instance_name , const char * service_type , const char * proto ,
64276542 const char * hostname , mdns_subtype_item_t subtype [], uint8_t num_items )
64286543{
@@ -6435,7 +6550,13 @@ esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instan
64356550 mdns_srv_item_t * s = _mdns_get_service_item_instance (instance_name , service_type , proto , hostname );
64366551 ESP_GOTO_ON_FALSE (s , ESP_ERR_NOT_FOUND , err , TAG , "Service doesn't exist" );
64376552
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 );
64396560 _mdns_free_service_subtype (s -> service );
64406561
64416562 for (; cur_index < num_items ; cur_index ++ ) {
0 commit comments