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 Message API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #include <openthread/message.h>
37
38 #include "common/instance.hpp"
39 #include "common/locator_getters.hpp"
40
41 using namespace ot;
42
otMessageFree(otMessage * aMessage)43 void otMessageFree(otMessage *aMessage)
44 {
45 static_cast<Message *>(aMessage)->Free();
46 }
47
otMessageGetLength(const otMessage * aMessage)48 uint16_t otMessageGetLength(const otMessage *aMessage)
49 {
50 const Message &message = *static_cast<const Message *>(aMessage);
51 return message.GetLength();
52 }
53
otMessageSetLength(otMessage * aMessage,uint16_t aLength)54 otError otMessageSetLength(otMessage *aMessage, uint16_t aLength)
55 {
56 Message &message = *static_cast<Message *>(aMessage);
57 return message.SetLength(aLength);
58 }
59
otMessageGetOffset(const otMessage * aMessage)60 uint16_t otMessageGetOffset(const otMessage *aMessage)
61 {
62 const Message &message = *static_cast<const Message *>(aMessage);
63 return message.GetOffset();
64 }
65
otMessageSetOffset(otMessage * aMessage,uint16_t aOffset)66 void otMessageSetOffset(otMessage *aMessage, uint16_t aOffset)
67 {
68 Message &message = *static_cast<Message *>(aMessage);
69 message.SetOffset(aOffset);
70 }
71
otMessageIsLinkSecurityEnabled(const otMessage * aMessage)72 bool otMessageIsLinkSecurityEnabled(const otMessage *aMessage)
73 {
74 const Message &message = *static_cast<const Message *>(aMessage);
75 return message.IsLinkSecurityEnabled();
76 }
77
otMessageSetDirectTransmission(otMessage * aMessage,bool aEnabled)78 void otMessageSetDirectTransmission(otMessage *aMessage, bool aEnabled)
79 {
80 Message &message = *static_cast<Message *>(aMessage);
81
82 if (aEnabled)
83 {
84 message.SetDirectTransmission();
85 }
86 else
87 {
88 message.ClearDirectTransmission();
89 }
90 }
91
otMessageGetRss(const otMessage * aMessage)92 int8_t otMessageGetRss(const otMessage *aMessage)
93 {
94 const Message &message = *static_cast<const Message *>(aMessage);
95 return message.GetAverageRss();
96 }
97
otMessageAppend(otMessage * aMessage,const void * aBuf,uint16_t aLength)98 otError otMessageAppend(otMessage *aMessage, const void *aBuf, uint16_t aLength)
99 {
100 Message &message = *static_cast<Message *>(aMessage);
101 return message.AppendBytes(aBuf, aLength);
102 }
103
otMessageRead(const otMessage * aMessage,uint16_t aOffset,void * aBuf,uint16_t aLength)104 uint16_t otMessageRead(const otMessage *aMessage, uint16_t aOffset, void *aBuf, uint16_t aLength)
105 {
106 const Message &message = *static_cast<const Message *>(aMessage);
107 return message.ReadBytes(aOffset, aBuf, aLength);
108 }
109
otMessageWrite(otMessage * aMessage,uint16_t aOffset,const void * aBuf,uint16_t aLength)110 int otMessageWrite(otMessage *aMessage, uint16_t aOffset, const void *aBuf, uint16_t aLength)
111 {
112 Message &message = *static_cast<Message *>(aMessage);
113 message.WriteBytes(aOffset, aBuf, aLength);
114
115 return aLength;
116 }
117
otMessageQueueInit(otMessageQueue * aQueue)118 void otMessageQueueInit(otMessageQueue *aQueue)
119 {
120 aQueue->mData = nullptr;
121 }
122
otMessageQueueEnqueue(otMessageQueue * aQueue,otMessage * aMessage)123 void otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage)
124 {
125 Message & message = *static_cast<Message *>(aMessage);
126 MessageQueue &queue = *static_cast<MessageQueue *>(aQueue);
127
128 queue.Enqueue(message);
129 }
130
otMessageQueueEnqueueAtHead(otMessageQueue * aQueue,otMessage * aMessage)131 void otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage)
132 {
133 Message & message = *static_cast<Message *>(aMessage);
134 MessageQueue &queue = *static_cast<MessageQueue *>(aQueue);
135
136 queue.Enqueue(message, MessageQueue::kQueuePositionHead);
137 }
138
otMessageQueueDequeue(otMessageQueue * aQueue,otMessage * aMessage)139 void otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage)
140 {
141 Message & message = *static_cast<Message *>(aMessage);
142 MessageQueue &queue = *static_cast<MessageQueue *>(aQueue);
143
144 queue.Dequeue(message);
145 }
146
otMessageQueueGetHead(otMessageQueue * aQueue)147 otMessage *otMessageQueueGetHead(otMessageQueue *aQueue)
148 {
149 MessageQueue &queue = *static_cast<MessageQueue *>(aQueue);
150 return queue.GetHead();
151 }
152
otMessageQueueGetNext(otMessageQueue * aQueue,const otMessage * aMessage)153 otMessage *otMessageQueueGetNext(otMessageQueue *aQueue, const otMessage *aMessage)
154 {
155 Message *next;
156
157 VerifyOrExit(aMessage != nullptr, next = nullptr);
158
159 {
160 const Message &message = *static_cast<const Message *>(aMessage);
161 MessageQueue & queue = *static_cast<MessageQueue *>(aQueue);
162
163 VerifyOrExit(message.GetMessageQueue() == &queue, next = nullptr);
164 next = message.GetNext();
165 }
166
167 exit:
168 return next;
169 }
170
171 #if OPENTHREAD_MTD || OPENTHREAD_FTD
otMessageGetBufferInfo(otInstance * aInstance,otBufferInfo * aBufferInfo)172 void otMessageGetBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo)
173 {
174 uint16_t messages, buffers;
175 Instance &instance = *static_cast<Instance *>(aInstance);
176
177 aBufferInfo->mTotalBuffers = instance.Get<MessagePool>().GetTotalBufferCount();
178
179 aBufferInfo->mFreeBuffers = instance.Get<MessagePool>().GetFreeBufferCount();
180
181 instance.Get<MeshForwarder>().GetSendQueue().GetInfo(aBufferInfo->m6loSendMessages, aBufferInfo->m6loSendBuffers);
182
183 instance.Get<MeshForwarder>().GetReassemblyQueue().GetInfo(aBufferInfo->m6loReassemblyMessages,
184 aBufferInfo->m6loReassemblyBuffers);
185
186 #if OPENTHREAD_FTD
187 instance.Get<MeshForwarder>().GetResolvingQueue().GetInfo(aBufferInfo->mArpMessages, aBufferInfo->mArpBuffers);
188 #else
189 aBufferInfo->mArpMessages = 0;
190 aBufferInfo->mArpBuffers = 0;
191 #endif
192
193 instance.Get<Ip6::Ip6>().GetSendQueue().GetInfo(aBufferInfo->mIp6Messages, aBufferInfo->mIp6Buffers);
194
195 #if OPENTHREAD_FTD
196 instance.Get<Ip6::Mpl>().GetBufferedMessageSet().GetInfo(aBufferInfo->mMplMessages, aBufferInfo->mMplBuffers);
197 #else
198 aBufferInfo->mMplMessages = 0;
199 aBufferInfo->mMplBuffers = 0;
200 #endif
201
202 instance.Get<Mle::MleRouter>().GetMessageQueue().GetInfo(aBufferInfo->mMleMessages, aBufferInfo->mMleBuffers);
203
204 instance.Get<Tmf::Agent>().GetRequestMessages().GetInfo(aBufferInfo->mCoapMessages, aBufferInfo->mCoapBuffers);
205 instance.Get<Tmf::Agent>().GetCachedResponses().GetInfo(messages, buffers);
206 aBufferInfo->mCoapMessages += messages;
207 aBufferInfo->mCoapBuffers += buffers;
208
209 #if OPENTHREAD_CONFIG_DTLS_ENABLE
210 instance.Get<Coap::CoapSecure>().GetRequestMessages().GetInfo(aBufferInfo->mCoapSecureMessages,
211 aBufferInfo->mCoapSecureBuffers);
212 instance.Get<Coap::CoapSecure>().GetCachedResponses().GetInfo(messages, buffers);
213 aBufferInfo->mCoapSecureMessages += messages;
214 aBufferInfo->mCoapSecureBuffers += buffers;
215 #else
216 aBufferInfo->mCoapSecureMessages = 0;
217 aBufferInfo->mCoapSecureBuffers = 0;
218 #endif
219
220 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
221 instance.GetApplicationCoap().GetRequestMessages().GetInfo(aBufferInfo->mApplicationCoapMessages,
222 aBufferInfo->mApplicationCoapBuffers);
223 instance.GetApplicationCoap().GetCachedResponses().GetInfo(messages, buffers);
224 aBufferInfo->mApplicationCoapMessages += messages;
225 aBufferInfo->mApplicationCoapBuffers += buffers;
226 #else
227 aBufferInfo->mApplicationCoapMessages = 0;
228 aBufferInfo->mApplicationCoapBuffers = 0;
229 #endif
230 }
231 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
232