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