xref: /aosp_15_r20/external/openthread/src/cli/cli_udp.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2017, 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 CoAP service.
32*cfb92d14SAndroid Build Coastguard Worker  */
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include "cli_udp.hpp"
35*cfb92d14SAndroid Build Coastguard Worker 
36*cfb92d14SAndroid Build Coastguard Worker #include <openthread/message.h>
37*cfb92d14SAndroid Build Coastguard Worker #include <openthread/nat64.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/udp.h>
39*cfb92d14SAndroid Build Coastguard Worker 
40*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli.hpp"
41*cfb92d14SAndroid Build Coastguard Worker #include "common/encoding.hpp"
42*cfb92d14SAndroid Build Coastguard Worker 
43*cfb92d14SAndroid Build Coastguard Worker namespace ot {
44*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
45*cfb92d14SAndroid Build Coastguard Worker 
UdpExample(otInstance * aInstance,OutputImplementer & aOutputImplementer)46*cfb92d14SAndroid Build Coastguard Worker UdpExample::UdpExample(otInstance *aInstance, OutputImplementer &aOutputImplementer)
47*cfb92d14SAndroid Build Coastguard Worker     : Utils(aInstance, aOutputImplementer)
48*cfb92d14SAndroid Build Coastguard Worker     , mLinkSecurityEnabled(true)
49*cfb92d14SAndroid Build Coastguard Worker {
50*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(mSocket);
51*cfb92d14SAndroid Build Coastguard Worker }
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker /**
54*cfb92d14SAndroid Build Coastguard Worker  * @cli udp bind
55*cfb92d14SAndroid Build Coastguard Worker  * @code
56*cfb92d14SAndroid Build Coastguard Worker  * udp bind :: 1234
57*cfb92d14SAndroid Build Coastguard Worker  * Done
58*cfb92d14SAndroid Build Coastguard Worker  * @endcode
59*cfb92d14SAndroid Build Coastguard Worker  * @code
60*cfb92d14SAndroid Build Coastguard Worker  * udp bind -u :: 1234
61*cfb92d14SAndroid Build Coastguard Worker  * Done
62*cfb92d14SAndroid Build Coastguard Worker  * @endcode
63*cfb92d14SAndroid Build Coastguard Worker  * @code
64*cfb92d14SAndroid Build Coastguard Worker  * udp bind -b :: 1234
65*cfb92d14SAndroid Build Coastguard Worker  * Done
66*cfb92d14SAndroid Build Coastguard Worker  * @endcode
67*cfb92d14SAndroid Build Coastguard Worker  * @cparam udp bind [@ca{netif}] @ca{ip} @ca{port}
68*cfb92d14SAndroid Build Coastguard Worker  * - `netif`: The binding network interface, which is determined as follows:
69*cfb92d14SAndroid Build Coastguard Worker  *   - No value (leaving out this parameter from the command): Thread network interface is used.
70*cfb92d14SAndroid Build Coastguard Worker  *   - `-u`: Unspecified network interface, which means that the UDP/IPv6 stack determines which
71*cfb92d14SAndroid Build Coastguard Worker  *   network interface to bind the socket to.
72*cfb92d14SAndroid Build Coastguard Worker  *   - `-b`: Backbone network interface is used.
73*cfb92d14SAndroid Build Coastguard Worker  * - `ip`: Unicast IPv6 address to bind to. If you wish to have the UDP/IPv6 stack assign the binding
74*cfb92d14SAndroid Build Coastguard Worker  *   IPv6 address, or if you wish to bind to multicast IPv6 addresses, then you can use the following
75*cfb92d14SAndroid Build Coastguard Worker  *   value to use the unspecified IPv6 address: `::`. Each example uses the unspecified IPv6 address.
76*cfb92d14SAndroid Build Coastguard Worker  * - `port`: UDP port number to bind to. Each of the examples is using port number 1234.
77*cfb92d14SAndroid Build Coastguard Worker  * @par
78*cfb92d14SAndroid Build Coastguard Worker  * Assigns an IPv6 address and a port to an open socket, which binds the socket for communication.
79*cfb92d14SAndroid Build Coastguard Worker  * Assigning the IPv6 address and port is referred to as naming the socket. @moreinfo{@udp}.
80*cfb92d14SAndroid Build Coastguard Worker  * @sa otUdpBind
81*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])82*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("bind")>(Arg aArgs[])
83*cfb92d14SAndroid Build Coastguard Worker {
84*cfb92d14SAndroid Build Coastguard Worker     otError           error;
85*cfb92d14SAndroid Build Coastguard Worker     otSockAddr        sockaddr;
86*cfb92d14SAndroid Build Coastguard Worker     otNetifIdentifier netif = OT_NETIF_THREAD;
87*cfb92d14SAndroid Build Coastguard Worker 
88*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "-u")
89*cfb92d14SAndroid Build Coastguard Worker     {
90*cfb92d14SAndroid Build Coastguard Worker         netif = OT_NETIF_UNSPECIFIED;
91*cfb92d14SAndroid Build Coastguard Worker         aArgs++;
92*cfb92d14SAndroid Build Coastguard Worker     }
93*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "-b")
94*cfb92d14SAndroid Build Coastguard Worker     {
95*cfb92d14SAndroid Build Coastguard Worker         netif = OT_NETIF_BACKBONE;
96*cfb92d14SAndroid Build Coastguard Worker         aArgs++;
97*cfb92d14SAndroid Build Coastguard Worker     }
98*cfb92d14SAndroid Build Coastguard Worker 
99*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[0].ParseAsIp6Address(sockaddr.mAddress));
100*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
101*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
102*cfb92d14SAndroid Build Coastguard Worker 
103*cfb92d14SAndroid Build Coastguard Worker     error = otUdpBind(GetInstancePtr(), &mSocket, &sockaddr, netif);
104*cfb92d14SAndroid Build Coastguard Worker 
105*cfb92d14SAndroid Build Coastguard Worker exit:
106*cfb92d14SAndroid Build Coastguard Worker     return error;
107*cfb92d14SAndroid Build Coastguard Worker }
108*cfb92d14SAndroid Build Coastguard Worker 
109*cfb92d14SAndroid Build Coastguard Worker /**
110*cfb92d14SAndroid Build Coastguard Worker  * @cli udp connect
111*cfb92d14SAndroid Build Coastguard Worker  * @code
112*cfb92d14SAndroid Build Coastguard Worker  * udp connect fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234
113*cfb92d14SAndroid Build Coastguard Worker  * Done
114*cfb92d14SAndroid Build Coastguard Worker  * @endcode
115*cfb92d14SAndroid Build Coastguard Worker  * @code
116*cfb92d14SAndroid Build Coastguard Worker  * udp connect 172.17.0.1 1234
117*cfb92d14SAndroid Build Coastguard Worker  * Connecting to synthesized IPv6 address: fdde:ad00:beef:2:0:0:ac11:1
118*cfb92d14SAndroid Build Coastguard Worker  * Done
119*cfb92d14SAndroid Build Coastguard Worker  * @endcode
120*cfb92d14SAndroid Build Coastguard Worker  * @cparam udp connect @ca{ip} @ca{port}
121*cfb92d14SAndroid Build Coastguard Worker  * The following parameters are required:
122*cfb92d14SAndroid Build Coastguard Worker  * - `ip`: IP address of the peer.
123*cfb92d14SAndroid Build Coastguard Worker  * - `port`: UDP port number of the peer.
124*cfb92d14SAndroid Build Coastguard Worker  * The address can be an IPv4 address, which gets synthesized to an IPv6 address
125*cfb92d14SAndroid Build Coastguard Worker  * using the preferred NAT64 prefix from the network data. The command returns
126*cfb92d14SAndroid Build Coastguard Worker  * `InvalidState` when the preferred NAT64 prefix is unavailable.
127*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
128*cfb92d14SAndroid Build Coastguard Worker  * #otUdpConnect
129*cfb92d14SAndroid Build Coastguard Worker  * @moreinfo{@udp}.
130*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])131*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("connect")>(Arg aArgs[])
132*cfb92d14SAndroid Build Coastguard Worker {
133*cfb92d14SAndroid Build Coastguard Worker     otError    error;
134*cfb92d14SAndroid Build Coastguard Worker     otSockAddr sockaddr;
135*cfb92d14SAndroid Build Coastguard Worker     bool       nat64Synth;
136*cfb92d14SAndroid Build Coastguard Worker 
137*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth));
138*cfb92d14SAndroid Build Coastguard Worker 
139*cfb92d14SAndroid Build Coastguard Worker     if (nat64Synth)
140*cfb92d14SAndroid Build Coastguard Worker     {
141*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("Connecting to synthesized IPv6 address: ");
142*cfb92d14SAndroid Build Coastguard Worker         OutputIp6AddressLine(sockaddr.mAddress);
143*cfb92d14SAndroid Build Coastguard Worker     }
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
146*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
147*cfb92d14SAndroid Build Coastguard Worker 
148*cfb92d14SAndroid Build Coastguard Worker     error = otUdpConnect(GetInstancePtr(), &mSocket, &sockaddr);
149*cfb92d14SAndroid Build Coastguard Worker 
150*cfb92d14SAndroid Build Coastguard Worker exit:
151*cfb92d14SAndroid Build Coastguard Worker     return error;
152*cfb92d14SAndroid Build Coastguard Worker }
153*cfb92d14SAndroid Build Coastguard Worker 
154*cfb92d14SAndroid Build Coastguard Worker /**
155*cfb92d14SAndroid Build Coastguard Worker  * @cli udp close
156*cfb92d14SAndroid Build Coastguard Worker  * @code
157*cfb92d14SAndroid Build Coastguard Worker  * udp close
158*cfb92d14SAndroid Build Coastguard Worker  * Done
159*cfb92d14SAndroid Build Coastguard Worker  * @endcode
160*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
161*cfb92d14SAndroid Build Coastguard Worker  * #otUdpClose
162*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])163*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("close")>(Arg aArgs[])
164*cfb92d14SAndroid Build Coastguard Worker {
165*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
166*cfb92d14SAndroid Build Coastguard Worker 
167*cfb92d14SAndroid Build Coastguard Worker     return otUdpClose(GetInstancePtr(), &mSocket);
168*cfb92d14SAndroid Build Coastguard Worker }
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker /**
171*cfb92d14SAndroid Build Coastguard Worker  * @cli udp open
172*cfb92d14SAndroid Build Coastguard Worker  * @code
173*cfb92d14SAndroid Build Coastguard Worker  * udp open
174*cfb92d14SAndroid Build Coastguard Worker  * Done
175*cfb92d14SAndroid Build Coastguard Worker  * @endcode
176*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
177*cfb92d14SAndroid Build Coastguard Worker  * #otUdpOpen
178*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])179*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("open")>(Arg aArgs[])
180*cfb92d14SAndroid Build Coastguard Worker {
181*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
182*cfb92d14SAndroid Build Coastguard Worker 
183*cfb92d14SAndroid Build Coastguard Worker     otError error;
184*cfb92d14SAndroid Build Coastguard Worker 
185*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(!otUdpIsOpen(GetInstancePtr(), &mSocket), error = OT_ERROR_ALREADY);
186*cfb92d14SAndroid Build Coastguard Worker     error = otUdpOpen(GetInstancePtr(), &mSocket, HandleUdpReceive, this);
187*cfb92d14SAndroid Build Coastguard Worker 
188*cfb92d14SAndroid Build Coastguard Worker exit:
189*cfb92d14SAndroid Build Coastguard Worker     return error;
190*cfb92d14SAndroid Build Coastguard Worker }
191*cfb92d14SAndroid Build Coastguard Worker 
192*cfb92d14SAndroid Build Coastguard Worker /**
193*cfb92d14SAndroid Build Coastguard Worker  * @cli udp send
194*cfb92d14SAndroid Build Coastguard Worker  * @code
195*cfb92d14SAndroid Build Coastguard Worker  * udp send hello
196*cfb92d14SAndroid Build Coastguard Worker  * Done
197*cfb92d14SAndroid Build Coastguard Worker  * @endcode
198*cfb92d14SAndroid Build Coastguard Worker  * @code
199*cfb92d14SAndroid Build Coastguard Worker  * udp send -t hello
200*cfb92d14SAndroid Build Coastguard Worker  * Done
201*cfb92d14SAndroid Build Coastguard Worker  * @endcode
202*cfb92d14SAndroid Build Coastguard Worker  * @code
203*cfb92d14SAndroid Build Coastguard Worker  * udp send -x 68656c6c6f
204*cfb92d14SAndroid Build Coastguard Worker  * Done
205*cfb92d14SAndroid Build Coastguard Worker  * @endcode
206*cfb92d14SAndroid Build Coastguard Worker  * @code
207*cfb92d14SAndroid Build Coastguard Worker  * udp send -s 800
208*cfb92d14SAndroid Build Coastguard Worker  * Done
209*cfb92d14SAndroid Build Coastguard Worker  * @endcode
210*cfb92d14SAndroid Build Coastguard Worker  * @code
211*cfb92d14SAndroid Build Coastguard Worker  * udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 hello
212*cfb92d14SAndroid Build Coastguard Worker  * Done
213*cfb92d14SAndroid Build Coastguard Worker  * @endcode
214*cfb92d14SAndroid Build Coastguard Worker  * @code
215*cfb92d14SAndroid Build Coastguard Worker  * udp send 172.17.0.1 1234 hello
216*cfb92d14SAndroid Build Coastguard Worker  * Sending to synthesized IPv6 address: fdde:ad00:beef:2:0:0:ac11:1
217*cfb92d14SAndroid Build Coastguard Worker  * Done
218*cfb92d14SAndroid Build Coastguard Worker  * @endcode
219*cfb92d14SAndroid Build Coastguard Worker  * @code
220*cfb92d14SAndroid Build Coastguard Worker  * udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 -t hello
221*cfb92d14SAndroid Build Coastguard Worker  * Done
222*cfb92d14SAndroid Build Coastguard Worker  * @endcode
223*cfb92d14SAndroid Build Coastguard Worker  * @code
224*cfb92d14SAndroid Build Coastguard Worker  * udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 -x 68656c6c6f
225*cfb92d14SAndroid Build Coastguard Worker  * Done
226*cfb92d14SAndroid Build Coastguard Worker  * @endcode
227*cfb92d14SAndroid Build Coastguard Worker  * @code
228*cfb92d14SAndroid Build Coastguard Worker  * udp send fdde:ad00:beef:0:bb1:ebd6:ad10:f33 1234 -s 800
229*cfb92d14SAndroid Build Coastguard Worker  * Done
230*cfb92d14SAndroid Build Coastguard Worker  * @endcode
231*cfb92d14SAndroid Build Coastguard Worker  * @cparam udp send [@ca{ip} @ca{port}] [@ca{type}] @ca{value}
232*cfb92d14SAndroid Build Coastguard Worker  * The `ip` and `port` are optional as a pair, but if you specify one you must
233*cfb92d14SAndroid Build Coastguard Worker  * specify the other. If `ip` and `port` are not specified, the socket peer address
234*cfb92d14SAndroid Build Coastguard Worker  * is used from `udp connect`.
235*cfb92d14SAndroid Build Coastguard Worker  * - `ip`: Destination address. This address can be either an IPv4 or IPv6 address,
236*cfb92d14SAndroid Build Coastguard Worker  *   An IPv4 address gets synthesized to an IPv6 address with the preferred
237*cfb92d14SAndroid Build Coastguard Worker  *   NAT64 prefix from the network data. (If the preferred NAT64 prefix
238*cfb92d14SAndroid Build Coastguard Worker  *   is unavailable, the command returns `InvalidState`).
239*cfb92d14SAndroid Build Coastguard Worker  * - `port`: UDP destination port.
240*cfb92d14SAndroid Build Coastguard Worker  * - `type`/`value` combinations:
241*cfb92d14SAndroid Build Coastguard Worker  *   - `-t`: The payload in the `value` parameter is treated as text. If no `type` value
242*cfb92d14SAndroid Build Coastguard Worker  *   is entered, the payload in the `value` parameter is also treated as text.
243*cfb92d14SAndroid Build Coastguard Worker  *   - `-s`: Auto-generated payload with the specified length given in the `value` parameter.
244*cfb92d14SAndroid Build Coastguard Worker  *   - `-x`: Binary data in hexadecimal representation given in the `value` parameter.
245*cfb92d14SAndroid Build Coastguard Worker  * @par
246*cfb92d14SAndroid Build Coastguard Worker  * Sends a UDP message using the socket. @moreinfo{@udp}.
247*cfb92d14SAndroid Build Coastguard Worker  * @csa{udp open}
248*cfb92d14SAndroid Build Coastguard Worker  * @csa{udp bind}
249*cfb92d14SAndroid Build Coastguard Worker  * @csa{udp connect}
250*cfb92d14SAndroid Build Coastguard Worker  * @sa otUdpSend
251*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])252*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("send")>(Arg aArgs[])
253*cfb92d14SAndroid Build Coastguard Worker {
254*cfb92d14SAndroid Build Coastguard Worker     otError           error   = OT_ERROR_NONE;
255*cfb92d14SAndroid Build Coastguard Worker     otMessage        *message = nullptr;
256*cfb92d14SAndroid Build Coastguard Worker     otMessageInfo     messageInfo;
257*cfb92d14SAndroid Build Coastguard Worker     otMessageSettings messageSettings = {mLinkSecurityEnabled, OT_MESSAGE_PRIORITY_NORMAL};
258*cfb92d14SAndroid Build Coastguard Worker 
259*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(otUdpIsOpen(GetInstancePtr(), &mSocket), error = OT_ERROR_INVALID_STATE);
260*cfb92d14SAndroid Build Coastguard Worker 
261*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(messageInfo);
262*cfb92d14SAndroid Build Coastguard Worker 
263*cfb92d14SAndroid Build Coastguard Worker     // Possible argument formats:
264*cfb92d14SAndroid Build Coastguard Worker     //
265*cfb92d14SAndroid Build Coastguard Worker     // send             <text>
266*cfb92d14SAndroid Build Coastguard Worker     // send             <type> <value>
267*cfb92d14SAndroid Build Coastguard Worker     // send <ip> <port> <text>
268*cfb92d14SAndroid Build Coastguard Worker     // send <ip> <port> <type> <value>
269*cfb92d14SAndroid Build Coastguard Worker 
270*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[2].IsEmpty())
271*cfb92d14SAndroid Build Coastguard Worker     {
272*cfb92d14SAndroid Build Coastguard Worker         bool nat64Synth;
273*cfb92d14SAndroid Build Coastguard Worker 
274*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], messageInfo.mPeerAddr, nat64Synth));
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker         if (nat64Synth)
277*cfb92d14SAndroid Build Coastguard Worker         {
278*cfb92d14SAndroid Build Coastguard Worker             OutputFormat("Sending to synthesized IPv6 address: ");
279*cfb92d14SAndroid Build Coastguard Worker             OutputIp6AddressLine(messageInfo.mPeerAddr);
280*cfb92d14SAndroid Build Coastguard Worker         }
281*cfb92d14SAndroid Build Coastguard Worker 
282*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[1].ParseAsUint16(messageInfo.mPeerPort));
283*cfb92d14SAndroid Build Coastguard Worker         aArgs += 2;
284*cfb92d14SAndroid Build Coastguard Worker     }
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker     message = otUdpNewMessage(GetInstancePtr(), &messageSettings);
287*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
288*cfb92d14SAndroid Build Coastguard Worker 
289*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "-s")
290*cfb92d14SAndroid Build Coastguard Worker     {
291*cfb92d14SAndroid Build Coastguard Worker         // Auto-generated payload with a given length
292*cfb92d14SAndroid Build Coastguard Worker 
293*cfb92d14SAndroid Build Coastguard Worker         uint16_t payloadLength;
294*cfb92d14SAndroid Build Coastguard Worker 
295*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[1].ParseAsUint16(payloadLength));
296*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = PrepareAutoGeneratedPayload(*message, payloadLength));
297*cfb92d14SAndroid Build Coastguard Worker     }
298*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "-x")
299*cfb92d14SAndroid Build Coastguard Worker     {
300*cfb92d14SAndroid Build Coastguard Worker         // Binary hex data payload
301*cfb92d14SAndroid Build Coastguard Worker 
302*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
303*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = PrepareHexStringPayload(*message, aArgs[1].GetCString()));
304*cfb92d14SAndroid Build Coastguard Worker     }
305*cfb92d14SAndroid Build Coastguard Worker     else
306*cfb92d14SAndroid Build Coastguard Worker     {
307*cfb92d14SAndroid Build Coastguard Worker         // Text payload (same as without specifying the type)
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker         if (aArgs[0] == "-t")
310*cfb92d14SAndroid Build Coastguard Worker         {
311*cfb92d14SAndroid Build Coastguard Worker             aArgs++;
312*cfb92d14SAndroid Build Coastguard Worker         }
313*cfb92d14SAndroid Build Coastguard Worker 
314*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(!aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
315*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otMessageAppend(message, aArgs[0].GetCString(), aArgs[0].GetLength()));
316*cfb92d14SAndroid Build Coastguard Worker     }
317*cfb92d14SAndroid Build Coastguard Worker 
318*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otUdpSend(GetInstancePtr(), &mSocket, message, &messageInfo));
319*cfb92d14SAndroid Build Coastguard Worker 
320*cfb92d14SAndroid Build Coastguard Worker     message = nullptr;
321*cfb92d14SAndroid Build Coastguard Worker 
322*cfb92d14SAndroid Build Coastguard Worker exit:
323*cfb92d14SAndroid Build Coastguard Worker     if (message != nullptr)
324*cfb92d14SAndroid Build Coastguard Worker     {
325*cfb92d14SAndroid Build Coastguard Worker         otMessageFree(message);
326*cfb92d14SAndroid Build Coastguard Worker     }
327*cfb92d14SAndroid Build Coastguard Worker 
328*cfb92d14SAndroid Build Coastguard Worker     return error;
329*cfb92d14SAndroid Build Coastguard Worker }
330*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])331*cfb92d14SAndroid Build Coastguard Worker template <> otError UdpExample::Process<Cmd("linksecurity")>(Arg aArgs[])
332*cfb92d14SAndroid Build Coastguard Worker {
333*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
334*cfb92d14SAndroid Build Coastguard Worker 
335*cfb92d14SAndroid Build Coastguard Worker     /**
336*cfb92d14SAndroid Build Coastguard Worker      * @cli udp linksecurity
337*cfb92d14SAndroid Build Coastguard Worker      * @code
338*cfb92d14SAndroid Build Coastguard Worker      * udp linksecurity
339*cfb92d14SAndroid Build Coastguard Worker      * Enabled
340*cfb92d14SAndroid Build Coastguard Worker      * Done
341*cfb92d14SAndroid Build Coastguard Worker      * @endcode
342*cfb92d14SAndroid Build Coastguard Worker      * @par
343*cfb92d14SAndroid Build Coastguard Worker      * Indicates whether link security is enabled or disabled.
344*cfb92d14SAndroid Build Coastguard Worker      */
345*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
346*cfb92d14SAndroid Build Coastguard Worker     {
347*cfb92d14SAndroid Build Coastguard Worker         OutputEnabledDisabledStatus(mLinkSecurityEnabled);
348*cfb92d14SAndroid Build Coastguard Worker     }
349*cfb92d14SAndroid Build Coastguard Worker     /**
350*cfb92d14SAndroid Build Coastguard Worker      * @cli udp linksecurity (enable,disable)
351*cfb92d14SAndroid Build Coastguard Worker      * @code
352*cfb92d14SAndroid Build Coastguard Worker      * udp linksecurity enable
353*cfb92d14SAndroid Build Coastguard Worker      * Done
354*cfb92d14SAndroid Build Coastguard Worker      * @endcode
355*cfb92d14SAndroid Build Coastguard Worker      * @code
356*cfb92d14SAndroid Build Coastguard Worker      * udp linksecurity disable
357*cfb92d14SAndroid Build Coastguard Worker      * Done
358*cfb92d14SAndroid Build Coastguard Worker      * @endcode
359*cfb92d14SAndroid Build Coastguard Worker      * @par
360*cfb92d14SAndroid Build Coastguard Worker      * Enables or disables link security.
361*cfb92d14SAndroid Build Coastguard Worker      */
362*cfb92d14SAndroid Build Coastguard Worker     else
363*cfb92d14SAndroid Build Coastguard Worker     {
364*cfb92d14SAndroid Build Coastguard Worker         error = ParseEnableOrDisable(aArgs[0], mLinkSecurityEnabled);
365*cfb92d14SAndroid Build Coastguard Worker     }
366*cfb92d14SAndroid Build Coastguard Worker 
367*cfb92d14SAndroid Build Coastguard Worker     return error;
368*cfb92d14SAndroid Build Coastguard Worker }
369*cfb92d14SAndroid Build Coastguard Worker 
PrepareAutoGeneratedPayload(otMessage & aMessage,uint16_t aPayloadLength)370*cfb92d14SAndroid Build Coastguard Worker otError UdpExample::PrepareAutoGeneratedPayload(otMessage &aMessage, uint16_t aPayloadLength)
371*cfb92d14SAndroid Build Coastguard Worker {
372*cfb92d14SAndroid Build Coastguard Worker     otError error     = OT_ERROR_NONE;
373*cfb92d14SAndroid Build Coastguard Worker     uint8_t character = '0';
374*cfb92d14SAndroid Build Coastguard Worker 
375*cfb92d14SAndroid Build Coastguard Worker     for (; aPayloadLength != 0; aPayloadLength--)
376*cfb92d14SAndroid Build Coastguard Worker     {
377*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otMessageAppend(&aMessage, &character, sizeof(character)));
378*cfb92d14SAndroid Build Coastguard Worker 
379*cfb92d14SAndroid Build Coastguard Worker         switch (character)
380*cfb92d14SAndroid Build Coastguard Worker         {
381*cfb92d14SAndroid Build Coastguard Worker         case '9':
382*cfb92d14SAndroid Build Coastguard Worker             character = 'A';
383*cfb92d14SAndroid Build Coastguard Worker             break;
384*cfb92d14SAndroid Build Coastguard Worker         case 'Z':
385*cfb92d14SAndroid Build Coastguard Worker             character = 'a';
386*cfb92d14SAndroid Build Coastguard Worker             break;
387*cfb92d14SAndroid Build Coastguard Worker         case 'z':
388*cfb92d14SAndroid Build Coastguard Worker             character = '0';
389*cfb92d14SAndroid Build Coastguard Worker             break;
390*cfb92d14SAndroid Build Coastguard Worker         default:
391*cfb92d14SAndroid Build Coastguard Worker             character++;
392*cfb92d14SAndroid Build Coastguard Worker             break;
393*cfb92d14SAndroid Build Coastguard Worker         }
394*cfb92d14SAndroid Build Coastguard Worker     }
395*cfb92d14SAndroid Build Coastguard Worker 
396*cfb92d14SAndroid Build Coastguard Worker exit:
397*cfb92d14SAndroid Build Coastguard Worker     return error;
398*cfb92d14SAndroid Build Coastguard Worker }
399*cfb92d14SAndroid Build Coastguard Worker 
PrepareHexStringPayload(otMessage & aMessage,const char * aHexString)400*cfb92d14SAndroid Build Coastguard Worker otError UdpExample::PrepareHexStringPayload(otMessage &aMessage, const char *aHexString)
401*cfb92d14SAndroid Build Coastguard Worker {
402*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint16_t kBufferSize = 50;
403*cfb92d14SAndroid Build Coastguard Worker 
404*cfb92d14SAndroid Build Coastguard Worker     otError  error;
405*cfb92d14SAndroid Build Coastguard Worker     uint8_t  buf[kBufferSize];
406*cfb92d14SAndroid Build Coastguard Worker     uint16_t length;
407*cfb92d14SAndroid Build Coastguard Worker     bool     done = false;
408*cfb92d14SAndroid Build Coastguard Worker 
409*cfb92d14SAndroid Build Coastguard Worker     while (!done)
410*cfb92d14SAndroid Build Coastguard Worker     {
411*cfb92d14SAndroid Build Coastguard Worker         length = sizeof(buf);
412*cfb92d14SAndroid Build Coastguard Worker         error  = ot::Utils::CmdLineParser::ParseAsHexStringSegment(aHexString, length, buf);
413*cfb92d14SAndroid Build Coastguard Worker 
414*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit((error == OT_ERROR_NONE) || (error == OT_ERROR_PENDING));
415*cfb92d14SAndroid Build Coastguard Worker         done = (error == OT_ERROR_NONE);
416*cfb92d14SAndroid Build Coastguard Worker 
417*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otMessageAppend(&aMessage, buf, length));
418*cfb92d14SAndroid Build Coastguard Worker     }
419*cfb92d14SAndroid Build Coastguard Worker 
420*cfb92d14SAndroid Build Coastguard Worker exit:
421*cfb92d14SAndroid Build Coastguard Worker     return error;
422*cfb92d14SAndroid Build Coastguard Worker }
423*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])424*cfb92d14SAndroid Build Coastguard Worker otError UdpExample::Process(Arg aArgs[])
425*cfb92d14SAndroid Build Coastguard Worker {
426*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString)                                  \
427*cfb92d14SAndroid Build Coastguard Worker     {                                                             \
428*cfb92d14SAndroid Build Coastguard Worker         aCommandString, &UdpExample::Process<Cmd(aCommandString)> \
429*cfb92d14SAndroid Build Coastguard Worker     }
430*cfb92d14SAndroid Build Coastguard Worker 
431*cfb92d14SAndroid Build Coastguard Worker     static constexpr Command kCommands[] = {
432*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("bind"),         CmdEntry("close"), CmdEntry("connect"),
433*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("linksecurity"), CmdEntry("open"),  CmdEntry("send"),
434*cfb92d14SAndroid Build Coastguard Worker     };
435*cfb92d14SAndroid Build Coastguard Worker 
436*cfb92d14SAndroid Build Coastguard Worker     static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
437*cfb92d14SAndroid Build Coastguard Worker 
438*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_INVALID_COMMAND;
439*cfb92d14SAndroid Build Coastguard Worker     const Command *command;
440*cfb92d14SAndroid Build Coastguard Worker 
441*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
442*cfb92d14SAndroid Build Coastguard Worker     {
443*cfb92d14SAndroid Build Coastguard Worker         OutputCommandTable(kCommands);
444*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
445*cfb92d14SAndroid Build Coastguard Worker     }
446*cfb92d14SAndroid Build Coastguard Worker 
447*cfb92d14SAndroid Build Coastguard Worker     command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
448*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(command != nullptr);
449*cfb92d14SAndroid Build Coastguard Worker 
450*cfb92d14SAndroid Build Coastguard Worker     error = (this->*command->mHandler)(aArgs + 1);
451*cfb92d14SAndroid Build Coastguard Worker 
452*cfb92d14SAndroid Build Coastguard Worker exit:
453*cfb92d14SAndroid Build Coastguard Worker     return error;
454*cfb92d14SAndroid Build Coastguard Worker }
455*cfb92d14SAndroid Build Coastguard Worker 
HandleUdpReceive(void * aContext,otMessage * aMessage,const otMessageInfo * aMessageInfo)456*cfb92d14SAndroid Build Coastguard Worker void UdpExample::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
457*cfb92d14SAndroid Build Coastguard Worker {
458*cfb92d14SAndroid Build Coastguard Worker     static_cast<UdpExample *>(aContext)->HandleUdpReceive(aMessage, aMessageInfo);
459*cfb92d14SAndroid Build Coastguard Worker }
460*cfb92d14SAndroid Build Coastguard Worker 
HandleUdpReceive(otMessage * aMessage,const otMessageInfo * aMessageInfo)461*cfb92d14SAndroid Build Coastguard Worker void UdpExample::HandleUdpReceive(otMessage *aMessage, const otMessageInfo *aMessageInfo)
462*cfb92d14SAndroid Build Coastguard Worker {
463*cfb92d14SAndroid Build Coastguard Worker     char buf[1500];
464*cfb92d14SAndroid Build Coastguard Worker     int  length;
465*cfb92d14SAndroid Build Coastguard Worker 
466*cfb92d14SAndroid Build Coastguard Worker     OutputFormat("%d bytes from ", otMessageGetLength(aMessage) - otMessageGetOffset(aMessage));
467*cfb92d14SAndroid Build Coastguard Worker     OutputIp6Address(aMessageInfo->mPeerAddr);
468*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(" %d ", aMessageInfo->mPeerPort);
469*cfb92d14SAndroid Build Coastguard Worker 
470*cfb92d14SAndroid Build Coastguard Worker     length      = otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, sizeof(buf) - 1);
471*cfb92d14SAndroid Build Coastguard Worker     buf[length] = '\0';
472*cfb92d14SAndroid Build Coastguard Worker 
473*cfb92d14SAndroid Build Coastguard Worker     OutputLine("%s", buf);
474*cfb92d14SAndroid Build Coastguard Worker }
475*cfb92d14SAndroid Build Coastguard Worker 
476*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
477*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
478