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 Link Raw API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
37
38 #include <string.h>
39 #include <openthread/diag.h>
40 #include <openthread/thread.h>
41 #include <openthread/platform/diag.h>
42 #include <openthread/platform/time.h>
43
44 #include "common/debug.hpp"
45 #include "common/instance.hpp"
46 #include "common/locator_getters.hpp"
47 #include "common/random.hpp"
48 #include "mac/mac_frame.hpp"
49
50 using namespace ot;
51
otLinkRawSetReceiveDone(otInstance * aInstance,otLinkRawReceiveDone aCallback)52 otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback)
53 {
54 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetReceiveDone(aCallback);
55 }
56
otLinkRawIsEnabled(otInstance * aInstance)57 bool otLinkRawIsEnabled(otInstance *aInstance)
58 {
59 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().IsEnabled();
60 }
61
otLinkRawSetShortAddress(otInstance * aInstance,uint16_t aShortAddress)62 otError otLinkRawSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
63 {
64 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetShortAddress(aShortAddress);
65 }
66
otLinkRawGetPromiscuous(otInstance * aInstance)67 bool otLinkRawGetPromiscuous(otInstance *aInstance)
68 {
69 return static_cast<Instance *>(aInstance)->Get<Radio>().GetPromiscuous();
70 }
71
otLinkRawSetPromiscuous(otInstance * aInstance,bool aEnable)72 otError otLinkRawSetPromiscuous(otInstance *aInstance, bool aEnable)
73 {
74 Error error = kErrorNone;
75 Instance &instance = *static_cast<Instance *>(aInstance);
76
77 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
78 instance.Get<Radio>().SetPromiscuous(aEnable);
79
80 exit:
81 return error;
82 }
83
otLinkRawSleep(otInstance * aInstance)84 otError otLinkRawSleep(otInstance *aInstance)
85 {
86 Error error = kErrorNone;
87 Instance &instance = *static_cast<Instance *>(aInstance);
88
89 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
90
91 error = instance.Get<Radio>().Sleep();
92
93 exit:
94 return error;
95 }
96
otLinkRawReceive(otInstance * aInstance)97 otError otLinkRawReceive(otInstance *aInstance)
98 {
99 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Receive();
100 }
101
otLinkRawGetTransmitBuffer(otInstance * aInstance)102 otRadioFrame *otLinkRawGetTransmitBuffer(otInstance *aInstance)
103 {
104 return &static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetTransmitFrame();
105 }
106
otLinkRawTransmit(otInstance * aInstance,otLinkRawTransmitDone aCallback)107 otError otLinkRawTransmit(otInstance *aInstance, otLinkRawTransmitDone aCallback)
108 {
109 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Transmit(aCallback);
110 }
111
otLinkRawGetRssi(otInstance * aInstance)112 int8_t otLinkRawGetRssi(otInstance *aInstance)
113 {
114 return static_cast<Instance *>(aInstance)->Get<Radio>().GetRssi();
115 }
116
otLinkRawGetCaps(otInstance * aInstance)117 otRadioCaps otLinkRawGetCaps(otInstance *aInstance)
118 {
119 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetCaps();
120 }
121
otLinkRawEnergyScan(otInstance * aInstance,uint8_t aScanChannel,uint16_t aScanDuration,otLinkRawEnergyScanDone aCallback)122 otError otLinkRawEnergyScan(otInstance * aInstance,
123 uint8_t aScanChannel,
124 uint16_t aScanDuration,
125 otLinkRawEnergyScanDone aCallback)
126 {
127 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().EnergyScan(aScanChannel, aScanDuration, aCallback);
128 }
129
otLinkRawSrcMatchEnable(otInstance * aInstance,bool aEnable)130 otError otLinkRawSrcMatchEnable(otInstance *aInstance, bool aEnable)
131 {
132 Error error = kErrorNone;
133 Instance &instance = *static_cast<Instance *>(aInstance);
134
135 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
136
137 instance.Get<Radio>().EnableSrcMatch(aEnable);
138
139 exit:
140 return error;
141 }
142
otLinkRawSrcMatchAddShortEntry(otInstance * aInstance,uint16_t aShortAddress)143 otError otLinkRawSrcMatchAddShortEntry(otInstance *aInstance, uint16_t aShortAddress)
144 {
145 Error error = kErrorNone;
146 Instance &instance = *static_cast<Instance *>(aInstance);
147
148 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
149
150 error = instance.Get<Radio>().AddSrcMatchShortEntry(aShortAddress);
151
152 exit:
153 return error;
154 }
155
otLinkRawSrcMatchAddExtEntry(otInstance * aInstance,const otExtAddress * aExtAddress)156 otError otLinkRawSrcMatchAddExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
157 {
158 Mac::ExtAddress address;
159 Error error = kErrorNone;
160 Instance & instance = *static_cast<Instance *>(aInstance);
161
162 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
163
164 address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder);
165 error = instance.Get<Radio>().AddSrcMatchExtEntry(address);
166
167 exit:
168 return error;
169 }
170
otLinkRawSrcMatchClearShortEntry(otInstance * aInstance,uint16_t aShortAddress)171 otError otLinkRawSrcMatchClearShortEntry(otInstance *aInstance, uint16_t aShortAddress)
172 {
173 Error error = kErrorNone;
174 Instance &instance = *static_cast<Instance *>(aInstance);
175
176 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
177 error = instance.Get<Radio>().ClearSrcMatchShortEntry(aShortAddress);
178
179 exit:
180 return error;
181 }
182
otLinkRawSrcMatchClearExtEntry(otInstance * aInstance,const otExtAddress * aExtAddress)183 otError otLinkRawSrcMatchClearExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
184 {
185 Mac::ExtAddress address;
186 Error error = kErrorNone;
187 Instance & instance = *static_cast<Instance *>(aInstance);
188
189 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
190
191 address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder);
192 error = instance.Get<Radio>().ClearSrcMatchExtEntry(address);
193
194 exit:
195 return error;
196 }
197
otLinkRawSrcMatchClearShortEntries(otInstance * aInstance)198 otError otLinkRawSrcMatchClearShortEntries(otInstance *aInstance)
199 {
200 Error error = kErrorNone;
201 Instance &instance = *static_cast<Instance *>(aInstance);
202
203 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
204
205 instance.Get<Radio>().ClearSrcMatchShortEntries();
206
207 exit:
208 return error;
209 }
210
otLinkRawSrcMatchClearExtEntries(otInstance * aInstance)211 otError otLinkRawSrcMatchClearExtEntries(otInstance *aInstance)
212 {
213 Error error = kErrorNone;
214 Instance &instance = *static_cast<Instance *>(aInstance);
215
216 VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
217
218 instance.Get<Radio>().ClearSrcMatchExtEntries();
219
220 exit:
221 return error;
222 }
223
otLinkRawSetMacKey(otInstance * aInstance,uint8_t aKeyIdMode,uint8_t aKeyId,const otMacKey * aPrevKey,const otMacKey * aCurrKey,const otMacKey * aNextKey)224 otError otLinkRawSetMacKey(otInstance * aInstance,
225 uint8_t aKeyIdMode,
226 uint8_t aKeyId,
227 const otMacKey *aPrevKey,
228 const otMacKey *aCurrKey,
229 const otMacKey *aNextKey)
230 {
231 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacKey(
232 aKeyIdMode, aKeyId, *static_cast<const Mac::Key *>(aPrevKey), *static_cast<const Mac::Key *>(aCurrKey),
233 *static_cast<const Mac::Key *>(aNextKey));
234 }
235
otLinkRawSetMacFrameCounter(otInstance * aInstance,uint32_t aMacFrameCounter)236 otError otLinkRawSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
237 {
238 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacFrameCounter(aMacFrameCounter);
239 }
240
otLinkRawGetRadioTime(otInstance * aInstance)241 uint64_t otLinkRawGetRadioTime(otInstance *aInstance)
242 {
243 OT_UNUSED_VARIABLE(aInstance);
244 return otPlatTimeGet();
245 }
246
247 #if OPENTHREAD_RADIO
248
otThreadGetDeviceRole(otInstance * aInstance)249 otDeviceRole otThreadGetDeviceRole(otInstance *aInstance)
250 {
251 OT_UNUSED_VARIABLE(aInstance);
252 return OT_DEVICE_ROLE_DISABLED;
253 }
254
otLinkGetChannel(otInstance * aInstance)255 uint8_t otLinkGetChannel(otInstance *aInstance)
256 {
257 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetChannel();
258 }
259
otLinkSetChannel(otInstance * aInstance,uint8_t aChannel)260 otError otLinkSetChannel(otInstance *aInstance, uint8_t aChannel)
261 {
262 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetChannel(aChannel);
263 }
264
otLinkGetPanId(otInstance * aInstance)265 otPanId otLinkGetPanId(otInstance *aInstance)
266 {
267 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetPanId();
268 }
269
otLinkSetPanId(otInstance * aInstance,uint16_t aPanId)270 otError otLinkSetPanId(otInstance *aInstance, uint16_t aPanId)
271 {
272 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetPanId(aPanId);
273 }
274
otLinkGetExtendedAddress(otInstance * aInstance)275 const otExtAddress *otLinkGetExtendedAddress(otInstance *aInstance)
276 {
277 return &static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetExtAddress();
278 }
279
otLinkSetExtendedAddress(otInstance * aInstance,const otExtAddress * aExtAddress)280 otError otLinkSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
281 {
282 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetExtAddress(
283 *static_cast<const Mac::ExtAddress *>(aExtAddress));
284 }
285
otLinkGetShortAddress(otInstance * aInstance)286 uint16_t otLinkGetShortAddress(otInstance *aInstance)
287 {
288 return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().GetShortAddress();
289 }
290
otLinkGetFactoryAssignedIeeeEui64(otInstance * aInstance,otExtAddress * aEui64)291 void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui64)
292 {
293 otPlatRadioGetIeeeEui64(aInstance, aEui64->m8);
294 }
295
296 #endif // OPENTHREAD_RADIO
297
298 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
299