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