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