1 /*
2 * Copyright (c) 2019, 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" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /**
29 * @file
30 * This file implements the radio platform callbacks into OpenThread and default/weak radio platform APIs.
31 */
32
33 #include <openthread/instance.h>
34 #include <openthread/platform/time.h>
35
36 #include "common/as_core_type.hpp"
37 #include "common/code_utils.hpp"
38 #include "common/instance.hpp"
39 #include "radio/radio.hpp"
40
41 using namespace ot;
42
43 //---------------------------------------------------------------------------------------------------------------------
44 // otPlatRadio callbacks
45
46 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
47
otPlatRadioReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,otError aError)48 extern "C" void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
49 {
50 Instance & instance = AsCoreType(aInstance);
51 Mac::RxFrame *rxFrame = static_cast<Mac::RxFrame *>(aFrame);
52
53 VerifyOrExit(instance.IsInitialized());
54
55 #if OPENTHREAD_CONFIG_MULTI_RADIO
56 if (rxFrame != nullptr)
57 {
58 rxFrame->SetRadioType(Mac::kRadioTypeIeee802154);
59 }
60 #endif
61
62 instance.Get<Radio::Callbacks>().HandleReceiveDone(rxFrame, aError);
63
64 exit:
65 return;
66 }
67
otPlatRadioTxStarted(otInstance * aInstance,otRadioFrame * aFrame)68 extern "C" void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame)
69 {
70 Instance & instance = AsCoreType(aInstance);
71 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
72
73 VerifyOrExit(instance.IsInitialized());
74
75 #if OPENTHREAD_CONFIG_MULTI_RADIO
76 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
77 #endif
78
79 instance.Get<Radio::Callbacks>().HandleTransmitStarted(txFrame);
80
81 exit:
82 return;
83 }
84
otPlatRadioTxDone(otInstance * aInstance,otRadioFrame * aFrame,otRadioFrame * aAckFrame,otError aError)85 extern "C" void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
86 {
87 Instance & instance = AsCoreType(aInstance);
88 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
89 Mac::RxFrame *ackFrame = static_cast<Mac::RxFrame *>(aAckFrame);
90
91 VerifyOrExit(instance.IsInitialized());
92
93 #if OPENTHREAD_CONFIG_MULTI_RADIO
94 if (ackFrame != nullptr)
95 {
96 ackFrame->SetRadioType(Mac::kRadioTypeIeee802154);
97 }
98
99 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
100 #endif
101
102 instance.Get<Radio::Callbacks>().HandleTransmitDone(txFrame, ackFrame, aError);
103
104 exit:
105 return;
106 }
107
otPlatRadioEnergyScanDone(otInstance * aInstance,int8_t aEnergyScanMaxRssi)108 extern "C" void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi)
109 {
110 Instance &instance = AsCoreType(aInstance);
111
112 VerifyOrExit(instance.IsInitialized());
113 instance.Get<Radio::Callbacks>().HandleEnergyScanDone(aEnergyScanMaxRssi);
114
115 exit:
116 return;
117 }
118
119 #if OPENTHREAD_CONFIG_DIAG_ENABLE
otPlatDiagRadioReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,otError aError)120 extern "C" void otPlatDiagRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
121 {
122 Mac::RxFrame *rxFrame = static_cast<Mac::RxFrame *>(aFrame);
123
124 #if OPENTHREAD_CONFIG_MULTI_RADIO
125 if (rxFrame != nullptr)
126 {
127 rxFrame->SetRadioType(Mac::kRadioTypeIeee802154);
128 }
129 #endif
130
131 AsCoreType(aInstance).Get<Radio::Callbacks>().HandleDiagsReceiveDone(rxFrame, aError);
132 }
133
otPlatDiagRadioTransmitDone(otInstance * aInstance,otRadioFrame * aFrame,otError aError)134 extern "C" void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
135 {
136 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
137
138 #if OPENTHREAD_CONFIG_MULTI_RADIO
139 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
140 #endif
141
142 AsCoreType(aInstance).Get<Radio::Callbacks>().HandleDiagsTransmitDone(txFrame, aError);
143 }
144 #endif
145
146 #else // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
147
otPlatRadioReceiveDone(otInstance *,otRadioFrame *,otError)148 extern "C" void otPlatRadioReceiveDone(otInstance *, otRadioFrame *, otError)
149 {
150 }
151
otPlatRadioTxStarted(otInstance *,otRadioFrame *)152 extern "C" void otPlatRadioTxStarted(otInstance *, otRadioFrame *)
153 {
154 }
155
otPlatRadioTxDone(otInstance *,otRadioFrame *,otRadioFrame *,otError)156 extern "C" void otPlatRadioTxDone(otInstance *, otRadioFrame *, otRadioFrame *, otError)
157 {
158 }
159
otPlatRadioEnergyScanDone(otInstance *,int8_t)160 extern "C" void otPlatRadioEnergyScanDone(otInstance *, int8_t)
161 {
162 }
163
164 #if OPENTHREAD_CONFIG_DIAG_ENABLE
otPlatDiagRadioReceiveDone(otInstance *,otRadioFrame *,otError)165 extern "C" void otPlatDiagRadioReceiveDone(otInstance *, otRadioFrame *, otError)
166 {
167 }
168
otPlatDiagRadioTransmitDone(otInstance *,otRadioFrame *,otError)169 extern "C" void otPlatDiagRadioTransmitDone(otInstance *, otRadioFrame *, otError)
170 {
171 }
172 #endif
173
174 #endif // // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
175
176 //---------------------------------------------------------------------------------------------------------------------
177 // Default/weak implementation of radio platform APIs
178
otPlatRadioGetSupportedChannelMask(otInstance * aInstance)179 OT_TOOL_WEAK uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
180 {
181 OT_UNUSED_VARIABLE(aInstance);
182
183 return Radio::kSupportedChannels;
184 }
185
otPlatRadioGetPreferredChannelMask(otInstance * aInstance)186 OT_TOOL_WEAK uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
187 {
188 return otPlatRadioGetSupportedChannelMask(aInstance);
189 }
190
otPlatRadioGetVersionString(otInstance * aInstance)191 OT_TOOL_WEAK const char *otPlatRadioGetVersionString(otInstance *aInstance)
192 {
193 OT_UNUSED_VARIABLE(aInstance);
194 return otGetVersionString();
195 }
196
otPlatRadioGetState(otInstance * aInstance)197 OT_TOOL_WEAK otRadioState otPlatRadioGetState(otInstance *aInstance)
198 {
199 OT_UNUSED_VARIABLE(aInstance);
200
201 return OT_RADIO_STATE_INVALID;
202 }
203
otPlatRadioSetMacKey(otInstance * aInstance,uint8_t aKeyIdMode,uint8_t aKeyId,const otMacKeyMaterial * aPrevKey,const otMacKeyMaterial * aCurrKey,const otMacKeyMaterial * aNextKey,otRadioKeyType aKeyType)204 OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance,
205 uint8_t aKeyIdMode,
206 uint8_t aKeyId,
207 const otMacKeyMaterial *aPrevKey,
208 const otMacKeyMaterial *aCurrKey,
209 const otMacKeyMaterial *aNextKey,
210 otRadioKeyType aKeyType)
211 {
212 OT_UNUSED_VARIABLE(aInstance);
213 OT_UNUSED_VARIABLE(aKeyIdMode);
214 OT_UNUSED_VARIABLE(aKeyId);
215 OT_UNUSED_VARIABLE(aPrevKey);
216 OT_UNUSED_VARIABLE(aCurrKey);
217 OT_UNUSED_VARIABLE(aNextKey);
218 OT_UNUSED_VARIABLE(aKeyType);
219 }
220
otPlatRadioSetMacFrameCounter(otInstance * aInstance,uint32_t aMacFrameCounter)221 OT_TOOL_WEAK void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
222 {
223 OT_UNUSED_VARIABLE(aInstance);
224 OT_UNUSED_VARIABLE(aMacFrameCounter);
225 }
226
otPlatTimeGet(void)227 OT_TOOL_WEAK uint64_t otPlatTimeGet(void)
228 {
229 return UINT64_MAX;
230 }
231
otPlatRadioGetNow(otInstance * aInstance)232 OT_TOOL_WEAK uint64_t otPlatRadioGetNow(otInstance *aInstance)
233 {
234 OT_UNUSED_VARIABLE(aInstance);
235
236 return UINT64_MAX;
237 }
238
otPlatRadioGetBusSpeed(otInstance * aInstance)239 OT_TOOL_WEAK uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance)
240 {
241 OT_UNUSED_VARIABLE(aInstance);
242
243 return 0;
244 }
245
otPlatRadioGetCslAccuracy(otInstance * aInstance)246 OT_TOOL_WEAK uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
247 {
248 OT_UNUSED_VARIABLE(aInstance);
249
250 return UINT8_MAX;
251 }
252
otPlatRadioGetCslUncertainty(otInstance * aInstance)253 OT_TOOL_WEAK uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance)
254 {
255 OT_UNUSED_VARIABLE(aInstance);
256
257 return UINT8_MAX;
258 }
259
otPlatRadioGetFemLnaGain(otInstance * aInstance,int8_t * aGain)260 OT_TOOL_WEAK otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
261 {
262 OT_UNUSED_VARIABLE(aInstance);
263 OT_UNUSED_VARIABLE(aGain);
264
265 return kErrorNotImplemented;
266 }
267
otPlatRadioSetFemLnaGain(otInstance * aInstance,int8_t aGain)268 OT_TOOL_WEAK otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
269 {
270 OT_UNUSED_VARIABLE(aInstance);
271 OT_UNUSED_VARIABLE(aGain);
272
273 return kErrorNotImplemented;
274 }
275
otPlatRadioSetChannelMaxTransmitPower(otInstance * aInstance,uint8_t aChannel,int8_t aMaxPower)276 OT_TOOL_WEAK otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower)
277 {
278 OT_UNUSED_VARIABLE(aInstance);
279 OT_UNUSED_VARIABLE(aChannel);
280 OT_UNUSED_VARIABLE(aMaxPower);
281
282 return kErrorNotImplemented;
283 }
284
otPlatRadioSetRegion(otInstance * aInstance,uint16_t aRegionCode)285 OT_TOOL_WEAK otError otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode)
286 {
287 OT_UNUSED_VARIABLE(aInstance);
288 OT_UNUSED_VARIABLE(aRegionCode);
289
290 return kErrorNotImplemented;
291 }
292
otPlatRadioGetRegion(otInstance * aInstance,uint16_t * aRegionCode)293 OT_TOOL_WEAK otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
294 {
295 OT_UNUSED_VARIABLE(aInstance);
296 OT_UNUSED_VARIABLE(aRegionCode);
297
298 return kErrorNotImplemented;
299 }
300
otPlatRadioReceiveAt(otInstance * aInstance,uint8_t aChannel,uint32_t aStart,uint32_t aDuration)301 OT_TOOL_WEAK otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
302 {
303 OT_UNUSED_VARIABLE(aInstance);
304 OT_UNUSED_VARIABLE(aChannel);
305 OT_UNUSED_VARIABLE(aStart);
306 OT_UNUSED_VARIABLE(aDuration);
307
308 return kErrorNotImplemented;
309 }
310