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