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