diff --git a/src/agent/application.cpp b/src/agent/application.cpp index c656d249a4d..7183a4aa4a4 100644 --- a/src/agent/application.cpp +++ b/src/agent/application.cpp @@ -66,7 +66,8 @@ Application::Application(const std::string &aInterfaceName, /* aDryRun */ false, aEnableAutoAttach)) #if OTBR_ENABLE_MDNS - , mPublisher(Mdns::Publisher::Create([this](Mdns::Publisher::State aState) { this->HandleMdnsState(aState); })) + , mPublisher( + Mdns::Publisher::Create([this](Mdns::Publisher::State aState) { mMdnsStateSubject.UpdateState(aState); })) #endif #if OTBR_ENABLE_DBUS_SERVER && OTBR_ENABLE_BORDER_AGENT , mDBusAgent(MakeUnique(*mHost, *mPublisher)) @@ -191,24 +192,6 @@ otbrError Application::Run(void) return error; } -void Application::HandleMdnsState(Mdns::Publisher::State aState) -{ - OTBR_UNUSED_VARIABLE(aState); - -#if OTBR_ENABLE_BORDER_AGENT - mBorderAgent->HandleMdnsState(aState); -#endif -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy->HandleMdnsState(aState); -#endif -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - mDiscoveryProxy->HandleMdnsState(aState); -#endif -#if OTBR_ENABLE_TREL - mTrelDnssd->HandleMdnsState(aState); -#endif -} - void Application::HandleSignal(int aSignal) { sShouldTerminate = true; @@ -249,6 +232,19 @@ void Application::CreateRcpMode(const std::string &aRestListenAddress, int aRest void Application::InitRcpMode(void) { +#if OTBR_ENABLE_BORDER_AGENT + mMdnsStateSubject.AddObserver(mBorderAgent.get()); +#endif +#if OTBR_ENABLE_SRP_ADVERTISING_PROXY + mMdnsStateSubject.AddObserver(mAdvertisingProxy.get()); +#endif +#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY + mMdnsStateSubject.AddObserver(mDiscoveryProxy.get()); +#endif +#if OTBR_ENABLE_TREL + mMdnsStateSubject.AddObserver(mTrelDnssd.get()); +#endif + #if OTBR_ENABLE_MDNS mPublisher->Start(); #endif diff --git a/src/agent/application.hpp b/src/agent/application.hpp index 92b44ef1580..c09d6908ff7 100644 --- a/src/agent/application.hpp +++ b/src/agent/application.hpp @@ -237,13 +237,6 @@ class Application : private NonCopyable } #endif - /** - * This method handles mDNS publisher's state changes. - * - * @param[in] aState The state of mDNS publisher. - */ - void HandleMdnsState(Mdns::Publisher::State aState); - private: // Default poll timeout. static const struct timeval kPollTimeout; @@ -264,6 +257,7 @@ class Application : private NonCopyable const char *mBackboneInterfaceName; std::unique_ptr mHost; #if OTBR_ENABLE_MDNS + Mdns::StateSubject mMdnsStateSubject; std::unique_ptr mPublisher; #endif #if OTBR_ENABLE_BORDER_AGENT diff --git a/src/border_agent/border_agent.hpp b/src/border_agent/border_agent.hpp index ed9686f4c3f..f10144bebc0 100644 --- a/src/border_agent/border_agent.hpp +++ b/src/border_agent/border_agent.hpp @@ -75,7 +75,7 @@ namespace otbr { /** * This class implements Thread border agent functionality. */ -class BorderAgent : private NonCopyable +class BorderAgent : private NonCopyable, public Mdns::StateObserver { public: /** The callback for receiving ephemeral key changes. */ @@ -139,7 +139,7 @@ class BorderAgent : private NonCopyable * * @param[in] aState The state of mDNS publisher. */ - void HandleMdnsState(Mdns::Publisher::State aState); + void HandleMdnsState(Mdns::Publisher::State aState) override; /** * This method creates ephemeral key in the Border Agent. diff --git a/src/mdns/mdns.cpp b/src/mdns/mdns.cpp index 3774a8b477d..454690320a8 100644 --- a/src/mdns/mdns.cpp +++ b/src/mdns/mdns.cpp @@ -779,6 +779,22 @@ void Publisher::RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddr } } +void StateSubject::AddObserver(StateObserver *aObserver) +{ + if (aObserver != nullptr) + { + mObservers.push_back(aObserver); + } +} + +void StateSubject::UpdateState(Publisher::State aState) +{ + for (StateObserver *observer : mObservers) + { + observer->HandleMdnsState(aState); + } +} + } // namespace Mdns } // namespace otbr diff --git a/src/mdns/mdns.hpp b/src/mdns/mdns.hpp index 45dff98d29c..32c40dd5391 100644 --- a/src/mdns/mdns.hpp +++ b/src/mdns/mdns.hpp @@ -665,6 +665,59 @@ class Publisher : private NonCopyable MdnsTelemetryInfo mTelemetryInfo{}; }; +/** + * This interface is a mDNS State Observer. + */ +class StateObserver +{ +public: + /** + * This method notifies the mDNS state to the observer. + * + * @param[in] aState The mDNS State. + */ + virtual void HandleMdnsState(Publisher::State aState) = 0; + + /** + * The destructor. + */ + virtual ~StateObserver(void) = default; +}; + +/** + * This class defines a mDNS State Subject. + */ +class StateSubject +{ +public: + /** + * Constructor. + */ + StateSubject(void) = default; + + /** + * Destructor. + */ + ~StateSubject(void) = default; + + /** + * This method adds an mDNS State Observer to this subject. + * + * @param[in] aObserver A pointer to the observer. If it's nullptr, it won't be added. + */ + void AddObserver(StateObserver *aObserver); + + /** + * This method updates the mDNS State. + * + * @param[in] aState The mDNS State. + */ + void UpdateState(Publisher::State aState); + +private: + std::vector mObservers; +}; + /** * @} */ diff --git a/src/sdp_proxy/advertising_proxy.hpp b/src/sdp_proxy/advertising_proxy.hpp index 2077d35010e..3d0c40dab63 100644 --- a/src/sdp_proxy/advertising_proxy.hpp +++ b/src/sdp_proxy/advertising_proxy.hpp @@ -52,7 +52,7 @@ namespace otbr { /** * This class implements the Advertising Proxy. */ -class AdvertisingProxy : private NonCopyable +class AdvertisingProxy : private NonCopyable, public Mdns::StateObserver { public: /** @@ -80,7 +80,7 @@ class AdvertisingProxy : private NonCopyable * * @param[in] aState The state of mDNS publisher. */ - void HandleMdnsState(Mdns::Publisher::State aState); + void HandleMdnsState(Mdns::Publisher::State aState) override; private: struct OutstandingUpdate diff --git a/src/sdp_proxy/discovery_proxy.hpp b/src/sdp_proxy/discovery_proxy.hpp index 9278cf49667..9a29bdb11fd 100644 --- a/src/sdp_proxy/discovery_proxy.hpp +++ b/src/sdp_proxy/discovery_proxy.hpp @@ -56,7 +56,7 @@ namespace Dnssd { /** * This class implements the DNS-SD Discovery Proxy. */ -class DiscoveryProxy : private NonCopyable +class DiscoveryProxy : private NonCopyable, public Mdns::StateObserver { public: /** diff --git a/src/trel_dnssd/trel_dnssd.hpp b/src/trel_dnssd/trel_dnssd.hpp index d6856b1d8ae..5c50a3ebd18 100644 --- a/src/trel_dnssd/trel_dnssd.hpp +++ b/src/trel_dnssd/trel_dnssd.hpp @@ -60,7 +60,7 @@ namespace TrelDnssd { * @{ */ -class TrelDnssd +class TrelDnssd : public Mdns::StateObserver { public: /** @@ -107,7 +107,7 @@ class TrelDnssd * * @param[in] aState The state of mDNS publisher. */ - void HandleMdnsState(Mdns::Publisher::State aState); + void HandleMdnsState(Mdns::Publisher::State aState) override; private: static constexpr size_t kPeerCacheSize = 256;