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