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                                                 &timestamp);
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