Skip to content

Commit

Permalink
[mdns] refactor mDNS State subscription (#2560)
Browse files Browse the repository at this point in the history
This commit refactors the mDNS State subscription using the
Subject-Observer pattern.

The commit makes the state subscription more flexible. Currently the
mDNS state is published in `Application::HandleMdnsState`. Now we have
both NCP and RCP case. This function will be difficult to
implement. With this new pattern, we can register different observers
during NCP/RCP initialization.
  • Loading branch information
Irving-cl authored Oct 29, 2024
1 parent 7c8e39a commit aa00c76
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 33 deletions.
35 changes: 16 additions & 19 deletions src/agent/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,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<DBus::DBusAgent>(*mHost, *mPublisher))
Expand Down Expand Up @@ -195,24 +196,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;
Expand Down Expand Up @@ -253,6 +236,19 @@ void Application::CreateRcpMode(const std::string &aRestListenAddress, int aRest

void Application::InitRcpMode(void)
{
#if OTBR_ENABLE_BORDER_AGENT
mMdnsStateSubject.AddObserver(*mBorderAgent);
#endif
#if OTBR_ENABLE_SRP_ADVERTISING_PROXY
mMdnsStateSubject.AddObserver(*mAdvertisingProxy);
#endif
#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
mMdnsStateSubject.AddObserver(*mDiscoveryProxy);
#endif
#if OTBR_ENABLE_TREL
mMdnsStateSubject.AddObserver(*mTrelDnssd);
#endif

#if OTBR_ENABLE_MDNS
mPublisher->Start();
#endif
Expand Down Expand Up @@ -300,6 +296,7 @@ void Application::DeinitRcpMode(void)
mBorderAgent->SetEnabled(false);
#endif
#if OTBR_ENABLE_MDNS
mMdnsStateSubject.Clear();
mPublisher->Stop();
#endif
}
Expand Down
8 changes: 1 addition & 7 deletions src/agent/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -264,6 +257,7 @@ class Application : private NonCopyable
const char *mBackboneInterfaceName;
std::unique_ptr<Ncp::ThreadHost> mHost;
#if OTBR_ENABLE_MDNS
Mdns::StateSubject mMdnsStateSubject;
std::unique_ptr<Mdns::Publisher> mPublisher;
#endif
#if OTBR_ENABLE_BORDER_AGENT
Expand Down
4 changes: 2 additions & 2 deletions src/border_agent/border_agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace otbr {
/**
* This class implements Thread border agent functionality.
*/
class BorderAgent : private NonCopyable
class BorderAgent : public Mdns::StateObserver, private NonCopyable
{
public:
/** The callback for receiving ephemeral key changes. */
Expand Down Expand Up @@ -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.
Expand Down
18 changes: 18 additions & 0 deletions src/mdns/mdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,24 @@ void Publisher::RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddr
}
}

void StateSubject::AddObserver(StateObserver &aObserver)
{
mObservers.push_back(&aObserver);
}

void StateSubject::UpdateState(Publisher::State aState)
{
for (StateObserver *observer : mObservers)
{
observer->HandleMdnsState(aState);
}
}

void StateSubject::Clear(void)
{
mObservers.clear();
}

} // namespace Mdns
} // namespace otbr

Expand Down
58 changes: 58 additions & 0 deletions src/mdns/mdns.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,64 @@ 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 reference 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);

/**
* This method removes all the observers.
*/
void Clear(void);

private:
std::vector<StateObserver *> mObservers;
};

/**
* @}
*/
Expand Down
4 changes: 2 additions & 2 deletions src/sdp_proxy/advertising_proxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace otbr {
/**
* This class implements the Advertising Proxy.
*/
class AdvertisingProxy : private NonCopyable
class AdvertisingProxy : public Mdns::StateObserver, private NonCopyable
{
public:
/**
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/sdp_proxy/discovery_proxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace Dnssd {
/**
* This class implements the DNS-SD Discovery Proxy.
*/
class DiscoveryProxy : private NonCopyable
class DiscoveryProxy : public Mdns::StateObserver, private NonCopyable
{
public:
/**
Expand Down
4 changes: 2 additions & 2 deletions src/trel_dnssd/trel_dnssd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace TrelDnssd {
* @{
*/

class TrelDnssd
class TrelDnssd : public Mdns::StateObserver
{
public:
/**
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit aa00c76

Please sign in to comment.