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