@@ -610,9 +610,9 @@ CHIP_ERROR MdnsAvahi::Browse(const char * type, DnssdServiceProtocol protocol, c
610
610
{
611
611
avahiInterface = AVAHI_IF_UNSPEC;
612
612
}
613
- browseContext->mInterface = avahiInterface;
614
- browseContext->mProtocol = GetFullType (type, protocol);
615
- browseContext->mBrowseRetries = 0 ;
613
+ browseContext->mInterface = avahiInterface;
614
+ browseContext->mProtocol = GetFullType (type, protocol);
615
+ browseContext->mReceivedAllCached = false ;
616
616
browseContext->mStopped .store (false );
617
617
618
618
browser = avahi_service_browser_new (mClient , avahiInterface, AVAHI_PROTO_UNSPEC, browseContext->mProtocol .c_str (), nullptr ,
@@ -685,23 +685,22 @@ void CopyTypeWithoutProtocol(char (&dest)[N], const char * typeAndProtocol)
685
685
}
686
686
}
687
687
688
- void MdnsAvahi::BrowseRetryCallback (chip::System::Layer * aLayer, void * appState )
688
+ void MdnsAvahi::InvokeDelegateOrCleanUp (BrowseContext * context, AvahiServiceBrowser * browser )
689
689
{
690
- BrowseContext * context = static_cast <BrowseContext *>(appState);
691
- // Don't schedule anything new if we've stopped.
692
- if (context->mStopped .load ())
690
+ // If we were already asked to stop, no need to send a callback - no one is listening.
691
+ if (!context->mStopped .load ())
693
692
{
694
- chip::Platform::Delete (context);
695
- return ;
693
+ // since this is continuous browse, finalBrowse will always be false.
694
+ context->mCallback (context->mContext , context->mServices .data (), context->mServices .size (), false , CHIP_NO_ERROR);
695
+
696
+ // Clearing records/services already passed to application through delegate. Keeping it may cause
697
+ // duplicates in next query / retry attempt as currently found will also come again from cache.
698
+ context->mServices .clear ();
696
699
}
697
- AvahiServiceBrowser * newBrowser =
698
- avahi_service_browser_new (context->mInstance ->mClient , context->mInterface , AVAHI_PROTO_UNSPEC, context->mProtocol .c_str (),
699
- nullptr , static_cast <AvahiLookupFlags>(0 ), HandleBrowse, context);
700
- if (newBrowser == nullptr )
700
+ else
701
701
{
702
- // If we failed to create the browser, this browse context is effectively done. We need to call the final callback and
703
- // delete the context.
704
- context->mCallback (context->mContext , context->mServices .data (), context->mServices .size (), true , CHIP_NO_ERROR);
702
+ // browse is stopped, so free browse handle and context
703
+ avahi_service_browser_free (browser);
705
704
chip::Platform::Delete (context);
706
705
}
707
706
}
@@ -721,6 +720,13 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa
721
720
break ;
722
721
case AVAHI_BROWSER_NEW:
723
722
ChipLogProgress (DeviceLayer, " Avahi browse: cache new" );
723
+ if (context->mStopped .load ())
724
+ {
725
+ // browse is stopped, so free browse handle and context
726
+ avahi_service_browser_free (browser);
727
+ chip::Platform::Delete (context);
728
+ break ;
729
+ }
724
730
if (strcmp (" local" , domain) == 0 )
725
731
{
726
732
DnssdService service = {};
@@ -737,41 +743,53 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa
737
743
}
738
744
service.mType [kDnssdTypeMaxSize ] = 0 ;
739
745
context->mServices .push_back (service);
746
+ if (context->mReceivedAllCached )
747
+ {
748
+ InvokeDelegateOrCleanUp (context, browser);
749
+ }
740
750
}
741
751
break ;
742
752
case AVAHI_BROWSER_ALL_FOR_NOW: {
743
753
ChipLogProgress (DeviceLayer, " Avahi browse: all for now" );
744
- bool needRetries = context->mBrowseRetries ++ < kMaxBrowseRetries && !context->mStopped .load ();
745
- // If we were already asked to stop, no need to send a callback - no one is listening.
746
- if (!context->mStopped .load ())
747
- {
748
- context->mCallback (context->mContext , context->mServices .data (), context->mServices .size (), !needRetries,
749
- CHIP_NO_ERROR);
750
- }
751
- avahi_service_browser_free (browser);
752
- if (needRetries)
753
- {
754
- context->mNextRetryDelay *= 2 ;
755
- // Hand the ownership of the context over to the timer. It will either schedule a new browse on the context,
756
- // triggering this function, or it will delete and not reschedule (if stopped).
757
- DeviceLayer::SystemLayer ().StartTimer (context->mNextRetryDelay / 2 , BrowseRetryCallback, context);
758
- }
759
- else
760
- {
761
- // We didn't schedule a timer, so we're responsible for deleting the context
762
- chip::Platform::Delete (context);
763
- }
754
+ context->mReceivedAllCached = true ;
755
+
756
+ InvokeDelegateOrCleanUp (context, browser);
764
757
break ;
765
758
}
766
759
case AVAHI_BROWSER_REMOVE:
767
760
ChipLogProgress (DeviceLayer, " Avahi browse: remove" );
768
761
if (strcmp (" local" , domain) == 0 )
769
762
{
770
- context->mServices .erase (
771
- std::remove_if (context->mServices .begin (), context->mServices .end (), [name, type](const DnssdService & service) {
772
- return strcmp (name, service.mName ) == 0 && type == GetFullType (service.mType , service.mProtocol );
773
- }));
763
+ // don't attempt to erase if vector has been cleared
764
+ if (context->mServices .size ())
765
+ {
766
+ context->mServices .erase (std::remove_if (
767
+ context->mServices .begin (), context->mServices .end (), [name, type](const DnssdService & service) {
768
+ return strcmp (name, service.mName ) == 0 && type == GetFullType (service.mType , service.mProtocol );
769
+ }));
770
+ }
771
+
772
+ if (context->mReceivedAllCached )
773
+ {
774
+ DnssdService service = {};
775
+
776
+ Platform::CopyString (service.mName , name);
777
+ CopyTypeWithoutProtocol (service.mType , type);
778
+ service.mProtocol = GetProtocolInType (type);
779
+ service.mAddressType = context->mAddressType ;
780
+ service.mTransportType = ToAddressType (protocol);
781
+ service.mInterface = Inet::InterfaceId::Null ();
782
+ if (interface != AVAHI_IF_UNSPEC)
783
+ {
784
+ service.mInterface = static_cast <chip::Inet::InterfaceId>(interface);
785
+ }
786
+ service.mTtlSeconds = 0 ;
787
+
788
+ context->mServices .push_back (service);
789
+ InvokeDelegateOrCleanUp (context, browser);
790
+ }
774
791
}
792
+
775
793
break ;
776
794
case AVAHI_BROWSER_CACHE_EXHAUSTED:
777
795
ChipLogProgress (DeviceLayer, " Avahi browse: cache exhausted" );
0 commit comments