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