diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 1287a5ba0..9f9ea2522 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (149) +#define OPENTHREAD_API_VERSION (150) /** * @addtogroup api-instance diff --git a/include/openthread/srp_server.h b/include/openthread/srp_server.h index 6889f9025..bde0b642b 100644 --- a/include/openthread/srp_server.h +++ b/include/openthread/srp_server.h @@ -131,6 +131,17 @@ enum OT_SRP_SERVER_SERVICE_FLAG_ACTIVE), }; +/** + * Represents the state of an SRP server + * + */ +typedef enum +{ + OT_SRP_SERVER_STATE_DISABLED = 0, ///< The SRP server is disabled. + OT_SRP_SERVER_STATE_RUNNING = 1, ///< The SRP server is running. + OT_SRP_SERVER_STATE_STOPPED = 2, ///< The SRP server is stopped. +} otSrpServerState; + /** * This structure includes SRP server LEASE and KEY-LEASE configurations. * @@ -173,6 +184,16 @@ const char *otSrpServerGetDomain(otInstance *aInstance); */ otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain); +/** + * This function returns the state of the SRP server. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The current state of the SRP server. + * + */ +otSrpServerState otSrpServerGetState(otInstance *aInstance); + /** * This function enables/disables the SRP server. * diff --git a/src/cli/README_SRP_SERVER.md b/src/cli/README_SRP_SERVER.md index 27de54755..22b6257d2 100644 --- a/src/cli/README_SRP_SERVER.md +++ b/src/cli/README_SRP_SERVER.md @@ -13,6 +13,7 @@ See [README_SRP.md](README_SRP.md). - [host](#host) - [lease](#lease) - [service](#service) +- [state](#state) ## Command Details @@ -31,6 +32,7 @@ help host lease service +state Done ``` @@ -142,3 +144,15 @@ srp-api-test-0._ipps._tcp.default.service.arpa. addresses: [fdde:ad00:beef:0:0:ff:fe00:fc10] Done ``` + +### state + +Usage: `srp server state` + +Print the state of the SRP server. + +```bash +> srp server state +running +Done +``` diff --git a/src/cli/cli_srp_server.cpp b/src/cli/cli_srp_server.cpp index 19ea38169..fbfe1a9ea 100644 --- a/src/cli/cli_srp_server.cpp +++ b/src/cli/cli_srp_server.cpp @@ -81,6 +81,29 @@ otError SrpServer::ProcessDomain(Arg aArgs[]) return error; } +otError SrpServer::ProcessState(Arg aArgs[]) +{ + OT_UNUSED_VARIABLE(aArgs); + + switch (otSrpServerGetState(mInterpreter.mInstance)) + { + case OT_SRP_SERVER_STATE_DISABLED: + mInterpreter.OutputLine("disabled"); + break; + case OT_SRP_SERVER_STATE_RUNNING: + mInterpreter.OutputLine("running"); + break; + case OT_SRP_SERVER_STATE_STOPPED: + mInterpreter.OutputLine("stopped"); + break; + default: + mInterpreter.OutputLine("invalid state"); + break; + } + + return OT_ERROR_NONE; +} + otError SrpServer::ProcessEnable(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); diff --git a/src/cli/cli_srp_server.hpp b/src/cli/cli_srp_server.hpp index 6f5dee766..f394fbc7f 100644 --- a/src/cli/cli_srp_server.hpp +++ b/src/cli/cli_srp_server.hpp @@ -87,6 +87,7 @@ private: }; otError ProcessDomain(Arg aArgs[]); + otError ProcessState(Arg aArgs[]); otError ProcessEnable(Arg aArgs[]); otError ProcessDisable(Arg aArgs[]); otError ProcessLease(Arg aArgs[]); @@ -100,7 +101,7 @@ private: {"disable", &SrpServer::ProcessDisable}, {"domain", &SrpServer::ProcessDomain}, {"enable", &SrpServer::ProcessEnable}, {"help", &SrpServer::ProcessHelp}, {"host", &SrpServer::ProcessHost}, {"lease", &SrpServer::ProcessLease}, - {"service", &SrpServer::ProcessService}, + {"service", &SrpServer::ProcessService}, {"state", &SrpServer::ProcessState}, }; static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted"); diff --git a/src/core/api/srp_server_api.cpp b/src/core/api/srp_server_api.cpp index 9e6635be1..554fc91b7 100644 --- a/src/core/api/srp_server_api.cpp +++ b/src/core/api/srp_server_api.cpp @@ -56,6 +56,13 @@ otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain) return instance.Get().SetDomain(aDomain); } +otSrpServerState otSrpServerGetState(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + return static_cast(instance.Get().GetState()); +} + void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled) { Instance &instance = *static_cast(aInstance); diff --git a/src/core/net/srp_server.hpp b/src/core/net/srp_server.hpp index c056c92b4..63bd40015 100644 --- a/src/core/net/srp_server.hpp +++ b/src/core/net/srp_server.hpp @@ -95,6 +95,13 @@ public: class Host; + enum State : uint8_t + { + kStateDisabled = OT_SRP_SERVER_STATE_DISABLED, + kStateRunning = OT_SRP_SERVER_STATE_RUNNING, + kStateStopped = OT_SRP_SERVER_STATE_STOPPED, + }; + /** * This class implements a server-side SRP service. * @@ -600,6 +607,14 @@ public: */ bool IsRunning(void) const { return (mState == kStateRunning); } + /** + * This method tells the state of the SRP server. + * + * @returns An enum that represents the state of the server. + * + */ + State GetState(void) const { return mState; } + /** * This method enables/disables the SRP server. * @@ -660,13 +675,6 @@ private: static constexpr uint32_t kDefaultMaxKeyLease = 3600u * 24 * 14; // 14 days (in seconds). static constexpr uint32_t kDefaultEventsHandlerTimeout = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_UPDATE_TIMEOUT; - enum State : uint8_t - { - kStateDisabled, - kStateRunning, - kStateStopped, - }; - // This class includes metadata for processing a SRP update (register, deregister) // and sending DNS response to the client. class UpdateMetadata : public InstanceLocator, public LinkedListEntry diff --git a/tests/scripts/thread-cert/border_router/test_advertising_proxy.py b/tests/scripts/thread-cert/border_router/test_advertising_proxy.py index 6dfdf2810..c0ead0d00 100755 --- a/tests/scripts/thread-cert/border_router/test_advertising_proxy.py +++ b/tests/scripts/thread-cert/border_router/test_advertising_proxy.py @@ -77,14 +77,17 @@ class SingleHostAndService(thread_cert.TestCase): server = self.nodes[BR] client = self.nodes[ROUTER] + server.srp_server_set_enabled(False) host.start(start_radvd=False) self.simulator.go(5) + self.assertEqual(server.srp_server_get_state(), 'disabled') server.srp_server_set_enabled(True) server.srp_server_set_lease_range(LEASE, LEASE, KEY_LEASE, KEY_LEASE) server.start() - self.simulator.go(5) + self.simulator.go(10) self.assertEqual('leader', server.get_state()) + self.assertEqual(server.srp_server_get_state(), 'running') client.start() self.simulator.go(5) diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py index 754261676..04cdbb127 100755 --- a/tests/scripts/thread-cert/node.py +++ b/tests/scripts/thread-cert/node.py @@ -795,6 +795,11 @@ class NodeImpl: self.send_command(cmd) self._expect_done() + def srp_server_get_state(self): + states = ['disabled', 'running', 'stopped'] + self.send_command('srp server state') + return self._expect_result(states) + def srp_server_set_enabled(self, enable): cmd = f'srp server {"enable" if enable else "disable"}' self.send_command(cmd) diff --git a/tests/scripts/thread-cert/test_netdata_publisher.py b/tests/scripts/thread-cert/test_netdata_publisher.py index b3d6b23c0..66546fa0e 100755 --- a/tests/scripts/thread-cert/test_netdata_publisher.py +++ b/tests/scripts/thread-cert/test_netdata_publisher.py @@ -268,7 +268,6 @@ class NetDataPublisher(thread_cert.TestCase): # MLE-EID address, then change to use specific address. Verify # that number of entries in network data is correct in each step # and that entries are switched correctly. - num = 0 for node in routers: node.netdata_publish_dnssrp_unicast_mleid(DNSSRP_PORT) @@ -285,6 +284,14 @@ class NetDataPublisher(thread_cert.TestCase): self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNCIAST)) self.verify_unicast_services(services) + for node in routers: + node.srp_server_set_enabled(True) + self.simulator.go(WAIT_TIME) + self.assertEqual(sum(node.srp_server_get_state() == 'running' for node in routers), + min(len(routers), DESIRED_NUM_DNSSRP_UNCIAST)) + self.assertEqual(sum(node.srp_server_get_state() == 'stopped' for node in routers), + max(len(routers) - DESIRED_NUM_DNSSRP_UNCIAST, 0)) + for node in routers: node.netdata_unpublish_dnssrp() self.simulator.go(WAIT_TIME) @@ -292,6 +299,9 @@ class NetDataPublisher(thread_cert.TestCase): services = leader.get_services() self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNCIAST)) self.verify_unicast_services(services) + for node in routers: + node.srp_server_set_enabled(False) + self.assertEqual(node.srp_server_get_state(), 'disabled') #--------------------------------------------------------------------------------- # DNS/SRP entries: Verify publisher preference when removing diff --git a/tools/otci/otci/otci.py b/tools/otci/otci/otci.py index 990a737f9..3c17ca1aa 100644 --- a/tools/otci/otci/otci.py +++ b/tools/otci/otci/otci.py @@ -851,6 +851,10 @@ class OTCI(object): # SRP server & client utilities # + def srp_server_get_state(self): + """Get the SRP server state""" + return self.__parse_str(self.execute_command('srp server state')) + def srp_server_enable(self): """Enable SRP server.""" self.execute_command('srp server enable') diff --git a/tools/otci/tests/test_otci.py b/tools/otci/tests/test_otci.py index d0519fb53..84dd88435 100644 --- a/tools/otci/tests/test_otci.py +++ b/tools/otci/tests/test_otci.py @@ -367,6 +367,7 @@ class TestOTCI(unittest.TestCase): logging.info('dns resolve: %r', client.dns_resolve('host1.default.service.arpa.')) def _test_otci_srp(self, client: OTCI, server: OTCI): + self.assertEqual('disabled', server.srp_server_get_state()) self.assertEqual('default.service.arpa.', server.srp_server_get_domain()) server.srp_server_set_domain('example1.com') self.assertEqual('example1.com.', server.srp_server_get_domain()) @@ -394,8 +395,9 @@ class TestOTCI(unittest.TestCase): server.srp_server_disable() client.wait(3) server.srp_server_enable() - client.wait(3) + client.wait(10) self.assertEqual([], server.srp_server_get_hosts()) + self.assertEqual('running', server.srp_server_get_state()) self.assertFalse(client.srp_client_get_autostart()) client.srp_client_enable_autostart()