xref: /aosp_15_r20/external/openthread/src/core/api/coap_api.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
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 
otCoapMessageAppendUriQueryOptions(otMessage * aMessage,const char * aUriQuery)102 otError otCoapMessageAppendUriQueryOptions(otMessage *aMessage, const char *aUriQuery)
103 {
104     return AsCoapMessage(aMessage).AppendUriQueryOptions(aUriQuery);
105 }
106 
otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)107 uint16_t otCoapBlockSizeFromExponent(otCoapBlockSzx aSize)
108 {
109     return static_cast<uint16_t>(1 << (static_cast<uint8_t>(aSize) + Coap::Message::kBlockSzxBase));
110 }
111 
otCoapMessageAppendBlock2Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)112 otError otCoapMessageAppendBlock2Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
113 {
114     return AsCoapMessage(aMessage).AppendBlockOption(Coap::Message::kBlockType2, aNum, aMore, aSize);
115 }
116 
otCoapMessageAppendBlock1Option(otMessage * aMessage,uint32_t aNum,bool aMore,otCoapBlockSzx aSize)117 otError otCoapMessageAppendBlock1Option(otMessage *aMessage, uint32_t aNum, bool aMore, otCoapBlockSzx aSize)
118 {
119     return AsCoapMessage(aMessage).AppendBlockOption(Coap::Message::kBlockType1, aNum, aMore, aSize);
120 }
121 
otCoapMessageAppendProxyUriOption(otMessage * aMessage,const char * aUriPath)122 otError otCoapMessageAppendProxyUriOption(otMessage *aMessage, const char *aUriPath)
123 {
124     return AsCoapMessage(aMessage).AppendProxyUriOption(aUriPath);
125 }
126 
otCoapMessageAppendMaxAgeOption(otMessage * aMessage,uint32_t aMaxAge)127 otError otCoapMessageAppendMaxAgeOption(otMessage *aMessage, uint32_t aMaxAge)
128 {
129     return AsCoapMessage(aMessage).AppendMaxAgeOption(aMaxAge);
130 }
131 
otCoapMessageAppendUriQueryOption(otMessage * aMessage,const char * aUriQuery)132 otError otCoapMessageAppendUriQueryOption(otMessage *aMessage, const char *aUriQuery)
133 {
134     return AsCoapMessage(aMessage).AppendUriQueryOption(aUriQuery);
135 }
136 
otCoapMessageSetPayloadMarker(otMessage * aMessage)137 otError otCoapMessageSetPayloadMarker(otMessage *aMessage) { return AsCoapMessage(aMessage).SetPayloadMarker(); }
138 
otCoapMessageGetType(const otMessage * aMessage)139 otCoapType otCoapMessageGetType(const otMessage *aMessage)
140 {
141     return static_cast<otCoapType>(AsCoapMessage(aMessage).GetType());
142 }
143 
otCoapMessageGetCode(const otMessage * aMessage)144 otCoapCode otCoapMessageGetCode(const otMessage *aMessage)
145 {
146     return static_cast<otCoapCode>(AsCoapMessage(aMessage).GetCode());
147 }
148 
otCoapMessageSetCode(otMessage * aMessage,otCoapCode aCode)149 void otCoapMessageSetCode(otMessage *aMessage, otCoapCode aCode) { AsCoapMessage(aMessage).SetCode(MapEnum(aCode)); }
150 
otCoapMessageCodeToString(const otMessage * aMessage)151 const char *otCoapMessageCodeToString(const otMessage *aMessage) { return AsCoapMessage(aMessage).CodeToString(); }
152 
otCoapMessageGetMessageId(const otMessage * aMessage)153 uint16_t otCoapMessageGetMessageId(const otMessage *aMessage) { return AsCoapMessage(aMessage).GetMessageId(); }
154 
otCoapMessageGetTokenLength(const otMessage * aMessage)155 uint8_t otCoapMessageGetTokenLength(const otMessage *aMessage) { return AsCoapMessage(aMessage).GetTokenLength(); }
156 
otCoapMessageGetToken(const otMessage * aMessage)157 const uint8_t *otCoapMessageGetToken(const otMessage *aMessage) { return AsCoapMessage(aMessage).GetToken(); }
158 
otCoapOptionIteratorInit(otCoapOptionIterator * aIterator,const otMessage * aMessage)159 otError otCoapOptionIteratorInit(otCoapOptionIterator *aIterator, const otMessage *aMessage)
160 {
161     return AsCoreType(aIterator).Init(AsCoapMessage(aMessage));
162 }
163 
otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)164 const otCoapOption *otCoapOptionIteratorGetFirstOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
165 {
166     Coap::Option::Iterator &iterator = AsCoreType(aIterator);
167 
168     IgnoreError(iterator.Init(iterator.GetMessage(), aOption));
169     return iterator.GetOption();
170 }
171 
otCoapOptionIteratorGetFirstOption(otCoapOptionIterator * aIterator)172 const otCoapOption *otCoapOptionIteratorGetFirstOption(otCoapOptionIterator *aIterator)
173 {
174     Coap::Option::Iterator &iterator = AsCoreType(aIterator);
175 
176     IgnoreError(iterator.Init(iterator.GetMessage()));
177     return iterator.GetOption();
178 }
179 
otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator * aIterator,uint16_t aOption)180 const otCoapOption *otCoapOptionIteratorGetNextOptionMatching(otCoapOptionIterator *aIterator, uint16_t aOption)
181 {
182     Coap::Option::Iterator &iterator = AsCoreType(aIterator);
183 
184     IgnoreError(iterator.Advance(aOption));
185     return iterator.GetOption();
186 }
187 
otCoapOptionIteratorGetNextOption(otCoapOptionIterator * aIterator)188 const otCoapOption *otCoapOptionIteratorGetNextOption(otCoapOptionIterator *aIterator)
189 {
190     Coap::Option::Iterator &iterator = AsCoreType(aIterator);
191 
192     IgnoreError(iterator.Advance());
193     return iterator.GetOption();
194 }
195 
otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator * aIterator,uint64_t * aValue)196 otError otCoapOptionIteratorGetOptionUintValue(otCoapOptionIterator *aIterator, uint64_t *aValue)
197 {
198     return AsCoreType(aIterator).ReadOptionValue(*aValue);
199 }
200 
otCoapOptionIteratorGetOptionValue(otCoapOptionIterator * aIterator,void * aValue)201 otError otCoapOptionIteratorGetOptionValue(otCoapOptionIterator *aIterator, void *aValue)
202 {
203     return AsCoreType(aIterator).ReadOptionValue(aValue);
204 }
205 
206 #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)207 otError otCoapSendRequestBlockWiseWithParameters(otInstance                 *aInstance,
208                                                  otMessage                  *aMessage,
209                                                  const otMessageInfo        *aMessageInfo,
210                                                  otCoapResponseHandler       aHandler,
211                                                  void                       *aContext,
212                                                  const otCoapTxParameters   *aTxParameters,
213                                                  otCoapBlockwiseTransmitHook aTransmitHook,
214                                                  otCoapBlockwiseReceiveHook  aReceiveHook)
215 {
216     Error                     error;
217     const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
218 
219     VerifyOrExit(!AsCoreType(aMessage).IsOriginThreadNetif(), error = kErrorInvalidArgs);
220 
221     if (aTxParameters != nullptr)
222     {
223         VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
224     }
225 
226     error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
227                                                                    txParameters, aHandler, aContext, aTransmitHook,
228                                                                    aReceiveHook);
229 
230 exit:
231     return error;
232 }
233 #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
234 
otCoapSendRequestWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,otCoapResponseHandler aHandler,void * aContext,const otCoapTxParameters * aTxParameters)235 otError otCoapSendRequestWithParameters(otInstance               *aInstance,
236                                         otMessage                *aMessage,
237                                         const otMessageInfo      *aMessageInfo,
238                                         otCoapResponseHandler     aHandler,
239                                         void                     *aContext,
240                                         const otCoapTxParameters *aTxParameters)
241 {
242     Error error;
243 
244     const Coap::TxParameters &txParameters = Coap::TxParameters::From(aTxParameters);
245 
246     VerifyOrExit(!AsCoreType(aMessage).IsOriginThreadNetif(), error = kErrorInvalidArgs);
247 
248     if (aTxParameters != nullptr)
249     {
250         VerifyOrExit(txParameters.IsValid(), error = kErrorInvalidArgs);
251     }
252 
253     error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
254                                                                    txParameters, aHandler, aContext);
255 
256 exit:
257     return error;
258 }
259 
otCoapStart(otInstance * aInstance,uint16_t aPort)260 otError otCoapStart(otInstance *aInstance, uint16_t aPort)
261 {
262     return AsCoreType(aInstance).GetApplicationCoap().Start(aPort);
263 }
264 
otCoapStop(otInstance * aInstance)265 otError otCoapStop(otInstance *aInstance) { return AsCoreType(aInstance).GetApplicationCoap().Stop(); }
266 
267 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapAddBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)268 void otCoapAddBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
269 {
270     AsCoreType(aInstance).GetApplicationCoap().AddBlockWiseResource(AsCoreType(aResource));
271 }
272 
otCoapRemoveBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)273 void otCoapRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
274 {
275     AsCoreType(aInstance).GetApplicationCoap().RemoveBlockWiseResource(AsCoreType(aResource));
276 }
277 #endif
278 
otCoapAddResource(otInstance * aInstance,otCoapResource * aResource)279 void otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
280 {
281     AsCoreType(aInstance).GetApplicationCoap().AddResource(AsCoreType(aResource));
282 }
283 
otCoapRemoveResource(otInstance * aInstance,otCoapResource * aResource)284 void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
285 {
286     AsCoreType(aInstance).GetApplicationCoap().RemoveResource(AsCoreType(aResource));
287 }
288 
otCoapSetDefaultHandler(otInstance * aInstance,otCoapRequestHandler aHandler,void * aContext)289 void otCoapSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
290 {
291     AsCoreType(aInstance).GetApplicationCoap().SetDefaultHandler(aHandler, aContext);
292 }
293 
294 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSendResponseBlockWiseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters,void * aContext,otCoapBlockwiseTransmitHook aTransmitHook)295 otError otCoapSendResponseBlockWiseWithParameters(otInstance                 *aInstance,
296                                                   otMessage                  *aMessage,
297                                                   const otMessageInfo        *aMessageInfo,
298                                                   const otCoapTxParameters   *aTxParameters,
299                                                   void                       *aContext,
300                                                   otCoapBlockwiseTransmitHook aTransmitHook)
301 {
302     otError error;
303 
304     VerifyOrExit(!AsCoreType(aMessage).IsOriginThreadNetif(), error = kErrorInvalidArgs);
305 
306     error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(AsCoapMessage(aMessage), AsCoreType(aMessageInfo),
307                                                                    Coap::TxParameters::From(aTxParameters), nullptr,
308                                                                    aContext, aTransmitHook, nullptr);
309 exit:
310     return error;
311 }
312 #endif
313 
otCoapSendResponseWithParameters(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,const otCoapTxParameters * aTxParameters)314 otError otCoapSendResponseWithParameters(otInstance               *aInstance,
315                                          otMessage                *aMessage,
316                                          const otMessageInfo      *aMessageInfo,
317                                          const otCoapTxParameters *aTxParameters)
318 {
319     otError error;
320 
321     VerifyOrExit(!AsCoreType(aMessage).IsOriginThreadNetif(), error = kErrorInvalidArgs);
322 
323     error = AsCoreType(aInstance).GetApplicationCoap().SendMessage(
324         AsCoapMessage(aMessage), AsCoreType(aMessageInfo), Coap::TxParameters::From(aTxParameters), nullptr, nullptr);
325 
326 exit:
327     return error;
328 }
329 
330 #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
331