1 /*
2 * Copyright (c) 2016, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file implements the OpenThread CoAP API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
37
38 #include <openthread/coap.h>
39
40 #include "coap/coap_message.hpp"
41 #include "common/instance.hpp"
42 #include "common/locator_getters.hpp"
43
44 using namespace ot;
45
otCoapNewMessage(otInstance * aInstance,const otMessageSettings * aSettings)46 otMessage *otCoapNewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
47 {
48 Instance &instance = *static_cast<Instance *>(aInstance);
49
50 return instance.GetApplicationCoap().NewMessage(Message::Settings(aSettings));
51 }
52
otCoapMessageInit(otMessage * aMessage,otCoapType aType,otCoapCode aCode)53 void otCoapMessageInit(otMessage *aMessage, otCoapType aType, otCoapCode aCode)
54 {
55 static_cast<Coap::Message *>(aMessage)->Init(static_cast<Coap::Type>(aType), static_cast<Coap::Code>(aCode));
56 }
57
otCoapMessageInitResponse(otMessage * aResponse,const otMessage * aRequest,otCoapType aType,otCoapCode aCode)58 otError otCoapMessageInitResponse(otMessage *aResponse, const otMessage *aRequest, otCoapType aType, otCoapCode aCode)
59 {
60 Coap::Message & response = *static_cast<Coap::Message *>(aResponse);
61 const Coap::Message &request = *static_cast<const Coap::Message *>(aRequest);
62
63 response.Init(static_cast<Coap::Type>(aType), static_cast<Coap::Code>(aCode));
64 response.SetMessageId(request.GetMessageId());
65
66 return response.SetTokenFromMessage(request);
67 }
68
otCoapMessageSetToken(otMessage * aMessage,const uint8_t * aToken,uint8_t aTokenLength)69 otError otCoapMessageSetToken(otMessage *aMessage, const uint8_t *aToken, uint8_t aTokenLength)
70 {
71 return static_cast<Coap::Message *>(aMessage)->SetToken(aToken, aTokenLength);
72 }
73
otCoapMessageGenerateToken(otMessage * aMessage,uint8_t aTokenLength)74 void otCoapMessageGenerateToken(otMessage *aMessage, uint8_t aTokenLength)
75 {
76 IgnoreError(static_cast<Coap::Message *>(aMessage)->GenerateRandomToken(aTokenLength));
77 }
78
otCoapMessageAppendContentFormatOption(otMessage * aMessage,otCoapOptionContentFormat aContentFormat)79 otError otCoapMessageAppendContentFormatOption(otMessage *aMessage, otCoapOptionContentFormat aContentFormat)
80 {
81 return static_cast<Coap::Message *>(aMessage)->AppendContentFormatOption(aContentFormat);
82 }
83
otCoapMessageAppendOption(otMessage * aMessage,uint16_t aNumber,uint16_t aLength,const void * aValue)84 otError otCoapMessageAppendOption(otMessage *aMessage, uint16_t aNumber, uint16_t aLength, const void *aValue)
85 {
86 return static_cast<Coap::Message *>(aMessage)->AppendOption(aNumber, aLength, aValue);
87 }
88
otCoapMessageAppendUintOption(otMessage * aMessage,uint16_t aNumber,uint32_t aValue)89 otError otCoapMessageAppendUintOption(otMessage *aMessage, uint16_t aNumber, uint32_t aValue)
90 {
91 return static_cast<Coap::Message *>(aMessage)->AppendUintOption(aNumber, aValue);
92 }
93
otCoapMessageAppendObserveOption(otMessage * aMessage,uint32_t aObserve)94 otError otCoapMessageAppendObserveOption(otMessage *aMessage, uint32_t aObserve)
95 {
96 return static_cast<Coap::Message *>(aMessage)->AppendObserveOption(aObserve);
97 }
98
otCoapMessageAppendUriPathOptions(otMessage * aMessage,const char * aUriPath)99 otError otCoapMessageAppendUriPathOptions(otMessage *aMessage, const char *aUriPath)
100 {
101 return static_cast<Coap::Message *>(aMessage)->AppendUriPathOptions(aUriPath);
102 }
103
otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)104 uint16_t otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)
105 {
106 return static_cast<uint16_t>(1 << (static_cast<uint8_t>(aSize) + Coap::Message::kBlockSzxBase));
107 }
108
otCoapMessageAppendBlock2Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)109 otError otCoapMessageAppendBlock2Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
110 {
111 return static_cast<Coap::Message *>(aMessage)->AppendBlockOption(Coap::Message::kBlockType2, aNum, aMore, aSize);
112 }
113
otCoapMessageAppendBlock1Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)114 otError otCoapMessageAppendBlock1Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
115 {
116 return static_cast<Coap::Message *>(aMessage)->AppendBlockOption(Coap::Message::kBlockType1, aNum, aMore, aSize);
117 }
118
otCoapMessageAppendProxyUriOption(otMessage * aMessage,const char * aUriPath)119 otError otCoapMessageAppendProxyUriOption(otMessage *aMessage, const char *aUriPath)
120 {
121 return static_cast<Coap::Message *>(aMessage)->AppendProxyUriOption(aUriPath);
122 }
123
otCoapMessageAppendMaxAgeOption(otMessage * aMessage,uint32_t aMaxAge)124 otError otCoapMessageAppendMaxAgeOption(otMessage *aMessage, uint32_t aMaxAge)
125 {
126 return static_cast<Coap::Message *>(aMessage)->AppendMaxAgeOption(aMaxAge);
127 }
128
otCoapMessageAppendUriQueryOption(otMessage * aMessage,const char * aUriQuery)129 otError otCoapMessageAppendUriQueryOption(otMessage *aMessage, const char *aUriQuery)
130 {
131 return static_cast<Coap::Message *>(aMessage)->AppendUriQueryOption(aUriQuery);
132 }
133
otCoapMessageSetPayloadMarker(otMessage * aMessage)134 otError otCoapMessageSetPayloadMarker(otMessage *aMessage)
135 {
136 return static_cast<Coap::Message *>(aMessage)->SetPayloadMarker();
137 }
138
otCoapMessageGetType(const otMessage * aMessage)139 otCoapType otCoapMessageGetType(const otMessage *aMessage)
140 {
141 return static_cast<otCoapType>(static_cast<const Coap::Message *>(aMessage)->GetType());
142 }
143
otCoapMessageGetCode(const otMessage * aMessage)144 otCoapCode otCoapMessageGetCode(const otMessage *aMessage)
145 {
146 return static_cast<otCoapCode>(static_cast<const Coap::Message *>(aMessage)->GetCode());
147 }
148
otCoapMessageCodeToString(const otMessage * aMessage)149 const char *otCoapMessageCodeToString(const otMessage *aMessage)
150 {
151 return static_cast<const Coap::Message *>(aMessage)->CodeToString();
152 }
153
otCoapMessageGetMessageId(const otMessage * aMessage)154 uint16_t otCoapMessageGetMessageId(const otMessage *aMessage)
155 {
156 return static_cast<const Coap::Message *>(aMessage)->GetMessageId();
157 }
158
otCoapMessageGetTokenLength(const otMessage * aMessage)159 uint8_t otCoapMessageGetTokenLength(const otMessage *aMessage)
160 {
161 return static_cast<const Coap::Message *>(aMessage)->GetTokenLength();
162 }
163
otCoapMessageGetToken(const otMessage * aMessage)164 const uint8_t *otCoapMessageGetToken(const otMessage *aMessage)
165 {
166 return static_cast<const Coap::Message *>(aMessage)->GetToken();
167 }
168
otCoapOptionIteratorInit(otCoapOptionIterator * aIterator,const otMessage * aMessage)169 otError otCoapOptionIteratorInit(otCoapOptionIterator *aIterator, const otMessage *aMessage)
170 {
171 return static_cast<Coap::Option::Iterator *>(aIterator)->Init(*static_cast<const Coap::Message *>(aMessage));
172 }
173
otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)174 const otCoapOption *otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
175 {
176 Coap::Option::Iterator &iterator = *static_cast<Coap::Option::Iterator *>(aIterator);
177
178 IgnoreError(iterator.Init(iterator.GetMessage(), aOption));
179 return iterator.GetOption();
180 }
181
otCoapOptionIteratorGetFirstOption(otCoapOptionIterator * aIterator)182 const otCoapOption *otCoapOptionIteratorGetFirstOption(otCoapOptionIterator *aIterator)
183 {
184 Coap::Option::Iterator &iterator = *static_cast<Coap::Option::Iterator *>(aIterator);
185
186 IgnoreError(iterator.Init(iterator.GetMessage()));
187 return iterator.GetOption();
188 }
189
otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)190 const otCoapOption *otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
191 {
192 Coap::Option::Iterator &iterator = *static_cast<Coap::Option::Iterator *>(aIterator);
193
194 IgnoreError(iterator.Advance(aOption));
195 return iterator.GetOption();
196 }
197
otCoapOptionIteratorGetNextOption(otCoapOptionIterator * aIterator)198 const otCoapOption *otCoapOptionIteratorGetNextOption(otCoapOptionIterator *aIterator)
199 {
200 Coap::Option::Iterator &iterator = *static_cast<Coap::Option::Iterator *>(aIterator);
201
202 IgnoreError(iterator.Advance());
203 return iterator.GetOption();
204 }
205
otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator * aIterator,uint64_t * aValue)206 otError otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator *aIterator, uint64_t *aValue)
207 {
208 return static_cast<Coap::Option::Iterator *>(aIterator)->ReadOptionValue(*aValue);
209 }
210
otCoapOptionIteratorGetOptionValue(otCoapOptionIterator * aIterator,void * aValue)211 otError otCoapOptionIteratorGetOptionValue(otCoapOptionIterator *aIterator, void *aValue)
212 {
213 return static_cast<Coap::Option::Iterator *>(aIterator)->ReadOptionValue(aValue);
214 }
215
216 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSendRequestBlockWiseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,otCoapResponseHandler aHandler,void * aContext,const otCoapTxParameters * aTxParameters,otCoapBlockwiseTransmitHook aTransmitHook,otCoapBlockwiseReceiveHook aReceiveHook)217 otError otCoapSendRequestBlockWiseWithParameters(otInstance * aInstance,
218 otMessage * aMessage,
219 const otMessageInfo * aMessageInfo,
220 otCoapResponseHandler aHandler,
221 void * aContext,
222 const otCoapTxParameters * aTxParameters,
223 otCoapBlockwiseTransmitHook aTransmitHook,
224 otCoapBlockwiseReceiveHook aReceiveHook)
225 {
226 Error error;
227 Instance & instance = *static_cast<Instance *>(aInstance);
228 const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
229
230 if (aTxParameters != nullptr)
231 {
232 VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
233 }
234
235 error = instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
236 *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
237 txParameters, aHandler, aContext, aTransmitHook, aReceiveHook);
238
239 exit:
240 return error;
241 }
242 #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
243
otCoapSendRequestWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,otCoapResponseHandler aHandler,void * aContext,const otCoapTxParameters * aTxParameters)244 otError otCoapSendRequestWithParameters(otInstance * aInstance,
245 otMessage * aMessage,
246 const otMessageInfo * aMessageInfo,
247 otCoapResponseHandler aHandler,
248 void * aContext,
249 const otCoapTxParameters *aTxParameters)
250 {
251 Error error;
252 Instance & instance = *static_cast<Instance *>(aInstance);
253 const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
254
255 if (aTxParameters != nullptr)
256 {
257 VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
258 }
259
260 error = instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
261 *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
262 txParameters, aHandler, aContext);
263
264 exit:
265 return error;
266 }
267
otCoapStart(otInstance * aInstance,uint16_t aPort)268 otError otCoapStart(otInstance *aInstance, uint16_t aPort)
269 {
270 Instance &instance = *static_cast<Instance *>(aInstance);
271
272 return instance.GetApplicationCoap().Start(aPort);
273 }
274
otCoapStop(otInstance * aInstance)275 otError otCoapStop(otInstance *aInstance)
276 {
277 Instance &instance = *static_cast<Instance *>(aInstance);
278
279 return instance.GetApplicationCoap().Stop();
280 }
281
282 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapAddBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)283 void otCoapAddBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
284 {
285 Instance &instance = *static_cast<Instance *>(aInstance);
286
287 instance.GetApplicationCoap().AddBlockWiseResource(*static_cast<Coap::ResourceBlockWise *>(aResource));
288 }
289
otCoapRemoveBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)290 void otCoapRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
291 {
292 Instance &instance = *static_cast<Instance *>(aInstance);
293
294 instance.GetApplicationCoap().RemoveBlockWiseResource(*static_cast<Coap::ResourceBlockWise *>(aResource));
295 }
296 #endif
297
otCoapAddResource(otInstance * aInstance,otCoapResource * aResource)298 void otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
299 {
300 Instance &instance = *static_cast<Instance *>(aInstance);
301
302 instance.GetApplicationCoap().AddResource(*static_cast<Coap::Resource *>(aResource));
303 }
304
otCoapRemoveResource(otInstance * aInstance,otCoapResource * aResource)305 void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
306 {
307 Instance &instance = *static_cast<Instance *>(aInstance);
308
309 instance.GetApplicationCoap().RemoveResource(*static_cast<Coap::Resource *>(aResource));
310 }
311
otCoapSetDefaultHandler(otInstance * aInstance,otCoapRequestHandler aHandler,void * aContext)312 void otCoapSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
313 {
314 Instance &instance = *static_cast<Instance *>(aInstance);
315
316 instance.GetApplicationCoap().SetDefaultHandler(aHandler, aContext);
317 }
318
319 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSendResponseBlockWiseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters,void * aContext,otCoapBlockwiseTransmitHook aTransmitHook)320 otError otCoapSendResponseBlockWiseWithParameters(otInstance * aInstance,
321 otMessage * aMessage,
322 const otMessageInfo * aMessageInfo,
323 const otCoapTxParameters * aTxParameters,
324 void * aContext,
325 otCoapBlockwiseTransmitHook aTransmitHook)
326 {
327 Instance &instance = *static_cast<Instance *>(aInstance);
328
329 return instance.GetApplicationCoap().SendMessage(
330 *static_cast<Coap::Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
331 Coap::TxParameters::From(aTxParameters), nullptr, aContext, aTransmitHook, nullptr);
332 }
333 #endif
334
otCoapSendResponseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters)335 otError otCoapSendResponseWithParameters(otInstance * aInstance,
336 otMessage * aMessage,
337 const otMessageInfo * aMessageInfo,
338 const otCoapTxParameters *aTxParameters)
339 {
340 Instance &instance = *static_cast<Instance *>(aInstance);
341
342 return instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
343 *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
344 Coap::TxParameters::From(aTxParameters), nullptr, nullptr);
345 }
346
347 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
348