1 /*
2 * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 #include <assert.h>
36 #include <stddef.h>
37 #include <string.h>
38
39 #ifndef TEST
40 #include <nrfx.h>
41 #endif
42
43 #include "../spinel_base/spinel.h"
44 #include "nrf_802154_spinel.h"
45 #include "nrf_802154_spinel_datatypes.h"
46 #include "nrf_802154_spinel_dec.h"
47 #include "nrf_802154_spinel_response_notifier.h"
48 #include "nrf_802154_spinel_log.h"
49 #include "nrf_802154_serialization_error.h"
50 #include "nrf_802154_buffer_mgr_dst.h"
51 #include "nrf_802154_buffer_mgr_src.h"
52
53 #include "nrf_802154.h"
54 #include "nrf_802154_config.h"
55
56 /**
57 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_DONE.
58 *
59 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
60 * @param[in] property_data_len Size of the @ref p_data buffer.
61 */
spinel_decode_prop_nrf_802154_cca_done(const void * p_property_data,size_t property_data_len)62 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_cca_done(
63 const void * p_property_data,
64 size_t property_data_len)
65 {
66 bool channel_free = false;
67
68 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
69 property_data_len,
70 SPINEL_DATATYPE_NRF_802154_CCA_DONE,
71 &channel_free);
72
73 if (siz < 0)
74 {
75 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
76 }
77
78 nrf_802154_cca_done(channel_free);
79
80 return NRF_802154_SERIALIZATION_ERROR_OK;
81 }
82
83 /**
84 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_FAILED.
85 *
86 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
87 * @param[in] property_data_len Size of the @ref p_data buffer.
88 */
spinel_decode_prop_nrf_802154_cca_failed(const void * p_property_data,size_t property_data_len)89 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_cca_failed(
90 const void * p_property_data,
91 size_t property_data_len)
92 {
93 nrf_802154_cca_error_t err = NRF_802154_CCA_ERROR_ABORTED;
94
95 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
96 property_data_len,
97 SPINEL_DATATYPE_NRF_802154_CCA_FAILED,
98 &err);
99
100 if (siz < 0)
101 {
102 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
103 }
104
105 nrf_802154_cca_failed(err);
106
107 return NRF_802154_SERIALIZATION_ERROR_OK;
108 }
109
110 /**
111 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTED.
112 *
113 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
114 * @param[in] property_data_len Size of the @ref p_data buffer.
115 */
spinel_decode_prop_nrf_802154_energy_detected(const void * p_property_data,size_t property_data_len)116 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_energy_detected(
117 const void * p_property_data,
118 size_t property_data_len)
119 {
120 uint8_t result;
121
122 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
123 property_data_len,
124 SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTED,
125 &result);
126
127 if (siz < 0)
128 {
129 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
130 }
131
132 nrf_802154_energy_detected(result);
133
134 return NRF_802154_SERIALIZATION_ERROR_OK;
135 }
136
137 /**
138 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION_FAILED.
139 *
140 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
141 * @param[in] property_data_len Size of the @ref p_data buffer.
142 */
spinel_decode_prop_nrf_802154_energy_detection_failed(const void * p_property_data,size_t property_data_len)143 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_energy_detection_failed(
144 const void * p_property_data,
145 size_t property_data_len)
146 {
147 nrf_802154_ed_error_t err = NRF_802154_CCA_ERROR_ABORTED;
148
149 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
150 property_data_len,
151 SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_FAILED,
152 &err);
153
154 if (siz < 0)
155 {
156 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
157 }
158
159 nrf_802154_energy_detection_failed(err);
160
161 return NRF_802154_SERIALIZATION_ERROR_OK;
162 }
163
164 /**
165 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVED_TIMESTAMP_RAW.
166 *
167 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
168 * @param[in] property_data_len Size of the @ref p_data buffer.
169 */
spinel_decode_prop_nrf_802154_received_timestamp_raw(const void * p_property_data,size_t property_data_len)170 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_received_timestamp_raw(
171 const void * p_property_data,
172 size_t property_data_len)
173 {
174 uint32_t remote_frame_handle;
175 void * p_frame;
176 size_t frame_hdata_len;
177 int8_t power;
178 uint8_t lqi;
179 uint64_t timestamp;
180 void * p_local_ptr;
181
182 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
183 property_data_len,
184 SPINEL_DATATYPE_NRF_802154_RECEIVED_TIMESTAMP_RAW,
185 NRF_802154_HDATA_DECODE(remote_frame_handle,
186 p_frame,
187 frame_hdata_len),
188 &power,
189 &lqi,
190 ×tamp);
191
192 if (siz < 0)
193 {
194 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
195 }
196
197 // Associate the remote frame handle with a local pointer
198 // and copy the buffer content there
199 bool frame_added = nrf_802154_buffer_mgr_dst_add(
200 nrf_802154_spinel_dst_buffer_mgr_get(),
201 remote_frame_handle,
202 p_frame,
203 NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len),
204 &p_local_ptr);
205
206 if (!frame_added)
207 {
208 return NRF_802154_SERIALIZATION_ERROR_NO_MEMORY;
209 }
210
211 nrf_802154_received_timestamp_raw(p_local_ptr, power, lqi, timestamp);
212
213 return NRF_802154_SERIALIZATION_ERROR_OK;
214 }
215
216 /**
217 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_FAILED
218 *
219 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
220 * @param[in] property_data_len Size of the @ref p_data buffer.
221 */
spinel_decode_prop_nrf_802154_receive_failed(const void * p_property_data,size_t property_data_len)222 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive_failed(
223 const void * p_property_data,
224 size_t property_data_len)
225 {
226 uint8_t error;
227 uint32_t id;
228
229 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
230 property_data_len,
231 SPINEL_DATATYPE_NRF_802154_RECEIVE_FAILED,
232 &error,
233 &id);
234
235 if (siz < 0)
236 {
237 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
238 }
239
240 nrf_802154_receive_failed(error, id);
241
242 return NRF_802154_SERIALIZATION_ERROR_OK;
243 }
244
245 /**
246 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_ACK_STARTED
247 *
248 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
249 * @param[in] property_data_len Size of the @ref p_data buffer.
250 */
spinel_decode_prop_nrf_802154_tx_ack_started(const void * p_property_data,size_t property_data_len)251 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_ack_started(
252 const void * p_property_data,
253 size_t property_data_len)
254 {
255 const uint8_t * p_tx_ack;
256 size_t tx_ack_len;
257
258 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
259 property_data_len,
260 SPINEL_DATATYPE_NRF_802154_TX_ACK_STARTED,
261 &p_tx_ack,
262 &tx_ack_len);
263
264 if ((siz < 0) || (p_tx_ack == NULL) || (p_tx_ack[0] != tx_ack_len))
265 {
266 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
267 }
268
269 nrf_802154_tx_ack_started(p_tx_ack);
270
271 return NRF_802154_SERIALIZATION_ERROR_OK;
272 }
273
274 /**
275 * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMITTED_RAW.
276 *
277 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
278 * @param[in] property_data_len Size of the @ref p_data buffer.
279 */
spinel_decode_prop_nrf_802154_transmitted_raw(const void * p_property_data,size_t property_data_len)280 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmitted_raw(
281 const void * p_property_data,
282 size_t property_data_len)
283 {
284 uint32_t frame_handle;
285 uint32_t remote_ack_handle;
286 void * p_ack;
287 size_t ack_hdata_len;
288 size_t frame_hdata_len;
289 void * p_local_frame;
290 void * p_serialized_frame;
291 void * p_ack_local_ptr = NULL;
292 nrf_802154_transmit_done_metadata_t metadata = {0};
293
294 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
295 property_data_len,
296 SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW,
297 NRF_802154_TRANSMITTED_RAW_DECODE(frame_handle,
298 p_serialized_frame,
299 frame_hdata_len,
300 metadata,
301 remote_ack_handle,
302 ack_hdata_len));
303
304 p_ack = metadata.data.transmitted.p_ack;
305
306 if (siz < 0)
307 {
308 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
309 }
310
311 // Search for the original frame buffer based on the provided handle
312 bool frame_found = nrf_802154_buffer_mgr_src_search_by_buffer_handle(
313 nrf_802154_spinel_src_buffer_mgr_get(),
314 frame_handle,
315 &p_local_frame);
316
317 if (!frame_found)
318 {
319 // The frame is expected to be found, because it's the application that requested
320 // to transmit it in the first place. Return error if it has not been found
321 return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
322 }
323
324 // Handle the Ack
325 if (NRF_802154_DATA_LEN_FROM_HDATA_LEN(ack_hdata_len) == 0)
326 {
327 // Length equal to 0 indicates that p_ack was originally a NULL pointer
328 // Do not handle the Ack
329 }
330 else
331 {
332 // Associate the remote Ack handle with a local pointer and copy the buffer content there
333 bool ack_added = nrf_802154_buffer_mgr_dst_add(
334 nrf_802154_spinel_dst_buffer_mgr_get(),
335 remote_ack_handle,
336 p_ack,
337 NRF_802154_DATA_LEN_FROM_HDATA_LEN(ack_hdata_len),
338 &p_ack_local_ptr);
339
340 if (!ack_added)
341 {
342 return NRF_802154_SERIALIZATION_ERROR_NO_MEMORY;
343 }
344 }
345
346 frame_found = nrf_802154_buffer_mgr_src_remove_by_buffer_handle(
347 nrf_802154_spinel_src_buffer_mgr_get(),
348 frame_handle);
349
350 if (!frame_found)
351 {
352 return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
353 }
354
355 memcpy(p_local_frame,
356 p_serialized_frame,
357 NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len));
358
359 // Overwrite ACK frame pointer with a newly allocated one.
360 metadata.data.transmitted.p_ack = p_ack_local_ptr;
361 nrf_802154_transmitted_raw(p_local_frame, &metadata);
362
363 return NRF_802154_SERIALIZATION_ERROR_OK;
364 }
365
366 /**
367 * @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED.
368 *
369 * @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
370 * @param[in] property_data_len Size of the @ref p_data buffer.
371 */
spinel_decode_prop_nrf_802154_transmit_failed(const void * p_property_data,size_t property_data_len)372 static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_failed(
373 const void * p_property_data,
374 size_t property_data_len)
375 {
376 uint32_t frame_handle;
377 nrf_802154_tx_error_t tx_error;
378 void * p_serialized_frame;
379 void * p_local_frame;
380 size_t frame_hdata_len;
381 nrf_802154_transmit_done_metadata_t metadata = {0};
382
383 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
384 property_data_len,
385 SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED,
386 NRF_802154_TRANSMIT_FAILED_DECODE(frame_handle,
387 p_serialized_frame,
388 frame_hdata_len,
389 tx_error,
390 metadata));
391
392 if (siz < 0)
393 {
394 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
395 }
396
397 // Search for the original frame buffer based on the provided handle
398 bool frame_found = nrf_802154_buffer_mgr_src_search_by_buffer_handle(
399 nrf_802154_spinel_src_buffer_mgr_get(),
400 frame_handle,
401 &p_local_frame);
402
403 if (!frame_found)
404 {
405 // The frame is expected to be found, because it's the application that requested
406 // to transmit it in the first place. Return error if it has not been found
407 return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
408 }
409
410 frame_found = nrf_802154_buffer_mgr_src_remove_by_buffer_handle(
411 nrf_802154_spinel_src_buffer_mgr_get(),
412 frame_handle);
413
414 if (!frame_found)
415 {
416 return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
417 }
418
419 memcpy(p_local_frame,
420 p_serialized_frame,
421 NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len));
422
423 nrf_802154_transmit_failed(p_local_frame, tx_error, &metadata);
424
425 return NRF_802154_SERIALIZATION_ERROR_OK;
426 }
427
nrf_802154_spinel_decode_prop_last_status(const void * p_property_data,size_t property_data_len,spinel_status_t * status)428 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_last_status(
429 const void * p_property_data,
430 size_t property_data_len,
431 spinel_status_t * status)
432 {
433 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
434 property_data_len,
435 SPINEL_DATATYPE_SPINEL_PROP_LAST_STATUS,
436 status);
437
438 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
439 NRF_802154_SERIALIZATION_ERROR_OK);
440 }
441
nrf_802154_spinel_decode_prop_generic_bool(const void * p_property_data,size_t property_data_len,bool * p_bool_response)442 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_bool(
443 const void * p_property_data,
444 size_t property_data_len,
445 bool * p_bool_response)
446 {
447 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
448 property_data_len,
449 SPINEL_DATATYPE_BOOL_S,
450 p_bool_response);
451
452 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
453 NRF_802154_SERIALIZATION_ERROR_OK);
454 }
455
nrf_802154_spinel_decode_prop_generic_uint8(const void * p_property_data,size_t property_data_len,uint8_t * p_uint8_response)456 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_uint8(
457 const void * p_property_data,
458 size_t property_data_len,
459 uint8_t * p_uint8_response)
460 {
461 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
462 property_data_len,
463 SPINEL_DATATYPE_UINT8_S,
464 p_uint8_response);
465
466 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
467 NRF_802154_SERIALIZATION_ERROR_OK);
468 }
469
nrf_802154_spinel_decode_prop_generic_uint16(const void * p_property_data,size_t property_data_len,uint16_t * p_uint16_response)470 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_uint16(
471 const void * p_property_data,
472 size_t property_data_len,
473 uint16_t * p_uint16_response)
474 {
475 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
476 property_data_len,
477 SPINEL_DATATYPE_UINT16_S,
478 p_uint16_response);
479
480 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
481 NRF_802154_SERIALIZATION_ERROR_OK);
482 }
483
nrf_802154_spinel_decode_prop_nrf_802154_tx_power_get_ret(const void * p_property_data,size_t property_data_len,int8_t * p_power)484 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_tx_power_get_ret(
485 const void * p_property_data,
486 size_t property_data_len,
487 int8_t * p_power)
488 {
489 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
490 property_data_len,
491 SPINEL_DATATYPE_NRF_802154_TX_POWER_GET_RET,
492 p_power);
493
494 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
495 NRF_802154_SERIALIZATION_ERROR_OK);
496 }
497
nrf_802154_spinel_decode_prop_nrf_802154_capabilities_get_ret(const void * p_property_data,size_t property_data_len,nrf_802154_capabilities_t * p_capabilities)498 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_capabilities_get_ret(
499 const void * p_property_data,
500 size_t property_data_len,
501 nrf_802154_capabilities_t * p_capabilities)
502 {
503 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
504 property_data_len,
505 SPINEL_DATATYPE_NRF_802154_CAPABILITIES_GET_RET,
506 p_capabilities);
507
508 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
509 NRF_802154_SERIALIZATION_ERROR_OK);
510 }
511
nrf_802154_spinel_decode_prop_nrf_802154_time_get_ret(const void * p_property_data,size_t property_data_len,uint64_t * p_time)512 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_time_get_ret(
513 const void * p_property_data,
514 size_t property_data_len,
515 uint64_t * p_time)
516 {
517 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
518 property_data_len,
519 SPINEL_DATATYPE_NRF_802154_TIME_GET_RET,
520 p_time);
521
522 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
523 NRF_802154_SERIALIZATION_ERROR_OK);
524 }
525
nrf_802154_spinel_decode_prop_nrf_802154_cca_cfg_get_ret(const void * p_property_data,size_t property_data_len,nrf_802154_cca_cfg_t * p_cfg)526 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_cca_cfg_get_ret(
527 const void * p_property_data,
528 size_t property_data_len,
529 nrf_802154_cca_cfg_t * p_cfg)
530 {
531 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
532 property_data_len,
533 SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET_RET,
534 NRF_802154_CCA_CFG_DECODE(*p_cfg));
535
536 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
537 NRF_802154_SERIALIZATION_ERROR_OK);
538 }
539
nrf_802154_spinel_decode_prop_nrf_802154_stat_timestamps_get_ret(const void * p_property_data,size_t property_data_len,nrf_802154_stat_timestamps_t * p_stat_timestamps)540 nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_stat_timestamps_get_ret(
541 const void * p_property_data,
542 size_t property_data_len,
543 nrf_802154_stat_timestamps_t * p_stat_timestamps)
544 {
545 spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
546 property_data_len,
547 SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET_RET,
548 NRF_802154_STAT_TIMESTAMPS_DECODE(
549 *p_stat_timestamps));
550
551 return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
552 NRF_802154_SERIALIZATION_ERROR_OK);
553 }
554
nrf_802154_spinel_decode_cmd_prop_value_is(const void * p_cmd_data,size_t cmd_data_len)555 nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is(
556 const void * p_cmd_data,
557 size_t cmd_data_len)
558 {
559 spinel_prop_key_t property;
560 const void * p_property_data;
561 size_t property_data_len;
562 spinel_ssize_t siz;
563
564 siz = spinel_datatype_unpack(p_cmd_data,
565 cmd_data_len,
566 SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_DATA_S,
567 &property,
568 &p_property_data,
569 &property_data_len);
570
571 if (siz < 0)
572 {
573 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
574 }
575
576 switch (property)
577 {
578 case SPINEL_PROP_LAST_STATUS:
579 // fall through
580 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SLEEP:
581 // fall through
582 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SLEEP_IF_IDLE:
583 // fall through
584 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE:
585 // fall through
586 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT:
587 // fall through
588 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL:
589 // fall through
590 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA:
591 // fall through
592 #if NRF_802154_CARRIER_FUNCTIONS_ENABLED
593 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER:
594 // fall through
595 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER:
596 // fall through
597 #endif
598 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION:
599 // fall through
600 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_POWER_GET:
601 // fall through
602 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CHANNEL_GET:
603 // fall through
604 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CAPABILITIES_GET:
605 // fall through
606 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TIME_GET:
607 // fall through
608 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET:
609 // fall through
610 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE:
611 // fall through
612 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE:
613 // fall through
614 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_SET:
615 // fall through
616 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_CLEAR:
617 // fall through
618 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_SET:
619 // fall through
620 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_CLEAR:
621 // fall through
622 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW:
623 // fall through
624 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT:
625 // fall through
626 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL:
627 // fall through
628 #if NRF_802154_CSMA_CA_ENABLED
629 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_CSMA_CA_RAW:
630 // fall through
631 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET:
632 // fall through
633 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET:
634 // fall through
635 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET:
636 // fall through
637 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET:
638 // fall through
639 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET:
640 // fall through
641 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET:
642 // fall through
643 #endif // NRF_802154_CSMA_CA_ENABLED
644 #if NRF_802154_TEST_MODES_ENABLED
645 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TEST_MODE_CSMACA_BACKOFF_SET:
646 // fall through
647 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TEST_MODE_CSMACA_BACKOFF_GET:
648 // fall through
649 #endif // NRF_802154_TEST_MODES_ENABLED
650 #if NRF_802154_IFS_ENABLED
651 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_IFS_MODE_SET:
652 // fall through
653 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_IFS_MODE_GET:
654 // fall through
655 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_IFS_MIN_SIFS_PERIOD_GET:
656 // fall through
657 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_IFS_MIN_LIFS_PERIOD_GET:
658 // fall through
659 #endif // NRF_802154_IFS_ENABLED
660 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET:
661 nrf_802154_spinel_response_notifier_property_notify(property,
662 p_property_data,
663 property_data_len);
664 return NRF_802154_SERIALIZATION_ERROR_OK;
665
666 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_DONE:
667 return spinel_decode_prop_nrf_802154_cca_done(p_property_data,
668 property_data_len);
669
670 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_FAILED:
671 return spinel_decode_prop_nrf_802154_cca_failed(p_property_data,
672 property_data_len);
673
674 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTED:
675 return spinel_decode_prop_nrf_802154_energy_detected(p_property_data,
676 property_data_len);
677
678 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION_FAILED:
679 return spinel_decode_prop_nrf_802154_energy_detection_failed(p_property_data,
680 property_data_len);
681
682 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVED_TIMESTAMP_RAW:
683 return spinel_decode_prop_nrf_802154_received_timestamp_raw(p_property_data,
684 property_data_len);
685
686 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMITTED_RAW:
687 return spinel_decode_prop_nrf_802154_transmitted_raw(p_property_data,
688 property_data_len);
689
690 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_FAILED:
691 return spinel_decode_prop_nrf_802154_transmit_failed(p_property_data,
692 property_data_len);
693
694 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_FAILED:
695 return spinel_decode_prop_nrf_802154_receive_failed(p_property_data,
696 property_data_len);
697
698 case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_ACK_STARTED:
699 return spinel_decode_prop_nrf_802154_tx_ack_started(p_property_data,
700 property_data_len);
701
702 default:
703 NRF_802154_SPINEL_LOG_RAW("Unsupported property: %s(%u)\n",
704 spinel_prop_key_to_cstr(property),
705 property);
706 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
707 }
708 }
709
nrf_802154_spinel_dispatch_cmd(spinel_command_t cmd,const void * p_cmd_data,size_t cmd_data_len)710 nrf_802154_ser_err_t nrf_802154_spinel_dispatch_cmd(spinel_command_t cmd,
711 const void * p_cmd_data,
712 size_t cmd_data_len)
713 {
714 switch (cmd)
715 {
716 case SPINEL_CMD_PROP_VALUE_IS:
717 return nrf_802154_spinel_decode_cmd_prop_value_is(p_cmd_data, cmd_data_len);
718
719 default:
720 NRF_802154_SPINEL_LOG_RAW("Unsupported command: %s(%u)\n",
721 spinel_command_to_cstr(cmd),
722 cmd);
723 return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
724 }
725 }
726
727 #ifndef TEST
nrf_802154_received_timestamp_raw(uint8_t * p_data,int8_t rssi,uint8_t lqi,uint64_t timestamp)728 __WEAK void nrf_802154_received_timestamp_raw(uint8_t * p_data,
729 int8_t rssi,
730 uint8_t lqi,
731 uint64_t timestamp)
732 {
733 (void)p_data;
734 (void)rssi;
735 (void)lqi;
736 (void)timestamp;
737 // Intentionally empty
738 }
739
nrf_802154_receive_failed(nrf_802154_rx_error_t error,uint32_t id)740 __WEAK void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
741 {
742 (void)error;
743 (void)id;
744 // Intentionally empty
745 }
746
nrf_802154_transmitted_raw(uint8_t * p_data,const nrf_802154_transmit_done_metadata_t * p_metadata)747 __WEAK void nrf_802154_transmitted_raw(uint8_t * p_data,
748 const nrf_802154_transmit_done_metadata_t * p_metadata)
749 {
750 (void)p_data;
751 (void)p_metadata;
752 // Intentionally empty
753 }
754
nrf_802154_transmit_failed(uint8_t * p_data,nrf_802154_tx_error_t error,const nrf_802154_transmit_done_metadata_t * p_metadata)755 __WEAK void nrf_802154_transmit_failed(uint8_t * p_data,
756 nrf_802154_tx_error_t error,
757 const nrf_802154_transmit_done_metadata_t * p_metadata)
758 {
759 (void)p_data;
760 (void)error;
761 (void)p_metadata;
762 // Intentionally empty
763 }
764
nrf_802154_tx_ack_started(const uint8_t * p_data)765 __WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data)
766 {
767 (void)p_data;
768 // Intentionally empty
769 }
770
nrf_802154_cca_done(bool channel_free)771 __WEAK void nrf_802154_cca_done(bool channel_free)
772 {
773 (void)channel_free;
774 // Intentionally empty
775 }
776
nrf_802154_cca_failed(nrf_802154_cca_error_t error)777 __WEAK void nrf_802154_cca_failed(nrf_802154_cca_error_t error)
778 {
779 (void)error;
780 // Intentionally empty
781 }
782
nrf_802154_energy_detected(uint8_t ed_level)783 __WEAK void nrf_802154_energy_detected(uint8_t ed_level)
784 {
785 (void)ed_level;
786 // Intentionally empty
787 }
788
nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)789 __WEAK void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)
790 {
791 (void)error;
792 // Intentionally empty
793 }
794
795 #endif // TEST
796