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/code_utils.hpp"
37 #include "common/instance.hpp"
38 #include "radio/radio.hpp"
39
40 using namespace ot;
41
42 //---------------------------------------------------------------------------------------------------------------------
43 // otPlatRadio callbacks
44
45 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
46
otPlatRadioReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,Error aError)47 extern "C" void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, Error aError)
48 {
49 Instance & instance = *static_cast<Instance *>(aInstance);
50 Mac::RxFrame *rxFrame = static_cast<Mac::RxFrame *>(aFrame);
51
52 VerifyOrExit(instance.IsInitialized());
53
54 #if OPENTHREAD_CONFIG_MULTI_RADIO
55 if (rxFrame != nullptr)
56 {
57 rxFrame->SetRadioType(Mac::kRadioTypeIeee802154);
58 }
59 #endif
60
61 instance.Get<Radio::Callbacks>().HandleReceiveDone(rxFrame, aError);
62
63 exit:
64 return;
65 }
66
otPlatRadioTxStarted(otInstance * aInstance,otRadioFrame * aFrame)67 extern "C" void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame)
68 {
69 Instance & instance = *static_cast<Instance *>(aInstance);
70 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
71
72 VerifyOrExit(instance.IsInitialized());
73
74 #if OPENTHREAD_CONFIG_MULTI_RADIO
75 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
76 #endif
77
78 instance.Get<Radio::Callbacks>().HandleTransmitStarted(txFrame);
79
80 exit:
81 return;
82 }
83
otPlatRadioTxDone(otInstance * aInstance,otRadioFrame * aFrame,otRadioFrame * aAckFrame,Error aError)84 extern "C" void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, Error aError)
85 {
86 Instance & instance = *static_cast<Instance *>(aInstance);
87 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
88 Mac::RxFrame *ackFrame = static_cast<Mac::RxFrame *>(aAckFrame);
89
90 VerifyOrExit(instance.IsInitialized());
91
92 #if OPENTHREAD_CONFIG_MULTI_RADIO
93 if (ackFrame != nullptr)
94 {
95 ackFrame->SetRadioType(Mac::kRadioTypeIeee802154);
96 }
97
98 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
99 #endif
100
101 instance.Get<Radio::Callbacks>().HandleTransmitDone(txFrame, ackFrame, aError);
102
103 exit:
104 return;
105 }
106
otPlatRadioEnergyScanDone(otInstance * aInstance,int8_t aEnergyScanMaxRssi)107 extern "C" void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi)
108 {
109 Instance &instance = *static_cast<Instance *>(aInstance);
110
111 VerifyOrExit(instance.IsInitialized());
112 instance.Get<Radio::Callbacks>().HandleEnergyScanDone(aEnergyScanMaxRssi);
113
114 exit:
115 return;
116 }
117
118 #if OPENTHREAD_CONFIG_DIAG_ENABLE
otPlatDiagRadioReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,Error aError)119 extern "C" void otPlatDiagRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, Error aError)
120 {
121 Instance & instance = *static_cast<Instance *>(aInstance);
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 instance.Get<Radio::Callbacks>().HandleDiagsReceiveDone(rxFrame, aError);
132 }
133
otPlatDiagRadioTransmitDone(otInstance * aInstance,otRadioFrame * aFrame,Error aError)134 extern "C" void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, Error aError)
135 {
136 Instance & instance = *static_cast<Instance *>(aInstance);
137 Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
138
139 #if OPENTHREAD_CONFIG_MULTI_RADIO
140 txFrame.SetRadioType(Mac::kRadioTypeIeee802154);
141 #endif
142
143 instance.Get<Radio::Callbacks>().HandleDiagsTransmitDone(txFrame, aError);
144 }
145 #endif
146
147 #else // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
148
otPlatRadioReceiveDone(otInstance *,otRadioFrame *,Error)149 extern "C" void otPlatRadioReceiveDone(otInstance *, otRadioFrame *, Error)
150 {
151 }
152
otPlatRadioTxStarted(otInstance *,otRadioFrame *)153 extern "C" void otPlatRadioTxStarted(otInstance *, otRadioFrame *)
154 {
155 }
156
otPlatRadioTxDone(otInstance *,otRadioFrame *,otRadioFrame *,Error)157 extern "C" void otPlatRadioTxDone(otInstance *, otRadioFrame *, otRadioFrame *, Error)
158 {
159 }
160
otPlatRadioEnergyScanDone(otInstance *,int8_t)161 extern "C" void otPlatRadioEnergyScanDone(otInstance *, int8_t)
162 {
163 }
164
165 #if OPENTHREAD_CONFIG_DIAG_ENABLE
otPlatDiagRadioReceiveDone(otInstance *,otRadioFrame *,Error)166 extern "C" void otPlatDiagRadioReceiveDone(otInstance *, otRadioFrame *, Error)
167 {
168 }
169
otPlatDiagRadioTransmitDone(otInstance *,otRadioFrame *,Error)170 extern "C" void otPlatDiagRadioTransmitDone(otInstance *, otRadioFrame *, Error)
171 {
172 }
173 #endif
174
175 #endif // // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
176
177 //---------------------------------------------------------------------------------------------------------------------
178 // Default/weak implementation of radio platform APIs
179
otPlatRadioGetSupportedChannelMask(otInstance * aInstance)180 OT_TOOL_WEAK uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
181 {
182 OT_UNUSED_VARIABLE(aInstance);
183
184 return Radio::kSupportedChannels;
185 }
186
otPlatRadioGetPreferredChannelMask(otInstance * aInstance)187 OT_TOOL_WEAK uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
188 {
189 return otPlatRadioGetSupportedChannelMask(aInstance);
190 }
191
otPlatRadioGetVersionString(otInstance * aInstance)192 OT_TOOL_WEAK const char *otPlatRadioGetVersionString(otInstance *aInstance)
193 {
194 OT_UNUSED_VARIABLE(aInstance);
195 return otGetVersionString();
196 }
197
otPlatRadioGetState(otInstance * aInstance)198 OT_TOOL_WEAK otRadioState otPlatRadioGetState(otInstance *aInstance)
199 {
200 OT_UNUSED_VARIABLE(aInstance);
201
202 return OT_RADIO_STATE_INVALID;
203 }
204
otPlatRadioSetMacKey(otInstance * aInstance,uint8_t aKeyIdMode,uint8_t aKeyId,const otMacKey * aPrevKey,const otMacKey * aCurrKey,const otMacKey * aNextKey)205 OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance,
206 uint8_t aKeyIdMode,
207 uint8_t aKeyId,
208 const otMacKey *aPrevKey,
209 const otMacKey *aCurrKey,
210 const otMacKey *aNextKey)
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 }
219
otPlatRadioSetMacFrameCounter(otInstance * aInstance,uint32_t aMacFrameCounter)220 OT_TOOL_WEAK void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
221 {
222 OT_UNUSED_VARIABLE(aInstance);
223 OT_UNUSED_VARIABLE(aMacFrameCounter);
224 }
225
otPlatTimeGet(void)226 OT_TOOL_WEAK uint64_t otPlatTimeGet(void)
227 {
228 return UINT64_MAX;
229 }
230
otPlatRadioGetNow(otInstance * aInstance)231 OT_TOOL_WEAK uint64_t otPlatRadioGetNow(otInstance *aInstance)
232 {
233 OT_UNUSED_VARIABLE(aInstance);
234
235 return UINT64_MAX;
236 }
237
otPlatRadioGetBusSpeed(otInstance * aInstance)238 OT_TOOL_WEAK uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance)
239 {
240 OT_UNUSED_VARIABLE(aInstance);
241
242 return 0;
243 }
244
otPlatRadioGetCslAccuracy(otInstance * aInstance)245 OT_TOOL_WEAK uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
246 {
247 OT_UNUSED_VARIABLE(aInstance);
248
249 return UINT8_MAX;
250 }
251
otPlatRadioGetCslClockUncertainty(otInstance * aInstance)252 OT_TOOL_WEAK uint8_t otPlatRadioGetCslClockUncertainty(otInstance *aInstance)
253 {
254 OT_UNUSED_VARIABLE(aInstance);
255
256 return OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT;
257 }
258
otPlatRadioGetFemLnaGain(otInstance * aInstance,int8_t * aGain)259 OT_TOOL_WEAK Error otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
260 {
261 OT_UNUSED_VARIABLE(aInstance);
262 OT_UNUSED_VARIABLE(aGain);
263
264 return kErrorNotImplemented;
265 }
266
otPlatRadioSetFemLnaGain(otInstance * aInstance,int8_t aGain)267 OT_TOOL_WEAK Error otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
268 {
269 OT_UNUSED_VARIABLE(aInstance);
270 OT_UNUSED_VARIABLE(aGain);
271
272 return kErrorNotImplemented;
273 }
274
otPlatRadioSetChannelMaxTransmitPower(otInstance * aInstance,uint8_t aChannel,int8_t aMaxPower)275 OT_TOOL_WEAK Error otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower)
276 {
277 OT_UNUSED_VARIABLE(aInstance);
278 OT_UNUSED_VARIABLE(aChannel);
279 OT_UNUSED_VARIABLE(aMaxPower);
280
281 return kErrorNotImplemented;
282 }
283
otPlatRadioSetRegion(otInstance * aInstance,uint16_t aRegionCode)284 OT_TOOL_WEAK Error otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode)
285 {
286 OT_UNUSED_VARIABLE(aInstance);
287 OT_UNUSED_VARIABLE(aRegionCode);
288
289 return kErrorNotImplemented;
290 }
291
otPlatRadioGetRegion(otInstance * aInstance,uint16_t * aRegionCode)292 OT_TOOL_WEAK Error otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
293 {
294 OT_UNUSED_VARIABLE(aInstance);
295 OT_UNUSED_VARIABLE(aRegionCode);
296
297 return kErrorNotImplemented;
298 }
299
otPlatRadioReceiveAt(otInstance * aInstance,uint8_t aChannel,uint32_t aStart,uint32_t aDuration)300 OT_TOOL_WEAK Error otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
301 {
302 OT_UNUSED_VARIABLE(aInstance);
303 OT_UNUSED_VARIABLE(aChannel);
304 OT_UNUSED_VARIABLE(aStart);
305 OT_UNUSED_VARIABLE(aDuration);
306
307 return kErrorNotImplemented;
308 }
309