From ba9381649d60fcc0f794221b154aca40d5be0ea6 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 4 Feb 2021 18:56:31 -0800 Subject: [PATCH] [srp-client] new method to get server address, set callback (#6134) This commit adds some new methods/APIs in `Srp::Client` class: `GetServerAddress()` to get the SRP server's socket address that is being used by the client, `IsRunning()` to check whether the SRP client is started and running or not, and `SetCallback()` to allow user to set the callback at any point (before/after call to `Start()`). It also adds a new `srp client` sub-command to get the server address and/or its port number. --- include/openthread/instance.h | 2 +- include/openthread/srp_client.h | 45 ++++++++++++++++++++++++++++----- src/cli/README_SRP_CLIENT.md | 33 ++++++++++++++++++++++++ src/cli/cli_srp_client.cpp | 37 ++++++++++++++++++++++++++- src/cli/cli_srp_client.hpp | 2 ++ src/core/api/srp_client_api.cpp | 28 ++++++++++++++++---- src/core/net/srp_client.cpp | 11 +++++--- src/core/net/srp_client.hpp | 37 ++++++++++++++++++++++++--- src/ncp/ncp_base.cpp | 4 ++- src/ncp/ncp_base_mtd.cpp | 2 +- 10 files changed, 177 insertions(+), 24 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index c1b4db1b1..4770c9608 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 (67) +#define OPENTHREAD_API_VERSION (68) /** * @addtogroup api-instance diff --git a/include/openthread/srp_client.h b/include/openthread/srp_client.h index 6a4021b46..30681d997 100644 --- a/include/openthread/srp_client.h +++ b/include/openthread/srp_client.h @@ -189,19 +189,14 @@ typedef void (*otSrpClientCallback)(otError aError, * * @param[in] aInstance A pointer to the OpenThread instance. * @param[in] aServerSockAddr The socket address (IPv6 address and port number) of the SRP server. - * @param[in] aCallback The callback which is used to notify events and changes. Can be NULL if not needed. - * @param[in] aContext An arbitrary context used with @p aCallback. * * @retval OT_ERROR_NONE SRP client operation started successfully or it is already running with same server * socket address and callback. - * @retval OT_ERROR_BUSY SRP client is busy running with a different socket address and/or callback. + * @retval OT_ERROR_BUSY SRP client is busy running with a different socket address. * @retval OT_ERROR_FAILED Failed to open/connect the client's UDP socket. * */ -otError otSrpClientStart(otInstance * aInstance, - const otSockAddr * aServerSockAddr, - otSrpClientCallback aCallback, - void * aContext); +otError otSrpClientStart(otInstance *aInstance, const otSockAddr *aServerSockAddr); /** * This function stops the SRP client operation. @@ -214,6 +209,42 @@ otError otSrpClientStart(otInstance * aInstance, */ void otSrpClientStop(otInstance *aInstance); +/** + * This function indicates whether the SRP client is running or not. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + * @returns TRUE if the SRP client is running, FALSE otherwise. + * + */ +bool otSrpClientIsRunning(otInstance *aInstance); + +/** + * This function gets the socket address (IPv6 address and port number) of the SRP server which is being used by SRP + * client. + * + * If the client is not running, the address is unspecified (all zero) with zero port number. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + * @returns A pointer to the SRP server's socket address (is always non-NULL). + * + */ +const otSockAddr *otSrpClientGetServerAddress(otInstance *aInstance); + +/** + * This function sets the callback to notify caller of events/changes from SRP client. + * + * The SRP client allows a single callback to be registered. So consecutive calls to this function will overwrite any + * previously set callback functions. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * @param[in] aCallback The callback to notify of events and changes. Can be NULL if not needed. + * @param[in] aContext An arbitrary context used with @p aCallback. + * + */ +void otSrpClientSetCallback(otInstance *aInstance, otSrpClientCallback aCallback, void *aContext); + /** * This function gets the lease interval used in SRP update requests. * diff --git a/src/cli/README_SRP_CLIENT.md b/src/cli/README_SRP_CLIENT.md index 075ac1829..adf6a106f 100644 --- a/src/cli/README_SRP_CLIENT.md +++ b/src/cli/README_SRP_CLIENT.md @@ -9,6 +9,7 @@ Usage : `srp client [command] ...` - [host](#host) - [keyleaseinterval](#keyleaseinterval) - [leaseinterval](#leaseinterval) +- [server](#server) - [service](#service) - [start](#start) - [stop](#stop) @@ -231,6 +232,38 @@ Set the lease interval. Done ``` +### server + +Usage: `srp client server` + +Print the server socket address (IPv6 address and port number). + +```bash +> srp client server +[fd00:0:0:0:d88a:618b:384d:e760]:4724 +Done +``` + +### server address + +Print the server IPv6 address. + +```bash +> srp client server address +fd00:0:0:0:d88a:618b:384d:e760 +Done +``` + +### server port + +Print the server port number + +```bash +> srp client server port +4724 +Done +``` + ### service Usage: `srp client service` diff --git a/src/cli/cli_srp_client.cpp b/src/cli/cli_srp_client.cpp index 15f9a4fea..332fa9dbe 100644 --- a/src/cli/cli_srp_client.cpp +++ b/src/cli/cli_srp_client.cpp @@ -76,6 +76,8 @@ SrpClient::SrpClient(Interpreter &aInterpreter) } memset(mHostAddresses, 0, sizeof(mHostAddresses)); + + otSrpClientSetCallback(mInterpreter.mInstance, SrpClient::HandleCallback, this); } otError SrpClient::Process(uint8_t aArgsLength, char *aArgs[]) @@ -269,6 +271,39 @@ exit: return error; } +otError SrpClient::ProcessServer(uint8_t aArgsLength, char *aArgs[]) +{ + otError error = OT_ERROR_NONE; + const otSockAddr *serverSockAddr = otSrpClientGetServerAddress(mInterpreter.mInstance); + + if (aArgsLength == 0) + { + mInterpreter.OutputFormat("["); + mInterpreter.OutputIp6Address(serverSockAddr->mAddress); + mInterpreter.OutputLine("]:%u", serverSockAddr->mPort); + ExitNow(); + } + + VerifyOrExit(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS); + + if (strcmp(aArgs[0], "address") == 0) + { + mInterpreter.OutputIp6Address(serverSockAddr->mAddress); + mInterpreter.OutputLine(""); + } + else if (strcmp(aArgs[0], "port") == 0) + { + mInterpreter.OutputLine("%u", serverSockAddr->mPort); + } + else + { + error = OT_ERROR_INVALID_COMMAND; + } + +exit: + return error; +} + otError SrpClient::ProcessService(uint8_t aArgsLength, char *aArgs[]) { otError error = OT_ERROR_NONE; @@ -422,7 +457,7 @@ otError SrpClient::ProcessStart(uint8_t aArgsLength, char *aArgs[]) SuccessOrExit(error = ParseAsIp6Address(aArgs[0], serverSockAddr.mAddress)); SuccessOrExit(error = ParseAsUint16(aArgs[1], serverSockAddr.mPort)); - error = otSrpClientStart(mInterpreter.mInstance, &serverSockAddr, SrpClient::HandleCallback, this); + error = otSrpClientStart(mInterpreter.mInstance, &serverSockAddr); exit: return error; diff --git a/src/cli/cli_srp_client.hpp b/src/cli/cli_srp_client.hpp index aef6562e0..4ce70ed88 100644 --- a/src/cli/cli_srp_client.hpp +++ b/src/cli/cli_srp_client.hpp @@ -105,6 +105,7 @@ private: otError ProcessHost(uint8_t aArgsLength, char *aArgs[]); otError ProcessLeaseInterval(uint8_t aArgsLength, char *aArgs[]); otError ProcessKeyLeaseInterval(uint8_t aArgsLength, char *aArgs[]); + otError ProcessServer(uint8_t aArgsLength, char *aArgs[]); otError ProcessService(uint8_t aArgsLength, char *aArgs[]); otError ProcessStart(uint8_t aArgsLength, char *aArgs[]); otError ProcessStop(uint8_t aArgsLength, char *aArgs[]); @@ -129,6 +130,7 @@ private: {"host", &SrpClient::ProcessHost}, {"keyleaseinterval", &SrpClient::ProcessKeyLeaseInterval}, {"leaseinterval", &SrpClient::ProcessLeaseInterval}, + {"server", &SrpClient::ProcessServer}, {"service", &SrpClient::ProcessService}, {"start", &SrpClient::ProcessStart}, {"stop", &SrpClient::ProcessStop}, diff --git a/src/core/api/srp_client_api.cpp b/src/core/api/srp_client_api.cpp index 08b307a0e..e9c88810e 100644 --- a/src/core/api/srp_client_api.cpp +++ b/src/core/api/srp_client_api.cpp @@ -43,14 +43,11 @@ using namespace ot; #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE -otError otSrpClientStart(otInstance * aInstance, - const otSockAddr * aServerSockAddr, - otSrpClientCallback aCallback, - void * aContext) +otError otSrpClientStart(otInstance *aInstance, const otSockAddr *aServerSockAddr) { Instance &instance = *static_cast(aInstance); - return instance.Get().Start(*static_cast(aServerSockAddr), aCallback, aContext); + return instance.Get().Start(*static_cast(aServerSockAddr)); } void otSrpClientStop(otInstance *aInstance) @@ -60,6 +57,27 @@ void otSrpClientStop(otInstance *aInstance) return instance.Get().Stop(); } +bool otSrpClientIsRunning(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + return instance.Get().IsRunning(); +} + +const otSockAddr *otSrpClientGetServerAddress(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + return &instance.Get().GetServerAddress(); +} + +void otSrpClientSetCallback(otInstance *aInstance, otSrpClientCallback aCallback, void *aContext) +{ + Instance &instance = *static_cast(aInstance); + + instance.Get().SetCallback(aCallback, aContext); +} + uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance) { Instance &instance = *static_cast(aInstance); diff --git a/src/core/net/srp_client.cpp b/src/core/net/srp_client.cpp index 4ba071520..1e48b8d64 100644 --- a/src/core/net/srp_client.cpp +++ b/src/core/net/srp_client.cpp @@ -164,14 +164,13 @@ Client::Client(Instance &aInstance) static_assert(kRemoved == 7, "kRemoved value is not correct"); } -otError Client::Start(const Ip6::SockAddr &aServerSockAddr, Callback aCallback, void *aContext) +otError Client::Start(const Ip6::SockAddr &aServerSockAddr) { otError error = OT_ERROR_NONE; if (GetState() != kStateStopped) { VerifyOrExit(aServerSockAddr == mSocket.GetPeerName(), error = OT_ERROR_BUSY); - VerifyOrExit((mCallback == aCallback) && (mCallbackContext == aContext), error = OT_ERROR_BUSY); ExitNow(); } @@ -181,8 +180,6 @@ otError Client::Start(const Ip6::SockAddr &aServerSockAddr, Callback aCallback, otLogInfoSrp("[client] Starting, server [%s]:%d", aServerSockAddr.GetAddress().ToString().AsCString(), aServerSockAddr.mPort); - mCallback = aCallback; - mCallbackContext = aContext; Resume(); exit: @@ -230,6 +227,12 @@ exit: return; } +void Client::SetCallback(Callback aCallback, void *aContext) +{ + mCallback = aCallback; + mCallbackContext = aContext; +} + void Client::Resume(void) { SetState(kStateUpdated); diff --git a/src/core/net/srp_client.hpp b/src/core/net/srp_client.hpp index d86c60464..809dd9991 100644 --- a/src/core/net/srp_client.hpp +++ b/src/core/net/srp_client.hpp @@ -269,16 +269,14 @@ public: * single SRP Update is sent containing all the info). * * @param[in] aServerSockAddr The socket address (IPv6 address and port number) of the SRP server. - * @param[in] aCallback The callback to notify of events and changes. Can be nullptr if not needed. - * @param[in] aContext An arbitrary context used with @p aCallback. * * @retval OT_ERROR_NONE SRP client operation started successfully or it is already running with same server * socket address and callback. - * @retval OT_ERROR_BUSY SRP client is busy running with a different socket address and/or callback. + * @retval OT_ERROR_BUSY SRP client is busy running with a different socket address. * @retval OT_ERROR_FAILED Failed to open/connect the client's UDP socket. * */ - otError Start(const Ip6::SockAddr &aServerSockAddr, Callback aCallback, void *aContext); + otError Start(const Ip6::SockAddr &aServerSockAddr); /** * This method stops the SRP client operation. @@ -289,6 +287,37 @@ public: */ void Stop(void); + /** + * This method indicates whether the SRP client is running or not. + * + * @returns TRUE if the SRP client is running, FALSE otherwise. + * + */ + bool IsRunning(void) const { return (mState != kStateStopped); } + + /** + * This method gets the socket address (IPv6 address and port number) of the SRP server which is being used by SRP + * client. + * + * If the client is not running, the address is unspecified (all zero) with zero port number. + * + * @returns The SRP server's socket address. + * + */ + const Ip6::SockAddr &GetServerAddress(void) const { return mSocket.GetPeerName(); } + + /** + * This method sets the callback used to notify caller of events/changes. + * + * The SRP client allows a single callback to be registered. So consecutive calls to this method will overwrite any + * previously set callback functions. + * + * @param[in] aCallback The callback to notify of events and changes. Can be nullptr if not needed. + * @param[in] aContext An arbitrary context used with @p aCallback. + * + */ + void SetCallback(Callback aCallback, void *aContext); + /** * This method gets the lease interval used in SRP update requests. * diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 784e8f263..aba230e6c 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -285,7 +285,9 @@ NcpBase::NcpBase(Instance *aInstance) #endif otThreadRegisterParentResponseCallback(mInstance, &NcpBase::HandleParentResponseInfo, static_cast(this)); #endif // OPENTHREAD_FTD - +#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE + otSrpClientSetCallback(mInstance, HandleSrpClientCallback, this); +#endif #if OPENTHREAD_CONFIG_LEGACY_ENABLE mLegacyNodeDidJoin = false; mLegacyHandlers = nullptr; diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp index 459caa387..6548231ad 100644 --- a/src/ncp/ncp_base_mtd.cpp +++ b/src/ncp/ncp_base_mtd.cpp @@ -3295,7 +3295,7 @@ template <> otError NcpBase::HandlePropertySet(voi SuccessOrExit(error = mDecoder.ReadUint16(serverAddr.mPort)); SuccessOrExit(error = mDecoder.ReadBool(callbackEnabled)); - SuccessOrExit(error = otSrpClientStart(mInstance, &serverAddr, HandleSrpClientCallback, this)); + SuccessOrExit(error = otSrpClientStart(mInstance, &serverAddr)); mSrpClientCallbackEnabled = callbackEnabled; exit: