diff --git a/src/border_agent/border_agent.cpp b/src/border_agent/border_agent.cpp index 247d0c0d1e9..e0eb1a18dda 100644 --- a/src/border_agent/border_agent.cpp +++ b/src/border_agent/border_agent.cpp @@ -71,6 +71,9 @@ namespace otbr { static const char kBorderAgentServiceType[] = "_meshcop._udp"; ///< Border agent service type of mDNS static constexpr int kBorderAgentServiceDummyPort = 49152; +#if OTBR_ENABLE_EPSKC +static const char kBorderAgentEpskcServiceType[] = "_meshcop-e._udp"; ///< Border agent ePSKc service +#endif /** * Locators @@ -146,6 +149,10 @@ BorderAgent::BorderAgent(otbr::Ncp::ControllerOpenThread &aNcp, Mdns::Publisher , mBaseServiceInstanceName(OTBR_MESHCOP_SERVICE_INSTANCE_NAME) { mNcp.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { HandleThreadStateChanged(aFlags); }); + +#if OTBR_ENABLE_EPSKC + otBorderAgentSetEphemeralKeyCallback(mNcp.GetInstance(), BorderAgent::HandleEpskcStateChanged, this); +#endif } otbrError BorderAgent::SetMeshCopServiceValues(const std::string &aServiceInstanceName, @@ -210,6 +217,68 @@ void BorderAgent::Stop(void) UnpublishMeshCopService(); } +#if OTBR_ENABLE_EPSKC +void BorderAgent::HandleEpskcStateChanged(void *aContext) +{ + BorderAgent *borderAgent = static_cast(aContext); + + if (otBorderAgentIsEphemeralKeyActive(borderAgent->mNcp.GetInstance())) + { + borderAgent->PublishEpskcService(); + } + else + { + borderAgent->UnpublishEpskcService(); + } +} + +void BorderAgent::PublishEpskcService() +{ + otInstance *instance = mNcp.GetInstance(); + int port = otBorderAgentGetUdpPort(instance); + + otbrLogInfo("Publish meshcop-e service %s.%s.local. port %d", mServiceInstanceName.c_str(), + kBorderAgentEpskcServiceType, port); + + mPublisher.PublishService(/* aHostName */ "", mServiceInstanceName, kBorderAgentEpskcServiceType, + Mdns::Publisher::SubTypeList{}, port, {}, [this](otbrError aError) { + if (aError == OTBR_ERROR_ABORTED) + { + // OTBR_ERROR_ABORTED is thrown when an ongoing service registration is + // cancelled. This can happen when the meshcop-e service is being updated + // frequently. To avoid false alarms, it should not be logged like a real error. + otbrLogInfo("Cancelled previous publishing meshcop-e service %s.%s.local", + mServiceInstanceName.c_str(), kBorderAgentEpskcServiceType); + } + else + { + otbrLogResult(aError, "Result of publish meshcop-e service %s.%s.local", + mServiceInstanceName.c_str(), kBorderAgentEpskcServiceType); + } + + if (aError == OTBR_ERROR_DUPLICATED) + { + // Try to unpublish current service in case we are trying to register + // multiple new services simultaneously when the original service name + // is conflicted. + UnpublishEpskcService(); + mServiceInstanceName = GetAlternativeServiceInstanceName(); + PublishEpskcService(); + } + }); +} + +void BorderAgent::UnpublishEpskcService() +{ + otbrLogInfo("Unpublish meshcop-e service %s.%s.local", mServiceInstanceName.c_str(), kBorderAgentEpskcServiceType); + + mPublisher.UnpublishService(mServiceInstanceName, kBorderAgentEpskcServiceType, [this](otbrError aError) { + otbrLogResult(aError, "Result of unpublish meshcop-e service %s.%s.local", mServiceInstanceName.c_str(), + kBorderAgentEpskcServiceType); + }); +} +#endif + void BorderAgent::HandleMdnsState(Mdns::Publisher::State aState) { VerifyOrExit(IsEnabled()); diff --git a/src/border_agent/border_agent.hpp b/src/border_agent/border_agent.hpp index 39a0d2c672c..22f4b33d554 100644 --- a/src/border_agent/border_agent.hpp +++ b/src/border_agent/border_agent.hpp @@ -149,6 +149,12 @@ class BorderAgent : private NonCopyable std::string GetServiceInstanceNameWithExtAddr(const std::string &aServiceInstanceName) const; std::string GetAlternativeServiceInstanceName() const; +#if OTBR_ENABLE_EPSKC + static void HandleEpskcStateChanged(void *aContext); + void PublishEpskcService(void); + void UnpublishEpskcService(void); +#endif + otbr::Ncp::ControllerOpenThread &mNcp; Mdns::Publisher &mPublisher; bool mIsEnabled;