1 /*
2  * Copyright (c) 2018, 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 /**
36  * @brief Module that contains frame parsing utilities for the 802.15.4 radio driver.
37  *
38  */
39 
40 #ifndef NRF_802154_FRAME_PARSER_H
41 #define NRF_802154_FRAME_PARSER_H
42 
43 #include "nrf_802154_const.h"
44 #include "nrf_802154_utils_byteorder.h"
45 #include <stdbool.h>
46 #include <stdint.h>
47 #include <stddef.h>
48 
49 #define NRF_802154_FRAME_PARSER_INVALID_OFFSET 0xff
50 
51 typedef enum
52 {
53     /**
54      * @brief Parse level at which no parsing has been performed on the frame.
55      *
56      * All frame fields and offsets should be considered as incomplete and invalid at this parse level.
57      */
58     PARSE_LEVEL_NONE,
59 
60     /**
61      * @brief Parse level at which the offsets that can be determined based on the FCF can be considered valid.
62      *
63      * The following fields can be considered valid and complete:
64      *    - FCF field
65      *
66      * The following offsets can be considered valid by the user:
67      *    - DSN field offset
68      *    - Addressing offsets
69      * The data stored under the offsets should be considered as incomplete.
70      */
71     PARSE_LEVEL_FCF_OFFSETS,
72 
73     /**
74      * @brief Parse level at which the destination address data can be considered complete.
75      *
76      * The following fields can be considered valid and complete:
77      *    - DSN field
78      *    - Destination addressing fields
79      * The completeness doesn't indicate that the fields are actually present in the frame.
80      */
81     PARSE_LEVEL_DST_ADDRESSING_END,
82 
83     /**
84      * @brief Parse level at which the data under offsets determined by the FCF can be considered complete.
85      *
86      * The following fields can be considered valid and complete:
87      *    - DSN field
88      *    - Addressing fields
89      * The completeness doesn't indicate that the fields are actually present in the frame.
90      */
91     PARSE_LEVEL_ADDRESSING_END,
92 
93     /**
94      * @brief Parse level at which the offsets that can be determined based on Security Control Field can be considered valid.
95      *
96      * The following offsets can be considered valid by the user:
97      *    - All offsets before the Auxiliary Security Header
98      *    - All Auxiliary Security Header field offsets and field sizes
99      * The data stored under the offsets should be considered as incomplete.
100      */
101     PARSE_LEVEL_SEC_CTRL_OFFSETS,
102 
103     /**
104      * @brief Parse level at which the data under offsets determined by the Security Control Field can be considered complete.
105      *
106      * The following fields can be considered valid and complete:
107      *    - All fields before the Auxiliary Security Header
108      *    - All Auxiliary Security Header fields
109      * The completeness doesn't indicate that the fields are actually present in the frame.
110      */
111     PARSE_LEVEL_AUX_SEC_HDR_END,
112 
113     /**
114      * @brief Parse level for fully parsed frame. All fields can be considered valid and complete.
115      *
116      * The following fields can be considered valid and complete:
117      *    - All fields in the frame
118      * The completeness doesn't indicate that the fields are actually present in the frame.
119      *
120      * This is the only parse level at which the PSDU length is taken into account and is expected to be correct.
121      */
122     PARSE_LEVEL_FULL,
123 
124     PARSE_LEVEL_MAX = PARSE_LEVEL_FULL
125 } nrf_802154_frame_parser_level_t;
126 
127 typedef struct
128 {
129     const uint8_t                 * p_frame;        ///< Pointer to a frame associated with parser data.
130     nrf_802154_frame_parser_level_t parse_level;    ///< Current frame parse level.
131     uint8_t                         valid_data_len; ///< Number of valid bytes in the frame.
132 
133     struct
134     {
135         struct
136         {
137             uint8_t panid_offset; ///< Destination PAN ID offset.
138             uint8_t addr_offset;  ///< Destination address offset.
139         } dst;
140 
141         struct
142         {
143             uint8_t panid_offset; ///< Source PAN ID offset.
144             uint8_t addr_offset;  ///< Source address offset.
145         } src;
146 
147         struct
148         {
149             uint8_t sec_ctrl_offset;      ///< Security Control Field offset.
150             uint8_t frame_counter_offset; ///< Frame Counter field offset.
151             uint8_t key_id_offset;        ///< Key ID offset.
152             uint8_t key_src_offset;       ///< Key Source offset.
153             uint8_t key_idx_offset;       ///< Key Index offset.
154         }       aux_sec_hdr;
155 
156         uint8_t header_ie_offset;         ///< Header IE offset.
157     } mhr;
158 
159     struct
160     {
161         uint8_t mac_payload_offset; ///< MAC payload offset.
162     } mac_payload;
163 
164     struct
165     {
166         uint8_t dst_addr_size;             ///< Destination address size;
167         uint8_t src_addr_size;             ///< Source address size;
168         uint8_t dst_addressing_end_offset; ///< Destination addressing end offset.
169         uint8_t addressing_end_offset;     ///< Addressing end offset.
170         uint8_t aux_sec_hdr_end_offset;    ///< Auxiliary Security Header offset.
171         uint8_t key_src_size;              ///< Key Source size.
172         uint8_t mic_size;                  ///< Message Integrity Code size.
173     } helper;
174 } nrf_802154_frame_parser_data_t;
175 
176 /**
177  * @brief Initializes the frame parse data and parses the frame.
178  *
179  * This function initializes and parses the given frame to the requested level.
180  * The parsing is performed to the extent that is achievable with the amount
181  * of valid data. The resulting parse level may be higher that the requested one,
182  * if it can be achieved without additional parsing.
183  *
184  * @param[in]    p_frame               Pointer to a frame.
185  * @param[in]    valid_data_len        Number of valid bytes in the frame.
186  * @param[in]    requested_parse_level Requested parse level.
187  * @param[out]   p_parser_data         Pointer to a parser data that will be initialized.
188  *
189  * @retval  true  The parsing succeeded and requested parse level was achieved.
190  * @retval  false The parsing failed or requested parse level could not be achieved.
191  */
192 bool nrf_802154_frame_parser_data_init(const uint8_t                  * p_frame,
193                                        uint8_t                          valid_data_len,
194                                        nrf_802154_frame_parser_level_t  requested_parse_level,
195                                        nrf_802154_frame_parser_data_t * p_parser_data);
196 
197 /**
198  * @brief Extends the valid data and parses the frame.
199  *
200  * This function extends the valid data and parses the given frame to the requested level.
201  * The parsing is performed to the extent that is achievable with the amount
202  * of valid data. The resulting parse level may be higher that the requested one,
203  * if it can be achieved without additional parsing.
204  *
205  * @param[inout] p_parser_data         Pointer to a parser data to extend.
206  * @param[in]    valid_data_len        Number of valid bytes in the frame.
207  * @param[in]    requested_parse_level Requested parse level.
208  *
209  * @retval  true  The parsing succeeded and requested parse level was achieved.
210  * @retval  false The parsing failed or requested parse level could not be achieved.
211  */
212 bool nrf_802154_frame_parser_valid_data_extend(nrf_802154_frame_parser_data_t * p_parser_data,
213                                                uint8_t                          valid_data_len,
214                                                nrf_802154_frame_parser_level_t  requested_parse_level);
215 
216 /**
217  * @brief Gets current parse level of the provided parser data.
218  *
219  * @param[in] p_parser_data  Pointer to a parser data to check.
220  *
221  * @returns Current parse level of @p p_parser_data.
222  */
nrf_802154_frame_parser_parse_level_get(const nrf_802154_frame_parser_data_t * p_parser_data)223 static inline nrf_802154_frame_parser_level_t nrf_802154_frame_parser_parse_level_get(
224     const nrf_802154_frame_parser_data_t * p_parser_data)
225 {
226     return p_parser_data->parse_level;
227 }
228 
229 /**
230  * @brief Gets the PSDU length of the frame.
231  *
232  * @param[in]   p_parser_data   Pointer to a frame parser data.
233  *
234  * @returns  PSDU length of the frame.
235  *
236  * @note This function assumes that the PHR is correct.
237  */
nrf_802154_frame_parser_frame_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)238 static inline uint8_t nrf_802154_frame_parser_frame_length_get(
239     const nrf_802154_frame_parser_data_t * p_parser_data)
240 {
241     return p_parser_data->p_frame[PHR_OFFSET];
242 }
243 
244 /**
245  * @brief Gets the PSDU start offset of the frame.
246  *
247  * @param[in]   p_parser_data   Pointer to a frame parser data.
248  *
249  * @returns  PSDU start offset of the frame.
250  */
nrf_802154_frame_parser_psdu_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)251 static inline uint8_t nrf_802154_frame_parser_psdu_offset_get(
252     const nrf_802154_frame_parser_data_t * p_parser_data)
253 {
254     return PSDU_OFFSET;
255 }
256 
257 /**
258  * @brief Gets the PSDU start address of the frame.
259  *
260  * @param[in]   p_parser_data   Pointer to a frame parser data.
261  *
262  * @returns  PSDU start address of the frame.
263  */
nrf_802154_frame_parser_psdu_get(const nrf_802154_frame_parser_data_t * p_parser_data)264 static inline const uint8_t * nrf_802154_frame_parser_psdu_get(
265     const nrf_802154_frame_parser_data_t * p_parser_data)
266 {
267     return &p_parser_data->p_frame[PSDU_OFFSET];
268 }
269 
270 /**
271  * @brief Gets the MAC frame version value from the Frame Control Field.
272  *
273  * @param[in]   p_parser_data   Pointer to a frame parser data.
274  *
275  * @returns  Masked MAC frame version value.
276  */
nrf_802154_frame_parser_frame_version_get(const nrf_802154_frame_parser_data_t * p_parser_data)277 static inline uint8_t nrf_802154_frame_parser_frame_version_get(
278     const nrf_802154_frame_parser_data_t * p_parser_data)
279 {
280     return p_parser_data->p_frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK;
281 }
282 
283 /**
284  * @brief Gets the value of the DSN suppress bit from the Frame Control Field.
285  *
286  * @param[in]   p_parser_data   Pointer to a frame parser data.
287  *
288  * @retval  true  DSN suppress bit is set.
289  * @retval  false DSN suppress bit is not set.
290  */
nrf_802154_frame_parser_dsn_suppress_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)291 static inline bool nrf_802154_frame_parser_dsn_suppress_bit_is_set(
292     const nrf_802154_frame_parser_data_t * p_parser_data)
293 {
294     return (p_parser_data->p_frame[DSN_SUPPRESS_OFFSET] & DSN_SUPPRESS_BIT) ? true : false;
295 }
296 
297 /**
298  * @brief Gets the MAC frame destination address type from the Frame Control Field.
299  *
300  * @param[in]   p_parser_data   Pointer to a frame parser data.
301  *
302  * @returns  Masked MAC frame destination address type.
303  */
nrf_802154_frame_parser_dst_addr_type_get(const nrf_802154_frame_parser_data_t * p_parser_data)304 static inline uint8_t nrf_802154_frame_parser_dst_addr_type_get(
305     const nrf_802154_frame_parser_data_t * p_parser_data)
306 {
307     return p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK;
308 }
309 
310 /**
311  * @brief Determines if the destination address is extended.
312  *
313  * @param[in]   p_parser_data   Pointer to a frame parser data.
314  *
315  * @retval  true  The destination address is extended.
316  * @retval  false The destination address is not extended.
317  */
nrf_802154_frame_parser_dst_addr_is_extended(const nrf_802154_frame_parser_data_t * p_parser_data)318 static inline bool nrf_802154_frame_parser_dst_addr_is_extended(
319     const nrf_802154_frame_parser_data_t * p_parser_data)
320 {
321     return (p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) ==
322            DEST_ADDR_TYPE_EXTENDED;
323 }
324 
325 /**
326  * @brief Gets the MAC frame source address type from the Frame Control Field.
327  *
328  * @param[in]   p_parser_data   Pointer to a frame parser data.
329  *
330  * @returns  Masked MAC frame source address type.
331  */
nrf_802154_frame_parser_src_addr_type_get(const nrf_802154_frame_parser_data_t * p_parser_data)332 static inline uint8_t nrf_802154_frame_parser_src_addr_type_get(
333     const nrf_802154_frame_parser_data_t * p_parser_data)
334 {
335     return p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK;
336 }
337 
338 /**
339  * @brief Determines if the source address is extended.
340  *
341  * @param[in]   p_parser_data   Pointer to a frame parser data.
342  *
343  * @retval  true  The destination address is extended.
344  * @retval  false The destination address is not extended.
345  */
nrf_802154_frame_parser_src_addr_is_extended(const nrf_802154_frame_parser_data_t * p_parser_data)346 static inline bool nrf_802154_frame_parser_src_addr_is_extended(
347     const nrf_802154_frame_parser_data_t * p_parser_data)
348 {
349     return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) ==
350            SRC_ADDR_TYPE_EXTENDED;
351 }
352 
353 /**
354  * @brief Determines if the source address is short.
355  *
356  * @param[in]   p_parser_data   Pointer to a frame parser data.
357  *
358  * @retval  true  The destination address is short.
359  * @retval  false The destination address is not short.
360  */
nrf_802154_frame_parser_src_addr_is_short(const nrf_802154_frame_parser_data_t * p_parser_data)361 static inline bool nrf_802154_frame_parser_src_addr_is_short(
362     const nrf_802154_frame_parser_data_t * p_parser_data)
363 {
364     return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) ==
365            SRC_ADDR_TYPE_SHORT;
366 }
367 
368 /**
369  * @brief Gets the value of the Security Enabled bit from the Frame Control Field.
370  *
371  * @param[in]   p_parser_data   Pointer to a frame parser data.
372  *
373  * @retval  true  The security is enabled.
374  * @retval  false The security is not enabled.
375  */
nrf_802154_frame_parser_security_enabled_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)376 static inline bool nrf_802154_frame_parser_security_enabled_bit_is_set(
377     const nrf_802154_frame_parser_data_t * p_parser_data)
378 {
379     return (p_parser_data->p_frame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT) ? true : false;
380 }
381 
382 /**
383  * @brief Gets the value of the IE present bit from the Frame Control Field.
384  *
385  * @param[in]   p_parser_data   Pointer to a frame parser data.
386  *
387  * @retval  true  The Information Elements are present.
388  * @retval  false The Information Elements are not present.
389  */
nrf_802154_frame_parser_ie_present_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)390 static inline bool nrf_802154_frame_parser_ie_present_bit_is_set(
391     const nrf_802154_frame_parser_data_t * p_parser_data)
392 {
393     return (p_parser_data->p_frame[IE_PRESENT_OFFSET] & IE_PRESENT_BIT) ? true : false;
394 }
395 
396 /**
397  * @brief Gets the value of the frame type field from the Frame Control Field.
398  *
399  * @param[in]   p_parser_data   Pointer to a frame parser data.
400  *
401  * @returns  Masked value of the frame type.
402  */
nrf_802154_frame_parser_frame_type_get(const nrf_802154_frame_parser_data_t * p_parser_data)403 static inline uint8_t nrf_802154_frame_parser_frame_type_get(
404     const nrf_802154_frame_parser_data_t * p_parser_data)
405 {
406     return p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK;
407 }
408 
409 /**
410  * @brief Gets the value of the PAN ID compressions bit from the Frame Control Field.
411  *
412  * @param[in]   p_parser_data   Pointer to a frame parser data.
413  *
414  * @retval  true  PAN ID compressions is set.
415  * @retval  false PAN ID compressions is not set.
416  */
nrf_802154_frame_parser_panid_compression_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)417 static inline bool nrf_802154_frame_parser_panid_compression_is_set(
418     const nrf_802154_frame_parser_data_t * p_parser_data)
419 {
420     return (p_parser_data->p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK) ? true : false;
421 }
422 
423 /**
424  * @brief Gets the value of the AR bit from the Frame Control Field.
425  *
426  * @param[in]   p_parser_data   Pointer to a frame parser data.
427  *
428  * @retval  true  AR bit is set.
429  * @retval  false AR bit is not set.
430  */
nrf_802154_frame_parser_ar_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)431 static inline bool nrf_802154_frame_parser_ar_bit_is_set(
432     const nrf_802154_frame_parser_data_t * p_parser_data)
433 {
434     if ((p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) == FRAME_TYPE_MULTIPURPOSE)
435     {
436         return false;
437     }
438     else
439     {
440         return (p_parser_data->p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false;
441     }
442 }
443 
444 /**
445  * @brief Gets the value of the DSN field.
446  *
447  * @param[in]   p_parser_data   Pointer to a frame parser data.
448  *
449  * @returns  The value of the DSN field.
450  */
nrf_802154_frame_parser_dsn_get(const nrf_802154_frame_parser_data_t * p_parser_data)451 static inline const uint8_t * nrf_802154_frame_parser_dsn_get(
452     const nrf_802154_frame_parser_data_t * p_parser_data)
453 {
454     if (nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_parser_data))
455     {
456         return NULL;
457     }
458 
459     return &p_parser_data->p_frame[DSN_OFFSET];
460 }
461 
462 /**
463  * @brief Gets the offset of the Destination PAN ID field.
464  *
465  * @param[in]   p_parser_data   Pointer to a frame parser data.
466  *
467  * @returns  Offset of the Destination PAN ID field.
468  */
nrf_802154_frame_parser_dst_panid_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)469 static inline uint8_t nrf_802154_frame_parser_dst_panid_offset_get(
470     const nrf_802154_frame_parser_data_t * p_parser_data)
471 {
472     return p_parser_data->mhr.dst.panid_offset;
473 }
474 
475 /**
476  * @brief Gets the address of the Destination PAN field.
477  *
478  * @param[in]   p_parser_data   Pointer to a frame parser data.
479  *
480  * @returns  Address of the Destination PAN field.
481  */
nrf_802154_frame_parser_dst_panid_get(const nrf_802154_frame_parser_data_t * p_parser_data)482 static inline const uint8_t * nrf_802154_frame_parser_dst_panid_get(
483     const nrf_802154_frame_parser_data_t * p_parser_data)
484 {
485     uint8_t offset = nrf_802154_frame_parser_dst_panid_offset_get(p_parser_data);
486 
487     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
488     {
489         return NULL;
490     }
491 
492     return &p_parser_data->p_frame[offset];
493 }
494 
495 /**
496  * @brief Gets the offset of frame Destination Address.
497  *
498  * @param[in]   p_parser_data   Pointer to a frame parser data.
499  *
500  * @returns  Offset of the frame Destination Address field.
501  */
nrf_802154_frame_parser_dst_addr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)502 static inline uint8_t nrf_802154_frame_parser_dst_addr_offset_get(
503     const nrf_802154_frame_parser_data_t * p_parser_data)
504 {
505     return p_parser_data->mhr.dst.addr_offset;
506 }
507 
508 /**
509  * @brief Gets the address of the Destination Address field.
510  *
511  * @param[in]   p_parser_data   Pointer to a frame parser data.
512  *
513  * @returns  Address of the Destination Address field.
514  */
nrf_802154_frame_parser_dst_addr_get(const nrf_802154_frame_parser_data_t * p_parser_data)515 static inline const uint8_t * nrf_802154_frame_parser_dst_addr_get(
516     const nrf_802154_frame_parser_data_t * p_parser_data)
517 {
518     uint8_t offset = nrf_802154_frame_parser_dst_addr_offset_get(p_parser_data);
519 
520     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
521     {
522         return NULL;
523     }
524 
525     return &p_parser_data->p_frame[offset];
526 }
527 
528 /**
529  * @brief Gets the offset of frame Source PAN ID.
530  *
531  * @param[in]   p_parser_data   Pointer to a frame parser data.
532  *
533  * @returns  Offset of the frame Source PAN ID field.
534  */
nrf_802154_frame_parser_src_panid_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)535 static inline uint8_t nrf_802154_frame_parser_src_panid_offset_get(
536     const nrf_802154_frame_parser_data_t * p_parser_data)
537 {
538     return p_parser_data->mhr.src.panid_offset;
539 }
540 
541 /**
542  * @brief Gets the address of the Source PAN ID field.
543  *
544  * @param[in]   p_parser_data   Pointer to a frame parser data.
545  *
546  * @returns  Address of the Source PAN ID field.
547  */
nrf_802154_frame_parser_src_panid_get(const nrf_802154_frame_parser_data_t * p_parser_data)548 static inline const uint8_t * nrf_802154_frame_parser_src_panid_get(
549     const nrf_802154_frame_parser_data_t * p_parser_data)
550 {
551     uint8_t offset = nrf_802154_frame_parser_src_panid_offset_get(p_parser_data);
552 
553     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
554     {
555         return NULL;
556     }
557 
558     return &p_parser_data->p_frame[offset];
559 }
560 
561 /**
562  * @brief Gets the offset of frame Source Address.
563  *
564  * @param[in]   p_parser_data   Pointer to a frame parser data.
565  *
566  * @returns  Offset of the frame Source Address field.
567  */
nrf_802154_frame_parser_src_addr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)568 static inline uint8_t nrf_802154_frame_parser_src_addr_offset_get(
569     const nrf_802154_frame_parser_data_t * p_parser_data)
570 {
571     return p_parser_data->mhr.src.addr_offset;
572 }
573 
574 /**
575  * @brief Gets the address of the Source Address field.
576  *
577  * @param[in]   p_parser_data   Pointer to a frame parser data.
578  *
579  * @returns  Address of the Source Address field.
580  */
nrf_802154_frame_parser_src_addr_get(const nrf_802154_frame_parser_data_t * p_parser_data)581 static inline const uint8_t * nrf_802154_frame_parser_src_addr_get(
582     const nrf_802154_frame_parser_data_t * p_parser_data)
583 {
584     uint8_t offset = nrf_802154_frame_parser_src_addr_offset_get(p_parser_data);
585 
586     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
587     {
588         return NULL;
589     }
590 
591     return &p_parser_data->p_frame[offset];
592 }
593 
594 /**
595  * @brief Gets the size of the source address.
596  *
597  * @param[in]   p_parser_data   Pointer to a frame parser data.
598  *
599  * @returns  Source address size in bytes.
600  */
nrf_802154_frame_parser_src_addr_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)601 static inline uint8_t nrf_802154_frame_parser_src_addr_size_get(
602     const nrf_802154_frame_parser_data_t * p_parser_data)
603 {
604     return p_parser_data->helper.src_addr_size;
605 }
606 
607 /**
608  * @brief Gets the size of the destination address.
609  *
610  * @param[in]   p_parser_data   Pointer to a frame parser data.
611  *
612  * @returns  Destination address size in bytes.
613  */
nrf_802154_frame_parser_dst_addr_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)614 static inline uint8_t nrf_802154_frame_parser_dst_addr_size_get(
615     const nrf_802154_frame_parser_data_t * p_parser_data)
616 {
617     return p_parser_data->helper.dst_addr_size;
618 }
619 
620 /**
621  * @brief Gets the offset of the Security Control Field.
622  *
623  * @param[in]   p_parser_data   Pointer to a frame parser data.
624  *
625  * @returns  Offset of the Security Control Field.
626  */
nrf_802154_frame_parser_sec_ctrl_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)627 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_offset_get(
628     const nrf_802154_frame_parser_data_t * p_parser_data)
629 {
630     return p_parser_data->mhr.aux_sec_hdr.sec_ctrl_offset;
631 }
632 
633 /**
634  * @brief Gets the value of the Security Level field from the Security Control Field.
635  *
636  * @param[in]   p_parser_data   Pointer to a frame parser data.
637  *
638  * @returns  Masked Security Level field value.
639  */
nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(const nrf_802154_frame_parser_data_t * p_parser_data)640 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(
641     const nrf_802154_frame_parser_data_t * p_parser_data)
642 {
643     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
644 
645     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
646     {
647         return 0;
648     }
649 
650     return p_parser_data->p_frame[offset] & SECURITY_LEVEL_MASK;
651 }
652 
653 /**
654  * @brief Gets the value of the Frame Counter Suppress bit from the Security Control Field.
655  *
656  * @param[in]   p_parser_data   Pointer to a frame parser data.
657  *
658  * @retval  true  FC suppress bit is set.
659  * @retval  false FC suppress bit is not set.
660  */
nrf_802154_frame_parser_sec_ctrl_fc_suppress_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)661 static inline bool nrf_802154_frame_parser_sec_ctrl_fc_suppress_bit_is_set(
662     const nrf_802154_frame_parser_data_t * p_parser_data)
663 {
664     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
665 
666     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
667     {
668         return false;
669     }
670 
671     return p_parser_data->p_frame[offset] & FRAME_COUNTER_SUPPRESS_BIT;
672 }
673 
674 /**
675  * @brief Gets the value of the Key ID Mode field from the Security Control Field.
676  *
677  * @param[in]   p_parser_data   Pointer to a frame parser data.
678  *
679  * @returns  Masked Key ID Mode field value.
680  */
nrf_802154_frame_parser_sec_ctrl_key_id_mode_get(const nrf_802154_frame_parser_data_t * p_parser_data)681 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_key_id_mode_get(
682     const nrf_802154_frame_parser_data_t * p_parser_data)
683 {
684     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
685 
686     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
687     {
688         return 0;
689     }
690 
691     return (p_parser_data->p_frame[offset] & KEY_ID_MODE_MASK) >> KEY_ID_MODE_BIT_OFFSET;
692 }
693 
694 /**
695  * @brief Gets the value of the ASN in Nonce bit from the Security Control Field.
696  *
697  * @param[in]   p_parser_data   Pointer to a frame parser data.
698  *
699  * @retval  true  ASN in Nonce bit is set.
700  * @retval  false ASN in Nonce bit is not set.
701  */
nrf_802154_frame_parser_sec_ctrl_asn_in_nonce_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)702 static inline bool nrf_802154_frame_parser_sec_ctrl_asn_in_nonce_bit_is_set(
703     const nrf_802154_frame_parser_data_t * p_parser_data)
704 {
705     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
706 
707     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
708     {
709         return false;
710     }
711 
712     return p_parser_data->p_frame[offset] & ASN_IN_NONCE_BIT;
713 }
714 
715 /**
716  * @brief Gets the address of the Security Control Field.
717  *
718  * @param[in]   p_parser_data   Pointer to a frame parser data.
719  *
720  * @returns  Address of the Security Control Field.
721  */
nrf_802154_frame_parser_sec_ctrl_get(const nrf_802154_frame_parser_data_t * p_parser_data)722 static inline const uint8_t * nrf_802154_frame_parser_sec_ctrl_get(
723     const nrf_802154_frame_parser_data_t * p_parser_data)
724 {
725     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
726 
727     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
728     {
729         return NULL;
730     }
731 
732     return &p_parser_data->p_frame[offset];
733 }
734 
735 /**
736  * @brief Gets the offset of the Frame Counter field.
737  *
738  * @param[in]   p_parser_data   Pointer to a frame parser data.
739  *
740  * @returns  Offset of the Frame Counter field.
741  */
nrf_802154_frame_parser_frame_counter_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)742 static inline uint8_t nrf_802154_frame_parser_frame_counter_offset_get(
743     const nrf_802154_frame_parser_data_t * p_parser_data)
744 {
745     return p_parser_data->mhr.aux_sec_hdr.frame_counter_offset;
746 }
747 
748 /**
749  * @brief Gets the address of the Frame Counter field.
750  *
751  * @param[in]   p_parser_data   Pointer to a frame parser data.
752  *
753  * @returns  Address of the Frame Counter field.
754  */
nrf_802154_frame_parser_frame_counter_get(const nrf_802154_frame_parser_data_t * p_parser_data)755 static inline const uint8_t * nrf_802154_frame_parser_frame_counter_get(
756     const nrf_802154_frame_parser_data_t * p_parser_data)
757 {
758     uint8_t offset = nrf_802154_frame_parser_frame_counter_offset_get(p_parser_data);
759 
760     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
761     {
762         return NULL;
763     }
764 
765     return &p_parser_data->p_frame[offset];
766 }
767 
768 /**
769  * @brief Gets the offset of the Key ID field.
770  *
771  * @param[in]   p_parser_data   Pointer to a frame parser data.
772  *
773  * @returns  Offset of the Key ID field.
774  */
nrf_802154_frame_parser_key_id_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)775 static inline uint8_t nrf_802154_frame_parser_key_id_offset_get(
776     const nrf_802154_frame_parser_data_t * p_parser_data)
777 {
778     return p_parser_data->mhr.aux_sec_hdr.key_id_offset;
779 }
780 
781 /**
782  * @brief Gets the address of the Key ID field.
783  *
784  * @param[in]   p_parser_data   Pointer to a frame parser data.
785  *
786  * @returns  Address of the Key ID field.
787  */
nrf_802154_frame_parser_key_id_get(const nrf_802154_frame_parser_data_t * p_parser_data)788 static inline const uint8_t * nrf_802154_frame_parser_key_id_get(
789     const nrf_802154_frame_parser_data_t * p_parser_data)
790 {
791     uint8_t offset = nrf_802154_frame_parser_key_id_offset_get(p_parser_data);
792 
793     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
794     {
795         return NULL;
796     }
797 
798     return &p_parser_data->p_frame[offset];
799 }
800 
801 /**
802  * @brief Gets the offset of the Key Source field.
803  *
804  * @param[in]   p_parser_data   Pointer to a frame parser data.
805  *
806  * @returns  Offset of the Key Source field.
807  */
nrf_802154_frame_parser_key_source_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)808 static inline uint8_t nrf_802154_frame_parser_key_source_offset_get(
809     const nrf_802154_frame_parser_data_t * p_parser_data)
810 {
811     return p_parser_data->mhr.aux_sec_hdr.key_src_offset;
812 }
813 
814 /**
815  * @brief Gets the address of the Key Source field.
816  *
817  * @param[in]   p_parser_data   Pointer to a frame parser data.
818  *
819  * @returns  Address of the Key Source field.
820  */
nrf_802154_frame_parser_key_source_get(const nrf_802154_frame_parser_data_t * p_parser_data)821 static inline const uint8_t * nrf_802154_frame_parser_key_source_get(
822     const nrf_802154_frame_parser_data_t * p_parser_data)
823 {
824     uint8_t offset = nrf_802154_frame_parser_key_source_offset_get(p_parser_data);
825 
826     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
827     {
828         return NULL;
829     }
830 
831     return &p_parser_data->p_frame[offset];
832 }
833 
834 /**
835  * @brief Gets the length of the Key Source field.
836  *
837  * @param[in]   p_parser_data   Pointer to a frame parser data.
838  *
839  * @returns  Length of the Key Source field.
840  */
nrf_802154_frame_parser_key_source_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)841 static inline uint8_t nrf_802154_frame_parser_key_source_length_get(
842     const nrf_802154_frame_parser_data_t * p_parser_data)
843 {
844     return p_parser_data->helper.key_src_size;
845 }
846 
847 /**
848  * @brief Gets the offset of the Key Index field.
849  *
850  * @param[in]   p_parser_data   Pointer to a frame parser data.
851  *
852  * @returns  Offset of the Key Index field.
853  */
nrf_802154_frame_parser_key_index_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)854 static inline uint8_t nrf_802154_frame_parser_key_index_offset_get(
855     const nrf_802154_frame_parser_data_t * p_parser_data)
856 {
857     return p_parser_data->mhr.aux_sec_hdr.key_idx_offset;
858 }
859 
860 /**
861  * @brief Gets the address of the Key Index field.
862  *
863  * @param[in]   p_parser_data   Pointer to a frame parser data.
864  *
865  * @returns  Address of the Key Index field.
866  */
nrf_802154_frame_parser_key_index_get(const nrf_802154_frame_parser_data_t * p_parser_data)867 static inline uint8_t nrf_802154_frame_parser_key_index_get(
868     const nrf_802154_frame_parser_data_t * p_parser_data)
869 {
870     uint8_t offset = nrf_802154_frame_parser_key_index_offset_get(p_parser_data);
871 
872     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
873     {
874         return 0;
875     }
876 
877     return p_parser_data->p_frame[offset];
878 }
879 
880 /**
881  * @brief Gets the offset of the IE header.
882  *
883  * @param[in]   p_parser_data   Pointer to a frame parser data.
884  *
885  * @returns  Offset of the IE header.
886  */
nrf_802154_frame_parser_ie_header_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)887 static inline uint8_t nrf_802154_frame_parser_ie_header_offset_get(
888     const nrf_802154_frame_parser_data_t * p_parser_data)
889 {
890     return p_parser_data->mhr.header_ie_offset;
891 }
892 
893 /**
894  * @brief Gets the address of the IE header.
895  *
896  * @param[in]   p_parser_data   Pointer to a frame parser data.
897  *
898  * @returns  Address of the IE header.
899  */
nrf_802154_frame_parser_ie_header_get(const nrf_802154_frame_parser_data_t * p_parser_data)900 static inline const uint8_t * nrf_802154_frame_parser_ie_header_get(
901     const nrf_802154_frame_parser_data_t * p_parser_data)
902 {
903     uint8_t offset = nrf_802154_frame_parser_ie_header_offset_get(p_parser_data);
904 
905     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
906     {
907         return NULL;
908     }
909 
910     return &p_parser_data->p_frame[offset];
911 }
912 
913 /**
914  * @brief Gets the offset of the MAC payload.
915  *
916  * @param[in]   p_parser_data   Pointer to a frame parser data.
917  *
918  * @returns  Offset of the MAC payload.
919  */
nrf_802154_frame_parser_mac_payload_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)920 static inline uint8_t nrf_802154_frame_parser_mac_payload_offset_get(
921     const nrf_802154_frame_parser_data_t * p_parser_data)
922 {
923     return p_parser_data->mac_payload.mac_payload_offset;
924 }
925 
926 /**
927  * @brief Gets the address of the MAC payload.
928  *
929  * @param[in]   p_parser_data   Pointer to a frame parser data.
930  *
931  * @returns  Address of the MAC payload.
932  */
nrf_802154_frame_parser_mac_payload_get(const nrf_802154_frame_parser_data_t * p_parser_data)933 static inline const uint8_t * nrf_802154_frame_parser_mac_payload_get(
934     const nrf_802154_frame_parser_data_t * p_parser_data)
935 {
936     uint8_t offset = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
937 
938     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
939     {
940         return NULL;
941     }
942 
943     return &p_parser_data->p_frame[offset];
944 }
945 
946 /**
947  * @brief Gets the offset of the MAC Command ID field.
948  *
949  * @param[in]   p_parser_data   Pointer to a frame parser data.
950  *
951  * @returns  Offset of the MAC Command ID field.
952  */
nrf_802154_frame_parser_mac_command_id_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)953 static inline uint8_t nrf_802154_frame_parser_mac_command_id_offset_get(
954     const nrf_802154_frame_parser_data_t * p_parser_data)
955 {
956     if (nrf_802154_frame_parser_frame_type_get(p_parser_data) != FRAME_TYPE_COMMAND)
957     {
958         return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
959     }
960 
961     // MAC command frames containing Payload Information Elements are not supported.
962     return nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
963 }
964 
965 /**
966  * @brief Gets the address of the MAC Command ID field.
967  *
968  * @param[in]   p_parser_data   Pointer to a frame parser data.
969  *
970  * @returns  Address of the MAC Command ID field.
971  */
nrf_802154_frame_parser_mac_command_id_get(const nrf_802154_frame_parser_data_t * p_parser_data)972 static inline const uint8_t * nrf_802154_frame_parser_mac_command_id_get(
973     const nrf_802154_frame_parser_data_t * p_parser_data)
974 {
975     uint8_t offset = nrf_802154_frame_parser_mac_command_id_offset_get(p_parser_data);
976 
977     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
978     {
979         return NULL;
980     }
981 
982     return &p_parser_data->p_frame[offset];
983 }
984 
985 /**
986  * @brief Gets the offset of the MFR field.
987  *
988  * @param[in]   p_parser_data   Pointer to a frame parser data.
989  *
990  * @returns  Offset of the MFR field.
991  */
nrf_802154_frame_parser_mfr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)992 static inline uint8_t nrf_802154_frame_parser_mfr_offset_get(
993     const nrf_802154_frame_parser_data_t * p_parser_data)
994 {
995     return nrf_802154_frame_parser_frame_length_get(p_parser_data) - FCS_SIZE + PHR_SIZE;
996 }
997 
998 /**
999  * @brief Gets the address of the MFR field.
1000  *
1001  * @param[in]   p_parser_data   Pointer to a frame parser data.
1002  *
1003  * @returns  Address of the MFR field.
1004  */
nrf_802154_frame_parser_mfr_get(const nrf_802154_frame_parser_data_t * p_parser_data)1005 static inline const uint8_t * nrf_802154_frame_parser_mfr_get(
1006     const nrf_802154_frame_parser_data_t * p_parser_data)
1007 {
1008     uint8_t offset = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1009 
1010     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1011     {
1012         return NULL;
1013     }
1014 
1015     return &p_parser_data->p_frame[offset];
1016 }
1017 
1018 /**
1019  * @brief Gets the length of the MAC payload.
1020  *
1021  * @param[in]   p_parser_data   Pointer to a frame parser data.
1022  *
1023  * @returns  Length of the MAC payload.
1024  */
nrf_802154_frame_parser_mac_payload_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)1025 static inline uint8_t nrf_802154_frame_parser_mac_payload_length_get(
1026     const nrf_802154_frame_parser_data_t * p_parser_data)
1027 {
1028     uint8_t payload_start = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
1029     uint8_t payload_end   = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1030 
1031     return payload_end - payload_start;
1032 }
1033 
1034 /**
1035  * @brief Gets the length of the MAC header.
1036  *
1037  * @param[in]   p_parser_data   Pointer to a frame parser data.
1038  *
1039  * @returns  Length of the MAC header.
1040  */
nrf_802154_frame_parser_mac_header_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)1041 static inline uint8_t nrf_802154_frame_parser_mac_header_length_get(
1042     const nrf_802154_frame_parser_data_t * p_parser_data)
1043 {
1044     uint8_t mhr_start = nrf_802154_frame_parser_psdu_offset_get(p_parser_data);
1045     uint8_t mhr_end   = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
1046 
1047     if (mhr_end == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1048     {
1049         mhr_end = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1050     }
1051 
1052     return mhr_end - mhr_start;
1053 }
1054 
1055 /**
1056  * @brief Gets the length of the MIC field.
1057  *
1058  * @param[in]   p_parser_data   Pointer to a frame parser data.
1059  *
1060  * @returns  Length of the MIC field.
1061  */
nrf_802154_frame_parser_mic_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)1062 static inline uint8_t nrf_802154_frame_parser_mic_size_get(
1063     const nrf_802154_frame_parser_data_t * p_parser_data)
1064 {
1065     return p_parser_data->helper.mic_size;
1066 }
1067 
1068 /**
1069  * @brief Gets the end offset of the destination addressing section.
1070  *
1071  * @param[in]   p_parser_data   Pointer to a frame parser data.
1072  *
1073  * @returns  End offset of the destination addressing section.
1074  */
nrf_802154_frame_parser_dst_addressing_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1075 static inline uint8_t nrf_802154_frame_parser_dst_addressing_end_offset_get(
1076     const nrf_802154_frame_parser_data_t * p_parser_data)
1077 {
1078     return p_parser_data->helper.dst_addressing_end_offset;
1079 }
1080 
1081 /**
1082  * @brief Gets the end address of the destination addressing section.
1083  *
1084  * @param[in]   p_parser_data   Pointer to a frame parser data.
1085  *
1086  * @returns  End address of the destination addressing section.
1087  */
nrf_802154_frame_parser_dst_addressing_end_get(const nrf_802154_frame_parser_data_t * p_parser_data)1088 static inline const uint8_t * nrf_802154_frame_parser_dst_addressing_end_get(
1089     const nrf_802154_frame_parser_data_t * p_parser_data)
1090 {
1091     uint8_t offset = nrf_802154_frame_parser_dst_addressing_end_offset_get(p_parser_data);
1092 
1093     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1094     {
1095         return NULL;
1096     }
1097 
1098     return &p_parser_data->p_frame[offset];
1099 }
1100 
1101 /**
1102  * @brief Gets the end offset of the addressing section.
1103  *
1104  * @param[in]   p_parser_data   Pointer to a frame parser data.
1105  *
1106  * @returns  End offset of the addressing section.
1107  */
nrf_802154_frame_parser_addressing_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1108 static inline uint8_t nrf_802154_frame_parser_addressing_end_offset_get(
1109     const nrf_802154_frame_parser_data_t * p_parser_data)
1110 {
1111     return p_parser_data->helper.addressing_end_offset;
1112 }
1113 
1114 /**
1115  * @brief Gets the end address of the addressing section.
1116  *
1117  * @param[in]   p_parser_data   Pointer to a frame parser data.
1118  *
1119  * @returns  End address of the addressing section.
1120  */
nrf_802154_frame_parser_addressing_end_get(const nrf_802154_frame_parser_data_t * p_parser_data)1121 static inline const uint8_t * nrf_802154_frame_parser_addressing_end_get(
1122     const nrf_802154_frame_parser_data_t * p_parser_data)
1123 {
1124     uint8_t offset = nrf_802154_frame_parser_addressing_end_offset_get(p_parser_data);
1125 
1126     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1127     {
1128         return NULL;
1129     }
1130 
1131     return &p_parser_data->p_frame[offset];
1132 }
1133 
1134 /**
1135  * @brief Gets the end offset of the security header section.
1136  *
1137  * @param[in]   p_parser_data   Pointer to a frame parser data.
1138  *
1139  * @returns  End offset of the security header section.
1140  */
nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1141 static inline uint8_t nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(
1142     const nrf_802154_frame_parser_data_t * p_parser_data)
1143 {
1144     return p_parser_data->helper.aux_sec_hdr_end_offset;
1145 }
1146 
1147 /**
1148  * @brief Initializes the IE iterator with given IE header address.
1149  *
1150  * @param[in]   p_ie_header  Pointer to an IE header.
1151  *
1152  * @returns  Information element iterator.
1153  *
1154  */
nrf_802154_frame_parser_header_ie_iterator_begin(const uint8_t * p_ie_header)1155 static inline const uint8_t * nrf_802154_frame_parser_header_ie_iterator_begin(
1156     const uint8_t * p_ie_header)
1157 {
1158     return p_ie_header;
1159 }
1160 
1161 /**
1162  * @brief Gets payload address of currently iterated IE.
1163  *
1164  * @param[in]   p_ie_iterator  Information element iterator.
1165  *
1166  * @returns  Current IE payload address.
1167  *
1168  * @note  The user must ensure that the payload is properly bounded.
1169  *
1170  */
nrf_802154_frame_parser_ie_content_address_get(const uint8_t * p_ie_iterator)1171 static inline const uint8_t * nrf_802154_frame_parser_ie_content_address_get(
1172     const uint8_t * p_ie_iterator)
1173 {
1174     return p_ie_iterator + IE_DATA_OFFSET;
1175 }
1176 
1177 /**
1178  * @brief Gets length of currently iterated IE.
1179  *
1180  * @param[in]   p_ie_iterator  Information element iterator.
1181  *
1182  * @returns  Length of currently iterated information element.
1183  *
1184  */
nrf_802154_frame_parser_ie_length_get(const uint8_t * p_ie_iterator)1185 static inline uint8_t nrf_802154_frame_parser_ie_length_get(const uint8_t * p_ie_iterator)
1186 {
1187     return p_ie_iterator[IE_LENGTH_OFFSET] & IE_LENGTH_MASK;
1188 }
1189 
1190 /**
1191  * @brief Gets next information element iterator.
1192  *
1193  * @param[in]   p_ie_iterator  Current information element iterator.
1194  *
1195  * @returns  Next information element iterator.
1196  *
1197  */
nrf_802154_frame_parser_ie_iterator_next(const uint8_t * p_ie_iterator)1198 static inline const uint8_t * nrf_802154_frame_parser_ie_iterator_next(
1199     const uint8_t * p_ie_iterator)
1200 {
1201     return nrf_802154_frame_parser_ie_content_address_get(p_ie_iterator)
1202            + nrf_802154_frame_parser_ie_length_get(p_ie_iterator);
1203 }
1204 
1205 /**
1206  * @brief Gets identifier of currently iterated IE.
1207  *
1208  * @param[in]   p_ie_iterator  Information element iterator.
1209  *
1210  * @returns  Identifier of currently iterated information element.
1211  *
1212  */
nrf_802154_frame_parser_ie_id_get(const uint8_t * p_ie_iterator)1213 static inline uint8_t nrf_802154_frame_parser_ie_id_get(const uint8_t * p_ie_iterator)
1214 {
1215     return (p_ie_iterator[IE_ID_OFFSET_0] >> 7) | (p_ie_iterator[IE_ID_OFFSET_1] << 1);
1216 }
1217 
1218 /**
1219  * @brief Checks if the current IE is a terminator.
1220  *
1221  * @param[in]   p_ie_iterator  Information element iterator.
1222  * @param[in]   p_end_addr     Address past which the iteration shall stop.
1223  *
1224  * @retval  true   The IE is a terminator or iteration has passed the end address.
1225  * @retval  false  The IE is not a terminator and iteration has not passed the end address.
1226  *
1227  */
nrf_802154_frame_parser_ie_iterator_end(const uint8_t * p_ie_iterator,const uint8_t * p_end_addr)1228 static inline bool nrf_802154_frame_parser_ie_iterator_end(const uint8_t * p_ie_iterator,
1229                                                            const uint8_t * p_end_addr)
1230 {
1231     uint8_t ie_id = nrf_802154_frame_parser_ie_id_get(p_ie_iterator);
1232 
1233     return ((nrf_802154_frame_parser_ie_length_get(p_ie_iterator) == 0) &&
1234             ((ie_id == IE_HT1) || (ie_id == IE_HT2)))
1235            || (p_ie_iterator >= p_end_addr);
1236 }
1237 
1238 /**
1239  * @brief Gets vendor-specific OUI (organizationally unique identifier) of currently iterated IE.
1240  *
1241  * @param[in]   p_ie_iterator  Information element iterator.
1242  *
1243  * @note This field is only present in vendor-specific IE. The caller of this function should ensure
1244  * that @p p_ie_iterator points to an IE with:
1245  *  - ID: @ref IE_VENDOR_ID ID.
1246  *  - IE length: at least @ref IE_VENDOR_SIZE_MIN
1247  * Otherwise, returned value is not OUI.
1248  * See @ref nrf_802154_frame_parser_ie_id_get.
1249  *
1250  * @returns  Vendor-specific OUI.
1251  */
nrf_802154_frame_parser_ie_vendor_oui_get(const uint8_t * p_ie_iterator)1252 static inline uint32_t nrf_802154_frame_parser_ie_vendor_oui_get(const uint8_t * p_ie_iterator)
1253 {
1254     return little_24_to_host((uint8_t *)&p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_OUI_OFFSET]);
1255 }
1256 
1257 /**
1258  * @brief Gets subtype of Thread vendor-specific IE.
1259  *
1260  * @param[in]   p_ie_iterator  Information element iterator.
1261  *
1262  * @note This field is only present in Thread vendor-specific IE. The caller of this function should ensure
1263  * that @p p_ie_iterator points to an IE with:
1264  *  - ID: @ref IE_VENDOR_ID,
1265  *  - OUI: @ref IE_VENDOR_THREAD_OUI.
1266  *  - IE length: at least @ref IE_VENDOR_THREAD_SIZE_MIN
1267  * Otherwise, returned value is not Thread IE subtype.
1268  *  - @ref nrf_802154_frame_parser_ie_id_get,
1269  *  - @ref nrf_802154_frame_parser_ie_vendor_oui_get.
1270  *
1271  * @returns subtype of Thread vendor-specific IE.
1272  */
nrf_802154_frame_parser_ie_vendor_thread_subtype_get(const uint8_t * p_ie_iterator)1273 static inline uint8_t nrf_802154_frame_parser_ie_vendor_thread_subtype_get(
1274     const uint8_t * p_ie_iterator)
1275 {
1276     return p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_THREAD_SUBTYPE_OFFSET];
1277 }
1278 
1279 /**
1280  * @brief Gets vendor-specific IE thread data address of currently iterated IE.
1281  *
1282  * @param[in]   p_ie_iterator  Information element iterator.
1283  *
1284  * @note This field is only present in Thread vendor-specific IE. The caller of this function should ensure
1285  * that @p p_ie_iterator points to an IE with:
1286  *  - ID: @ref IE_VENDOR_ID,
1287  *  - OUI: @ref IE_VENDOR_THREAD_OUI,
1288  *  - subtype: @ref IE_VENDOR_THREAD_ACK_PROBING_ID.
1289  *  - IE length: at least @ref IE_VENDOR_THREAD_ACK_SIZE_MIN
1290  * Otherwise, returned pointer does not point to thread vendor-specific IE data.
1291  * See also:
1292  *  - @ref nrf_802154_frame_parser_ie_id_get,
1293  *  - @ref nrf_802154_frame_parser_ie_vendor_oui_get,
1294  *  - @ref nrf_802154_frame_parser_ie_vendor_thread_subtype_get.
1295  *
1296  * @returns  Current vendor-specific IE thread data address.
1297  */
nrf_802154_frame_parser_ie_vendor_thread_data_addr_get(const uint8_t * p_ie_iterator)1298 static inline const uint8_t * nrf_802154_frame_parser_ie_vendor_thread_data_addr_get(
1299     const uint8_t * p_ie_iterator)
1300 {
1301     return nrf_802154_frame_parser_ie_content_address_get(p_ie_iterator) +
1302            IE_VENDOR_THREAD_DATA_OFFSET;
1303 }
1304 
1305 #endif // NRF_802154_FRAME_PARSER_H
1306