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/as_core_type.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 return AsCoreType(aInstance).GetApplicationCoap().NewMessage(Message::Settings::From(aSettings));
49 }
50
otCoapMessageInit(otMessage * aMessage,otCoapType aType,otCoapCode aCode)51 void otCoapMessageInit(otMessage *aMessage, otCoapType aType, otCoapCode aCode)
52 {
53 AsCoapMessage(aMessage).Init(MapEnum(aType), MapEnum(aCode));
54 }
55
otCoapMessageInitResponse(otMessage * aResponse,const otMessage * aRequest,otCoapType aType,otCoapCode aCode)56 otError otCoapMessageInitResponse(otMessage *aResponse, const otMessage *aRequest, otCoapType aType, otCoapCode aCode)
57 {
58 Coap::Message & response = AsCoapMessage(aResponse);
59 const Coap::Message &request = AsCoapMessage(aRequest);
60
61 response.Init(MapEnum(aType), MapEnum(aCode));
62 response.SetMessageId(request.GetMessageId());
63
64 return response.SetTokenFromMessage(request);
65 }
66
otCoapMessageSetToken(otMessage * aMessage,const uint8_t * aToken,uint8_t aTokenLength)67 otError otCoapMessageSetToken(otMessage *aMessage, const uint8_t *aToken, uint8_t aTokenLength)
68 {
69 return AsCoapMessage(aMessage).SetToken(aToken, aTokenLength);
70 }
71
otCoapMessageGenerateToken(otMessage * aMessage,uint8_t aTokenLength)72 void otCoapMessageGenerateToken(otMessage *aMessage, uint8_t aTokenLength)
73 {
74 IgnoreError(AsCoapMessage(aMessage).GenerateRandomToken(aTokenLength));
75 }
76
otCoapMessageAppendContentFormatOption(otMessage * aMessage,otCoapOptionContentFormat aContentFormat)77 otError otCoapMessageAppendContentFormatOption(otMessage *aMessage, otCoapOptionContentFormat aContentFormat)
78 {
79 return AsCoapMessage(aMessage).AppendContentFormatOption(aContentFormat);
80 }
81
otCoapMessageAppendOption(otMessage * aMessage,uint16_t aNumber,uint16_t aLength,const void * aValue)82 otError otCoapMessageAppendOption(otMessage *aMessage, uint16_t aNumber, uint16_t aLength, const void *aValue)
83 {
84 return AsCoapMessage(aMessage).AppendOption(aNumber, aLength, aValue);
85 }
86
otCoapMessageAppendUintOption(otMessage * aMessage,uint16_t aNumber,uint32_t aValue)87 otError otCoapMessageAppendUintOption(otMessage *aMessage, uint16_t aNumber, uint32_t aValue)
88 {
89 return AsCoapMessage(aMessage).AppendUintOption(aNumber, aValue);
90 }
91
otCoapMessageAppendObserveOption(otMessage * aMessage,uint32_t aObserve)92 otError otCoapMessageAppendObserveOption(otMessage *aMessage, uint32_t aObserve)
93 {
94 return AsCoapMessage(aMessage).AppendObserveOption(aObserve);
95 }
96
otCoapMessageAppendUriPathOptions(otMessage * aMessage,const char * aUriPath)97 otError otCoapMessageAppendUriPathOptions(otMessage *aMessage, const char *aUriPath)
98 {
99 return AsCoapMessage(aMessage).AppendUriPathOptions(aUriPath);
100 }
101
otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)102 uint16_t otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)
103 {
104 return static_cast<uint16_t>(1 << (static_cast<uint8_t>(aSize) + Coap::Message::kBlockSzxBase));
105 }
106
otCoapMessageAppendBlock2Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)107 otError otCoapMessageAppendBlock2Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
108 {
109 return AsCoapMessage(aMessage).AppendBlockOption(Coap::Message::kBlockType2, aNum, aMore, aSize);
110 }
111
otCoapMessageAppendBlock1Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)112 otError otCoapMessageAppendBlock1Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
113 {
114 return AsCoapMessage(aMessage).AppendBlockOption(Coap::Message::kBlockType1, aNum, aMore, aSize);
115 }
116
otCoapMessageAppendProxyUriOption(otMessage * aMessage,const char * aUriPath)117 otError otCoapMessageAppendProxyUriOption(otMessage *aMessage, const char *aUriPath)
118 {
119 return AsCoapMessage(aMessage).AppendProxyUriOption(aUriPath);
120 }
121
otCoapMessageAppendMaxAgeOption(otMessage * aMessage,uint32_t aMaxAge)122 otError otCoapMessageAppendMaxAgeOption(otMessage *aMessage, uint32_t aMaxAge)
123 {
124 return AsCoapMessage(aMessage).AppendMaxAgeOption(aMaxAge);
125 }
126
otCoapMessageAppendUriQueryOption(otMessage * aMessage,const char * aUriQuery)127 otError otCoapMessageAppendUriQueryOption(otMessage *aMessage, const char *aUriQuery)
128 {
129 return AsCoapMessage(aMessage).AppendUriQueryOption(aUriQuery);
130 }
131
otCoapMessageSetPayloadMarker(otMessage * aMessage)132 otError otCoapMessageSetPayloadMarker(otMessage *aMessage)
133 {
134 return AsCoapMessage(aMessage).SetPayloadMarker();
135 }
136
otCoapMessageGetType(const otMessage * aMessage)137 otCoapType otCoapMessageGetType(const otMessage *aMessage)
138 {
139 return static_cast<otCoapType>(AsCoapMessage(aMessage).GetType());
140 }
141
otCoapMessageGetCode(const otMessage * aMessage)142 otCoapCode otCoapMessageGetCode(const otMessage *aMessage)
143 {
144 return static_cast<otCoapCode>(AsCoapMessage(aMessage).GetCode());
145 }
146
otCoapMessageSetCode(otMessage * aMessage,otCoapCode aCode)147 void otCoapMessageSetCode(otMessage *aMessage, otCoapCode aCode)
148 {
149 AsCoapMessage(aMessage).SetCode(MapEnum(aCode));
150 }
151
otCoapMessageCodeToString(const otMessage * aMessage)152 const char *otCoapMessageCodeToString(const otMessage *aMessage)
153 {
154 return AsCoapMessage(aMessage).CodeToString();
155 }
156
otCoapMessageGetMessageId(const otMessage * aMessage)157 uint16_t otCoapMessageGetMessageId(const otMessage *aMessage)
158 {
159 return AsCoapMessage(aMessage).GetMessageId();
160 }
161
otCoapMessageGetTokenLength(const otMessage * aMessage)162 uint8_t otCoapMessageGetTokenLength(const otMessage *aMessage)
163 {
164 return AsCoapMessage(aMessage).GetTokenLength();
165 }
166
otCoapMessageGetToken(const otMessage * aMessage)167 const uint8_t *otCoapMessageGetToken(const otMessage *aMessage)
168 {
169 return AsCoapMessage(aMessage).GetToken();
170 }
171
otCoapOptionIteratorInit(otCoapOptionIterator * aIterator,const otMessage * aMessage)172 otError otCoapOptionIteratorInit(otCoapOptionIterator *aIterator, const otMessage *aMessage)
173 {
174 return AsCoreType(aIterator).Init(AsCoapMessage(aMessage));
175 }
176
otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)177 const otCoapOption *otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
178 {
179 Coap::Option::Iterator &iterator = AsCoreType(aIterator);
180
181 IgnoreError(iterator.Init(iterator.GetMessage(), aOption));
182 return iterator.GetOption();
183 }
184
otCoapOptionIteratorGetFirstOption(otCoapOptionIterator * aIterator)185 const otCoapOption *otCoapOptionIteratorGetFirstOption(otCoapOptionIterator *aIterator)
186 {
187 Coap::Option::Iterator &iterator = AsCoreType(aIterator);
188
189 IgnoreError(iterator.Init(iterator.GetMessage()));
190 return iterator.GetOption();
191 }
192
otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)193 const otCoapOption *otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
194 {
195 Coap::Option::Iterator &iterator = AsCoreType(aIterator);
196
197 IgnoreError(iterator.Advance(aOption));
198 return iterator.GetOption();
199 }
200
otCoapOptionIteratorGetNextOption(otCoapOptionIterator * aIterator)201 const otCoapOption *otCoapOptionIteratorGetNextOption(otCoapOptionIterator *aIterator)
202 {
203 Coap::Option::Iterator &iterator = AsCoreType(aIterator);
204
205 IgnoreError(iterator.Advance());
206 return iterator.GetOption();
207 }
208
otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator * aIterator,uint64_t * aValue)209 otError otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator *aIterator, uint64_t *aValue)
210 {
211 return AsCoreType(aIterator).ReadOptionValue(*aValue);
212 }
213
otCoapOptionIteratorGetOptionValue(otCoapOptionIterator * aIterator,void * aValue)214 otError otCoapOptionIteratorGetOptionValue(otCoapOptionIterator *aIterator, void *aValue)
215 {
216 return AsCoreType(aIterator).ReadOptionValue(aValue);
217 }
218
219 #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)220 otError otCoapSendRequestBlockWiseWithParameters(otInstance * aInstance,
221 otMessage * aMessage,
222 const otMessageInfo * aMessageInfo,
223 otCoapResponseHandler aHandler,
224 void * aContext,
225 const otCoapTxParameters * aTxParameters,
226 otCoapBlockwiseTransmitHook aTransmitHook,
227 otCoapBlockwiseReceiveHook aReceiveHook)
228 {
229 Error error;
230 const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
231
232 if (aTxParameters != nullptr)
233 {
234 VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
235 }
236
237 error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
238 txParameters, aHandler, aContext, aTransmitHook,
239 aReceiveHook);
240
241 exit:
242 return error;
243 }
244 #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
245
otCoapSendRequestWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,otCoapResponseHandler aHandler,void * aContext,const otCoapTxParameters * aTxParameters)246 otError otCoapSendRequestWithParameters(otInstance * aInstance,
247 otMessage * aMessage,
248 const otMessageInfo * aMessageInfo,
249 otCoapResponseHandler aHandler,
250 void * aContext,
251 const otCoapTxParameters *aTxParameters)
252 {
253 Error error;
254
255 const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
256
257 if (aTxParameters != nullptr)
258 {
259 VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
260 }
261
262 error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
263 txParameters, aHandler, aContext);
264
265 exit:
266 return error;
267 }
268
otCoapStart(otInstance * aInstance,uint16_t aPort)269 otError otCoapStart(otInstance *aInstance, uint16_t aPort)
270 {
271 return AsCoreType(aInstance).GetApplicationCoap().Start(aPort);
272 }
273
otCoapStop(otInstance * aInstance)274 otError otCoapStop(otInstance *aInstance)
275 {
276 return AsCoreType(aInstance).GetApplicationCoap().Stop();
277 }
278
279 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapAddBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)280 void otCoapAddBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
281 {
282 AsCoreType(aInstance).GetApplicationCoap().AddBlockWiseResource(AsCoreType(aResource));
283 }
284
otCoapRemoveBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)285 void otCoapRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
286 {
287 AsCoreType(aInstance).GetApplicationCoap().RemoveBlockWiseResource(AsCoreType(aResource));
288 }
289 #endif
290
otCoapAddResource(otInstance * aInstance,otCoapResource * aResource)291 void otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
292 {
293 AsCoreType(aInstance).GetApplicationCoap().AddResource(AsCoreType(aResource));
294 }
295
otCoapRemoveResource(otInstance * aInstance,otCoapResource * aResource)296 void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
297 {
298 AsCoreType(aInstance).GetApplicationCoap().RemoveResource(AsCoreType(aResource));
299 }
300
otCoapSetDefaultHandler(otInstance * aInstance,otCoapRequestHandler aHandler,void * aContext)301 void otCoapSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
302 {
303 AsCoreType(aInstance).GetApplicationCoap().SetDefaultHandler(aHandler, aContext);
304 }
305
306 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSendResponseBlockWiseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters,void * aContext,otCoapBlockwiseTransmitHook aTransmitHook)307 otError otCoapSendResponseBlockWiseWithParameters(otInstance * aInstance,
308 otMessage * aMessage,
309 const otMessageInfo * aMessageInfo,
310 const otCoapTxParameters * aTxParameters,
311 void * aContext,
312 otCoapBlockwiseTransmitHook aTransmitHook)
313 {
314 return AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
315 Coap::TxParameters::From(aTxParameters), nullptr,
316 aContext, aTransmitHook, nullptr);
317 }
318 #endif
319
otCoapSendResponseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters)320 otError otCoapSendResponseWithParameters(otInstance * aInstance,
321 otMessage * aMessage,
322 const otMessageInfo * aMessageInfo,
323 const otCoapTxParameters *aTxParameters)
324 {
325 return AsCoreType(aInstance).GetApplicationCoap().SendMessage(
326 AsCoapMessage(aMessage), AsCoreType(aMessageInfo), Coap::TxParameters::From(aTxParameters), nullptr, nullptr);
327 }
328
329 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
330