xref: /aosp_15_r20/external/openthread/src/cli/cli_srp_client.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2020, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker /**
30*cfb92d14SAndroid Build Coastguard Worker  * @file
31*cfb92d14SAndroid Build Coastguard Worker  *   This file implements a simple CLI for the SRP Client.
32*cfb92d14SAndroid Build Coastguard Worker  */
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include "cli_srp_client.hpp"
35*cfb92d14SAndroid Build Coastguard Worker 
36*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
37*cfb92d14SAndroid Build Coastguard Worker 
38*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
39*cfb92d14SAndroid Build Coastguard Worker 
40*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli.hpp"
41*cfb92d14SAndroid Build Coastguard Worker 
42*cfb92d14SAndroid Build Coastguard Worker namespace ot {
43*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
44*cfb92d14SAndroid Build Coastguard Worker 
CopyString(char * aDest,uint16_t aDestSize,const char * aSource)45*cfb92d14SAndroid Build Coastguard Worker static otError CopyString(char *aDest, uint16_t aDestSize, const char *aSource)
46*cfb92d14SAndroid Build Coastguard Worker {
47*cfb92d14SAndroid Build Coastguard Worker     // Copies a string from `aSource` to `aDestination` (char array),
48*cfb92d14SAndroid Build Coastguard Worker     // verifying that the string fits in the destination array.
49*cfb92d14SAndroid Build Coastguard Worker 
50*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
51*cfb92d14SAndroid Build Coastguard Worker     size_t  len   = strlen(aSource);
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len + 1 <= aDestSize, error = OT_ERROR_INVALID_ARGS);
54*cfb92d14SAndroid Build Coastguard Worker     memcpy(aDest, aSource, len + 1);
55*cfb92d14SAndroid Build Coastguard Worker 
56*cfb92d14SAndroid Build Coastguard Worker exit:
57*cfb92d14SAndroid Build Coastguard Worker     return error;
58*cfb92d14SAndroid Build Coastguard Worker }
59*cfb92d14SAndroid Build Coastguard Worker 
SrpClient(otInstance * aInstance,OutputImplementer & aOutputImplementer)60*cfb92d14SAndroid Build Coastguard Worker SrpClient::SrpClient(otInstance *aInstance, OutputImplementer &aOutputImplementer)
61*cfb92d14SAndroid Build Coastguard Worker     : Utils(aInstance, aOutputImplementer)
62*cfb92d14SAndroid Build Coastguard Worker     , mCallbackEnabled(false)
63*cfb92d14SAndroid Build Coastguard Worker {
64*cfb92d14SAndroid Build Coastguard Worker     otSrpClientSetCallback(GetInstancePtr(), SrpClient::HandleCallback, this);
65*cfb92d14SAndroid Build Coastguard Worker }
66*cfb92d14SAndroid Build Coastguard Worker 
67*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
68*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])69*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("autostart")>(Arg aArgs[])
70*cfb92d14SAndroid Build Coastguard Worker {
71*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
72*cfb92d14SAndroid Build Coastguard Worker     bool    enable;
73*cfb92d14SAndroid Build Coastguard Worker 
74*cfb92d14SAndroid Build Coastguard Worker     /**
75*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client autostart (get)
76*cfb92d14SAndroid Build Coastguard Worker      * @code
77*cfb92d14SAndroid Build Coastguard Worker      * srp client autostart
78*cfb92d14SAndroid Build Coastguard Worker      * Disabled
79*cfb92d14SAndroid Build Coastguard Worker      * Done
80*cfb92d14SAndroid Build Coastguard Worker      * @endcode
81*cfb92d14SAndroid Build Coastguard Worker      * @par
82*cfb92d14SAndroid Build Coastguard Worker      * Indicates the current state of auto-start mode (enabled or disabled).
83*cfb92d14SAndroid Build Coastguard Worker      * @moreinfo{@srp}.
84*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientIsAutoStartModeEnabled
85*cfb92d14SAndroid Build Coastguard Worker      */
86*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
87*cfb92d14SAndroid Build Coastguard Worker     {
88*cfb92d14SAndroid Build Coastguard Worker         OutputEnabledDisabledStatus(otSrpClientIsAutoStartModeEnabled(GetInstancePtr()));
89*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
90*cfb92d14SAndroid Build Coastguard Worker     }
91*cfb92d14SAndroid Build Coastguard Worker 
92*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParseEnableOrDisable(aArgs[0], enable));
93*cfb92d14SAndroid Build Coastguard Worker 
94*cfb92d14SAndroid Build Coastguard Worker     /**
95*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client autostart enable
96*cfb92d14SAndroid Build Coastguard Worker      * @code
97*cfb92d14SAndroid Build Coastguard Worker      * srp client autostart enable
98*cfb92d14SAndroid Build Coastguard Worker      * Done
99*cfb92d14SAndroid Build Coastguard Worker      * @endcode
100*cfb92d14SAndroid Build Coastguard Worker      * @par
101*cfb92d14SAndroid Build Coastguard Worker      * Enables auto-start mode.
102*cfb92d14SAndroid Build Coastguard Worker      * @par
103*cfb92d14SAndroid Build Coastguard Worker      * When auto-start is enabled, the SRP client monitors Thread
104*cfb92d14SAndroid Build Coastguard Worker      * network data to discover SRP servers, to select the preferred
105*cfb92d14SAndroid Build Coastguard Worker      * server, and to automatically start and stop the client when
106*cfb92d14SAndroid Build Coastguard Worker      * an SRP server is detected.
107*cfb92d14SAndroid Build Coastguard Worker      * @par
108*cfb92d14SAndroid Build Coastguard Worker      * Three categories of network data entries indicate the presence of an SRP sever,
109*cfb92d14SAndroid Build Coastguard Worker      * and are preferred in the following order:
110*cfb92d14SAndroid Build Coastguard Worker      *  -# Unicast entries in which the server address is included in the service
111*cfb92d14SAndroid Build Coastguard Worker      *  data. If there are multiple options, the option with the lowest numerical
112*cfb92d14SAndroid Build Coastguard Worker      *  IPv6 address is preferred.
113*cfb92d14SAndroid Build Coastguard Worker      *  -# Anycast entries that each have a sequence number. The largest sequence
114*cfb92d14SAndroid Build Coastguard Worker      *  number as specified by Serial Number Arithmetic Logic
115*cfb92d14SAndroid Build Coastguard Worker      *  in RFC-1982 is preferred.
116*cfb92d14SAndroid Build Coastguard Worker      *  -# Unicast entries in which the server address information is included
117*cfb92d14SAndroid Build Coastguard Worker      *  with the server data. If there are multiple options, the option with the
118*cfb92d14SAndroid Build Coastguard Worker      *  lowest numerical IPv6 address is preferred.
119*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientEnableAutoStartMode
120*cfb92d14SAndroid Build Coastguard Worker      */
121*cfb92d14SAndroid Build Coastguard Worker     if (enable)
122*cfb92d14SAndroid Build Coastguard Worker     {
123*cfb92d14SAndroid Build Coastguard Worker         otSrpClientEnableAutoStartMode(GetInstancePtr(), /* aCallback */ nullptr, /* aContext */ nullptr);
124*cfb92d14SAndroid Build Coastguard Worker     }
125*cfb92d14SAndroid Build Coastguard Worker     /**
126*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client autostart disable
127*cfb92d14SAndroid Build Coastguard Worker      * @code
128*cfb92d14SAndroid Build Coastguard Worker      * srp client autostart disable
129*cfb92d14SAndroid Build Coastguard Worker      * Done
130*cfb92d14SAndroid Build Coastguard Worker      * @endcode
131*cfb92d14SAndroid Build Coastguard Worker      * @par
132*cfb92d14SAndroid Build Coastguard Worker      * Disables the auto-start mode.
133*cfb92d14SAndroid Build Coastguard Worker      * @par
134*cfb92d14SAndroid Build Coastguard Worker      * Disabling auto-start mode does not stop a running client.
135*cfb92d14SAndroid Build Coastguard Worker      * However, the SRP client stops monitoring Thread network data.
136*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientDisableAutoStartMode
137*cfb92d14SAndroid Build Coastguard Worker      */
138*cfb92d14SAndroid Build Coastguard Worker     else
139*cfb92d14SAndroid Build Coastguard Worker     {
140*cfb92d14SAndroid Build Coastguard Worker         otSrpClientDisableAutoStartMode(GetInstancePtr());
141*cfb92d14SAndroid Build Coastguard Worker     }
142*cfb92d14SAndroid Build Coastguard Worker 
143*cfb92d14SAndroid Build Coastguard Worker exit:
144*cfb92d14SAndroid Build Coastguard Worker     return error;
145*cfb92d14SAndroid Build Coastguard Worker }
146*cfb92d14SAndroid Build Coastguard Worker 
147*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
148*cfb92d14SAndroid Build Coastguard Worker 
149*cfb92d14SAndroid Build Coastguard Worker /**
150*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client callback (get,enable,disable)
151*cfb92d14SAndroid Build Coastguard Worker  * @code
152*cfb92d14SAndroid Build Coastguard Worker  * srp client callback enable
153*cfb92d14SAndroid Build Coastguard Worker  * Done
154*cfb92d14SAndroid Build Coastguard Worker  * @endcode
155*cfb92d14SAndroid Build Coastguard Worker  * @code
156*cfb92d14SAndroid Build Coastguard Worker  * srp client callback
157*cfb92d14SAndroid Build Coastguard Worker  * Enabled
158*cfb92d14SAndroid Build Coastguard Worker  * Done
159*cfb92d14SAndroid Build Coastguard Worker  * @endcode
160*cfb92d14SAndroid Build Coastguard Worker  * @cparam srp client callback [@ca{enable}|@ca{disable}]
161*cfb92d14SAndroid Build Coastguard Worker  * @par
162*cfb92d14SAndroid Build Coastguard Worker  * Gets or enables/disables printing callback events from the SRP client.
163*cfb92d14SAndroid Build Coastguard Worker  * @moreinfo{@srp}.
164*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientSetCallback
165*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])166*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("callback")>(Arg aArgs[])
167*cfb92d14SAndroid Build Coastguard Worker {
168*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
171*cfb92d14SAndroid Build Coastguard Worker     {
172*cfb92d14SAndroid Build Coastguard Worker         OutputEnabledDisabledStatus(mCallbackEnabled);
173*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
174*cfb92d14SAndroid Build Coastguard Worker     }
175*cfb92d14SAndroid Build Coastguard Worker 
176*cfb92d14SAndroid Build Coastguard Worker     error = ParseEnableOrDisable(aArgs[0], mCallbackEnabled);
177*cfb92d14SAndroid Build Coastguard Worker 
178*cfb92d14SAndroid Build Coastguard Worker exit:
179*cfb92d14SAndroid Build Coastguard Worker     return error;
180*cfb92d14SAndroid Build Coastguard Worker }
181*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])182*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("host")>(Arg aArgs[])
183*cfb92d14SAndroid Build Coastguard Worker {
184*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
185*cfb92d14SAndroid Build Coastguard Worker 
186*cfb92d14SAndroid Build Coastguard Worker     /**
187*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client host
188*cfb92d14SAndroid Build Coastguard Worker      * @code
189*cfb92d14SAndroid Build Coastguard Worker      * srp client host
190*cfb92d14SAndroid Build Coastguard Worker      * name:"dev4312", state:Registered, addrs:[fd00:0:0:0:0:0:0:1234, fd00:0:0:0:0:0:0:beef]
191*cfb92d14SAndroid Build Coastguard Worker      * Done
192*cfb92d14SAndroid Build Coastguard Worker      * @endcode
193*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
194*cfb92d14SAndroid Build Coastguard Worker      * #otSrpClientGetHostInfo
195*cfb92d14SAndroid Build Coastguard Worker      */
196*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
197*cfb92d14SAndroid Build Coastguard Worker     {
198*cfb92d14SAndroid Build Coastguard Worker         OutputHostInfo(0, *otSrpClientGetHostInfo(GetInstancePtr()));
199*cfb92d14SAndroid Build Coastguard Worker     }
200*cfb92d14SAndroid Build Coastguard Worker     /**
201*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client host name (get,set)
202*cfb92d14SAndroid Build Coastguard Worker      * @code
203*cfb92d14SAndroid Build Coastguard Worker      * srp client host name dev4312
204*cfb92d14SAndroid Build Coastguard Worker      * Done
205*cfb92d14SAndroid Build Coastguard Worker      * @endcode
206*cfb92d14SAndroid Build Coastguard Worker      * @code
207*cfb92d14SAndroid Build Coastguard Worker      * srp client host name
208*cfb92d14SAndroid Build Coastguard Worker      * dev4312
209*cfb92d14SAndroid Build Coastguard Worker      * Done
210*cfb92d14SAndroid Build Coastguard Worker      * @endcode
211*cfb92d14SAndroid Build Coastguard Worker      * @cparam srp client host name [@ca{name}]
212*cfb92d14SAndroid Build Coastguard Worker      * To set the client host name when the host has either been removed or not yet
213*cfb92d14SAndroid Build Coastguard Worker      * registered with the server, use the `name` parameter.
214*cfb92d14SAndroid Build Coastguard Worker      * @par
215*cfb92d14SAndroid Build Coastguard Worker      * Gets or sets the host name of the SRP client. @moreinfo{@srp}.
216*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientSetHostName
217*cfb92d14SAndroid Build Coastguard Worker      */
218*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "name")
219*cfb92d14SAndroid Build Coastguard Worker     {
220*cfb92d14SAndroid Build Coastguard Worker         if (aArgs[1].IsEmpty())
221*cfb92d14SAndroid Build Coastguard Worker         {
222*cfb92d14SAndroid Build Coastguard Worker             const char *name = otSrpClientGetHostInfo(GetInstancePtr())->mName;
223*cfb92d14SAndroid Build Coastguard Worker             OutputLine("%s", (name != nullptr) ? name : "(null)");
224*cfb92d14SAndroid Build Coastguard Worker         }
225*cfb92d14SAndroid Build Coastguard Worker         else
226*cfb92d14SAndroid Build Coastguard Worker         {
227*cfb92d14SAndroid Build Coastguard Worker             uint16_t len;
228*cfb92d14SAndroid Build Coastguard Worker             uint16_t size;
229*cfb92d14SAndroid Build Coastguard Worker             char    *hostName;
230*cfb92d14SAndroid Build Coastguard Worker 
231*cfb92d14SAndroid Build Coastguard Worker             VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
232*cfb92d14SAndroid Build Coastguard Worker             hostName = otSrpClientBuffersGetHostNameString(GetInstancePtr(), &size);
233*cfb92d14SAndroid Build Coastguard Worker 
234*cfb92d14SAndroid Build Coastguard Worker             len = aArgs[1].GetLength();
235*cfb92d14SAndroid Build Coastguard Worker             VerifyOrExit(len + 1 <= size, error = OT_ERROR_INVALID_ARGS);
236*cfb92d14SAndroid Build Coastguard Worker 
237*cfb92d14SAndroid Build Coastguard Worker             // We first make sure we can set the name, and if so
238*cfb92d14SAndroid Build Coastguard Worker             // we copy it to the persisted string buffer and set
239*cfb92d14SAndroid Build Coastguard Worker             // the host name again now with the persisted buffer.
240*cfb92d14SAndroid Build Coastguard Worker             // This ensures that we do not overwrite a previous
241*cfb92d14SAndroid Build Coastguard Worker             // buffer with a host name that cannot be set.
242*cfb92d14SAndroid Build Coastguard Worker 
243*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = otSrpClientSetHostName(GetInstancePtr(), aArgs[1].GetCString()));
244*cfb92d14SAndroid Build Coastguard Worker             memcpy(hostName, aArgs[1].GetCString(), len + 1);
245*cfb92d14SAndroid Build Coastguard Worker 
246*cfb92d14SAndroid Build Coastguard Worker             IgnoreError(otSrpClientSetHostName(GetInstancePtr(), hostName));
247*cfb92d14SAndroid Build Coastguard Worker         }
248*cfb92d14SAndroid Build Coastguard Worker     }
249*cfb92d14SAndroid Build Coastguard Worker     /**
250*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client host state
251*cfb92d14SAndroid Build Coastguard Worker      * @code
252*cfb92d14SAndroid Build Coastguard Worker      * srp client host state
253*cfb92d14SAndroid Build Coastguard Worker      * Registered
254*cfb92d14SAndroid Build Coastguard Worker      * Done
255*cfb92d14SAndroid Build Coastguard Worker      * @endcode
256*cfb92d14SAndroid Build Coastguard Worker      * @par
257*cfb92d14SAndroid Build Coastguard Worker      * Returns the state of the SRP client host. Possible states:
258*cfb92d14SAndroid Build Coastguard Worker      *   * `ToAdd`: Item to be added/registered.
259*cfb92d14SAndroid Build Coastguard Worker      *	 * `Adding`: Item is being added/registered.
260*cfb92d14SAndroid Build Coastguard Worker      *   * `ToRefresh`: Item to be refreshed for lease renewal.
261*cfb92d14SAndroid Build Coastguard Worker      *   * `Refreshing`: Item is beig refreshed.
262*cfb92d14SAndroid Build Coastguard Worker      *   * `ToRemove`: Item to be removed.
263*cfb92d14SAndroid Build Coastguard Worker      *   * `Removing`: Item is being removed.
264*cfb92d14SAndroid Build Coastguard Worker      *   * `Registered`: Item is registered with server.
265*cfb92d14SAndroid Build Coastguard Worker      *   * `Removed`: Item has been removed.
266*cfb92d14SAndroid Build Coastguard Worker      */
267*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "state")
268*cfb92d14SAndroid Build Coastguard Worker     {
269*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
270*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%s", otSrpClientItemStateToString(otSrpClientGetHostInfo(GetInstancePtr())->mState));
271*cfb92d14SAndroid Build Coastguard Worker     }
272*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "address")
273*cfb92d14SAndroid Build Coastguard Worker     {
274*cfb92d14SAndroid Build Coastguard Worker         /**
275*cfb92d14SAndroid Build Coastguard Worker          * @cli srp client host address (get)
276*cfb92d14SAndroid Build Coastguard Worker          * @code
277*cfb92d14SAndroid Build Coastguard Worker          * srp client host address
278*cfb92d14SAndroid Build Coastguard Worker          * auto
279*cfb92d14SAndroid Build Coastguard Worker          * Done
280*cfb92d14SAndroid Build Coastguard Worker          * @endcode
281*cfb92d14SAndroid Build Coastguard Worker          * @code
282*cfb92d14SAndroid Build Coastguard Worker          * srp client host address
283*cfb92d14SAndroid Build Coastguard Worker          * fd00:0:0:0:0:0:0:1234
284*cfb92d14SAndroid Build Coastguard Worker          * fd00:0:0:0:0:0:0:beef
285*cfb92d14SAndroid Build Coastguard Worker          * Done
286*cfb92d14SAndroid Build Coastguard Worker          * @endcode
287*cfb92d14SAndroid Build Coastguard Worker          * @par
288*cfb92d14SAndroid Build Coastguard Worker          * Indicates whether auto address mode is enabled. If auto address mode is not
289*cfb92d14SAndroid Build Coastguard Worker          * enabled, then the list of SRP client host addresses is returned.
290*cfb92d14SAndroid Build Coastguard Worker          * @moreinfo{@srp}.
291*cfb92d14SAndroid Build Coastguard Worker          * @sa otSrpClientGetHostInfo
292*cfb92d14SAndroid Build Coastguard Worker          */
293*cfb92d14SAndroid Build Coastguard Worker         if (aArgs[1].IsEmpty())
294*cfb92d14SAndroid Build Coastguard Worker         {
295*cfb92d14SAndroid Build Coastguard Worker             const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(GetInstancePtr());
296*cfb92d14SAndroid Build Coastguard Worker 
297*cfb92d14SAndroid Build Coastguard Worker             if (hostInfo->mAutoAddress)
298*cfb92d14SAndroid Build Coastguard Worker             {
299*cfb92d14SAndroid Build Coastguard Worker                 OutputLine("auto");
300*cfb92d14SAndroid Build Coastguard Worker             }
301*cfb92d14SAndroid Build Coastguard Worker             else
302*cfb92d14SAndroid Build Coastguard Worker             {
303*cfb92d14SAndroid Build Coastguard Worker                 for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
304*cfb92d14SAndroid Build Coastguard Worker                 {
305*cfb92d14SAndroid Build Coastguard Worker                     OutputIp6AddressLine(hostInfo->mAddresses[index]);
306*cfb92d14SAndroid Build Coastguard Worker                 }
307*cfb92d14SAndroid Build Coastguard Worker             }
308*cfb92d14SAndroid Build Coastguard Worker         }
309*cfb92d14SAndroid Build Coastguard Worker         /**
310*cfb92d14SAndroid Build Coastguard Worker          * @cli srp client host address (set)
311*cfb92d14SAndroid Build Coastguard Worker          * @code
312*cfb92d14SAndroid Build Coastguard Worker          * srp client host address auto
313*cfb92d14SAndroid Build Coastguard Worker          * Done
314*cfb92d14SAndroid Build Coastguard Worker          * @endcode
315*cfb92d14SAndroid Build Coastguard Worker          * @code
316*cfb92d14SAndroid Build Coastguard Worker          * srp client host address fd00::cafe
317*cfb92d14SAndroid Build Coastguard Worker          * Done
318*cfb92d14SAndroid Build Coastguard Worker          * @endcode
319*cfb92d14SAndroid Build Coastguard Worker          * @cparam srp client host address [auto|@ca{address...}]
320*cfb92d14SAndroid Build Coastguard Worker          *   * Use the `auto` parameter to enable auto host address mode.
321*cfb92d14SAndroid Build Coastguard Worker          *     When enabled, the client automatically uses all preferred Thread
322*cfb92d14SAndroid Build Coastguard Worker          *     `netif` unicast addresses except for link-local and mesh-local
323*cfb92d14SAndroid Build Coastguard Worker          *     addresses. If there is no valid address, the mesh local
324*cfb92d14SAndroid Build Coastguard Worker          *     EID address gets added. The SRP client automatically
325*cfb92d14SAndroid Build Coastguard Worker          *     re-registers if addresses on the Thread `netif` are
326*cfb92d14SAndroid Build Coastguard Worker          *     added or removed or marked as non-preferred.
327*cfb92d14SAndroid Build Coastguard Worker          *   * Explicitly specify the list of host addresses, separating
328*cfb92d14SAndroid Build Coastguard Worker          *     each address by a space. You can set this list while the client is
329*cfb92d14SAndroid Build Coastguard Worker          *     running. This will also disable auto host address mode.
330*cfb92d14SAndroid Build Coastguard Worker          * @par
331*cfb92d14SAndroid Build Coastguard Worker          * Enable auto host address mode or explicitly set the list of host
332*cfb92d14SAndroid Build Coastguard Worker          * addresses. @moreinfo{@srp}.
333*cfb92d14SAndroid Build Coastguard Worker          * @sa otSrpClientEnableAutoHostAddress
334*cfb92d14SAndroid Build Coastguard Worker          * @sa otSrpClientSetHostAddresses
335*cfb92d14SAndroid Build Coastguard Worker          */
336*cfb92d14SAndroid Build Coastguard Worker         else if (aArgs[1] == "auto")
337*cfb92d14SAndroid Build Coastguard Worker         {
338*cfb92d14SAndroid Build Coastguard Worker             error = otSrpClientEnableAutoHostAddress(GetInstancePtr());
339*cfb92d14SAndroid Build Coastguard Worker         }
340*cfb92d14SAndroid Build Coastguard Worker         else
341*cfb92d14SAndroid Build Coastguard Worker         {
342*cfb92d14SAndroid Build Coastguard Worker             uint8_t       numAddresses = 0;
343*cfb92d14SAndroid Build Coastguard Worker             otIp6Address  addresses[kMaxHostAddresses];
344*cfb92d14SAndroid Build Coastguard Worker             uint8_t       arrayLength;
345*cfb92d14SAndroid Build Coastguard Worker             otIp6Address *hostAddressArray;
346*cfb92d14SAndroid Build Coastguard Worker 
347*cfb92d14SAndroid Build Coastguard Worker             hostAddressArray = otSrpClientBuffersGetHostAddressesArray(GetInstancePtr(), &arrayLength);
348*cfb92d14SAndroid Build Coastguard Worker 
349*cfb92d14SAndroid Build Coastguard Worker             // We first make sure we can set the addresses, and if so
350*cfb92d14SAndroid Build Coastguard Worker             // we copy the address list into the persisted address array
351*cfb92d14SAndroid Build Coastguard Worker             // and set it again. This ensures that we do not overwrite
352*cfb92d14SAndroid Build Coastguard Worker             // a previous list before we know it is safe to set/change
353*cfb92d14SAndroid Build Coastguard Worker             // the address list.
354*cfb92d14SAndroid Build Coastguard Worker 
355*cfb92d14SAndroid Build Coastguard Worker             if (arrayLength > kMaxHostAddresses)
356*cfb92d14SAndroid Build Coastguard Worker             {
357*cfb92d14SAndroid Build Coastguard Worker                 arrayLength = kMaxHostAddresses;
358*cfb92d14SAndroid Build Coastguard Worker             }
359*cfb92d14SAndroid Build Coastguard Worker 
360*cfb92d14SAndroid Build Coastguard Worker             for (Arg *arg = &aArgs[1]; !arg->IsEmpty(); arg++)
361*cfb92d14SAndroid Build Coastguard Worker             {
362*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(numAddresses < arrayLength, error = OT_ERROR_NO_BUFS);
363*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = arg->ParseAsIp6Address(addresses[numAddresses]));
364*cfb92d14SAndroid Build Coastguard Worker                 numAddresses++;
365*cfb92d14SAndroid Build Coastguard Worker             }
366*cfb92d14SAndroid Build Coastguard Worker 
367*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = otSrpClientSetHostAddresses(GetInstancePtr(), addresses, numAddresses));
368*cfb92d14SAndroid Build Coastguard Worker 
369*cfb92d14SAndroid Build Coastguard Worker             memcpy(hostAddressArray, addresses, numAddresses * sizeof(hostAddressArray[0]));
370*cfb92d14SAndroid Build Coastguard Worker             IgnoreError(otSrpClientSetHostAddresses(GetInstancePtr(), hostAddressArray, numAddresses));
371*cfb92d14SAndroid Build Coastguard Worker         }
372*cfb92d14SAndroid Build Coastguard Worker     }
373*cfb92d14SAndroid Build Coastguard Worker     /**
374*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client host remove
375*cfb92d14SAndroid Build Coastguard Worker      * @code
376*cfb92d14SAndroid Build Coastguard Worker      * srp client host remove 1
377*cfb92d14SAndroid Build Coastguard Worker      * Done
378*cfb92d14SAndroid Build Coastguard Worker      * @endcode
379*cfb92d14SAndroid Build Coastguard Worker      * @cparam srp client host remove [@ca{removekeylease}] [@ca{sendunregtoserver}]
380*cfb92d14SAndroid Build Coastguard Worker      *   * The parameter `removekeylease` is an optional boolean value that indicates
381*cfb92d14SAndroid Build Coastguard Worker      *     whether the host key lease should also be removed (default is `false`).
382*cfb92d14SAndroid Build Coastguard Worker      *   * The parameter `sendunregtoserver` is an optional boolean value that indicates
383*cfb92d14SAndroid Build Coastguard Worker      *     whether the client host should send an "update" message to the server
384*cfb92d14SAndroid Build Coastguard Worker      *     even when the client host information has not yet been registered with the
385*cfb92d14SAndroid Build Coastguard Worker      *     server (default is `false`). This parameter can be specified only if the
386*cfb92d14SAndroid Build Coastguard Worker      *     `removekeylease` parameter is specified first in the command.
387*cfb92d14SAndroid Build Coastguard Worker      * @par
388*cfb92d14SAndroid Build Coastguard Worker      * Removes SRP client host information and all services from the SRP server.
389*cfb92d14SAndroid Build Coastguard Worker      * @moreinfo{@srp}.
390*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientRemoveHostAndServices
391*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientSetHostName
392*cfb92d14SAndroid Build Coastguard Worker      */
393*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "remove")
394*cfb92d14SAndroid Build Coastguard Worker     {
395*cfb92d14SAndroid Build Coastguard Worker         bool removeKeyLease    = false;
396*cfb92d14SAndroid Build Coastguard Worker         bool sendUnregToServer = false;
397*cfb92d14SAndroid Build Coastguard Worker 
398*cfb92d14SAndroid Build Coastguard Worker         if (!aArgs[1].IsEmpty())
399*cfb92d14SAndroid Build Coastguard Worker         {
400*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = aArgs[1].ParseAsBool(removeKeyLease));
401*cfb92d14SAndroid Build Coastguard Worker 
402*cfb92d14SAndroid Build Coastguard Worker             if (!aArgs[2].IsEmpty())
403*cfb92d14SAndroid Build Coastguard Worker             {
404*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = aArgs[2].ParseAsBool(sendUnregToServer));
405*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(aArgs[3].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
406*cfb92d14SAndroid Build Coastguard Worker             }
407*cfb92d14SAndroid Build Coastguard Worker         }
408*cfb92d14SAndroid Build Coastguard Worker 
409*cfb92d14SAndroid Build Coastguard Worker         error = otSrpClientRemoveHostAndServices(GetInstancePtr(), removeKeyLease, sendUnregToServer);
410*cfb92d14SAndroid Build Coastguard Worker     }
411*cfb92d14SAndroid Build Coastguard Worker     /**
412*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client host clear
413*cfb92d14SAndroid Build Coastguard Worker      * @code
414*cfb92d14SAndroid Build Coastguard Worker      * srp client host clear
415*cfb92d14SAndroid Build Coastguard Worker      * Done
416*cfb92d14SAndroid Build Coastguard Worker      * @endcode
417*cfb92d14SAndroid Build Coastguard Worker      * @par
418*cfb92d14SAndroid Build Coastguard Worker      * Clears all host information and all services.
419*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientBuffersFreeAllServices
420*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientClearHostAndServices
421*cfb92d14SAndroid Build Coastguard Worker      */
422*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "clear")
423*cfb92d14SAndroid Build Coastguard Worker     {
424*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
425*cfb92d14SAndroid Build Coastguard Worker         otSrpClientClearHostAndServices(GetInstancePtr());
426*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeAllServices(GetInstancePtr());
427*cfb92d14SAndroid Build Coastguard Worker     }
428*cfb92d14SAndroid Build Coastguard Worker     else
429*cfb92d14SAndroid Build Coastguard Worker     {
430*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_COMMAND;
431*cfb92d14SAndroid Build Coastguard Worker     }
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker exit:
434*cfb92d14SAndroid Build Coastguard Worker     return error;
435*cfb92d14SAndroid Build Coastguard Worker }
436*cfb92d14SAndroid Build Coastguard Worker 
437*cfb92d14SAndroid Build Coastguard Worker /**
438*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client leaseinterval (get,set)
439*cfb92d14SAndroid Build Coastguard Worker  * @code
440*cfb92d14SAndroid Build Coastguard Worker  * srp client leaseinterval 3600
441*cfb92d14SAndroid Build Coastguard Worker  * Done
442*cfb92d14SAndroid Build Coastguard Worker  * @endcode
443*cfb92d14SAndroid Build Coastguard Worker  * @code
444*cfb92d14SAndroid Build Coastguard Worker  * srp client leaseinterval
445*cfb92d14SAndroid Build Coastguard Worker  * 3600
446*cfb92d14SAndroid Build Coastguard Worker  * Done
447*cfb92d14SAndroid Build Coastguard Worker  * @endcode
448*cfb92d14SAndroid Build Coastguard Worker  * @cparam srp client leaseinterval [@ca{interval}]
449*cfb92d14SAndroid Build Coastguard Worker  * @par
450*cfb92d14SAndroid Build Coastguard Worker  * Gets or sets the lease interval in seconds.
451*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientGetLeaseInterval
452*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientSetLeaseInterval
453*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])454*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("leaseinterval")>(Arg aArgs[])
455*cfb92d14SAndroid Build Coastguard Worker {
456*cfb92d14SAndroid Build Coastguard Worker     return ProcessGetSet(aArgs, otSrpClientGetLeaseInterval, otSrpClientSetLeaseInterval);
457*cfb92d14SAndroid Build Coastguard Worker }
458*cfb92d14SAndroid Build Coastguard Worker 
459*cfb92d14SAndroid Build Coastguard Worker /**
460*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client keyleaseinterval (get,set)
461*cfb92d14SAndroid Build Coastguard Worker  * @code
462*cfb92d14SAndroid Build Coastguard Worker  * srp client keyleaseinterval 864000
463*cfb92d14SAndroid Build Coastguard Worker  * Done
464*cfb92d14SAndroid Build Coastguard Worker  * @endcode
465*cfb92d14SAndroid Build Coastguard Worker  * @code
466*cfb92d14SAndroid Build Coastguard Worker  * srp client keyleaseinterval
467*cfb92d14SAndroid Build Coastguard Worker  * 864000
468*cfb92d14SAndroid Build Coastguard Worker  * Done
469*cfb92d14SAndroid Build Coastguard Worker  * @endcode
470*cfb92d14SAndroid Build Coastguard Worker  * @cparam srp client keyleaseinterval [@ca{interval}]
471*cfb92d14SAndroid Build Coastguard Worker  * @par
472*cfb92d14SAndroid Build Coastguard Worker  * Gets or sets the key lease interval in seconds.
473*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientGetKeyLeaseInterval
474*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientSetKeyLeaseInterval
475*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])476*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("keyleaseinterval")>(Arg aArgs[])
477*cfb92d14SAndroid Build Coastguard Worker {
478*cfb92d14SAndroid Build Coastguard Worker     return ProcessGetSet(aArgs, otSrpClientGetKeyLeaseInterval, otSrpClientSetKeyLeaseInterval);
479*cfb92d14SAndroid Build Coastguard Worker }
480*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])481*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("server")>(Arg aArgs[])
482*cfb92d14SAndroid Build Coastguard Worker {
483*cfb92d14SAndroid Build Coastguard Worker     otError           error          = OT_ERROR_NONE;
484*cfb92d14SAndroid Build Coastguard Worker     const otSockAddr *serverSockAddr = otSrpClientGetServerAddress(GetInstancePtr());
485*cfb92d14SAndroid Build Coastguard Worker 
486*cfb92d14SAndroid Build Coastguard Worker     /**
487*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client server
488*cfb92d14SAndroid Build Coastguard Worker      * @code
489*cfb92d14SAndroid Build Coastguard Worker      * srp client server
490*cfb92d14SAndroid Build Coastguard Worker      * &lsqb;fd00:0:0:0:d88a:618b:384d:e760&rsqb;:4724
491*cfb92d14SAndroid Build Coastguard Worker      * Done
492*cfb92d14SAndroid Build Coastguard Worker      * @endcode
493*cfb92d14SAndroid Build Coastguard Worker      * @par
494*cfb92d14SAndroid Build Coastguard Worker      * Gets the socket address (IPv6 address and port number) of the SRP server
495*cfb92d14SAndroid Build Coastguard Worker      * that is being used by the SRP client. If the client is not running, the address
496*cfb92d14SAndroid Build Coastguard Worker      * is unspecified (all zeros) with a port number of 0. @moreinfo{@srp}.
497*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientGetServerAddress
498*cfb92d14SAndroid Build Coastguard Worker      */
499*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
500*cfb92d14SAndroid Build Coastguard Worker     {
501*cfb92d14SAndroid Build Coastguard Worker         OutputSockAddrLine(*serverSockAddr);
502*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
503*cfb92d14SAndroid Build Coastguard Worker     }
504*cfb92d14SAndroid Build Coastguard Worker 
505*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
506*cfb92d14SAndroid Build Coastguard Worker 
507*cfb92d14SAndroid Build Coastguard Worker     /**
508*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client server address
509*cfb92d14SAndroid Build Coastguard Worker      * @code
510*cfb92d14SAndroid Build Coastguard Worker      * srp client server address
511*cfb92d14SAndroid Build Coastguard Worker      * fd00:0:0:0:d88a:618b:384d:e760
512*cfb92d14SAndroid Build Coastguard Worker      * Done
513*cfb92d14SAndroid Build Coastguard Worker      * @endcode
514*cfb92d14SAndroid Build Coastguard Worker      * @par
515*cfb92d14SAndroid Build Coastguard Worker      * Returns the server's IPv6 address.
516*cfb92d14SAndroid Build Coastguard Worker      */
517*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "address")
518*cfb92d14SAndroid Build Coastguard Worker     {
519*cfb92d14SAndroid Build Coastguard Worker         OutputIp6AddressLine(serverSockAddr->mAddress);
520*cfb92d14SAndroid Build Coastguard Worker     }
521*cfb92d14SAndroid Build Coastguard Worker     /**
522*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client server port
523*cfb92d14SAndroid Build Coastguard Worker      * @code
524*cfb92d14SAndroid Build Coastguard Worker      * srp client server port
525*cfb92d14SAndroid Build Coastguard Worker      * 4724
526*cfb92d14SAndroid Build Coastguard Worker      * Done
527*cfb92d14SAndroid Build Coastguard Worker      * @endcode
528*cfb92d14SAndroid Build Coastguard Worker      * @par
529*cfb92d14SAndroid Build Coastguard Worker      * Returns the server's port number.
530*cfb92d14SAndroid Build Coastguard Worker      */
531*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "port")
532*cfb92d14SAndroid Build Coastguard Worker     {
533*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%u", serverSockAddr->mPort);
534*cfb92d14SAndroid Build Coastguard Worker     }
535*cfb92d14SAndroid Build Coastguard Worker     else
536*cfb92d14SAndroid Build Coastguard Worker     {
537*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_COMMAND;
538*cfb92d14SAndroid Build Coastguard Worker     }
539*cfb92d14SAndroid Build Coastguard Worker 
540*cfb92d14SAndroid Build Coastguard Worker exit:
541*cfb92d14SAndroid Build Coastguard Worker     return error;
542*cfb92d14SAndroid Build Coastguard Worker }
543*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])544*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("service")>(Arg aArgs[])
545*cfb92d14SAndroid Build Coastguard Worker {
546*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
547*cfb92d14SAndroid Build Coastguard Worker     bool    isRemove;
548*cfb92d14SAndroid Build Coastguard Worker 
549*cfb92d14SAndroid Build Coastguard Worker     /**
550*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client service
551*cfb92d14SAndroid Build Coastguard Worker      * @code
552*cfb92d14SAndroid Build Coastguard Worker      * srp client service
553*cfb92d14SAndroid Build Coastguard Worker      * instance:"ins2", name:"_test2._udp,_sub1,_sub2", state:Registered, port:111, priority:1, weight:1
554*cfb92d14SAndroid Build Coastguard Worker      * instance:"ins1", name:"_test1._udp", state:Registered, port:777, priority:0, weight:0
555*cfb92d14SAndroid Build Coastguard Worker      * Done
556*cfb92d14SAndroid Build Coastguard Worker      * @endcode
557*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
558*cfb92d14SAndroid Build Coastguard Worker      * #otSrpClientGetServices
559*cfb92d14SAndroid Build Coastguard Worker      */
560*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
561*cfb92d14SAndroid Build Coastguard Worker     {
562*cfb92d14SAndroid Build Coastguard Worker         OutputServiceList(0, otSrpClientGetServices(GetInstancePtr()));
563*cfb92d14SAndroid Build Coastguard Worker     }
564*cfb92d14SAndroid Build Coastguard Worker     /**
565*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client service add
566*cfb92d14SAndroid Build Coastguard Worker      * @code
567*cfb92d14SAndroid Build Coastguard Worker      * srp client service add ins1 _test1._udp 777
568*cfb92d14SAndroid Build Coastguard Worker      * Done
569*cfb92d14SAndroid Build Coastguard Worker      * @endcode
570*cfb92d14SAndroid Build Coastguard Worker      * @code
571*cfb92d14SAndroid Build Coastguard Worker      * srp client service add ins2 _test2._udp,_sub1,_sub2 111 1 1
572*cfb92d14SAndroid Build Coastguard Worker      * Done
573*cfb92d14SAndroid Build Coastguard Worker      * @endcode
574*cfb92d14SAndroid Build Coastguard Worker      * @cparam srp client service add @ca{instancename} @ca{servicename} <!--
575*cfb92d14SAndroid Build Coastguard Worker      * * -->                          @ca{port} [@ca{priority}] <!--
576*cfb92d14SAndroid Build Coastguard Worker      * * -->                          [@ca{weight}] [@ca{txt}]
577*cfb92d14SAndroid Build Coastguard Worker      * The `servicename` parameter can optionally include a list of service subtype labels that are
578*cfb92d14SAndroid Build Coastguard Worker      * separated by commas. The examples here use generic naming. The `priority` and `weight` (both are `uint16_t`
579*cfb92d14SAndroid Build Coastguard Worker      * values) parameters are optional, and if not provided zero is used. The optional `txt` parameter sets the TXT
580*cfb92d14SAndroid Build Coastguard Worker      * data associated with the service. The `txt` value must be in hex-string format and is treated as an already
581*cfb92d14SAndroid Build Coastguard Worker      * encoded TXT data byte sequence.
582*cfb92d14SAndroid Build Coastguard Worker      * @par
583*cfb92d14SAndroid Build Coastguard Worker      * Adds a service with a given instance name, service name, and port number.
584*cfb92d14SAndroid Build Coastguard Worker      * @moreinfo{@srp}.
585*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientAddService
586*cfb92d14SAndroid Build Coastguard Worker      */
587*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "add")
588*cfb92d14SAndroid Build Coastguard Worker     {
589*cfb92d14SAndroid Build Coastguard Worker         error = ProcessServiceAdd(aArgs);
590*cfb92d14SAndroid Build Coastguard Worker     }
591*cfb92d14SAndroid Build Coastguard Worker     /**
592*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client service remove
593*cfb92d14SAndroid Build Coastguard Worker      * @code
594*cfb92d14SAndroid Build Coastguard Worker      * srp client service remove ins2 _test2._udp
595*cfb92d14SAndroid Build Coastguard Worker      * Done
596*cfb92d14SAndroid Build Coastguard Worker      * @endcode
597*cfb92d14SAndroid Build Coastguard Worker      * @cparam srp client service remove @ca{instancename} @ca{servicename}
598*cfb92d14SAndroid Build Coastguard Worker      * @par
599*cfb92d14SAndroid Build Coastguard Worker      * Requests a service to be unregistered with the SRP server.
600*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientRemoveService
601*cfb92d14SAndroid Build Coastguard Worker      */
602*cfb92d14SAndroid Build Coastguard Worker     /**
603*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client service name clear
604*cfb92d14SAndroid Build Coastguard Worker      * @code
605*cfb92d14SAndroid Build Coastguard Worker      * srp client service clear ins2 _test2._udp
606*cfb92d14SAndroid Build Coastguard Worker      * Done
607*cfb92d14SAndroid Build Coastguard Worker      * @endcode
608*cfb92d14SAndroid Build Coastguard Worker      * @cparam srp client service clear @ca{instancename} @ca{servicename}
609*cfb92d14SAndroid Build Coastguard Worker      * @par
610*cfb92d14SAndroid Build Coastguard Worker      * Clears a service, immediately removing it from the client service list,
611*cfb92d14SAndroid Build Coastguard Worker      * with no interaction with the SRP server.
612*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientClearService
613*cfb92d14SAndroid Build Coastguard Worker      */
614*cfb92d14SAndroid Build Coastguard Worker     else if ((isRemove = (aArgs[0] == "remove")) || (aArgs[0] == "clear"))
615*cfb92d14SAndroid Build Coastguard Worker     {
616*cfb92d14SAndroid Build Coastguard Worker         // `remove`|`clear` <instance-name> <service-name>
617*cfb92d14SAndroid Build Coastguard Worker 
618*cfb92d14SAndroid Build Coastguard Worker         const otSrpClientService *service;
619*cfb92d14SAndroid Build Coastguard Worker 
620*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(!aArgs[2].IsEmpty() && aArgs[3].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
621*cfb92d14SAndroid Build Coastguard Worker 
622*cfb92d14SAndroid Build Coastguard Worker         for (service = otSrpClientGetServices(GetInstancePtr()); service != nullptr; service = service->mNext)
623*cfb92d14SAndroid Build Coastguard Worker         {
624*cfb92d14SAndroid Build Coastguard Worker             if ((aArgs[1] == service->mInstanceName) && (aArgs[2] == service->mName))
625*cfb92d14SAndroid Build Coastguard Worker             {
626*cfb92d14SAndroid Build Coastguard Worker                 break;
627*cfb92d14SAndroid Build Coastguard Worker             }
628*cfb92d14SAndroid Build Coastguard Worker         }
629*cfb92d14SAndroid Build Coastguard Worker 
630*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(service != nullptr, error = OT_ERROR_NOT_FOUND);
631*cfb92d14SAndroid Build Coastguard Worker 
632*cfb92d14SAndroid Build Coastguard Worker         if (isRemove)
633*cfb92d14SAndroid Build Coastguard Worker         {
634*cfb92d14SAndroid Build Coastguard Worker             error = otSrpClientRemoveService(GetInstancePtr(), const_cast<otSrpClientService *>(service));
635*cfb92d14SAndroid Build Coastguard Worker         }
636*cfb92d14SAndroid Build Coastguard Worker         else
637*cfb92d14SAndroid Build Coastguard Worker         {
638*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = otSrpClientClearService(GetInstancePtr(), const_cast<otSrpClientService *>(service)));
639*cfb92d14SAndroid Build Coastguard Worker 
640*cfb92d14SAndroid Build Coastguard Worker             otSrpClientBuffersFreeService(GetInstancePtr(), reinterpret_cast<otSrpClientBuffersServiceEntry *>(
641*cfb92d14SAndroid Build Coastguard Worker                                                                 const_cast<otSrpClientService *>(service)));
642*cfb92d14SAndroid Build Coastguard Worker         }
643*cfb92d14SAndroid Build Coastguard Worker     }
644*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
645*cfb92d14SAndroid Build Coastguard Worker     /**
646*cfb92d14SAndroid Build Coastguard Worker      * @cli srp client service key (get,set)
647*cfb92d14SAndroid Build Coastguard Worker      * @code
648*cfb92d14SAndroid Build Coastguard Worker      * srp client service key enable
649*cfb92d14SAndroid Build Coastguard Worker      * Done
650*cfb92d14SAndroid Build Coastguard Worker      * @endcode
651*cfb92d14SAndroid Build Coastguard Worker      * @code
652*cfb92d14SAndroid Build Coastguard Worker      * srp client service key
653*cfb92d14SAndroid Build Coastguard Worker      * Enabled
654*cfb92d14SAndroid Build Coastguard Worker      * Done
655*cfb92d14SAndroid Build Coastguard Worker      * @endcode
656*cfb92d14SAndroid Build Coastguard Worker      * @par
657*cfb92d14SAndroid Build Coastguard Worker      * Gets or sets the service key record inclusion mode in the SRP client.
658*cfb92d14SAndroid Build Coastguard Worker      * This command is intended for testing only, and requires that
659*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` be enabled. @moreinfo{@srp}.
660*cfb92d14SAndroid Build Coastguard Worker      * @sa otSrpClientIsServiceKeyRecordEnabled
661*cfb92d14SAndroid Build Coastguard Worker      */
662*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "key")
663*cfb92d14SAndroid Build Coastguard Worker     {
664*cfb92d14SAndroid Build Coastguard Worker         // `key [enable/disable]`
665*cfb92d14SAndroid Build Coastguard Worker 
666*cfb92d14SAndroid Build Coastguard Worker         error = ProcessEnableDisable(aArgs + 1, otSrpClientIsServiceKeyRecordEnabled,
667*cfb92d14SAndroid Build Coastguard Worker                                      otSrpClientSetServiceKeyRecordEnabled);
668*cfb92d14SAndroid Build Coastguard Worker     }
669*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
670*cfb92d14SAndroid Build Coastguard Worker     else
671*cfb92d14SAndroid Build Coastguard Worker     {
672*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_COMMAND;
673*cfb92d14SAndroid Build Coastguard Worker     }
674*cfb92d14SAndroid Build Coastguard Worker 
675*cfb92d14SAndroid Build Coastguard Worker exit:
676*cfb92d14SAndroid Build Coastguard Worker     return error;
677*cfb92d14SAndroid Build Coastguard Worker }
678*cfb92d14SAndroid Build Coastguard Worker 
ProcessServiceAdd(Arg aArgs[])679*cfb92d14SAndroid Build Coastguard Worker otError SrpClient::ProcessServiceAdd(Arg aArgs[])
680*cfb92d14SAndroid Build Coastguard Worker {
681*cfb92d14SAndroid Build Coastguard Worker     // `add` <instance-name> <service-name> <port> [priority] [weight] [txt] [lease] [key-lease]
682*cfb92d14SAndroid Build Coastguard Worker 
683*cfb92d14SAndroid Build Coastguard Worker     otSrpClientBuffersServiceEntry *entry = nullptr;
684*cfb92d14SAndroid Build Coastguard Worker     uint16_t                        size;
685*cfb92d14SAndroid Build Coastguard Worker     char                           *string;
686*cfb92d14SAndroid Build Coastguard Worker     otError                         error;
687*cfb92d14SAndroid Build Coastguard Worker     char                           *label;
688*cfb92d14SAndroid Build Coastguard Worker 
689*cfb92d14SAndroid Build Coastguard Worker     entry = otSrpClientBuffersAllocateService(GetInstancePtr());
690*cfb92d14SAndroid Build Coastguard Worker 
691*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
692*cfb92d14SAndroid Build Coastguard Worker 
693*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[3].ParseAsUint16(entry->mService.mPort));
694*cfb92d14SAndroid Build Coastguard Worker 
695*cfb92d14SAndroid Build Coastguard Worker     // Successfully parsing aArgs[3] indicates that aArgs[1] and
696*cfb92d14SAndroid Build Coastguard Worker     // aArgs[2] are also non-empty.
697*cfb92d14SAndroid Build Coastguard Worker 
698*cfb92d14SAndroid Build Coastguard Worker     string = otSrpClientBuffersGetServiceEntryInstanceNameString(entry, &size);
699*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = CopyString(string, size, aArgs[1].GetCString()));
700*cfb92d14SAndroid Build Coastguard Worker 
701*cfb92d14SAndroid Build Coastguard Worker     string = otSrpClientBuffersGetServiceEntryServiceNameString(entry, &size);
702*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = CopyString(string, size, aArgs[2].GetCString()));
703*cfb92d14SAndroid Build Coastguard Worker 
704*cfb92d14SAndroid Build Coastguard Worker     // Service subtypes are added as part of service name as a comma separated list
705*cfb92d14SAndroid Build Coastguard Worker     // e.g., "_service._udp,_sub1,_sub2"
706*cfb92d14SAndroid Build Coastguard Worker 
707*cfb92d14SAndroid Build Coastguard Worker     label = strchr(string, ',');
708*cfb92d14SAndroid Build Coastguard Worker 
709*cfb92d14SAndroid Build Coastguard Worker     if (label != nullptr)
710*cfb92d14SAndroid Build Coastguard Worker     {
711*cfb92d14SAndroid Build Coastguard Worker         uint16_t     arrayLength;
712*cfb92d14SAndroid Build Coastguard Worker         const char **subTypeLabels = otSrpClientBuffersGetSubTypeLabelsArray(entry, &arrayLength);
713*cfb92d14SAndroid Build Coastguard Worker 
714*cfb92d14SAndroid Build Coastguard Worker         // Leave the last array element as `nullptr` to indicate end of array.
715*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index + 1 < arrayLength; index++)
716*cfb92d14SAndroid Build Coastguard Worker         {
717*cfb92d14SAndroid Build Coastguard Worker             *label++             = '\0';
718*cfb92d14SAndroid Build Coastguard Worker             subTypeLabels[index] = label;
719*cfb92d14SAndroid Build Coastguard Worker 
720*cfb92d14SAndroid Build Coastguard Worker             label = strchr(label, ',');
721*cfb92d14SAndroid Build Coastguard Worker 
722*cfb92d14SAndroid Build Coastguard Worker             if (label == nullptr)
723*cfb92d14SAndroid Build Coastguard Worker             {
724*cfb92d14SAndroid Build Coastguard Worker                 break;
725*cfb92d14SAndroid Build Coastguard Worker             }
726*cfb92d14SAndroid Build Coastguard Worker         }
727*cfb92d14SAndroid Build Coastguard Worker 
728*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(label == nullptr, error = OT_ERROR_NO_BUFS);
729*cfb92d14SAndroid Build Coastguard Worker     }
730*cfb92d14SAndroid Build Coastguard Worker 
731*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[3].ParseAsUint16(entry->mService.mPort));
732*cfb92d14SAndroid Build Coastguard Worker 
733*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[4].IsEmpty())
734*cfb92d14SAndroid Build Coastguard Worker     {
735*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[4].ParseAsUint16(entry->mService.mPriority));
736*cfb92d14SAndroid Build Coastguard Worker     }
737*cfb92d14SAndroid Build Coastguard Worker 
738*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[5].IsEmpty())
739*cfb92d14SAndroid Build Coastguard Worker     {
740*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[5].ParseAsUint16(entry->mService.mWeight));
741*cfb92d14SAndroid Build Coastguard Worker     }
742*cfb92d14SAndroid Build Coastguard Worker 
743*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[6].IsEmpty() && (aArgs[6] != "-"))
744*cfb92d14SAndroid Build Coastguard Worker     {
745*cfb92d14SAndroid Build Coastguard Worker         uint8_t *txtBuffer;
746*cfb92d14SAndroid Build Coastguard Worker 
747*cfb92d14SAndroid Build Coastguard Worker         txtBuffer                     = otSrpClientBuffersGetServiceEntryTxtBuffer(entry, &size);
748*cfb92d14SAndroid Build Coastguard Worker         entry->mTxtEntry.mValueLength = size;
749*cfb92d14SAndroid Build Coastguard Worker 
750*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[6].ParseAsHexString(entry->mTxtEntry.mValueLength, txtBuffer));
751*cfb92d14SAndroid Build Coastguard Worker     }
752*cfb92d14SAndroid Build Coastguard Worker     else
753*cfb92d14SAndroid Build Coastguard Worker     {
754*cfb92d14SAndroid Build Coastguard Worker         entry->mService.mNumTxtEntries = 0;
755*cfb92d14SAndroid Build Coastguard Worker     }
756*cfb92d14SAndroid Build Coastguard Worker 
757*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[7].IsEmpty())
758*cfb92d14SAndroid Build Coastguard Worker     {
759*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[7].ParseAsUint32(entry->mService.mLease));
760*cfb92d14SAndroid Build Coastguard Worker     }
761*cfb92d14SAndroid Build Coastguard Worker 
762*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[8].IsEmpty())
763*cfb92d14SAndroid Build Coastguard Worker     {
764*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[8].ParseAsUint32(entry->mService.mKeyLease));
765*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aArgs[9].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
766*cfb92d14SAndroid Build Coastguard Worker     }
767*cfb92d14SAndroid Build Coastguard Worker 
768*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otSrpClientAddService(GetInstancePtr(), &entry->mService));
769*cfb92d14SAndroid Build Coastguard Worker 
770*cfb92d14SAndroid Build Coastguard Worker     entry = nullptr;
771*cfb92d14SAndroid Build Coastguard Worker 
772*cfb92d14SAndroid Build Coastguard Worker exit:
773*cfb92d14SAndroid Build Coastguard Worker     if (entry != nullptr)
774*cfb92d14SAndroid Build Coastguard Worker     {
775*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeService(GetInstancePtr(), entry);
776*cfb92d14SAndroid Build Coastguard Worker     }
777*cfb92d14SAndroid Build Coastguard Worker 
778*cfb92d14SAndroid Build Coastguard Worker     return error;
779*cfb92d14SAndroid Build Coastguard Worker }
780*cfb92d14SAndroid Build Coastguard Worker 
OutputHostInfo(uint8_t aIndentSize,const otSrpClientHostInfo & aHostInfo)781*cfb92d14SAndroid Build Coastguard Worker void SrpClient::OutputHostInfo(uint8_t aIndentSize, const otSrpClientHostInfo &aHostInfo)
782*cfb92d14SAndroid Build Coastguard Worker {
783*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(aIndentSize, "name:");
784*cfb92d14SAndroid Build Coastguard Worker 
785*cfb92d14SAndroid Build Coastguard Worker     if (aHostInfo.mName != nullptr)
786*cfb92d14SAndroid Build Coastguard Worker     {
787*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("\"%s\"", aHostInfo.mName);
788*cfb92d14SAndroid Build Coastguard Worker     }
789*cfb92d14SAndroid Build Coastguard Worker     else
790*cfb92d14SAndroid Build Coastguard Worker     {
791*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("(null)");
792*cfb92d14SAndroid Build Coastguard Worker     }
793*cfb92d14SAndroid Build Coastguard Worker 
794*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(", state:%s, addrs:", otSrpClientItemStateToString(aHostInfo.mState));
795*cfb92d14SAndroid Build Coastguard Worker 
796*cfb92d14SAndroid Build Coastguard Worker     if (aHostInfo.mAutoAddress)
797*cfb92d14SAndroid Build Coastguard Worker     {
798*cfb92d14SAndroid Build Coastguard Worker         OutputLine("auto");
799*cfb92d14SAndroid Build Coastguard Worker     }
800*cfb92d14SAndroid Build Coastguard Worker     else
801*cfb92d14SAndroid Build Coastguard Worker     {
802*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("[");
803*cfb92d14SAndroid Build Coastguard Worker 
804*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
805*cfb92d14SAndroid Build Coastguard Worker         {
806*cfb92d14SAndroid Build Coastguard Worker             if (index > 0)
807*cfb92d14SAndroid Build Coastguard Worker             {
808*cfb92d14SAndroid Build Coastguard Worker                 OutputFormat(", ");
809*cfb92d14SAndroid Build Coastguard Worker             }
810*cfb92d14SAndroid Build Coastguard Worker 
811*cfb92d14SAndroid Build Coastguard Worker             OutputIp6Address(aHostInfo.mAddresses[index]);
812*cfb92d14SAndroid Build Coastguard Worker         }
813*cfb92d14SAndroid Build Coastguard Worker 
814*cfb92d14SAndroid Build Coastguard Worker         OutputLine("]");
815*cfb92d14SAndroid Build Coastguard Worker     }
816*cfb92d14SAndroid Build Coastguard Worker }
817*cfb92d14SAndroid Build Coastguard Worker 
OutputServiceList(uint8_t aIndentSize,const otSrpClientService * aServices)818*cfb92d14SAndroid Build Coastguard Worker void SrpClient::OutputServiceList(uint8_t aIndentSize, const otSrpClientService *aServices)
819*cfb92d14SAndroid Build Coastguard Worker {
820*cfb92d14SAndroid Build Coastguard Worker     while (aServices != nullptr)
821*cfb92d14SAndroid Build Coastguard Worker     {
822*cfb92d14SAndroid Build Coastguard Worker         OutputService(aIndentSize, *aServices);
823*cfb92d14SAndroid Build Coastguard Worker         aServices = aServices->mNext;
824*cfb92d14SAndroid Build Coastguard Worker     }
825*cfb92d14SAndroid Build Coastguard Worker }
826*cfb92d14SAndroid Build Coastguard Worker 
OutputService(uint8_t aIndentSize,const otSrpClientService & aService)827*cfb92d14SAndroid Build Coastguard Worker void SrpClient::OutputService(uint8_t aIndentSize, const otSrpClientService &aService)
828*cfb92d14SAndroid Build Coastguard Worker {
829*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(aIndentSize, "instance:\"%s\", name:\"%s", aService.mInstanceName, aService.mName);
830*cfb92d14SAndroid Build Coastguard Worker 
831*cfb92d14SAndroid Build Coastguard Worker     if (aService.mSubTypeLabels != nullptr)
832*cfb92d14SAndroid Build Coastguard Worker     {
833*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; aService.mSubTypeLabels[index] != nullptr; index++)
834*cfb92d14SAndroid Build Coastguard Worker         {
835*cfb92d14SAndroid Build Coastguard Worker             OutputFormat(",%s", aService.mSubTypeLabels[index]);
836*cfb92d14SAndroid Build Coastguard Worker         }
837*cfb92d14SAndroid Build Coastguard Worker     }
838*cfb92d14SAndroid Build Coastguard Worker 
839*cfb92d14SAndroid Build Coastguard Worker     OutputLine("\", state:%s, port:%d, priority:%d, weight:%d", otSrpClientItemStateToString(aService.mState),
840*cfb92d14SAndroid Build Coastguard Worker                aService.mPort, aService.mPriority, aService.mWeight);
841*cfb92d14SAndroid Build Coastguard Worker }
842*cfb92d14SAndroid Build Coastguard Worker 
843*cfb92d14SAndroid Build Coastguard Worker /**
844*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client start
845*cfb92d14SAndroid Build Coastguard Worker  * @code
846*cfb92d14SAndroid Build Coastguard Worker  * srp client start fd00::d88a:618b:384d:e760 4724
847*cfb92d14SAndroid Build Coastguard Worker  * Done
848*cfb92d14SAndroid Build Coastguard Worker  * @endcode
849*cfb92d14SAndroid Build Coastguard Worker  * @cparam srp client start @ca{serveraddr} @ca{serverport}
850*cfb92d14SAndroid Build Coastguard Worker  * @par
851*cfb92d14SAndroid Build Coastguard Worker  * Starts the SRP client operation. @moreinfo{@srp}.
852*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientStart
853*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])854*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("start")>(Arg aArgs[])
855*cfb92d14SAndroid Build Coastguard Worker {
856*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
857*cfb92d14SAndroid Build Coastguard Worker     otSockAddr serverSockAddr;
858*cfb92d14SAndroid Build Coastguard Worker 
859*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[0].ParseAsIp6Address(serverSockAddr.mAddress));
860*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[1].ParseAsUint16(serverSockAddr.mPort));
861*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
862*cfb92d14SAndroid Build Coastguard Worker 
863*cfb92d14SAndroid Build Coastguard Worker     error = otSrpClientStart(GetInstancePtr(), &serverSockAddr);
864*cfb92d14SAndroid Build Coastguard Worker 
865*cfb92d14SAndroid Build Coastguard Worker exit:
866*cfb92d14SAndroid Build Coastguard Worker     return error;
867*cfb92d14SAndroid Build Coastguard Worker }
868*cfb92d14SAndroid Build Coastguard Worker 
869*cfb92d14SAndroid Build Coastguard Worker /**
870*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client state
871*cfb92d14SAndroid Build Coastguard Worker  * @code
872*cfb92d14SAndroid Build Coastguard Worker  * srp client state
873*cfb92d14SAndroid Build Coastguard Worker  * Enabled
874*cfb92d14SAndroid Build Coastguard Worker  * Done
875*cfb92d14SAndroid Build Coastguard Worker  * @endcode
876*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
877*cfb92d14SAndroid Build Coastguard Worker  * #otSrpClientIsRunning
878*cfb92d14SAndroid Build Coastguard Worker  * @moreinfo{@srp}.
879*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])880*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("state")>(Arg aArgs[])
881*cfb92d14SAndroid Build Coastguard Worker {
882*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
883*cfb92d14SAndroid Build Coastguard Worker 
884*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
885*cfb92d14SAndroid Build Coastguard Worker 
886*cfb92d14SAndroid Build Coastguard Worker     OutputEnabledDisabledStatus(otSrpClientIsRunning(GetInstancePtr()));
887*cfb92d14SAndroid Build Coastguard Worker 
888*cfb92d14SAndroid Build Coastguard Worker exit:
889*cfb92d14SAndroid Build Coastguard Worker     return error;
890*cfb92d14SAndroid Build Coastguard Worker }
891*cfb92d14SAndroid Build Coastguard Worker 
892*cfb92d14SAndroid Build Coastguard Worker /**
893*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client stop
894*cfb92d14SAndroid Build Coastguard Worker  * @code
895*cfb92d14SAndroid Build Coastguard Worker  * srp client stop
896*cfb92d14SAndroid Build Coastguard Worker  * Done
897*cfb92d14SAndroid Build Coastguard Worker  * @endcode
898*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
899*cfb92d14SAndroid Build Coastguard Worker  * #otSrpClientStop
900*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])901*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("stop")>(Arg aArgs[])
902*cfb92d14SAndroid Build Coastguard Worker {
903*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
904*cfb92d14SAndroid Build Coastguard Worker 
905*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
906*cfb92d14SAndroid Build Coastguard Worker     otSrpClientStop(GetInstancePtr());
907*cfb92d14SAndroid Build Coastguard Worker 
908*cfb92d14SAndroid Build Coastguard Worker exit:
909*cfb92d14SAndroid Build Coastguard Worker     return error;
910*cfb92d14SAndroid Build Coastguard Worker }
911*cfb92d14SAndroid Build Coastguard Worker 
912*cfb92d14SAndroid Build Coastguard Worker /**
913*cfb92d14SAndroid Build Coastguard Worker  * @cli srp client ttl (get,set)
914*cfb92d14SAndroid Build Coastguard Worker  * @code
915*cfb92d14SAndroid Build Coastguard Worker  * srp client ttl 3600
916*cfb92d14SAndroid Build Coastguard Worker  * Done
917*cfb92d14SAndroid Build Coastguard Worker  * @endcode
918*cfb92d14SAndroid Build Coastguard Worker  * @code
919*cfb92d14SAndroid Build Coastguard Worker  * srp client ttl
920*cfb92d14SAndroid Build Coastguard Worker  * 3600
921*cfb92d14SAndroid Build Coastguard Worker  * Done
922*cfb92d14SAndroid Build Coastguard Worker  * @endcode
923*cfb92d14SAndroid Build Coastguard Worker  * @cparam srp client ttl [@ca{value}]
924*cfb92d14SAndroid Build Coastguard Worker  * @par
925*cfb92d14SAndroid Build Coastguard Worker  * Gets or sets the `ttl`(time to live) value in seconds.
926*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientGetTtl
927*cfb92d14SAndroid Build Coastguard Worker  * @sa otSrpClientSetTtl
928*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])929*cfb92d14SAndroid Build Coastguard Worker template <> otError SrpClient::Process<Cmd("ttl")>(Arg aArgs[])
930*cfb92d14SAndroid Build Coastguard Worker {
931*cfb92d14SAndroid Build Coastguard Worker     return ProcessGetSet(aArgs, otSrpClientGetTtl, otSrpClientSetTtl);
932*cfb92d14SAndroid Build Coastguard Worker }
933*cfb92d14SAndroid Build Coastguard Worker 
HandleCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices,void * aContext)934*cfb92d14SAndroid Build Coastguard Worker void SrpClient::HandleCallback(otError                    aError,
935*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientHostInfo *aHostInfo,
936*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientService  *aServices,
937*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientService  *aRemovedServices,
938*cfb92d14SAndroid Build Coastguard Worker                                void                      *aContext)
939*cfb92d14SAndroid Build Coastguard Worker {
940*cfb92d14SAndroid Build Coastguard Worker     static_cast<SrpClient *>(aContext)->HandleCallback(aError, aHostInfo, aServices, aRemovedServices);
941*cfb92d14SAndroid Build Coastguard Worker }
942*cfb92d14SAndroid Build Coastguard Worker 
HandleCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices)943*cfb92d14SAndroid Build Coastguard Worker void SrpClient::HandleCallback(otError                    aError,
944*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientHostInfo *aHostInfo,
945*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientService  *aServices,
946*cfb92d14SAndroid Build Coastguard Worker                                const otSrpClientService  *aRemovedServices)
947*cfb92d14SAndroid Build Coastguard Worker {
948*cfb92d14SAndroid Build Coastguard Worker     otSrpClientService *next;
949*cfb92d14SAndroid Build Coastguard Worker 
950*cfb92d14SAndroid Build Coastguard Worker     if (mCallbackEnabled)
951*cfb92d14SAndroid Build Coastguard Worker     {
952*cfb92d14SAndroid Build Coastguard Worker         OutputLine("SRP client callback - error:%s", otThreadErrorToString(aError));
953*cfb92d14SAndroid Build Coastguard Worker         OutputLine("Host info:");
954*cfb92d14SAndroid Build Coastguard Worker         OutputHostInfo(kIndentSize, *aHostInfo);
955*cfb92d14SAndroid Build Coastguard Worker 
956*cfb92d14SAndroid Build Coastguard Worker         OutputLine("Service list:");
957*cfb92d14SAndroid Build Coastguard Worker         OutputServiceList(kIndentSize, aServices);
958*cfb92d14SAndroid Build Coastguard Worker 
959*cfb92d14SAndroid Build Coastguard Worker         if (aRemovedServices != nullptr)
960*cfb92d14SAndroid Build Coastguard Worker         {
961*cfb92d14SAndroid Build Coastguard Worker             OutputLine("Removed service list:");
962*cfb92d14SAndroid Build Coastguard Worker             OutputServiceList(kIndentSize, aRemovedServices);
963*cfb92d14SAndroid Build Coastguard Worker         }
964*cfb92d14SAndroid Build Coastguard Worker     }
965*cfb92d14SAndroid Build Coastguard Worker 
966*cfb92d14SAndroid Build Coastguard Worker     // Go through removed services and free all removed services
967*cfb92d14SAndroid Build Coastguard Worker 
968*cfb92d14SAndroid Build Coastguard Worker     for (const otSrpClientService *service = aRemovedServices; service != nullptr; service = next)
969*cfb92d14SAndroid Build Coastguard Worker     {
970*cfb92d14SAndroid Build Coastguard Worker         next = service->mNext;
971*cfb92d14SAndroid Build Coastguard Worker 
972*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeService(GetInstancePtr(), reinterpret_cast<otSrpClientBuffersServiceEntry *>(
973*cfb92d14SAndroid Build Coastguard Worker                                                             const_cast<otSrpClientService *>(service)));
974*cfb92d14SAndroid Build Coastguard Worker     }
975*cfb92d14SAndroid Build Coastguard Worker }
976*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])977*cfb92d14SAndroid Build Coastguard Worker otError SrpClient::Process(Arg aArgs[])
978*cfb92d14SAndroid Build Coastguard Worker {
979*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString)                                 \
980*cfb92d14SAndroid Build Coastguard Worker     {                                                            \
981*cfb92d14SAndroid Build Coastguard Worker         aCommandString, &SrpClient::Process<Cmd(aCommandString)> \
982*cfb92d14SAndroid Build Coastguard Worker     }
983*cfb92d14SAndroid Build Coastguard Worker 
984*cfb92d14SAndroid Build Coastguard Worker     static constexpr Command kCommands[] = {
985*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("autostart"),     CmdEntry("callback"), CmdEntry("host"),    CmdEntry("keyleaseinterval"),
986*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("leaseinterval"), CmdEntry("server"),   CmdEntry("service"), CmdEntry("start"),
987*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("state"),         CmdEntry("stop"),     CmdEntry("ttl"),
988*cfb92d14SAndroid Build Coastguard Worker     };
989*cfb92d14SAndroid Build Coastguard Worker 
990*cfb92d14SAndroid Build Coastguard Worker     static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
991*cfb92d14SAndroid Build Coastguard Worker 
992*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_INVALID_COMMAND;
993*cfb92d14SAndroid Build Coastguard Worker     const Command *command;
994*cfb92d14SAndroid Build Coastguard Worker 
995*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
996*cfb92d14SAndroid Build Coastguard Worker     {
997*cfb92d14SAndroid Build Coastguard Worker         OutputCommandTable(kCommands);
998*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
999*cfb92d14SAndroid Build Coastguard Worker     }
1000*cfb92d14SAndroid Build Coastguard Worker 
1001*cfb92d14SAndroid Build Coastguard Worker     command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
1002*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(command != nullptr);
1003*cfb92d14SAndroid Build Coastguard Worker 
1004*cfb92d14SAndroid Build Coastguard Worker     error = (this->*command->mHandler)(aArgs + 1);
1005*cfb92d14SAndroid Build Coastguard Worker 
1006*cfb92d14SAndroid Build Coastguard Worker exit:
1007*cfb92d14SAndroid Build Coastguard Worker     return error;
1008*cfb92d14SAndroid Build Coastguard Worker }
1009*cfb92d14SAndroid Build Coastguard Worker 
1010*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
1011*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
1012*cfb92d14SAndroid Build Coastguard Worker 
1013*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
1014