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_coap.hpp"
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_API_ENABLE
37*cfb92d14SAndroid Build Coastguard Worker
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/random_noncrypto.h>
39*cfb92d14SAndroid Build Coastguard Worker
40*cfb92d14SAndroid Build Coastguard Worker #include <ctype.h>
41*cfb92d14SAndroid Build Coastguard Worker
42*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli.hpp"
43*cfb92d14SAndroid Build Coastguard Worker
44*cfb92d14SAndroid Build Coastguard Worker namespace ot {
45*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
46*cfb92d14SAndroid Build Coastguard Worker
Coap(otInstance * aInstance,OutputImplementer & aOutputImplementer)47*cfb92d14SAndroid Build Coastguard Worker Coap::Coap(otInstance *aInstance, OutputImplementer &aOutputImplementer)
48*cfb92d14SAndroid Build Coastguard Worker : Utils(aInstance, aOutputImplementer)
49*cfb92d14SAndroid Build Coastguard Worker , mUseDefaultRequestTxParameters(true)
50*cfb92d14SAndroid Build Coastguard Worker , mUseDefaultResponseTxParameters(true)
51*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
52*cfb92d14SAndroid Build Coastguard Worker , mObserveSerial(0)
53*cfb92d14SAndroid Build Coastguard Worker , mRequestTokenLength(0)
54*cfb92d14SAndroid Build Coastguard Worker , mSubscriberTokenLength(0)
55*cfb92d14SAndroid Build Coastguard Worker , mSubscriberConfirmableNotifications(false)
56*cfb92d14SAndroid Build Coastguard Worker #endif
57*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
58*cfb92d14SAndroid Build Coastguard Worker , mBlockCount(1)
59*cfb92d14SAndroid Build Coastguard Worker #endif
60*cfb92d14SAndroid Build Coastguard Worker {
61*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mResource);
62*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
63*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mRequestAddr);
64*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mSubscriberSock);
65*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mRequestToken);
66*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mSubscriberToken);
67*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mRequestUri);
68*cfb92d14SAndroid Build Coastguard Worker #endif
69*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mUriPath);
70*cfb92d14SAndroid Build Coastguard Worker strncpy(mResourceContent, "0", sizeof(mResourceContent));
71*cfb92d14SAndroid Build Coastguard Worker mResourceContent[sizeof(mResourceContent) - 1] = '\0';
72*cfb92d14SAndroid Build Coastguard Worker }
73*cfb92d14SAndroid Build Coastguard Worker
74*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
CancelResourceSubscription(void)75*cfb92d14SAndroid Build Coastguard Worker otError Coap::CancelResourceSubscription(void)
76*cfb92d14SAndroid Build Coastguard Worker {
77*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
78*cfb92d14SAndroid Build Coastguard Worker otMessage *message = nullptr;
79*cfb92d14SAndroid Build Coastguard Worker otMessageInfo messageInfo;
80*cfb92d14SAndroid Build Coastguard Worker
81*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(messageInfo);
82*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerAddr = mRequestAddr;
83*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
84*cfb92d14SAndroid Build Coastguard Worker
85*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(mRequestTokenLength != 0, error = OT_ERROR_INVALID_STATE);
86*cfb92d14SAndroid Build Coastguard Worker
87*cfb92d14SAndroid Build Coastguard Worker message = otCoapNewMessage(GetInstancePtr(), nullptr);
88*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
89*cfb92d14SAndroid Build Coastguard Worker
90*cfb92d14SAndroid Build Coastguard Worker otCoapMessageInit(message, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_GET);
91*cfb92d14SAndroid Build Coastguard Worker
92*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetToken(message, mRequestToken, mRequestTokenLength));
93*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 1));
94*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, mRequestUri));
95*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapSendRequest(GetInstancePtr(), message, &messageInfo, &Coap::HandleResponse, this));
96*cfb92d14SAndroid Build Coastguard Worker
97*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mRequestAddr);
98*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mRequestUri);
99*cfb92d14SAndroid Build Coastguard Worker mRequestTokenLength = 0;
100*cfb92d14SAndroid Build Coastguard Worker
101*cfb92d14SAndroid Build Coastguard Worker exit:
102*cfb92d14SAndroid Build Coastguard Worker
103*cfb92d14SAndroid Build Coastguard Worker if ((error != OT_ERROR_NONE) && (message != nullptr))
104*cfb92d14SAndroid Build Coastguard Worker {
105*cfb92d14SAndroid Build Coastguard Worker otMessageFree(message);
106*cfb92d14SAndroid Build Coastguard Worker }
107*cfb92d14SAndroid Build Coastguard Worker
108*cfb92d14SAndroid Build Coastguard Worker return error;
109*cfb92d14SAndroid Build Coastguard Worker }
110*cfb92d14SAndroid Build Coastguard Worker
CancelSubscriber(void)111*cfb92d14SAndroid Build Coastguard Worker void Coap::CancelSubscriber(void)
112*cfb92d14SAndroid Build Coastguard Worker {
113*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(mSubscriberSock);
114*cfb92d14SAndroid Build Coastguard Worker mSubscriberTokenLength = 0;
115*cfb92d14SAndroid Build Coastguard Worker }
116*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
117*cfb92d14SAndroid Build Coastguard Worker
PrintPayload(otMessage * aMessage)118*cfb92d14SAndroid Build Coastguard Worker void Coap::PrintPayload(otMessage *aMessage)
119*cfb92d14SAndroid Build Coastguard Worker {
120*cfb92d14SAndroid Build Coastguard Worker uint8_t buf[kMaxBufferSize];
121*cfb92d14SAndroid Build Coastguard Worker uint16_t bytesToPrint;
122*cfb92d14SAndroid Build Coastguard Worker uint16_t bytesPrinted = 0;
123*cfb92d14SAndroid Build Coastguard Worker uint16_t length = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
124*cfb92d14SAndroid Build Coastguard Worker
125*cfb92d14SAndroid Build Coastguard Worker if (length > 0)
126*cfb92d14SAndroid Build Coastguard Worker {
127*cfb92d14SAndroid Build Coastguard Worker OutputFormat(" with payload: ");
128*cfb92d14SAndroid Build Coastguard Worker
129*cfb92d14SAndroid Build Coastguard Worker while (length > 0)
130*cfb92d14SAndroid Build Coastguard Worker {
131*cfb92d14SAndroid Build Coastguard Worker bytesToPrint = Min(length, static_cast<uint16_t>(sizeof(buf)));
132*cfb92d14SAndroid Build Coastguard Worker otMessageRead(aMessage, otMessageGetOffset(aMessage) + bytesPrinted, buf, bytesToPrint);
133*cfb92d14SAndroid Build Coastguard Worker
134*cfb92d14SAndroid Build Coastguard Worker OutputBytes(buf, static_cast<uint8_t>(bytesToPrint));
135*cfb92d14SAndroid Build Coastguard Worker
136*cfb92d14SAndroid Build Coastguard Worker length -= bytesToPrint;
137*cfb92d14SAndroid Build Coastguard Worker bytesPrinted += bytesToPrint;
138*cfb92d14SAndroid Build Coastguard Worker }
139*cfb92d14SAndroid Build Coastguard Worker }
140*cfb92d14SAndroid Build Coastguard Worker
141*cfb92d14SAndroid Build Coastguard Worker OutputNewLine();
142*cfb92d14SAndroid Build Coastguard Worker }
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
145*cfb92d14SAndroid Build Coastguard Worker /**
146*cfb92d14SAndroid Build Coastguard Worker * @cli coap cancel
147*cfb92d14SAndroid Build Coastguard Worker * @code
148*cfb92d14SAndroid Build Coastguard Worker * coap cancel
149*cfb92d14SAndroid Build Coastguard Worker * Done
150*cfb92d14SAndroid Build Coastguard Worker * @endcode
151*cfb92d14SAndroid Build Coastguard Worker * @par
152*cfb92d14SAndroid Build Coastguard Worker * Cancels an existing observation subscription to a remote resource on the CoAP server.
153*cfb92d14SAndroid Build Coastguard Worker * @note This command is available only when `OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE` is set.
154*cfb92d14SAndroid Build Coastguard Worker * @csa{coap observe}
155*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])156*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("cancel")>(Arg aArgs[])
157*cfb92d14SAndroid Build Coastguard Worker {
158*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aArgs);
159*cfb92d14SAndroid Build Coastguard Worker
160*cfb92d14SAndroid Build Coastguard Worker return CancelResourceSubscription();
161*cfb92d14SAndroid Build Coastguard Worker }
162*cfb92d14SAndroid Build Coastguard Worker #endif
163*cfb92d14SAndroid Build Coastguard Worker
164*cfb92d14SAndroid Build Coastguard Worker /**
165*cfb92d14SAndroid Build Coastguard Worker * @cli coap resource (get,set)
166*cfb92d14SAndroid Build Coastguard Worker * @code
167*cfb92d14SAndroid Build Coastguard Worker * coap resource test-resource
168*cfb92d14SAndroid Build Coastguard Worker * Done
169*cfb92d14SAndroid Build Coastguard Worker * @endcode
170*cfb92d14SAndroid Build Coastguard Worker * @code
171*cfb92d14SAndroid Build Coastguard Worker * coap resource
172*cfb92d14SAndroid Build Coastguard Worker * test-resource
173*cfb92d14SAndroid Build Coastguard Worker * Done
174*cfb92d14SAndroid Build Coastguard Worker * @endcode
175*cfb92d14SAndroid Build Coastguard Worker * @cparam coap resource [@ca{uri-path}]
176*cfb92d14SAndroid Build Coastguard Worker * @par
177*cfb92d14SAndroid Build Coastguard Worker * Gets or sets the URI path of the CoAP server resource.
178*cfb92d14SAndroid Build Coastguard Worker * @sa otCoapAddResource
179*cfb92d14SAndroid Build Coastguard Worker * @sa otCoapAddBlockWiseResource
180*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])181*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("resource")>(Arg aArgs[])
182*cfb92d14SAndroid Build Coastguard Worker {
183*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[0].IsEmpty())
186*cfb92d14SAndroid Build Coastguard Worker {
187*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(aArgs[0].GetLength() < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
188*cfb92d14SAndroid Build Coastguard Worker
189*cfb92d14SAndroid Build Coastguard Worker mResource.mUriPath = mUriPath;
190*cfb92d14SAndroid Build Coastguard Worker mResource.mContext = this;
191*cfb92d14SAndroid Build Coastguard Worker mResource.mHandler = &Coap::HandleRequest;
192*cfb92d14SAndroid Build Coastguard Worker
193*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
194*cfb92d14SAndroid Build Coastguard Worker mResource.mReceiveHook = &Coap::BlockwiseReceiveHook;
195*cfb92d14SAndroid Build Coastguard Worker mResource.mTransmitHook = &Coap::BlockwiseTransmitHook;
196*cfb92d14SAndroid Build Coastguard Worker
197*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[1].IsEmpty())
198*cfb92d14SAndroid Build Coastguard Worker {
199*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[1].ParseAsUint32(mBlockCount));
200*cfb92d14SAndroid Build Coastguard Worker }
201*cfb92d14SAndroid Build Coastguard Worker #endif
202*cfb92d14SAndroid Build Coastguard Worker
203*cfb92d14SAndroid Build Coastguard Worker strncpy(mUriPath, aArgs[0].GetCString(), sizeof(mUriPath) - 1);
204*cfb92d14SAndroid Build Coastguard Worker
205*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
206*cfb92d14SAndroid Build Coastguard Worker otCoapAddBlockWiseResource(GetInstancePtr(), &mResource);
207*cfb92d14SAndroid Build Coastguard Worker #else
208*cfb92d14SAndroid Build Coastguard Worker otCoapAddResource(GetInstancePtr(), &mResource);
209*cfb92d14SAndroid Build Coastguard Worker #endif
210*cfb92d14SAndroid Build Coastguard Worker }
211*cfb92d14SAndroid Build Coastguard Worker else
212*cfb92d14SAndroid Build Coastguard Worker {
213*cfb92d14SAndroid Build Coastguard Worker OutputLine("%s", mResource.mUriPath != nullptr ? mResource.mUriPath : "");
214*cfb92d14SAndroid Build Coastguard Worker }
215*cfb92d14SAndroid Build Coastguard Worker
216*cfb92d14SAndroid Build Coastguard Worker exit:
217*cfb92d14SAndroid Build Coastguard Worker return error;
218*cfb92d14SAndroid Build Coastguard Worker }
219*cfb92d14SAndroid Build Coastguard Worker
220*cfb92d14SAndroid Build Coastguard Worker /**
221*cfb92d14SAndroid Build Coastguard Worker * @cli coap set
222*cfb92d14SAndroid Build Coastguard Worker * @code
223*cfb92d14SAndroid Build Coastguard Worker * coap set Testing123
224*cfb92d14SAndroid Build Coastguard Worker * Done
225*cfb92d14SAndroid Build Coastguard Worker * @endcode
226*cfb92d14SAndroid Build Coastguard Worker * @cparam coap set @ca{new-content}
227*cfb92d14SAndroid Build Coastguard Worker * @par
228*cfb92d14SAndroid Build Coastguard Worker * Sets the content sent by the resource on the CoAP server.
229*cfb92d14SAndroid Build Coastguard Worker * If a CoAP client is observing the resource, a notification is sent to that client.
230*cfb92d14SAndroid Build Coastguard Worker * @csa{coap observe}
231*cfb92d14SAndroid Build Coastguard Worker * @sa otCoapMessageInit
232*cfb92d14SAndroid Build Coastguard Worker * @sa otCoapNewMessage
233*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])234*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("set")>(Arg aArgs[])
235*cfb92d14SAndroid Build Coastguard Worker {
236*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
237*cfb92d14SAndroid Build Coastguard Worker otMessage *notificationMessage = nullptr;
238*cfb92d14SAndroid Build Coastguard Worker otMessageInfo messageInfo;
239*cfb92d14SAndroid Build Coastguard Worker #endif
240*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
241*cfb92d14SAndroid Build Coastguard Worker
242*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[0].IsEmpty())
243*cfb92d14SAndroid Build Coastguard Worker {
244*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(aArgs[0].GetLength() < sizeof(mResourceContent), error = OT_ERROR_INVALID_ARGS);
245*cfb92d14SAndroid Build Coastguard Worker strncpy(mResourceContent, aArgs[0].GetCString(), sizeof(mResourceContent));
246*cfb92d14SAndroid Build Coastguard Worker mResourceContent[sizeof(mResourceContent) - 1] = '\0';
247*cfb92d14SAndroid Build Coastguard Worker
248*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
249*cfb92d14SAndroid Build Coastguard Worker if (mSubscriberTokenLength > 0)
250*cfb92d14SAndroid Build Coastguard Worker {
251*cfb92d14SAndroid Build Coastguard Worker // Notify the subscriber
252*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(messageInfo);
253*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerAddr = mSubscriberSock.mAddress;
254*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerPort = mSubscriberSock.mPort;
255*cfb92d14SAndroid Build Coastguard Worker
256*cfb92d14SAndroid Build Coastguard Worker OutputFormat("sending coap notification to ");
257*cfb92d14SAndroid Build Coastguard Worker OutputIp6AddressLine(mSubscriberSock.mAddress);
258*cfb92d14SAndroid Build Coastguard Worker
259*cfb92d14SAndroid Build Coastguard Worker notificationMessage = otCoapNewMessage(GetInstancePtr(), nullptr);
260*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(notificationMessage != nullptr, error = OT_ERROR_NO_BUFS);
261*cfb92d14SAndroid Build Coastguard Worker
262*cfb92d14SAndroid Build Coastguard Worker otCoapMessageInit(
263*cfb92d14SAndroid Build Coastguard Worker notificationMessage,
264*cfb92d14SAndroid Build Coastguard Worker ((mSubscriberConfirmableNotifications) ? OT_COAP_TYPE_CONFIRMABLE : OT_COAP_TYPE_NON_CONFIRMABLE),
265*cfb92d14SAndroid Build Coastguard Worker OT_COAP_CODE_CONTENT);
266*cfb92d14SAndroid Build Coastguard Worker
267*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetToken(notificationMessage, mSubscriberToken, mSubscriberTokenLength));
268*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendObserveOption(notificationMessage, mObserveSerial++));
269*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetPayloadMarker(notificationMessage));
270*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otMessageAppend(notificationMessage, mResourceContent,
271*cfb92d14SAndroid Build Coastguard Worker static_cast<uint16_t>(strlen(mResourceContent))));
272*cfb92d14SAndroid Build Coastguard Worker
273*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapSendRequest(GetInstancePtr(), notificationMessage, &messageInfo,
274*cfb92d14SAndroid Build Coastguard Worker &Coap::HandleNotificationResponse, this));
275*cfb92d14SAndroid Build Coastguard Worker }
276*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
277*cfb92d14SAndroid Build Coastguard Worker }
278*cfb92d14SAndroid Build Coastguard Worker else
279*cfb92d14SAndroid Build Coastguard Worker {
280*cfb92d14SAndroid Build Coastguard Worker OutputLine("%s", mResourceContent);
281*cfb92d14SAndroid Build Coastguard Worker }
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker exit:
284*cfb92d14SAndroid Build Coastguard Worker
285*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
286*cfb92d14SAndroid Build Coastguard Worker if ((error != OT_ERROR_NONE) && (notificationMessage != nullptr))
287*cfb92d14SAndroid Build Coastguard Worker {
288*cfb92d14SAndroid Build Coastguard Worker otMessageFree(notificationMessage);
289*cfb92d14SAndroid Build Coastguard Worker }
290*cfb92d14SAndroid Build Coastguard Worker #endif
291*cfb92d14SAndroid Build Coastguard Worker
292*cfb92d14SAndroid Build Coastguard Worker return error;
293*cfb92d14SAndroid Build Coastguard Worker }
294*cfb92d14SAndroid Build Coastguard Worker
295*cfb92d14SAndroid Build Coastguard Worker /**
296*cfb92d14SAndroid Build Coastguard Worker * @cli coap start
297*cfb92d14SAndroid Build Coastguard Worker * @code
298*cfb92d14SAndroid Build Coastguard Worker * coap start
299*cfb92d14SAndroid Build Coastguard Worker * Done
300*cfb92d14SAndroid Build Coastguard Worker * @endcode
301*cfb92d14SAndroid Build Coastguard Worker * @par
302*cfb92d14SAndroid Build Coastguard Worker * Starts the CoAP server. @moreinfo{@coap}.
303*cfb92d14SAndroid Build Coastguard Worker * @sa otCoapStart
304*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])305*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("start")>(Arg aArgs[])
306*cfb92d14SAndroid Build Coastguard Worker {
307*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aArgs);
308*cfb92d14SAndroid Build Coastguard Worker
309*cfb92d14SAndroid Build Coastguard Worker return otCoapStart(GetInstancePtr(), OT_DEFAULT_COAP_PORT);
310*cfb92d14SAndroid Build Coastguard Worker }
311*cfb92d14SAndroid Build Coastguard Worker
312*cfb92d14SAndroid Build Coastguard Worker /**
313*cfb92d14SAndroid Build Coastguard Worker * @cli coap stop
314*cfb92d14SAndroid Build Coastguard Worker * @code
315*cfb92d14SAndroid Build Coastguard Worker * coap stop
316*cfb92d14SAndroid Build Coastguard Worker * Done
317*cfb92d14SAndroid Build Coastguard Worker * @endcode
318*cfb92d14SAndroid Build Coastguard Worker * @par api_copy
319*cfb92d14SAndroid Build Coastguard Worker * #otCoapStop
320*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])321*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("stop")>(Arg aArgs[])
322*cfb92d14SAndroid Build Coastguard Worker {
323*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aArgs);
324*cfb92d14SAndroid Build Coastguard Worker
325*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
326*cfb92d14SAndroid Build Coastguard Worker otCoapRemoveBlockWiseResource(GetInstancePtr(), &mResource);
327*cfb92d14SAndroid Build Coastguard Worker #else
328*cfb92d14SAndroid Build Coastguard Worker otCoapRemoveResource(GetInstancePtr(), &mResource);
329*cfb92d14SAndroid Build Coastguard Worker #endif
330*cfb92d14SAndroid Build Coastguard Worker
331*cfb92d14SAndroid Build Coastguard Worker return otCoapStop(GetInstancePtr());
332*cfb92d14SAndroid Build Coastguard Worker }
333*cfb92d14SAndroid Build Coastguard Worker
334*cfb92d14SAndroid Build Coastguard Worker /**
335*cfb92d14SAndroid Build Coastguard Worker * @cli coap parameters(get,set)
336*cfb92d14SAndroid Build Coastguard Worker * @code
337*cfb92d14SAndroid Build Coastguard Worker * coap parameters request
338*cfb92d14SAndroid Build Coastguard Worker * Transmission parameters for request:
339*cfb92d14SAndroid Build Coastguard Worker * ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
340*cfb92d14SAndroid Build Coastguard Worker * Done
341*cfb92d14SAndroid Build Coastguard Worker * @endcode
342*cfb92d14SAndroid Build Coastguard Worker * @code
343*cfb92d14SAndroid Build Coastguard Worker * coap parameters request default
344*cfb92d14SAndroid Build Coastguard Worker * Transmission parameters for request:
345*cfb92d14SAndroid Build Coastguard Worker * default
346*cfb92d14SAndroid Build Coastguard Worker * Done
347*cfb92d14SAndroid Build Coastguard Worker * @endcode
348*cfb92d14SAndroid Build Coastguard Worker * @code
349*cfb92d14SAndroid Build Coastguard Worker * coap parameters request 1000 255 254 2
350*cfb92d14SAndroid Build Coastguard Worker * Transmission parameters for request:
351*cfb92d14SAndroid Build Coastguard Worker * ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
352*cfb92d14SAndroid Build Coastguard Worker * Done
353*cfb92d14SAndroid Build Coastguard Worker * @endcode
354*cfb92d14SAndroid Build Coastguard Worker * @cparam coap parameters @ca{type} [@ca{default} | <!--
355*cfb92d14SAndroid Build Coastguard Worker * -->@ca{ack_timeout ack_random_factor_numerator <!--
356*cfb92d14SAndroid Build Coastguard Worker * -->ack_random_factor_denominator max_retransmit}]
357*cfb92d14SAndroid Build Coastguard Worker * * `type`: `request` for CoAP requests, or `response` for CoAP responses.
358*cfb92d14SAndroid Build Coastguard Worker If no more parameters are given, the command prints the current configuration.
359*cfb92d14SAndroid Build Coastguard Worker * * `default`: Sets the transmission parameters to
360*cfb92d14SAndroid Build Coastguard Worker the following default values:
361*cfb92d14SAndroid Build Coastguard Worker * * `ack_timeout`: 2000 milliseconds
362*cfb92d14SAndroid Build Coastguard Worker * * `ack_random_factor_numerator`: 3
363*cfb92d14SAndroid Build Coastguard Worker * * `ack_random_factor_denominator`: 2
364*cfb92d14SAndroid Build Coastguard Worker * * `max_retransmit`: 4
365*cfb92d14SAndroid Build Coastguard Worker * * `ack_timeout`: The `ACK_TIMEOUT` (0-UINT32_MAX) in milliseconds.
366*cfb92d14SAndroid Build Coastguard Worker Refer to RFC7252.
367*cfb92d14SAndroid Build Coastguard Worker * * `ack_random_factor_numerator`:
368*cfb92d14SAndroid Build Coastguard Worker The `ACK_RANDOM_FACTOR` numerator, with possible values
369*cfb92d14SAndroid Build Coastguard Worker of 0-255. Refer to RFC7252.
370*cfb92d14SAndroid Build Coastguard Worker * * `ack_random_factor_denominator`:
371*cfb92d14SAndroid Build Coastguard Worker * The `ACK_RANDOM_FACTOR` denominator, with possible values
372*cfb92d14SAndroid Build Coastguard Worker * of 0-255. Refer to RFC7252.
373*cfb92d14SAndroid Build Coastguard Worker * * `max_retransmit`: The `MAX_RETRANSMIT` (0-255). Refer to RFC7252.
374*cfb92d14SAndroid Build Coastguard Worker * @par
375*cfb92d14SAndroid Build Coastguard Worker * Gets current CoAP parameter values if the command is run with no optional
376*cfb92d14SAndroid Build Coastguard Worker * parameters.
377*cfb92d14SAndroid Build Coastguard Worker * @par
378*cfb92d14SAndroid Build Coastguard Worker * Sets the CoAP parameters either to their default values or to the values
379*cfb92d14SAndroid Build Coastguard Worker * you specify, depending on the syntax chosen.
380*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])381*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("parameters")>(Arg aArgs[])
382*cfb92d14SAndroid Build Coastguard Worker {
383*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
384*cfb92d14SAndroid Build Coastguard Worker bool *defaultTxParameters;
385*cfb92d14SAndroid Build Coastguard Worker otCoapTxParameters *txParameters;
386*cfb92d14SAndroid Build Coastguard Worker
387*cfb92d14SAndroid Build Coastguard Worker if (aArgs[0] == "request")
388*cfb92d14SAndroid Build Coastguard Worker {
389*cfb92d14SAndroid Build Coastguard Worker txParameters = &mRequestTxParameters;
390*cfb92d14SAndroid Build Coastguard Worker defaultTxParameters = &mUseDefaultRequestTxParameters;
391*cfb92d14SAndroid Build Coastguard Worker }
392*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[0] == "response")
393*cfb92d14SAndroid Build Coastguard Worker {
394*cfb92d14SAndroid Build Coastguard Worker txParameters = &mResponseTxParameters;
395*cfb92d14SAndroid Build Coastguard Worker defaultTxParameters = &mUseDefaultResponseTxParameters;
396*cfb92d14SAndroid Build Coastguard Worker }
397*cfb92d14SAndroid Build Coastguard Worker else
398*cfb92d14SAndroid Build Coastguard Worker {
399*cfb92d14SAndroid Build Coastguard Worker ExitNow(error = OT_ERROR_INVALID_ARGS);
400*cfb92d14SAndroid Build Coastguard Worker }
401*cfb92d14SAndroid Build Coastguard Worker
402*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[1].IsEmpty())
403*cfb92d14SAndroid Build Coastguard Worker {
404*cfb92d14SAndroid Build Coastguard Worker if (aArgs[1] == "default")
405*cfb92d14SAndroid Build Coastguard Worker {
406*cfb92d14SAndroid Build Coastguard Worker *defaultTxParameters = true;
407*cfb92d14SAndroid Build Coastguard Worker }
408*cfb92d14SAndroid Build Coastguard Worker else
409*cfb92d14SAndroid Build Coastguard Worker {
410*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[1].ParseAsUint32(txParameters->mAckTimeout));
411*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[2].ParseAsUint8(txParameters->mAckRandomFactorNumerator));
412*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[3].ParseAsUint8(txParameters->mAckRandomFactorDenominator));
413*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[4].ParseAsUint8(txParameters->mMaxRetransmit));
414*cfb92d14SAndroid Build Coastguard Worker
415*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(txParameters->mAckRandomFactorNumerator > txParameters->mAckRandomFactorDenominator,
416*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_INVALID_ARGS);
417*cfb92d14SAndroid Build Coastguard Worker
418*cfb92d14SAndroid Build Coastguard Worker *defaultTxParameters = false;
419*cfb92d14SAndroid Build Coastguard Worker }
420*cfb92d14SAndroid Build Coastguard Worker }
421*cfb92d14SAndroid Build Coastguard Worker
422*cfb92d14SAndroid Build Coastguard Worker OutputLine("Transmission parameters for %s:", aArgs[0].GetCString());
423*cfb92d14SAndroid Build Coastguard Worker
424*cfb92d14SAndroid Build Coastguard Worker if (*defaultTxParameters)
425*cfb92d14SAndroid Build Coastguard Worker {
426*cfb92d14SAndroid Build Coastguard Worker OutputLine("default");
427*cfb92d14SAndroid Build Coastguard Worker }
428*cfb92d14SAndroid Build Coastguard Worker else
429*cfb92d14SAndroid Build Coastguard Worker {
430*cfb92d14SAndroid Build Coastguard Worker OutputLine("ACK_TIMEOUT=%lu ms, ACK_RANDOM_FACTOR=%u/%u, MAX_RETRANSMIT=%u", ToUlong(txParameters->mAckTimeout),
431*cfb92d14SAndroid Build Coastguard Worker txParameters->mAckRandomFactorNumerator, txParameters->mAckRandomFactorDenominator,
432*cfb92d14SAndroid Build Coastguard Worker txParameters->mMaxRetransmit);
433*cfb92d14SAndroid Build Coastguard Worker }
434*cfb92d14SAndroid Build Coastguard Worker
435*cfb92d14SAndroid Build Coastguard Worker exit:
436*cfb92d14SAndroid Build Coastguard Worker return error;
437*cfb92d14SAndroid Build Coastguard Worker }
438*cfb92d14SAndroid Build Coastguard Worker
439*cfb92d14SAndroid Build Coastguard Worker /**
440*cfb92d14SAndroid Build Coastguard Worker * @cli coap get
441*cfb92d14SAndroid Build Coastguard Worker * @code
442*cfb92d14SAndroid Build Coastguard Worker * coap get fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
443*cfb92d14SAndroid Build Coastguard Worker * Done
444*cfb92d14SAndroid Build Coastguard Worker * @endcode
445*cfb92d14SAndroid Build Coastguard Worker * @code
446*cfb92d14SAndroid Build Coastguard Worker * coap get fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024
447*cfb92d14SAndroid Build Coastguard Worker * Done
448*cfb92d14SAndroid Build Coastguard Worker * @endcode
449*cfb92d14SAndroid Build Coastguard Worker * @cparam coap get @ca{address} @ca{uri-path} [@ca{type}]
450*cfb92d14SAndroid Build Coastguard Worker * * `address`: IPv6 address of the CoAP server.
451*cfb92d14SAndroid Build Coastguard Worker * * `uri-path`: URI path of the resource.
452*cfb92d14SAndroid Build Coastguard Worker * * `type`:
453*cfb92d14SAndroid Build Coastguard Worker * * `con`: Confirmable
454*cfb92d14SAndroid Build Coastguard Worker * * `non-con`: Non-confirmable (default)
455*cfb92d14SAndroid Build Coastguard Worker * * `block-`: Use this option, followed by the block-wise value,
456*cfb92d14SAndroid Build Coastguard Worker * if the response should be transferred block-wise. Valid
457*cfb92d14SAndroid Build Coastguard Worker * values are: `block-16`, `block-32`, `block-64`, `block-128`,
458*cfb92d14SAndroid Build Coastguard Worker * `block-256`, `block-512`, or `block-1024`.
459*cfb92d14SAndroid Build Coastguard Worker * @par
460*cfb92d14SAndroid Build Coastguard Worker * Gets information about the specified CoAP resource on the CoAP server.
461*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])462*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("get")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_GET); }
463*cfb92d14SAndroid Build Coastguard Worker
464*cfb92d14SAndroid Build Coastguard Worker /**
465*cfb92d14SAndroid Build Coastguard Worker * @cli coap post
466*cfb92d14SAndroid Build Coastguard Worker * @code
467*cfb92d14SAndroid Build Coastguard Worker * coap post fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
468*cfb92d14SAndroid Build Coastguard Worker * Done
469*cfb92d14SAndroid Build Coastguard Worker * @endcode
470*cfb92d14SAndroid Build Coastguard Worker * @code
471*cfb92d14SAndroid Build Coastguard Worker * coap post fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024 10
472*cfb92d14SAndroid Build Coastguard Worker * Done
473*cfb92d14SAndroid Build Coastguard Worker * @endcode
474*cfb92d14SAndroid Build Coastguard Worker * @cparam coap post @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
475*cfb92d14SAndroid Build Coastguard Worker * * `address`: IPv6 address of the CoAP server.
476*cfb92d14SAndroid Build Coastguard Worker * * `uri-path`: URI path of the resource.
477*cfb92d14SAndroid Build Coastguard Worker * * `type`:
478*cfb92d14SAndroid Build Coastguard Worker * * `con`: Confirmable
479*cfb92d14SAndroid Build Coastguard Worker * * `non-con`: Non-confirmable (default)
480*cfb92d14SAndroid Build Coastguard Worker * * `block-`: Use this option, followed by the block-wise value,
481*cfb92d14SAndroid Build Coastguard Worker * to send blocks with a randomly generated number of bytes
482*cfb92d14SAndroid Build Coastguard Worker * for the payload. Valid values are:
483*cfb92d14SAndroid Build Coastguard Worker * `block-16`, `block-32`, `block-64`, `block-128`,
484*cfb92d14SAndroid Build Coastguard Worker * `block-256`, `block-512`, or `block-1024`.
485*cfb92d14SAndroid Build Coastguard Worker * * `payload`: CoAP payload request, which if used is either a string or an
486*cfb92d14SAndroid Build Coastguard Worker * integer, depending on the `type`. If the `type` is `con` or `non-con`,
487*cfb92d14SAndroid Build Coastguard Worker * the `payload` parameter is optional. If you leave out the
488*cfb92d14SAndroid Build Coastguard Worker * `payload` parameter, an empty payload is sent. However, If you use the
489*cfb92d14SAndroid Build Coastguard Worker * `payload` parameter, its value must be a string, such as
490*cfb92d14SAndroid Build Coastguard Worker * `hellothere`. If the `type` is `block-`,
491*cfb92d14SAndroid Build Coastguard Worker * the value of the`payload` parameter must be an integer that specifies
492*cfb92d14SAndroid Build Coastguard Worker * the number of blocks to send. The `block-` type requires
493*cfb92d14SAndroid Build Coastguard Worker * `OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE` to be set.
494*cfb92d14SAndroid Build Coastguard Worker * @par
495*cfb92d14SAndroid Build Coastguard Worker * Creates the specified CoAP resource. @moreinfo{@coap}.
496*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])497*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("post")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_POST); }
498*cfb92d14SAndroid Build Coastguard Worker
499*cfb92d14SAndroid Build Coastguard Worker /**
500*cfb92d14SAndroid Build Coastguard Worker * @cli coap put
501*cfb92d14SAndroid Build Coastguard Worker * @code
502*cfb92d14SAndroid Build Coastguard Worker * coap put fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
503*cfb92d14SAndroid Build Coastguard Worker * Done
504*cfb92d14SAndroid Build Coastguard Worker * @endcode
505*cfb92d14SAndroid Build Coastguard Worker * @code
506*cfb92d14SAndroid Build Coastguard Worker * coap put fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024 10
507*cfb92d14SAndroid Build Coastguard Worker * Done
508*cfb92d14SAndroid Build Coastguard Worker * @endcode
509*cfb92d14SAndroid Build Coastguard Worker * @cparam coap put @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
510*cfb92d14SAndroid Build Coastguard Worker * * `address`: IPv6 address of the CoAP server.
511*cfb92d14SAndroid Build Coastguard Worker * * `uri-path`: URI path of the resource.
512*cfb92d14SAndroid Build Coastguard Worker * * `type`:
513*cfb92d14SAndroid Build Coastguard Worker * * `con`: Confirmable
514*cfb92d14SAndroid Build Coastguard Worker * * `non-con`: Non-confirmable (default)
515*cfb92d14SAndroid Build Coastguard Worker * * `block-`: Use this option, followed by the block-wise value,
516*cfb92d14SAndroid Build Coastguard Worker * to send blocks with a randomly generated number of bytes
517*cfb92d14SAndroid Build Coastguard Worker * for the payload. Valid values are:
518*cfb92d14SAndroid Build Coastguard Worker * `block-16`, `block-32`, `block-64`, `block-128`,
519*cfb92d14SAndroid Build Coastguard Worker * `block-256`, `block-512`, or `block-1024`.
520*cfb92d14SAndroid Build Coastguard Worker * * `payload`: CoAP payload request, which if used is either a string or an
521*cfb92d14SAndroid Build Coastguard Worker * integer, depending on the `type`. If the `type` is `con` or `non-con`,
522*cfb92d14SAndroid Build Coastguard Worker * the `payload` parameter is optional. If you leave out the
523*cfb92d14SAndroid Build Coastguard Worker * `payload` parameter, an empty payload is sent. However, If you use the
524*cfb92d14SAndroid Build Coastguard Worker * `payload` parameter, its value must be a string, such as
525*cfb92d14SAndroid Build Coastguard Worker * `hellothere`. If the `type` is `block-`,
526*cfb92d14SAndroid Build Coastguard Worker * the value of the`payload` parameter must be an integer that specifies
527*cfb92d14SAndroid Build Coastguard Worker * the number of blocks to send. The `block-` type requires
528*cfb92d14SAndroid Build Coastguard Worker * `OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE` to be set.
529*cfb92d14SAndroid Build Coastguard Worker * @par
530*cfb92d14SAndroid Build Coastguard Worker * Modifies the specified CoAP resource. @moreinfo{@coap}.
531*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])532*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("put")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_PUT); }
533*cfb92d14SAndroid Build Coastguard Worker
534*cfb92d14SAndroid Build Coastguard Worker /**
535*cfb92d14SAndroid Build Coastguard Worker * @cli coap delete
536*cfb92d14SAndroid Build Coastguard Worker * @code
537*cfb92d14SAndroid Build Coastguard Worker * coap delete fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
538*cfb92d14SAndroid Build Coastguard Worker * Done
539*cfb92d14SAndroid Build Coastguard Worker * @endcode
540*cfb92d14SAndroid Build Coastguard Worker * @cparam coap delete @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
541*cfb92d14SAndroid Build Coastguard Worker * * `address`: IPv6 address of the CoAP server.
542*cfb92d14SAndroid Build Coastguard Worker * * `uri-path`: URI path of the resource.
543*cfb92d14SAndroid Build Coastguard Worker * * `type`:
544*cfb92d14SAndroid Build Coastguard Worker * * `con`: Confirmable
545*cfb92d14SAndroid Build Coastguard Worker * * `non-con`: Non-confirmable (default)
546*cfb92d14SAndroid Build Coastguard Worker * * `payload`: The CoAP payload string. For example, `hellothere`.
547*cfb92d14SAndroid Build Coastguard Worker * @par
548*cfb92d14SAndroid Build Coastguard Worker * Deletes the specified CoAP resource.
549*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])550*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("delete")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_DELETE); }
551*cfb92d14SAndroid Build Coastguard Worker
552*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
553*cfb92d14SAndroid Build Coastguard Worker /**
554*cfb92d14SAndroid Build Coastguard Worker * @cli coap observe
555*cfb92d14SAndroid Build Coastguard Worker * @code
556*cfb92d14SAndroid Build Coastguard Worker * coap observe fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
557*cfb92d14SAndroid Build Coastguard Worker * Done
558*cfb92d14SAndroid Build Coastguard Worker * @endcode
559*cfb92d14SAndroid Build Coastguard Worker * @cparam coap observe @ca{address} @ca{uri-path} [@ca{type}]
560*cfb92d14SAndroid Build Coastguard Worker * * `address`: IPv6 address of the CoAP server.
561*cfb92d14SAndroid Build Coastguard Worker * * `uri-path`: URI path of the resource.
562*cfb92d14SAndroid Build Coastguard Worker * * `type`:
563*cfb92d14SAndroid Build Coastguard Worker * * `con`: Confirmable
564*cfb92d14SAndroid Build Coastguard Worker * * `non-con`: Non-confirmable (default).
565*cfb92d14SAndroid Build Coastguard Worker * @par
566*cfb92d14SAndroid Build Coastguard Worker * Triggers a subscription request which allows the CoAP client to
567*cfb92d14SAndroid Build Coastguard Worker * observe the specified resource on the CoAP server for possible changes
568*cfb92d14SAndroid Build Coastguard Worker * in its state.
569*cfb92d14SAndroid Build Coastguard Worker * @note This command is available only when `OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE` is set.
570*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])571*cfb92d14SAndroid Build Coastguard Worker template <> otError Coap::Process<Cmd("observe")>(Arg aArgs[])
572*cfb92d14SAndroid Build Coastguard Worker {
573*cfb92d14SAndroid Build Coastguard Worker return ProcessRequest(aArgs, OT_COAP_CODE_GET, /* aCoapObserve */ true);
574*cfb92d14SAndroid Build Coastguard Worker }
575*cfb92d14SAndroid Build Coastguard Worker #endif
576*cfb92d14SAndroid Build Coastguard Worker
577*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
ProcessRequest(Arg aArgs[],otCoapCode aCoapCode,bool aCoapObserve)578*cfb92d14SAndroid Build Coastguard Worker otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve)
579*cfb92d14SAndroid Build Coastguard Worker #else
580*cfb92d14SAndroid Build Coastguard Worker otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode)
581*cfb92d14SAndroid Build Coastguard Worker #endif
582*cfb92d14SAndroid Build Coastguard Worker {
583*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
584*cfb92d14SAndroid Build Coastguard Worker otMessage *message = nullptr;
585*cfb92d14SAndroid Build Coastguard Worker otMessageInfo messageInfo;
586*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadLength = 0;
587*cfb92d14SAndroid Build Coastguard Worker char *uriQueryStartPtr = nullptr;
588*cfb92d14SAndroid Build Coastguard Worker
589*cfb92d14SAndroid Build Coastguard Worker // Default parameters
590*cfb92d14SAndroid Build Coastguard Worker char coapUri[kMaxUriLength] = "test";
591*cfb92d14SAndroid Build Coastguard Worker otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
592*cfb92d14SAndroid Build Coastguard Worker otIp6Address coapDestinationIp;
593*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
594*cfb92d14SAndroid Build Coastguard Worker bool coapBlock = false;
595*cfb92d14SAndroid Build Coastguard Worker otCoapBlockSzx coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_16;
596*cfb92d14SAndroid Build Coastguard Worker BlockType coapBlockType = (aCoapCode == OT_COAP_CODE_GET) ? kBlockType2 : kBlockType1;
597*cfb92d14SAndroid Build Coastguard Worker #endif
598*cfb92d14SAndroid Build Coastguard Worker
599*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE && OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
600*cfb92d14SAndroid Build Coastguard Worker if (aCoapObserve)
601*cfb92d14SAndroid Build Coastguard Worker {
602*cfb92d14SAndroid Build Coastguard Worker coapBlockType = kBlockType1;
603*cfb92d14SAndroid Build Coastguard Worker }
604*cfb92d14SAndroid Build Coastguard Worker #endif
605*cfb92d14SAndroid Build Coastguard Worker
606*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[0].ParseAsIp6Address(coapDestinationIp));
607*cfb92d14SAndroid Build Coastguard Worker
608*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
609*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(aArgs[1].GetLength() < sizeof(coapUri), error = OT_ERROR_INVALID_ARGS);
610*cfb92d14SAndroid Build Coastguard Worker strcpy(coapUri, aArgs[1].GetCString());
611*cfb92d14SAndroid Build Coastguard Worker
612*cfb92d14SAndroid Build Coastguard Worker // CoAP-Type
613*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[2].IsEmpty())
614*cfb92d14SAndroid Build Coastguard Worker {
615*cfb92d14SAndroid Build Coastguard Worker if (aArgs[2] == "con")
616*cfb92d14SAndroid Build Coastguard Worker {
617*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
618*cfb92d14SAndroid Build Coastguard Worker }
619*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
620*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-16")
621*cfb92d14SAndroid Build Coastguard Worker {
622*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
623*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
624*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_16;
625*cfb92d14SAndroid Build Coastguard Worker }
626*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-32")
627*cfb92d14SAndroid Build Coastguard Worker {
628*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
629*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
630*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_32;
631*cfb92d14SAndroid Build Coastguard Worker }
632*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-64")
633*cfb92d14SAndroid Build Coastguard Worker {
634*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
635*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
636*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_64;
637*cfb92d14SAndroid Build Coastguard Worker }
638*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-128")
639*cfb92d14SAndroid Build Coastguard Worker {
640*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
641*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
642*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_128;
643*cfb92d14SAndroid Build Coastguard Worker }
644*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-256")
645*cfb92d14SAndroid Build Coastguard Worker {
646*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
647*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
648*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_256;
649*cfb92d14SAndroid Build Coastguard Worker }
650*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-512")
651*cfb92d14SAndroid Build Coastguard Worker {
652*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
653*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
654*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_512;
655*cfb92d14SAndroid Build Coastguard Worker }
656*cfb92d14SAndroid Build Coastguard Worker else if (aArgs[2] == "block-1024")
657*cfb92d14SAndroid Build Coastguard Worker {
658*cfb92d14SAndroid Build Coastguard Worker coapType = OT_COAP_TYPE_CONFIRMABLE;
659*cfb92d14SAndroid Build Coastguard Worker coapBlock = true;
660*cfb92d14SAndroid Build Coastguard Worker coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_1024;
661*cfb92d14SAndroid Build Coastguard Worker }
662*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
663*cfb92d14SAndroid Build Coastguard Worker }
664*cfb92d14SAndroid Build Coastguard Worker
665*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
666*cfb92d14SAndroid Build Coastguard Worker if (aCoapObserve && mRequestTokenLength)
667*cfb92d14SAndroid Build Coastguard Worker {
668*cfb92d14SAndroid Build Coastguard Worker // New observe request, cancel any existing observation
669*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = CancelResourceSubscription());
670*cfb92d14SAndroid Build Coastguard Worker }
671*cfb92d14SAndroid Build Coastguard Worker #endif
672*cfb92d14SAndroid Build Coastguard Worker
673*cfb92d14SAndroid Build Coastguard Worker message = otCoapNewMessage(GetInstancePtr(), nullptr);
674*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
675*cfb92d14SAndroid Build Coastguard Worker
676*cfb92d14SAndroid Build Coastguard Worker otCoapMessageInit(message, coapType, aCoapCode);
677*cfb92d14SAndroid Build Coastguard Worker otCoapMessageGenerateToken(message, OT_COAP_DEFAULT_TOKEN_LENGTH);
678*cfb92d14SAndroid Build Coastguard Worker
679*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
680*cfb92d14SAndroid Build Coastguard Worker if (aCoapObserve)
681*cfb92d14SAndroid Build Coastguard Worker {
682*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 0));
683*cfb92d14SAndroid Build Coastguard Worker }
684*cfb92d14SAndroid Build Coastguard Worker #endif
685*cfb92d14SAndroid Build Coastguard Worker
686*cfb92d14SAndroid Build Coastguard Worker uriQueryStartPtr = const_cast<char *>(StringFind(coapUri, '?'));
687*cfb92d14SAndroid Build Coastguard Worker
688*cfb92d14SAndroid Build Coastguard Worker if (uriQueryStartPtr == nullptr)
689*cfb92d14SAndroid Build Coastguard Worker {
690*cfb92d14SAndroid Build Coastguard Worker // "?" doesn't present in URI --> contains only URI path parts
691*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri));
692*cfb92d14SAndroid Build Coastguard Worker }
693*cfb92d14SAndroid Build Coastguard Worker else
694*cfb92d14SAndroid Build Coastguard Worker {
695*cfb92d14SAndroid Build Coastguard Worker // "?" presents in URI --> contains URI path AND URI query parts
696*cfb92d14SAndroid Build Coastguard Worker *uriQueryStartPtr++ = '\0';
697*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri));
698*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendUriQueryOptions(message, uriQueryStartPtr));
699*cfb92d14SAndroid Build Coastguard Worker }
700*cfb92d14SAndroid Build Coastguard Worker
701*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
702*cfb92d14SAndroid Build Coastguard Worker if (coapBlock)
703*cfb92d14SAndroid Build Coastguard Worker {
704*cfb92d14SAndroid Build Coastguard Worker if (coapBlockType == kBlockType1)
705*cfb92d14SAndroid Build Coastguard Worker {
706*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendBlock1Option(message, 0, true, coapBlockSize));
707*cfb92d14SAndroid Build Coastguard Worker }
708*cfb92d14SAndroid Build Coastguard Worker else
709*cfb92d14SAndroid Build Coastguard Worker {
710*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendBlock2Option(message, 0, false, coapBlockSize));
711*cfb92d14SAndroid Build Coastguard Worker }
712*cfb92d14SAndroid Build Coastguard Worker }
713*cfb92d14SAndroid Build Coastguard Worker #endif
714*cfb92d14SAndroid Build Coastguard Worker
715*cfb92d14SAndroid Build Coastguard Worker if (!aArgs[3].IsEmpty())
716*cfb92d14SAndroid Build Coastguard Worker {
717*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
718*cfb92d14SAndroid Build Coastguard Worker if (coapBlock)
719*cfb92d14SAndroid Build Coastguard Worker {
720*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = aArgs[3].ParseAsUint32(mBlockCount));
721*cfb92d14SAndroid Build Coastguard Worker }
722*cfb92d14SAndroid Build Coastguard Worker else
723*cfb92d14SAndroid Build Coastguard Worker {
724*cfb92d14SAndroid Build Coastguard Worker #endif
725*cfb92d14SAndroid Build Coastguard Worker payloadLength = aArgs[3].GetLength();
726*cfb92d14SAndroid Build Coastguard Worker
727*cfb92d14SAndroid Build Coastguard Worker if (payloadLength > 0)
728*cfb92d14SAndroid Build Coastguard Worker {
729*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetPayloadMarker(message));
730*cfb92d14SAndroid Build Coastguard Worker }
731*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
732*cfb92d14SAndroid Build Coastguard Worker }
733*cfb92d14SAndroid Build Coastguard Worker #endif
734*cfb92d14SAndroid Build Coastguard Worker }
735*cfb92d14SAndroid Build Coastguard Worker
736*cfb92d14SAndroid Build Coastguard Worker // Embed content into message if given
737*cfb92d14SAndroid Build Coastguard Worker if (payloadLength > 0)
738*cfb92d14SAndroid Build Coastguard Worker {
739*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otMessageAppend(message, aArgs[3].GetCString(), payloadLength));
740*cfb92d14SAndroid Build Coastguard Worker }
741*cfb92d14SAndroid Build Coastguard Worker
742*cfb92d14SAndroid Build Coastguard Worker ClearAllBytes(messageInfo);
743*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerAddr = coapDestinationIp;
744*cfb92d14SAndroid Build Coastguard Worker messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
745*cfb92d14SAndroid Build Coastguard Worker
746*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
747*cfb92d14SAndroid Build Coastguard Worker if (aCoapObserve)
748*cfb92d14SAndroid Build Coastguard Worker {
749*cfb92d14SAndroid Build Coastguard Worker // Make a note of the message details for later so we can cancel it later.
750*cfb92d14SAndroid Build Coastguard Worker memcpy(&mRequestAddr, &coapDestinationIp, sizeof(mRequestAddr));
751*cfb92d14SAndroid Build Coastguard Worker mRequestTokenLength = otCoapMessageGetTokenLength(message);
752*cfb92d14SAndroid Build Coastguard Worker memcpy(mRequestToken, otCoapMessageGetToken(message), mRequestTokenLength);
753*cfb92d14SAndroid Build Coastguard Worker // Use `memcpy` instead of `strncpy` here because GCC will give warnings for `strncpy` when the dest's length is
754*cfb92d14SAndroid Build Coastguard Worker // not bigger than the src's length.
755*cfb92d14SAndroid Build Coastguard Worker memcpy(mRequestUri, coapUri, sizeof(mRequestUri) - 1);
756*cfb92d14SAndroid Build Coastguard Worker }
757*cfb92d14SAndroid Build Coastguard Worker #endif
758*cfb92d14SAndroid Build Coastguard Worker
759*cfb92d14SAndroid Build Coastguard Worker if ((coapType == OT_COAP_TYPE_CONFIRMABLE) || (aCoapCode == OT_COAP_CODE_GET))
760*cfb92d14SAndroid Build Coastguard Worker {
761*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
762*cfb92d14SAndroid Build Coastguard Worker if (coapBlock)
763*cfb92d14SAndroid Build Coastguard Worker {
764*cfb92d14SAndroid Build Coastguard Worker if (aCoapCode == OT_COAP_CODE_PUT || aCoapCode == OT_COAP_CODE_POST)
765*cfb92d14SAndroid Build Coastguard Worker {
766*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetPayloadMarker(message));
767*cfb92d14SAndroid Build Coastguard Worker }
768*cfb92d14SAndroid Build Coastguard Worker error = otCoapSendRequestBlockWiseWithParameters(GetInstancePtr(), message, &messageInfo,
769*cfb92d14SAndroid Build Coastguard Worker &Coap::HandleResponse, this, GetRequestTxParameters(),
770*cfb92d14SAndroid Build Coastguard Worker Coap::BlockwiseTransmitHook, Coap::BlockwiseReceiveHook);
771*cfb92d14SAndroid Build Coastguard Worker }
772*cfb92d14SAndroid Build Coastguard Worker else
773*cfb92d14SAndroid Build Coastguard Worker {
774*cfb92d14SAndroid Build Coastguard Worker #endif
775*cfb92d14SAndroid Build Coastguard Worker error = otCoapSendRequestWithParameters(GetInstancePtr(), message, &messageInfo, &Coap::HandleResponse,
776*cfb92d14SAndroid Build Coastguard Worker this, GetRequestTxParameters());
777*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
778*cfb92d14SAndroid Build Coastguard Worker }
779*cfb92d14SAndroid Build Coastguard Worker #endif
780*cfb92d14SAndroid Build Coastguard Worker }
781*cfb92d14SAndroid Build Coastguard Worker else
782*cfb92d14SAndroid Build Coastguard Worker {
783*cfb92d14SAndroid Build Coastguard Worker error = otCoapSendRequestWithParameters(GetInstancePtr(), message, &messageInfo, nullptr, nullptr,
784*cfb92d14SAndroid Build Coastguard Worker GetResponseTxParameters());
785*cfb92d14SAndroid Build Coastguard Worker }
786*cfb92d14SAndroid Build Coastguard Worker
787*cfb92d14SAndroid Build Coastguard Worker exit:
788*cfb92d14SAndroid Build Coastguard Worker
789*cfb92d14SAndroid Build Coastguard Worker if ((error != OT_ERROR_NONE) && (message != nullptr))
790*cfb92d14SAndroid Build Coastguard Worker {
791*cfb92d14SAndroid Build Coastguard Worker otMessageFree(message);
792*cfb92d14SAndroid Build Coastguard Worker }
793*cfb92d14SAndroid Build Coastguard Worker
794*cfb92d14SAndroid Build Coastguard Worker return error;
795*cfb92d14SAndroid Build Coastguard Worker }
796*cfb92d14SAndroid Build Coastguard Worker
Process(Arg aArgs[])797*cfb92d14SAndroid Build Coastguard Worker otError Coap::Process(Arg aArgs[])
798*cfb92d14SAndroid Build Coastguard Worker {
799*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString) \
800*cfb92d14SAndroid Build Coastguard Worker { \
801*cfb92d14SAndroid Build Coastguard Worker aCommandString, &Coap::Process<Cmd(aCommandString)> \
802*cfb92d14SAndroid Build Coastguard Worker }
803*cfb92d14SAndroid Build Coastguard Worker
804*cfb92d14SAndroid Build Coastguard Worker static constexpr Command kCommands[] = {
805*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
806*cfb92d14SAndroid Build Coastguard Worker CmdEntry("cancel"),
807*cfb92d14SAndroid Build Coastguard Worker #endif
808*cfb92d14SAndroid Build Coastguard Worker CmdEntry("delete"),
809*cfb92d14SAndroid Build Coastguard Worker CmdEntry("get"),
810*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
811*cfb92d14SAndroid Build Coastguard Worker CmdEntry("observe"),
812*cfb92d14SAndroid Build Coastguard Worker #endif
813*cfb92d14SAndroid Build Coastguard Worker CmdEntry("parameters"),
814*cfb92d14SAndroid Build Coastguard Worker CmdEntry("post"),
815*cfb92d14SAndroid Build Coastguard Worker CmdEntry("put"),
816*cfb92d14SAndroid Build Coastguard Worker CmdEntry("resource"),
817*cfb92d14SAndroid Build Coastguard Worker CmdEntry("set"),
818*cfb92d14SAndroid Build Coastguard Worker CmdEntry("start"),
819*cfb92d14SAndroid Build Coastguard Worker CmdEntry("stop"),
820*cfb92d14SAndroid Build Coastguard Worker };
821*cfb92d14SAndroid Build Coastguard Worker
822*cfb92d14SAndroid Build Coastguard Worker #undef CmdEntry
823*cfb92d14SAndroid Build Coastguard Worker
824*cfb92d14SAndroid Build Coastguard Worker static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
825*cfb92d14SAndroid Build Coastguard Worker
826*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_INVALID_COMMAND;
827*cfb92d14SAndroid Build Coastguard Worker const Command *command;
828*cfb92d14SAndroid Build Coastguard Worker
829*cfb92d14SAndroid Build Coastguard Worker if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
830*cfb92d14SAndroid Build Coastguard Worker {
831*cfb92d14SAndroid Build Coastguard Worker OutputCommandTable(kCommands);
832*cfb92d14SAndroid Build Coastguard Worker ExitNow(error = aArgs[0].IsEmpty() ? OT_ERROR_INVALID_ARGS : OT_ERROR_NONE);
833*cfb92d14SAndroid Build Coastguard Worker }
834*cfb92d14SAndroid Build Coastguard Worker
835*cfb92d14SAndroid Build Coastguard Worker command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
836*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(command != nullptr);
837*cfb92d14SAndroid Build Coastguard Worker
838*cfb92d14SAndroid Build Coastguard Worker error = (this->*command->mHandler)(aArgs + 1);
839*cfb92d14SAndroid Build Coastguard Worker
840*cfb92d14SAndroid Build Coastguard Worker exit:
841*cfb92d14SAndroid Build Coastguard Worker return error;
842*cfb92d14SAndroid Build Coastguard Worker }
843*cfb92d14SAndroid Build Coastguard Worker
HandleRequest(void * aContext,otMessage * aMessage,const otMessageInfo * aMessageInfo)844*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
845*cfb92d14SAndroid Build Coastguard Worker {
846*cfb92d14SAndroid Build Coastguard Worker static_cast<Coap *>(aContext)->HandleRequest(aMessage, aMessageInfo);
847*cfb92d14SAndroid Build Coastguard Worker }
848*cfb92d14SAndroid Build Coastguard Worker
HandleRequest(otMessage * aMessage,const otMessageInfo * aMessageInfo)849*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo)
850*cfb92d14SAndroid Build Coastguard Worker {
851*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
852*cfb92d14SAndroid Build Coastguard Worker otMessage *responseMessage = nullptr;
853*cfb92d14SAndroid Build Coastguard Worker otCoapCode responseCode = OT_COAP_CODE_EMPTY;
854*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
855*cfb92d14SAndroid Build Coastguard Worker uint64_t observe = 0;
856*cfb92d14SAndroid Build Coastguard Worker bool observePresent = false;
857*cfb92d14SAndroid Build Coastguard Worker #endif
858*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
859*cfb92d14SAndroid Build Coastguard Worker uint64_t blockValue = 0;
860*cfb92d14SAndroid Build Coastguard Worker bool blockPresent = false;
861*cfb92d14SAndroid Build Coastguard Worker #endif
862*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE || OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
863*cfb92d14SAndroid Build Coastguard Worker otCoapOptionIterator iterator;
864*cfb92d14SAndroid Build Coastguard Worker #endif
865*cfb92d14SAndroid Build Coastguard Worker
866*cfb92d14SAndroid Build Coastguard Worker OutputFormat("coap request from ");
867*cfb92d14SAndroid Build Coastguard Worker OutputIp6Address(aMessageInfo->mPeerAddr);
868*cfb92d14SAndroid Build Coastguard Worker OutputFormat(" ");
869*cfb92d14SAndroid Build Coastguard Worker
870*cfb92d14SAndroid Build Coastguard Worker switch (otCoapMessageGetCode(aMessage))
871*cfb92d14SAndroid Build Coastguard Worker {
872*cfb92d14SAndroid Build Coastguard Worker case OT_COAP_CODE_GET:
873*cfb92d14SAndroid Build Coastguard Worker OutputFormat("GET");
874*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE || OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
875*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapOptionIteratorInit(&iterator, aMessage));
876*cfb92d14SAndroid Build Coastguard Worker #endif
877*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
878*cfb92d14SAndroid Build Coastguard Worker if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE) != nullptr)
879*cfb92d14SAndroid Build Coastguard Worker {
880*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapOptionIteratorGetOptionUintValue(&iterator, &observe));
881*cfb92d14SAndroid Build Coastguard Worker observePresent = true;
882*cfb92d14SAndroid Build Coastguard Worker
883*cfb92d14SAndroid Build Coastguard Worker OutputFormat(" OBS=");
884*cfb92d14SAndroid Build Coastguard Worker OutputUint64(observe);
885*cfb92d14SAndroid Build Coastguard Worker }
886*cfb92d14SAndroid Build Coastguard Worker #endif
887*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
888*cfb92d14SAndroid Build Coastguard Worker if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_BLOCK2) != nullptr)
889*cfb92d14SAndroid Build Coastguard Worker {
890*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapOptionIteratorGetOptionUintValue(&iterator, &blockValue));
891*cfb92d14SAndroid Build Coastguard Worker blockPresent = true;
892*cfb92d14SAndroid Build Coastguard Worker }
893*cfb92d14SAndroid Build Coastguard Worker #endif
894*cfb92d14SAndroid Build Coastguard Worker break;
895*cfb92d14SAndroid Build Coastguard Worker
896*cfb92d14SAndroid Build Coastguard Worker case OT_COAP_CODE_DELETE:
897*cfb92d14SAndroid Build Coastguard Worker OutputFormat("DELETE");
898*cfb92d14SAndroid Build Coastguard Worker break;
899*cfb92d14SAndroid Build Coastguard Worker
900*cfb92d14SAndroid Build Coastguard Worker case OT_COAP_CODE_PUT:
901*cfb92d14SAndroid Build Coastguard Worker OutputFormat("PUT");
902*cfb92d14SAndroid Build Coastguard Worker break;
903*cfb92d14SAndroid Build Coastguard Worker
904*cfb92d14SAndroid Build Coastguard Worker case OT_COAP_CODE_POST:
905*cfb92d14SAndroid Build Coastguard Worker OutputFormat("POST");
906*cfb92d14SAndroid Build Coastguard Worker break;
907*cfb92d14SAndroid Build Coastguard Worker
908*cfb92d14SAndroid Build Coastguard Worker default:
909*cfb92d14SAndroid Build Coastguard Worker OutputLine("Undefined");
910*cfb92d14SAndroid Build Coastguard Worker ExitNow(error = OT_ERROR_PARSE);
911*cfb92d14SAndroid Build Coastguard Worker }
912*cfb92d14SAndroid Build Coastguard Worker
913*cfb92d14SAndroid Build Coastguard Worker PrintPayload(aMessage);
914*cfb92d14SAndroid Build Coastguard Worker
915*cfb92d14SAndroid Build Coastguard Worker if (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE ||
916*cfb92d14SAndroid Build Coastguard Worker otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
917*cfb92d14SAndroid Build Coastguard Worker {
918*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
919*cfb92d14SAndroid Build Coastguard Worker if (observePresent && (mSubscriberTokenLength > 0) && (observe == 0))
920*cfb92d14SAndroid Build Coastguard Worker {
921*cfb92d14SAndroid Build Coastguard Worker // There is already a subscriber
922*cfb92d14SAndroid Build Coastguard Worker responseCode = OT_COAP_CODE_SERVICE_UNAVAILABLE;
923*cfb92d14SAndroid Build Coastguard Worker }
924*cfb92d14SAndroid Build Coastguard Worker else
925*cfb92d14SAndroid Build Coastguard Worker #endif
926*cfb92d14SAndroid Build Coastguard Worker if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
927*cfb92d14SAndroid Build Coastguard Worker {
928*cfb92d14SAndroid Build Coastguard Worker responseCode = OT_COAP_CODE_CONTENT;
929*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
930*cfb92d14SAndroid Build Coastguard Worker if (observePresent)
931*cfb92d14SAndroid Build Coastguard Worker {
932*cfb92d14SAndroid Build Coastguard Worker if (observe == 0)
933*cfb92d14SAndroid Build Coastguard Worker {
934*cfb92d14SAndroid Build Coastguard Worker // New subscriber
935*cfb92d14SAndroid Build Coastguard Worker OutputLine("Subscribing client");
936*cfb92d14SAndroid Build Coastguard Worker mSubscriberSock.mAddress = aMessageInfo->mPeerAddr;
937*cfb92d14SAndroid Build Coastguard Worker mSubscriberSock.mPort = aMessageInfo->mPeerPort;
938*cfb92d14SAndroid Build Coastguard Worker mSubscriberTokenLength = otCoapMessageGetTokenLength(aMessage);
939*cfb92d14SAndroid Build Coastguard Worker memcpy(mSubscriberToken, otCoapMessageGetToken(aMessage), mSubscriberTokenLength);
940*cfb92d14SAndroid Build Coastguard Worker
941*cfb92d14SAndroid Build Coastguard Worker /*
942*cfb92d14SAndroid Build Coastguard Worker * Implementer note.
943*cfb92d14SAndroid Build Coastguard Worker *
944*cfb92d14SAndroid Build Coastguard Worker * Here, we try to match a confirmable GET request with confirmable
945*cfb92d14SAndroid Build Coastguard Worker * notifications, however this is not a requirement of RFC7641:
946*cfb92d14SAndroid Build Coastguard Worker * the server can send notifications of either type regardless of
947*cfb92d14SAndroid Build Coastguard Worker * what the client used to subscribe initially.
948*cfb92d14SAndroid Build Coastguard Worker */
949*cfb92d14SAndroid Build Coastguard Worker mSubscriberConfirmableNotifications = (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE);
950*cfb92d14SAndroid Build Coastguard Worker }
951*cfb92d14SAndroid Build Coastguard Worker else if (observe == 1)
952*cfb92d14SAndroid Build Coastguard Worker {
953*cfb92d14SAndroid Build Coastguard Worker // See if it matches our subscriber token
954*cfb92d14SAndroid Build Coastguard Worker if ((otCoapMessageGetTokenLength(aMessage) == mSubscriberTokenLength) &&
955*cfb92d14SAndroid Build Coastguard Worker (memcmp(otCoapMessageGetToken(aMessage), mSubscriberToken, mSubscriberTokenLength) == 0))
956*cfb92d14SAndroid Build Coastguard Worker {
957*cfb92d14SAndroid Build Coastguard Worker // Unsubscribe request
958*cfb92d14SAndroid Build Coastguard Worker CancelSubscriber();
959*cfb92d14SAndroid Build Coastguard Worker }
960*cfb92d14SAndroid Build Coastguard Worker }
961*cfb92d14SAndroid Build Coastguard Worker }
962*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
963*cfb92d14SAndroid Build Coastguard Worker }
964*cfb92d14SAndroid Build Coastguard Worker else
965*cfb92d14SAndroid Build Coastguard Worker {
966*cfb92d14SAndroid Build Coastguard Worker responseCode = OT_COAP_CODE_CHANGED;
967*cfb92d14SAndroid Build Coastguard Worker }
968*cfb92d14SAndroid Build Coastguard Worker
969*cfb92d14SAndroid Build Coastguard Worker responseMessage = otCoapNewMessage(GetInstancePtr(), nullptr);
970*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(responseMessage != nullptr, error = OT_ERROR_NO_BUFS);
971*cfb92d14SAndroid Build Coastguard Worker
972*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(
973*cfb92d14SAndroid Build Coastguard Worker error = otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode));
974*cfb92d14SAndroid Build Coastguard Worker
975*cfb92d14SAndroid Build Coastguard Worker if (responseCode == OT_COAP_CODE_CONTENT)
976*cfb92d14SAndroid Build Coastguard Worker {
977*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
978*cfb92d14SAndroid Build Coastguard Worker if (observePresent && (observe == 0))
979*cfb92d14SAndroid Build Coastguard Worker {
980*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendObserveOption(responseMessage, mObserveSerial++));
981*cfb92d14SAndroid Build Coastguard Worker }
982*cfb92d14SAndroid Build Coastguard Worker #endif
983*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
984*cfb92d14SAndroid Build Coastguard Worker if (blockPresent)
985*cfb92d14SAndroid Build Coastguard Worker {
986*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageAppendBlock2Option(responseMessage,
987*cfb92d14SAndroid Build Coastguard Worker static_cast<uint32_t>(blockValue >> 4), true,
988*cfb92d14SAndroid Build Coastguard Worker static_cast<otCoapBlockSzx>(blockValue & 0x7)));
989*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetPayloadMarker(responseMessage));
990*cfb92d14SAndroid Build Coastguard Worker }
991*cfb92d14SAndroid Build Coastguard Worker else
992*cfb92d14SAndroid Build Coastguard Worker {
993*cfb92d14SAndroid Build Coastguard Worker #endif
994*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapMessageSetPayloadMarker(responseMessage));
995*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otMessageAppend(responseMessage, mResourceContent,
996*cfb92d14SAndroid Build Coastguard Worker static_cast<uint16_t>(strlen(mResourceContent))));
997*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
998*cfb92d14SAndroid Build Coastguard Worker }
999*cfb92d14SAndroid Build Coastguard Worker #endif
1000*cfb92d14SAndroid Build Coastguard Worker }
1001*cfb92d14SAndroid Build Coastguard Worker
1002*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
1003*cfb92d14SAndroid Build Coastguard Worker if (blockPresent)
1004*cfb92d14SAndroid Build Coastguard Worker {
1005*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapSendResponseBlockWiseWithParameters(GetInstancePtr(), responseMessage,
1006*cfb92d14SAndroid Build Coastguard Worker aMessageInfo, GetResponseTxParameters(),
1007*cfb92d14SAndroid Build Coastguard Worker this, mResource.mTransmitHook));
1008*cfb92d14SAndroid Build Coastguard Worker }
1009*cfb92d14SAndroid Build Coastguard Worker else
1010*cfb92d14SAndroid Build Coastguard Worker {
1011*cfb92d14SAndroid Build Coastguard Worker #endif
1012*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otCoapSendResponseWithParameters(GetInstancePtr(), responseMessage, aMessageInfo,
1013*cfb92d14SAndroid Build Coastguard Worker GetResponseTxParameters()));
1014*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
1015*cfb92d14SAndroid Build Coastguard Worker }
1016*cfb92d14SAndroid Build Coastguard Worker #endif
1017*cfb92d14SAndroid Build Coastguard Worker }
1018*cfb92d14SAndroid Build Coastguard Worker
1019*cfb92d14SAndroid Build Coastguard Worker exit:
1020*cfb92d14SAndroid Build Coastguard Worker
1021*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
1022*cfb92d14SAndroid Build Coastguard Worker {
1023*cfb92d14SAndroid Build Coastguard Worker if (responseMessage != nullptr)
1024*cfb92d14SAndroid Build Coastguard Worker {
1025*cfb92d14SAndroid Build Coastguard Worker OutputLine("coap send response error %d: %s", error, otThreadErrorToString(error));
1026*cfb92d14SAndroid Build Coastguard Worker otMessageFree(responseMessage);
1027*cfb92d14SAndroid Build Coastguard Worker }
1028*cfb92d14SAndroid Build Coastguard Worker }
1029*cfb92d14SAndroid Build Coastguard Worker else if (responseCode >= OT_COAP_CODE_RESPONSE_MIN)
1030*cfb92d14SAndroid Build Coastguard Worker {
1031*cfb92d14SAndroid Build Coastguard Worker OutputLine("coap response sent");
1032*cfb92d14SAndroid Build Coastguard Worker }
1033*cfb92d14SAndroid Build Coastguard Worker }
1034*cfb92d14SAndroid Build Coastguard Worker
1035*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
HandleNotificationResponse(void * aContext,otMessage * aMessage,const otMessageInfo * aMessageInfo,otError aError)1036*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleNotificationResponse(void *aContext,
1037*cfb92d14SAndroid Build Coastguard Worker otMessage *aMessage,
1038*cfb92d14SAndroid Build Coastguard Worker const otMessageInfo *aMessageInfo,
1039*cfb92d14SAndroid Build Coastguard Worker otError aError)
1040*cfb92d14SAndroid Build Coastguard Worker {
1041*cfb92d14SAndroid Build Coastguard Worker static_cast<Coap *>(aContext)->HandleNotificationResponse(aMessage, aMessageInfo, aError);
1042*cfb92d14SAndroid Build Coastguard Worker }
1043*cfb92d14SAndroid Build Coastguard Worker
HandleNotificationResponse(otMessage * aMessage,const otMessageInfo * aMessageInfo,otError aError)1044*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleNotificationResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
1045*cfb92d14SAndroid Build Coastguard Worker {
1046*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aMessage);
1047*cfb92d14SAndroid Build Coastguard Worker
1048*cfb92d14SAndroid Build Coastguard Worker switch (aError)
1049*cfb92d14SAndroid Build Coastguard Worker {
1050*cfb92d14SAndroid Build Coastguard Worker case OT_ERROR_NONE:
1051*cfb92d14SAndroid Build Coastguard Worker if (aMessageInfo != nullptr)
1052*cfb92d14SAndroid Build Coastguard Worker {
1053*cfb92d14SAndroid Build Coastguard Worker OutputFormat("Received ACK in reply to notification from ");
1054*cfb92d14SAndroid Build Coastguard Worker OutputIp6AddressLine(aMessageInfo->mPeerAddr);
1055*cfb92d14SAndroid Build Coastguard Worker }
1056*cfb92d14SAndroid Build Coastguard Worker break;
1057*cfb92d14SAndroid Build Coastguard Worker
1058*cfb92d14SAndroid Build Coastguard Worker default:
1059*cfb92d14SAndroid Build Coastguard Worker OutputLine("coap receive notification response error %d: %s", aError, otThreadErrorToString(aError));
1060*cfb92d14SAndroid Build Coastguard Worker CancelSubscriber();
1061*cfb92d14SAndroid Build Coastguard Worker break;
1062*cfb92d14SAndroid Build Coastguard Worker }
1063*cfb92d14SAndroid Build Coastguard Worker }
1064*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
1065*cfb92d14SAndroid Build Coastguard Worker
HandleResponse(void * aContext,otMessage * aMessage,const otMessageInfo * aMessageInfo,otError aError)1066*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
1067*cfb92d14SAndroid Build Coastguard Worker {
1068*cfb92d14SAndroid Build Coastguard Worker static_cast<Coap *>(aContext)->HandleResponse(aMessage, aMessageInfo, aError);
1069*cfb92d14SAndroid Build Coastguard Worker }
1070*cfb92d14SAndroid Build Coastguard Worker
HandleResponse(otMessage * aMessage,const otMessageInfo * aMessageInfo,otError aError)1071*cfb92d14SAndroid Build Coastguard Worker void Coap::HandleResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
1072*cfb92d14SAndroid Build Coastguard Worker {
1073*cfb92d14SAndroid Build Coastguard Worker if (aError != OT_ERROR_NONE)
1074*cfb92d14SAndroid Build Coastguard Worker {
1075*cfb92d14SAndroid Build Coastguard Worker OutputLine("coap receive response error %d: %s", aError, otThreadErrorToString(aError));
1076*cfb92d14SAndroid Build Coastguard Worker }
1077*cfb92d14SAndroid Build Coastguard Worker else if ((aMessageInfo != nullptr) && (aMessage != nullptr))
1078*cfb92d14SAndroid Build Coastguard Worker {
1079*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
1080*cfb92d14SAndroid Build Coastguard Worker otCoapOptionIterator iterator;
1081*cfb92d14SAndroid Build Coastguard Worker #endif
1082*cfb92d14SAndroid Build Coastguard Worker
1083*cfb92d14SAndroid Build Coastguard Worker OutputFormat("coap response from ");
1084*cfb92d14SAndroid Build Coastguard Worker OutputIp6Address(aMessageInfo->mPeerAddr);
1085*cfb92d14SAndroid Build Coastguard Worker
1086*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
1087*cfb92d14SAndroid Build Coastguard Worker if (otCoapOptionIteratorInit(&iterator, aMessage) == OT_ERROR_NONE)
1088*cfb92d14SAndroid Build Coastguard Worker {
1089*cfb92d14SAndroid Build Coastguard Worker const otCoapOption *observeOpt =
1090*cfb92d14SAndroid Build Coastguard Worker otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE);
1091*cfb92d14SAndroid Build Coastguard Worker
1092*cfb92d14SAndroid Build Coastguard Worker if (observeOpt != nullptr)
1093*cfb92d14SAndroid Build Coastguard Worker {
1094*cfb92d14SAndroid Build Coastguard Worker uint64_t observeVal = 0;
1095*cfb92d14SAndroid Build Coastguard Worker otError error = otCoapOptionIteratorGetOptionUintValue(&iterator, &observeVal);
1096*cfb92d14SAndroid Build Coastguard Worker
1097*cfb92d14SAndroid Build Coastguard Worker if (error == OT_ERROR_NONE)
1098*cfb92d14SAndroid Build Coastguard Worker {
1099*cfb92d14SAndroid Build Coastguard Worker OutputFormat(" OBS=");
1100*cfb92d14SAndroid Build Coastguard Worker OutputUint64(observeVal);
1101*cfb92d14SAndroid Build Coastguard Worker }
1102*cfb92d14SAndroid Build Coastguard Worker }
1103*cfb92d14SAndroid Build Coastguard Worker }
1104*cfb92d14SAndroid Build Coastguard Worker #endif
1105*cfb92d14SAndroid Build Coastguard Worker PrintPayload(aMessage);
1106*cfb92d14SAndroid Build Coastguard Worker }
1107*cfb92d14SAndroid Build Coastguard Worker }
1108*cfb92d14SAndroid Build Coastguard Worker
1109*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
BlockwiseReceiveHook(void * aContext,const uint8_t * aBlock,uint32_t aPosition,uint16_t aBlockLength,bool aMore,uint32_t aTotalLength)1110*cfb92d14SAndroid Build Coastguard Worker otError Coap::BlockwiseReceiveHook(void *aContext,
1111*cfb92d14SAndroid Build Coastguard Worker const uint8_t *aBlock,
1112*cfb92d14SAndroid Build Coastguard Worker uint32_t aPosition,
1113*cfb92d14SAndroid Build Coastguard Worker uint16_t aBlockLength,
1114*cfb92d14SAndroid Build Coastguard Worker bool aMore,
1115*cfb92d14SAndroid Build Coastguard Worker uint32_t aTotalLength)
1116*cfb92d14SAndroid Build Coastguard Worker {
1117*cfb92d14SAndroid Build Coastguard Worker return static_cast<Coap *>(aContext)->BlockwiseReceiveHook(aBlock, aPosition, aBlockLength, aMore, aTotalLength);
1118*cfb92d14SAndroid Build Coastguard Worker }
1119*cfb92d14SAndroid Build Coastguard Worker
BlockwiseReceiveHook(const uint8_t * aBlock,uint32_t aPosition,uint16_t aBlockLength,bool aMore,uint32_t aTotalLength)1120*cfb92d14SAndroid Build Coastguard Worker otError Coap::BlockwiseReceiveHook(const uint8_t *aBlock,
1121*cfb92d14SAndroid Build Coastguard Worker uint32_t aPosition,
1122*cfb92d14SAndroid Build Coastguard Worker uint16_t aBlockLength,
1123*cfb92d14SAndroid Build Coastguard Worker bool aMore,
1124*cfb92d14SAndroid Build Coastguard Worker uint32_t aTotalLength)
1125*cfb92d14SAndroid Build Coastguard Worker {
1126*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aMore);
1127*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aTotalLength);
1128*cfb92d14SAndroid Build Coastguard Worker
1129*cfb92d14SAndroid Build Coastguard Worker OutputLine("received block: Num %i Len %i", aPosition / aBlockLength, aBlockLength);
1130*cfb92d14SAndroid Build Coastguard Worker
1131*cfb92d14SAndroid Build Coastguard Worker for (uint16_t i = 0; i < aBlockLength / 16; i++)
1132*cfb92d14SAndroid Build Coastguard Worker {
1133*cfb92d14SAndroid Build Coastguard Worker OutputBytesLine(&aBlock[i * 16], 16);
1134*cfb92d14SAndroid Build Coastguard Worker }
1135*cfb92d14SAndroid Build Coastguard Worker
1136*cfb92d14SAndroid Build Coastguard Worker return OT_ERROR_NONE;
1137*cfb92d14SAndroid Build Coastguard Worker }
1138*cfb92d14SAndroid Build Coastguard Worker
BlockwiseTransmitHook(void * aContext,uint8_t * aBlock,uint32_t aPosition,uint16_t * aBlockLength,bool * aMore)1139*cfb92d14SAndroid Build Coastguard Worker otError Coap::BlockwiseTransmitHook(void *aContext,
1140*cfb92d14SAndroid Build Coastguard Worker uint8_t *aBlock,
1141*cfb92d14SAndroid Build Coastguard Worker uint32_t aPosition,
1142*cfb92d14SAndroid Build Coastguard Worker uint16_t *aBlockLength,
1143*cfb92d14SAndroid Build Coastguard Worker bool *aMore)
1144*cfb92d14SAndroid Build Coastguard Worker {
1145*cfb92d14SAndroid Build Coastguard Worker return static_cast<Coap *>(aContext)->BlockwiseTransmitHook(aBlock, aPosition, aBlockLength, aMore);
1146*cfb92d14SAndroid Build Coastguard Worker }
1147*cfb92d14SAndroid Build Coastguard Worker
BlockwiseTransmitHook(uint8_t * aBlock,uint32_t aPosition,uint16_t * aBlockLength,bool * aMore)1148*cfb92d14SAndroid Build Coastguard Worker otError Coap::BlockwiseTransmitHook(uint8_t *aBlock, uint32_t aPosition, uint16_t *aBlockLength, bool *aMore)
1149*cfb92d14SAndroid Build Coastguard Worker {
1150*cfb92d14SAndroid Build Coastguard Worker static uint32_t blockCount = 0;
1151*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aPosition);
1152*cfb92d14SAndroid Build Coastguard Worker
1153*cfb92d14SAndroid Build Coastguard Worker // Send a random payload
1154*cfb92d14SAndroid Build Coastguard Worker otRandomNonCryptoFillBuffer(aBlock, *aBlockLength);
1155*cfb92d14SAndroid Build Coastguard Worker
1156*cfb92d14SAndroid Build Coastguard Worker OutputLine("send block: Num %i Len %i", blockCount, *aBlockLength);
1157*cfb92d14SAndroid Build Coastguard Worker
1158*cfb92d14SAndroid Build Coastguard Worker for (uint16_t i = 0; i < *aBlockLength / 16; i++)
1159*cfb92d14SAndroid Build Coastguard Worker {
1160*cfb92d14SAndroid Build Coastguard Worker OutputBytesLine(&aBlock[i * 16], 16);
1161*cfb92d14SAndroid Build Coastguard Worker }
1162*cfb92d14SAndroid Build Coastguard Worker
1163*cfb92d14SAndroid Build Coastguard Worker if (blockCount == mBlockCount - 1)
1164*cfb92d14SAndroid Build Coastguard Worker {
1165*cfb92d14SAndroid Build Coastguard Worker blockCount = 0;
1166*cfb92d14SAndroid Build Coastguard Worker *aMore = false;
1167*cfb92d14SAndroid Build Coastguard Worker }
1168*cfb92d14SAndroid Build Coastguard Worker else
1169*cfb92d14SAndroid Build Coastguard Worker {
1170*cfb92d14SAndroid Build Coastguard Worker *aMore = true;
1171*cfb92d14SAndroid Build Coastguard Worker blockCount++;
1172*cfb92d14SAndroid Build Coastguard Worker }
1173*cfb92d14SAndroid Build Coastguard Worker
1174*cfb92d14SAndroid Build Coastguard Worker return OT_ERROR_NONE;
1175*cfb92d14SAndroid Build Coastguard Worker }
1176*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
1177*cfb92d14SAndroid Build Coastguard Worker
1178*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
1179*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
1180*cfb92d14SAndroid Build Coastguard Worker
1181*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
1182