@@ -2389,6 +2389,53 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
23892389 }
23902390}
23912391
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+
23922439/**
23932440 * @brief Send announcement on particular PCB
23942441 */
@@ -2804,16 +2851,22 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
28042851 }
28052852}
28062853
2807- static void _mdns_free_service_subtype ( mdns_service_t * service )
2854+ static void _mdns_free_subtype ( mdns_subtype_t * subtype )
28082855{
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 ;
28142861 }
28152862}
28162863
2864+ static void _mdns_free_service_subtype (mdns_service_t * service )
2865+ {
2866+ _mdns_free_subtype (service -> subtype );
2867+ service -> subtype = NULL ;
2868+ }
2869+
28172870/**
28182871 * @brief free service memory
28192872 *
@@ -6357,11 +6410,23 @@ esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const
63576410 ret = _mdns_service_subtype_remove_for_host (s , subtype );
63586411 ESP_GOTO_ON_ERROR (ret , err , TAG , "Failed to remove the subtype: %s" , subtype );
63596412
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 );
63626422err :
63636423 MDNS_SERVICE_UNLOCK ();
63646424 return ret ;
6425+ out_of_mem :
6426+ HOOK_MALLOC_FAILED ;
6427+ free (remove_subtypes );
6428+ MDNS_SERVICE_UNLOCK ();
6429+ return ret ;
63656430}
63666431
63676432static 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
64336498 return mdns_service_subtype_add_multiple_items_for_host (instance_name , service_type , proto , hostname , _subtype , 1 );
64346499}
64356500
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+
64366551esp_err_t mdns_service_subtype_update_multiple_items_for_host (const char * instance_name , const char * service_type , const char * proto ,
64376552 const char * hostname , mdns_subtype_item_t subtype [], uint8_t num_items )
64386553{
@@ -6445,7 +6560,13 @@ esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instan
64456560 mdns_srv_item_t * s = _mdns_get_service_item_instance (instance_name , service_type , proto , hostname );
64466561 ESP_GOTO_ON_FALSE (s , ESP_ERR_NOT_FOUND , err , TAG , "Service doesn't exist" );
64476562
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 );
64496570 _mdns_free_service_subtype (s -> service );
64506571
64516572 for (; cur_index < num_items ; cur_index ++ ) {
0 commit comments