1 /*
2  * Copyright (c) 2018 - 2023, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 /**
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     return (p_parser_data->p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false;
435 }
436 
437 /**
438  * @brief Gets the value of the DSN field.
439  *
440  * @param[in]   p_parser_data   Pointer to a frame parser data.
441  *
442  * @returns  The value of the DSN field.
443  */
nrf_802154_frame_parser_dsn_get(const nrf_802154_frame_parser_data_t * p_parser_data)444 static inline const uint8_t * nrf_802154_frame_parser_dsn_get(
445     const nrf_802154_frame_parser_data_t * p_parser_data)
446 {
447     if (nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_parser_data))
448     {
449         return NULL;
450     }
451 
452     return &p_parser_data->p_frame[DSN_OFFSET];
453 }
454 
455 /**
456  * @brief Gets the offset of the Destination PAN ID field.
457  *
458  * @param[in]   p_parser_data   Pointer to a frame parser data.
459  *
460  * @returns  Offset of the Destination PAN ID field.
461  */
nrf_802154_frame_parser_dst_panid_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)462 static inline uint8_t nrf_802154_frame_parser_dst_panid_offset_get(
463     const nrf_802154_frame_parser_data_t * p_parser_data)
464 {
465     return p_parser_data->mhr.dst.panid_offset;
466 }
467 
468 /**
469  * @brief Gets the address of the Destination PAN field.
470  *
471  * @param[in]   p_parser_data   Pointer to a frame parser data.
472  *
473  * @returns  Address of the Destination PAN field.
474  */
nrf_802154_frame_parser_dst_panid_get(const nrf_802154_frame_parser_data_t * p_parser_data)475 static inline const uint8_t * nrf_802154_frame_parser_dst_panid_get(
476     const nrf_802154_frame_parser_data_t * p_parser_data)
477 {
478     uint8_t offset = nrf_802154_frame_parser_dst_panid_offset_get(p_parser_data);
479 
480     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
481     {
482         return NULL;
483     }
484 
485     return &p_parser_data->p_frame[offset];
486 }
487 
488 /**
489  * @brief Gets the offset of frame Destination Address.
490  *
491  * @param[in]   p_parser_data   Pointer to a frame parser data.
492  *
493  * @returns  Offset of the frame Destination Address field.
494  */
nrf_802154_frame_parser_dst_addr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)495 static inline uint8_t nrf_802154_frame_parser_dst_addr_offset_get(
496     const nrf_802154_frame_parser_data_t * p_parser_data)
497 {
498     return p_parser_data->mhr.dst.addr_offset;
499 }
500 
501 /**
502  * @brief Gets the address of the Destination Address field.
503  *
504  * @param[in]   p_parser_data   Pointer to a frame parser data.
505  *
506  * @returns  Address of the Destination Address field.
507  */
nrf_802154_frame_parser_dst_addr_get(const nrf_802154_frame_parser_data_t * p_parser_data)508 static inline const uint8_t * nrf_802154_frame_parser_dst_addr_get(
509     const nrf_802154_frame_parser_data_t * p_parser_data)
510 {
511     uint8_t offset = nrf_802154_frame_parser_dst_addr_offset_get(p_parser_data);
512 
513     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
514     {
515         return NULL;
516     }
517 
518     return &p_parser_data->p_frame[offset];
519 }
520 
521 /**
522  * @brief Gets the offset of frame Source PAN ID.
523  *
524  * @param[in]   p_parser_data   Pointer to a frame parser data.
525  *
526  * @returns  Offset of the frame Source PAN ID field.
527  */
nrf_802154_frame_parser_src_panid_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)528 static inline uint8_t nrf_802154_frame_parser_src_panid_offset_get(
529     const nrf_802154_frame_parser_data_t * p_parser_data)
530 {
531     return p_parser_data->mhr.src.panid_offset;
532 }
533 
534 /**
535  * @brief Gets the address of the Source PAN ID field.
536  *
537  * @param[in]   p_parser_data   Pointer to a frame parser data.
538  *
539  * @returns  Address of the Source PAN ID field.
540  */
nrf_802154_frame_parser_src_panid_get(const nrf_802154_frame_parser_data_t * p_parser_data)541 static inline const uint8_t * nrf_802154_frame_parser_src_panid_get(
542     const nrf_802154_frame_parser_data_t * p_parser_data)
543 {
544     uint8_t offset = nrf_802154_frame_parser_src_panid_offset_get(p_parser_data);
545 
546     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
547     {
548         return NULL;
549     }
550 
551     return &p_parser_data->p_frame[offset];
552 }
553 
554 /**
555  * @brief Gets the offset of frame Source Address.
556  *
557  * @param[in]   p_parser_data   Pointer to a frame parser data.
558  *
559  * @returns  Offset of the frame Source Address field.
560  */
nrf_802154_frame_parser_src_addr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)561 static inline uint8_t nrf_802154_frame_parser_src_addr_offset_get(
562     const nrf_802154_frame_parser_data_t * p_parser_data)
563 {
564     return p_parser_data->mhr.src.addr_offset;
565 }
566 
567 /**
568  * @brief Gets the address of the Source Address field.
569  *
570  * @param[in]   p_parser_data   Pointer to a frame parser data.
571  *
572  * @returns  Address of the Source Address field.
573  */
nrf_802154_frame_parser_src_addr_get(const nrf_802154_frame_parser_data_t * p_parser_data)574 static inline const uint8_t * nrf_802154_frame_parser_src_addr_get(
575     const nrf_802154_frame_parser_data_t * p_parser_data)
576 {
577     uint8_t offset = nrf_802154_frame_parser_src_addr_offset_get(p_parser_data);
578 
579     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
580     {
581         return NULL;
582     }
583 
584     return &p_parser_data->p_frame[offset];
585 }
586 
587 /**
588  * @brief Gets the size of the source address.
589  *
590  * @param[in]   p_parser_data   Pointer to a frame parser data.
591  *
592  * @returns  Source address size in bytes.
593  */
nrf_802154_frame_parser_src_addr_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)594 static inline uint8_t nrf_802154_frame_parser_src_addr_size_get(
595     const nrf_802154_frame_parser_data_t * p_parser_data)
596 {
597     return p_parser_data->helper.src_addr_size;
598 }
599 
600 /**
601  * @brief Gets the size of the destination address.
602  *
603  * @param[in]   p_parser_data   Pointer to a frame parser data.
604  *
605  * @returns  Destination address size in bytes.
606  */
nrf_802154_frame_parser_dst_addr_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)607 static inline uint8_t nrf_802154_frame_parser_dst_addr_size_get(
608     const nrf_802154_frame_parser_data_t * p_parser_data)
609 {
610     return p_parser_data->helper.dst_addr_size;
611 }
612 
613 /**
614  * @brief Gets the offset of the Security Control Field.
615  *
616  * @param[in]   p_parser_data   Pointer to a frame parser data.
617  *
618  * @returns  Offset of the Security Control Field.
619  */
nrf_802154_frame_parser_sec_ctrl_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)620 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_offset_get(
621     const nrf_802154_frame_parser_data_t * p_parser_data)
622 {
623     return p_parser_data->mhr.aux_sec_hdr.sec_ctrl_offset;
624 }
625 
626 /**
627  * @brief Gets the value of the Security Level field from the Security Control Field.
628  *
629  * @param[in]   p_parser_data   Pointer to a frame parser data.
630  *
631  * @returns  Masked Security Level field value.
632  */
nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(const nrf_802154_frame_parser_data_t * p_parser_data)633 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(
634     const nrf_802154_frame_parser_data_t * p_parser_data)
635 {
636     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
637 
638     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
639     {
640         return 0;
641     }
642 
643     return p_parser_data->p_frame[offset] & SECURITY_LEVEL_MASK;
644 }
645 
646 /**
647  * @brief Gets the value of the Frame Counter Suppress bit from the Security Control Field.
648  *
649  * @param[in]   p_parser_data   Pointer to a frame parser data.
650  *
651  * @retval  true  FC suppress bit is set.
652  * @retval  false FC suppress bit is not set.
653  */
nrf_802154_frame_parser_sec_ctrl_fc_suppress_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)654 static inline bool nrf_802154_frame_parser_sec_ctrl_fc_suppress_bit_is_set(
655     const nrf_802154_frame_parser_data_t * p_parser_data)
656 {
657     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
658 
659     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
660     {
661         return false;
662     }
663 
664     return p_parser_data->p_frame[offset] & FRAME_COUNTER_SUPPRESS_BIT;
665 }
666 
667 /**
668  * @brief Gets the value of the Key ID Mode field from the Security Control Field.
669  *
670  * @param[in]   p_parser_data   Pointer to a frame parser data.
671  *
672  * @returns  Masked Key ID Mode field value.
673  */
nrf_802154_frame_parser_sec_ctrl_key_id_mode_get(const nrf_802154_frame_parser_data_t * p_parser_data)674 static inline uint8_t nrf_802154_frame_parser_sec_ctrl_key_id_mode_get(
675     const nrf_802154_frame_parser_data_t * p_parser_data)
676 {
677     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
678 
679     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
680     {
681         return 0;
682     }
683 
684     return (p_parser_data->p_frame[offset] & KEY_ID_MODE_MASK) >> KEY_ID_MODE_BIT_OFFSET;
685 }
686 
687 /**
688  * @brief Gets the value of the ASN in Nonce bit from the Security Control Field.
689  *
690  * @param[in]   p_parser_data   Pointer to a frame parser data.
691  *
692  * @retval  true  ASN in Nonce bit is set.
693  * @retval  false ASN in Nonce bit is not set.
694  */
nrf_802154_frame_parser_sec_ctrl_asn_in_nonce_bit_is_set(const nrf_802154_frame_parser_data_t * p_parser_data)695 static inline bool nrf_802154_frame_parser_sec_ctrl_asn_in_nonce_bit_is_set(
696     const nrf_802154_frame_parser_data_t * p_parser_data)
697 {
698     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
699 
700     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
701     {
702         return false;
703     }
704 
705     return p_parser_data->p_frame[offset] & ASN_IN_NONCE_BIT;
706 }
707 
708 /**
709  * @brief Gets the address of the Security Control Field.
710  *
711  * @param[in]   p_parser_data   Pointer to a frame parser data.
712  *
713  * @returns  Address of the Security Control Field.
714  */
nrf_802154_frame_parser_sec_ctrl_get(const nrf_802154_frame_parser_data_t * p_parser_data)715 static inline const uint8_t * nrf_802154_frame_parser_sec_ctrl_get(
716     const nrf_802154_frame_parser_data_t * p_parser_data)
717 {
718     uint8_t offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_parser_data);
719 
720     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
721     {
722         return NULL;
723     }
724 
725     return &p_parser_data->p_frame[offset];
726 }
727 
728 /**
729  * @brief Gets the offset of the Frame Counter field.
730  *
731  * @param[in]   p_parser_data   Pointer to a frame parser data.
732  *
733  * @returns  Offset of the Frame Counter field.
734  */
nrf_802154_frame_parser_frame_counter_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)735 static inline uint8_t nrf_802154_frame_parser_frame_counter_offset_get(
736     const nrf_802154_frame_parser_data_t * p_parser_data)
737 {
738     return p_parser_data->mhr.aux_sec_hdr.frame_counter_offset;
739 }
740 
741 /**
742  * @brief Gets the address of the Frame Counter field.
743  *
744  * @param[in]   p_parser_data   Pointer to a frame parser data.
745  *
746  * @returns  Address of the Frame Counter field.
747  */
nrf_802154_frame_parser_frame_counter_get(const nrf_802154_frame_parser_data_t * p_parser_data)748 static inline const uint8_t * nrf_802154_frame_parser_frame_counter_get(
749     const nrf_802154_frame_parser_data_t * p_parser_data)
750 {
751     uint8_t offset = nrf_802154_frame_parser_frame_counter_offset_get(p_parser_data);
752 
753     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
754     {
755         return NULL;
756     }
757 
758     return &p_parser_data->p_frame[offset];
759 }
760 
761 /**
762  * @brief Gets the offset of the Key ID field.
763  *
764  * @param[in]   p_parser_data   Pointer to a frame parser data.
765  *
766  * @returns  Offset of the Key ID field.
767  */
nrf_802154_frame_parser_key_id_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)768 static inline uint8_t nrf_802154_frame_parser_key_id_offset_get(
769     const nrf_802154_frame_parser_data_t * p_parser_data)
770 {
771     return p_parser_data->mhr.aux_sec_hdr.key_id_offset;
772 }
773 
774 /**
775  * @brief Gets the address of the Key ID field.
776  *
777  * @param[in]   p_parser_data   Pointer to a frame parser data.
778  *
779  * @returns  Address of the Key ID field.
780  */
nrf_802154_frame_parser_key_id_get(const nrf_802154_frame_parser_data_t * p_parser_data)781 static inline const uint8_t * nrf_802154_frame_parser_key_id_get(
782     const nrf_802154_frame_parser_data_t * p_parser_data)
783 {
784     uint8_t offset = nrf_802154_frame_parser_key_id_offset_get(p_parser_data);
785 
786     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
787     {
788         return NULL;
789     }
790 
791     return &p_parser_data->p_frame[offset];
792 }
793 
794 /**
795  * @brief Gets the offset of the Key Source field.
796  *
797  * @param[in]   p_parser_data   Pointer to a frame parser data.
798  *
799  * @returns  Offset of the Key Source field.
800  */
nrf_802154_frame_parser_key_source_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)801 static inline uint8_t nrf_802154_frame_parser_key_source_offset_get(
802     const nrf_802154_frame_parser_data_t * p_parser_data)
803 {
804     return p_parser_data->mhr.aux_sec_hdr.key_src_offset;
805 }
806 
807 /**
808  * @brief Gets the address of the Key Source field.
809  *
810  * @param[in]   p_parser_data   Pointer to a frame parser data.
811  *
812  * @returns  Address of the Key Source field.
813  */
nrf_802154_frame_parser_key_source_get(const nrf_802154_frame_parser_data_t * p_parser_data)814 static inline const uint8_t * nrf_802154_frame_parser_key_source_get(
815     const nrf_802154_frame_parser_data_t * p_parser_data)
816 {
817     uint8_t offset = nrf_802154_frame_parser_key_source_offset_get(p_parser_data);
818 
819     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
820     {
821         return NULL;
822     }
823 
824     return &p_parser_data->p_frame[offset];
825 }
826 
827 /**
828  * @brief Gets the length of the Key Source field.
829  *
830  * @param[in]   p_parser_data   Pointer to a frame parser data.
831  *
832  * @returns  Length of the Key Source field.
833  */
nrf_802154_frame_parser_key_source_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)834 static inline uint8_t nrf_802154_frame_parser_key_source_length_get(
835     const nrf_802154_frame_parser_data_t * p_parser_data)
836 {
837     return p_parser_data->helper.key_src_size;
838 }
839 
840 /**
841  * @brief Gets the offset of the Key Index field.
842  *
843  * @param[in]   p_parser_data   Pointer to a frame parser data.
844  *
845  * @returns  Offset of the Key Index field.
846  */
nrf_802154_frame_parser_key_index_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)847 static inline uint8_t nrf_802154_frame_parser_key_index_offset_get(
848     const nrf_802154_frame_parser_data_t * p_parser_data)
849 {
850     return p_parser_data->mhr.aux_sec_hdr.key_idx_offset;
851 }
852 
853 /**
854  * @brief Gets the address of the Key Index field.
855  *
856  * @param[in]   p_parser_data   Pointer to a frame parser data.
857  *
858  * @returns  Address of the Key Index field.
859  */
nrf_802154_frame_parser_key_index_get(const nrf_802154_frame_parser_data_t * p_parser_data)860 static inline uint8_t nrf_802154_frame_parser_key_index_get(
861     const nrf_802154_frame_parser_data_t * p_parser_data)
862 {
863     uint8_t offset = nrf_802154_frame_parser_key_index_offset_get(p_parser_data);
864 
865     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
866     {
867         return 0;
868     }
869 
870     return p_parser_data->p_frame[offset];
871 }
872 
873 /**
874  * @brief Gets the offset of the IE header.
875  *
876  * @param[in]   p_parser_data   Pointer to a frame parser data.
877  *
878  * @returns  Offset of the IE header.
879  */
nrf_802154_frame_parser_ie_header_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)880 static inline uint8_t nrf_802154_frame_parser_ie_header_offset_get(
881     const nrf_802154_frame_parser_data_t * p_parser_data)
882 {
883     return p_parser_data->mhr.header_ie_offset;
884 }
885 
886 /**
887  * @brief Gets the address of the IE header.
888  *
889  * @param[in]   p_parser_data   Pointer to a frame parser data.
890  *
891  * @returns  Address of the IE header.
892  */
nrf_802154_frame_parser_ie_header_get(const nrf_802154_frame_parser_data_t * p_parser_data)893 static inline const uint8_t * nrf_802154_frame_parser_ie_header_get(
894     const nrf_802154_frame_parser_data_t * p_parser_data)
895 {
896     uint8_t offset = nrf_802154_frame_parser_ie_header_offset_get(p_parser_data);
897 
898     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
899     {
900         return NULL;
901     }
902 
903     return &p_parser_data->p_frame[offset];
904 }
905 
906 /**
907  * @brief Gets the offset of the MAC payload.
908  *
909  * @param[in]   p_parser_data   Pointer to a frame parser data.
910  *
911  * @returns  Offset of the MAC payload.
912  */
nrf_802154_frame_parser_mac_payload_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)913 static inline uint8_t nrf_802154_frame_parser_mac_payload_offset_get(
914     const nrf_802154_frame_parser_data_t * p_parser_data)
915 {
916     return p_parser_data->mac_payload.mac_payload_offset;
917 }
918 
919 /**
920  * @brief Gets the address of the MAC payload.
921  *
922  * @param[in]   p_parser_data   Pointer to a frame parser data.
923  *
924  * @returns  Address of the MAC payload.
925  */
nrf_802154_frame_parser_mac_payload_get(const nrf_802154_frame_parser_data_t * p_parser_data)926 static inline const uint8_t * nrf_802154_frame_parser_mac_payload_get(
927     const nrf_802154_frame_parser_data_t * p_parser_data)
928 {
929     uint8_t offset = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
930 
931     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
932     {
933         return NULL;
934     }
935 
936     return &p_parser_data->p_frame[offset];
937 }
938 
939 /**
940  * @brief Gets the offset of the MAC Command ID field.
941  *
942  * @param[in]   p_parser_data   Pointer to a frame parser data.
943  *
944  * @returns  Offset of the MAC Command ID field.
945  */
nrf_802154_frame_parser_mac_command_id_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)946 static inline uint8_t nrf_802154_frame_parser_mac_command_id_offset_get(
947     const nrf_802154_frame_parser_data_t * p_parser_data)
948 {
949     if (nrf_802154_frame_parser_frame_type_get(p_parser_data) != FRAME_TYPE_COMMAND)
950     {
951         return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
952     }
953 
954     // MAC command frames containing Payload Information Elements are not supported.
955     return nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
956 }
957 
958 /**
959  * @brief Gets the address of the MAC Command ID field.
960  *
961  * @param[in]   p_parser_data   Pointer to a frame parser data.
962  *
963  * @returns  Address of the MAC Command ID field.
964  */
nrf_802154_frame_parser_mac_command_id_get(const nrf_802154_frame_parser_data_t * p_parser_data)965 static inline const uint8_t * nrf_802154_frame_parser_mac_command_id_get(
966     const nrf_802154_frame_parser_data_t * p_parser_data)
967 {
968     uint8_t offset = nrf_802154_frame_parser_mac_command_id_offset_get(p_parser_data);
969 
970     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
971     {
972         return NULL;
973     }
974 
975     return &p_parser_data->p_frame[offset];
976 }
977 
978 /**
979  * @brief Gets the offset of the MFR field.
980  *
981  * @param[in]   p_parser_data   Pointer to a frame parser data.
982  *
983  * @returns  Offset of the MFR field.
984  */
nrf_802154_frame_parser_mfr_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)985 static inline uint8_t nrf_802154_frame_parser_mfr_offset_get(
986     const nrf_802154_frame_parser_data_t * p_parser_data)
987 {
988     return nrf_802154_frame_parser_frame_length_get(p_parser_data) - FCS_SIZE + PHR_SIZE;
989 }
990 
991 /**
992  * @brief Gets the address of the MFR field.
993  *
994  * @param[in]   p_parser_data   Pointer to a frame parser data.
995  *
996  * @returns  Address of the MFR field.
997  */
nrf_802154_frame_parser_mfr_get(const nrf_802154_frame_parser_data_t * p_parser_data)998 static inline const uint8_t * nrf_802154_frame_parser_mfr_get(
999     const nrf_802154_frame_parser_data_t * p_parser_data)
1000 {
1001     uint8_t offset = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1002 
1003     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1004     {
1005         return NULL;
1006     }
1007 
1008     return &p_parser_data->p_frame[offset];
1009 }
1010 
1011 /**
1012  * @brief Gets the length of the MAC payload.
1013  *
1014  * @param[in]   p_parser_data   Pointer to a frame parser data.
1015  *
1016  * @returns  Length of the MAC payload.
1017  */
nrf_802154_frame_parser_mac_payload_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)1018 static inline uint8_t nrf_802154_frame_parser_mac_payload_length_get(
1019     const nrf_802154_frame_parser_data_t * p_parser_data)
1020 {
1021     uint8_t payload_start = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
1022     uint8_t payload_end   = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1023 
1024     return payload_end - payload_start;
1025 }
1026 
1027 /**
1028  * @brief Gets the length of the MAC header.
1029  *
1030  * @param[in]   p_parser_data   Pointer to a frame parser data.
1031  *
1032  * @returns  Length of the MAC header.
1033  */
nrf_802154_frame_parser_mac_header_length_get(const nrf_802154_frame_parser_data_t * p_parser_data)1034 static inline uint8_t nrf_802154_frame_parser_mac_header_length_get(
1035     const nrf_802154_frame_parser_data_t * p_parser_data)
1036 {
1037     uint8_t mhr_start = nrf_802154_frame_parser_psdu_offset_get(p_parser_data);
1038     uint8_t mhr_end   = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data);
1039 
1040     if (mhr_end == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1041     {
1042         mhr_end = nrf_802154_frame_parser_mfr_offset_get(p_parser_data);
1043     }
1044 
1045     return mhr_end - mhr_start;
1046 }
1047 
1048 /**
1049  * @brief Gets the length of the MIC field.
1050  *
1051  * @param[in]   p_parser_data   Pointer to a frame parser data.
1052  *
1053  * @returns  Length of the MIC field.
1054  */
nrf_802154_frame_parser_mic_size_get(const nrf_802154_frame_parser_data_t * p_parser_data)1055 static inline uint8_t nrf_802154_frame_parser_mic_size_get(
1056     const nrf_802154_frame_parser_data_t * p_parser_data)
1057 {
1058     return p_parser_data->helper.mic_size;
1059 }
1060 
1061 /**
1062  * @brief Gets the end offset of the destination addressing section.
1063  *
1064  * @param[in]   p_parser_data   Pointer to a frame parser data.
1065  *
1066  * @returns  End offset of the destination addressing section.
1067  */
nrf_802154_frame_parser_dst_addressing_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1068 static inline uint8_t nrf_802154_frame_parser_dst_addressing_end_offset_get(
1069     const nrf_802154_frame_parser_data_t * p_parser_data)
1070 {
1071     return p_parser_data->helper.dst_addressing_end_offset;
1072 }
1073 
1074 /**
1075  * @brief Gets the end address of the destination addressing section.
1076  *
1077  * @param[in]   p_parser_data   Pointer to a frame parser data.
1078  *
1079  * @returns  End address of the destination addressing section.
1080  */
nrf_802154_frame_parser_dst_addressing_end_get(const nrf_802154_frame_parser_data_t * p_parser_data)1081 static inline const uint8_t * nrf_802154_frame_parser_dst_addressing_end_get(
1082     const nrf_802154_frame_parser_data_t * p_parser_data)
1083 {
1084     uint8_t offset = nrf_802154_frame_parser_dst_addressing_end_offset_get(p_parser_data);
1085 
1086     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1087     {
1088         return NULL;
1089     }
1090 
1091     return &p_parser_data->p_frame[offset];
1092 }
1093 
1094 /**
1095  * @brief Gets the end offset of the addressing section.
1096  *
1097  * @param[in]   p_parser_data   Pointer to a frame parser data.
1098  *
1099  * @returns  End offset of the addressing section.
1100  */
nrf_802154_frame_parser_addressing_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1101 static inline uint8_t nrf_802154_frame_parser_addressing_end_offset_get(
1102     const nrf_802154_frame_parser_data_t * p_parser_data)
1103 {
1104     return p_parser_data->helper.addressing_end_offset;
1105 }
1106 
1107 /**
1108  * @brief Gets the end address of the addressing section.
1109  *
1110  * @param[in]   p_parser_data   Pointer to a frame parser data.
1111  *
1112  * @returns  End address of the addressing section.
1113  */
nrf_802154_frame_parser_addressing_end_get(const nrf_802154_frame_parser_data_t * p_parser_data)1114 static inline const uint8_t * nrf_802154_frame_parser_addressing_end_get(
1115     const nrf_802154_frame_parser_data_t * p_parser_data)
1116 {
1117     uint8_t offset = nrf_802154_frame_parser_addressing_end_offset_get(p_parser_data);
1118 
1119     if (offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
1120     {
1121         return NULL;
1122     }
1123 
1124     return &p_parser_data->p_frame[offset];
1125 }
1126 
1127 /**
1128  * @brief Gets the end offset of the security header section.
1129  *
1130  * @param[in]   p_parser_data   Pointer to a frame parser data.
1131  *
1132  * @returns  End offset of the security header section.
1133  */
nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(const nrf_802154_frame_parser_data_t * p_parser_data)1134 static inline uint8_t nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(
1135     const nrf_802154_frame_parser_data_t * p_parser_data)
1136 {
1137     return p_parser_data->helper.aux_sec_hdr_end_offset;
1138 }
1139 
1140 /**
1141  * @brief Initializes the IE iterator with given IE header address.
1142  *
1143  * @param[in]   p_ie_header  Pointer to an IE header.
1144  *
1145  * @returns  Information element iterator.
1146  *
1147  */
nrf_802154_frame_parser_header_ie_iterator_begin(const uint8_t * p_ie_header)1148 static inline const uint8_t * nrf_802154_frame_parser_header_ie_iterator_begin(
1149     const uint8_t * p_ie_header)
1150 {
1151     return p_ie_header;
1152 }
1153 
1154 /**
1155  * @brief Gets payload address of currently iterated IE.
1156  *
1157  * @param[in]   p_ie_iterator  Information element iterator.
1158  *
1159  * @returns  Current IE payload address.
1160  *
1161  * @note  The user must ensure that the payload is properly bounded.
1162  *
1163  */
nrf_802154_frame_parser_ie_content_address_get(const uint8_t * p_ie_iterator)1164 static inline const uint8_t * nrf_802154_frame_parser_ie_content_address_get(
1165     const uint8_t * p_ie_iterator)
1166 {
1167     return p_ie_iterator + IE_DATA_OFFSET;
1168 }
1169 
1170 /**
1171  * @brief Gets length of currently iterated IE.
1172  *
1173  * @param[in]   p_ie_iterator  Information element iterator.
1174  *
1175  * @returns  Length of currently iterated information element.
1176  *
1177  */
nrf_802154_frame_parser_ie_length_get(const uint8_t * p_ie_iterator)1178 static inline uint8_t nrf_802154_frame_parser_ie_length_get(const uint8_t * p_ie_iterator)
1179 {
1180     return p_ie_iterator[IE_LENGTH_OFFSET] & IE_LENGTH_MASK;
1181 }
1182 
1183 /**
1184  * @brief Gets next information element iterator.
1185  *
1186  * @param[in]   p_ie_iterator  Current information element iterator.
1187  *
1188  * @returns  Next information element iterator.
1189  *
1190  */
nrf_802154_frame_parser_ie_iterator_next(const uint8_t * p_ie_iterator)1191 static inline const uint8_t * nrf_802154_frame_parser_ie_iterator_next(
1192     const uint8_t * p_ie_iterator)
1193 {
1194     return nrf_802154_frame_parser_ie_content_address_get(p_ie_iterator)
1195            + nrf_802154_frame_parser_ie_length_get(p_ie_iterator);
1196 }
1197 
1198 /**
1199  * @brief Gets identifier of currently iterated IE.
1200  *
1201  * @param[in]   p_ie_iterator  Information element iterator.
1202  *
1203  * @returns  Identifier of currently iterated information element.
1204  *
1205  */
nrf_802154_frame_parser_ie_id_get(const uint8_t * p_ie_iterator)1206 static inline uint8_t nrf_802154_frame_parser_ie_id_get(const uint8_t * p_ie_iterator)
1207 {
1208     return (p_ie_iterator[IE_ID_OFFSET_0] >> 7) | (p_ie_iterator[IE_ID_OFFSET_1] << 1);
1209 }
1210 
1211 /**
1212  * @brief Checks if the current IE is a terminator.
1213  *
1214  * @param[in]   p_ie_iterator  Information element iterator.
1215  * @param[in]   p_end_addr     Address past which the iteration shall stop.
1216  *
1217  * @retval  true   The IE is a terminator or iteration has passed the end address.
1218  * @retval  false  The IE is not a terminator and iteration has not passed the end address.
1219  *
1220  */
nrf_802154_frame_parser_ie_iterator_end(const uint8_t * p_ie_iterator,const uint8_t * p_end_addr)1221 static inline bool nrf_802154_frame_parser_ie_iterator_end(const uint8_t * p_ie_iterator,
1222                                                            const uint8_t * p_end_addr)
1223 {
1224     uint8_t ie_id = nrf_802154_frame_parser_ie_id_get(p_ie_iterator);
1225 
1226     return ((nrf_802154_frame_parser_ie_length_get(p_ie_iterator) == 0) &&
1227             ((ie_id == IE_HT1) || (ie_id == IE_HT2)))
1228            || (p_ie_iterator >= p_end_addr);
1229 }
1230 
1231 /**
1232  * @brief Gets vendor-specific OUI (organizationally unique identifier) of currently iterated IE.
1233  *
1234  * @param[in]   p_ie_iterator  Information element iterator.
1235  *
1236  * @note This field is only present in vendor-specific IE. The caller of this function should ensure
1237  * that @p p_ie_iterator points to an IE with:
1238  *  - ID: @ref IE_VENDOR_ID ID.
1239  *  - IE length: at least @ref IE_VENDOR_SIZE_MIN
1240  * Otherwise, returned value is not OUI.
1241  * See @ref nrf_802154_frame_parser_ie_id_get.
1242  *
1243  * @returns  Vendor-specific OUI.
1244  */
nrf_802154_frame_parser_ie_vendor_oui_get(const uint8_t * p_ie_iterator)1245 static inline uint32_t nrf_802154_frame_parser_ie_vendor_oui_get(const uint8_t * p_ie_iterator)
1246 {
1247     return little_24_to_host((uint8_t *)&p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_OUI_OFFSET]);
1248 }
1249 
1250 /**
1251  * @brief Gets subtype of Thread vendor-specific IE.
1252  *
1253  * @param[in]   p_ie_iterator  Information element iterator.
1254  *
1255  * @note This field is only present in Thread vendor-specific IE. The caller of this function should ensure
1256  * that @p p_ie_iterator points to an IE with:
1257  *  - ID: @ref IE_VENDOR_ID,
1258  *  - OUI: @ref IE_VENDOR_THREAD_OUI.
1259  *  - IE length: at least @ref IE_VENDOR_THREAD_SIZE_MIN
1260  * Otherwise, returned value is not Thread IE subtype.
1261  *  - @ref nrf_802154_frame_parser_ie_id_get,
1262  *  - @ref nrf_802154_frame_parser_ie_vendor_oui_get.
1263  *
1264  * @returns subtype of Thread vendor-specific IE.
1265  */
nrf_802154_frame_parser_ie_vendor_thread_subtype_get(const uint8_t * p_ie_iterator)1266 static inline uint8_t nrf_802154_frame_parser_ie_vendor_thread_subtype_get(
1267     const uint8_t * p_ie_iterator)
1268 {
1269     return p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_THREAD_SUBTYPE_OFFSET];
1270 }
1271 
1272 /**
1273  * @brief Gets vendor-specific IE thread data address of currently iterated IE.
1274  *
1275  * @param[in]   p_ie_iterator  Information element iterator.
1276  *
1277  * @note This field is only present in Thread vendor-specific IE. The caller of this function should ensure
1278  * that @p p_ie_iterator points to an IE with:
1279  *  - ID: @ref IE_VENDOR_ID,
1280  *  - OUI: @ref IE_VENDOR_THREAD_OUI,
1281  *  - subtype: @ref IE_VENDOR_THREAD_ACK_PROBING_ID.
1282  *  - IE length: at least @ref IE_VENDOR_THREAD_ACK_SIZE_MIN
1283  * Otherwise, returned pointer does not point to thread vendor-specific IE data.
1284  * See also:
1285  *  - @ref nrf_802154_frame_parser_ie_id_get,
1286  *  - @ref nrf_802154_frame_parser_ie_vendor_oui_get,
1287  *  - @ref nrf_802154_frame_parser_ie_vendor_thread_subtype_get.
1288  *
1289  * @returns  Current vendor-specific IE thread data address.
1290  */
nrf_802154_frame_parser_ie_vendor_thread_data_addr_get(const uint8_t * p_ie_iterator)1291 static inline const uint8_t * nrf_802154_frame_parser_ie_vendor_thread_data_addr_get(
1292     const uint8_t * p_ie_iterator)
1293 {
1294     return nrf_802154_frame_parser_ie_content_address_get(p_ie_iterator) +
1295            IE_VENDOR_THREAD_DATA_OFFSET;
1296 }
1297 
1298 #endif // NRF_802154_FRAME_PARSER_H
1299