LCOV - code coverage report
Current view: top level - zephyr/net - ieee802154_ie.h Coverage Total Hit
Test: new.info Lines: 95.2 % 42 40
Test Date: 2025-09-05 22:20:39

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2023 Florian Grandel, Zephyr Project.
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief IEEE 802.15.4 MAC information element (IE) related types and helpers
      10              :  *
      11              :  * This is not to be included by the application. This file contains only those
      12              :  * parts of the types required for IE support that need to be visible to IEEE
      13              :  * 802.15.4 drivers and L2 at the same time, i.e. everything related to header
      14              :  * IE representation, parsing and generation.
      15              :  *
      16              :  * All specification references in this file refer to IEEE 802.15.4-2020.
      17              :  *
      18              :  * @note All structs and attributes in this file that directly represent parts
      19              :  * of IEEE 802.15.4 frames are in LITTLE ENDIAN, see section 4, especially
      20              :  * section 4.3.
      21              :  */
      22              : 
      23              : #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_
      24              : #define ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_
      25              : 
      26              : #include <zephyr/net_buf.h>
      27              : #include <zephyr/sys/byteorder.h>
      28              : 
      29              : /**
      30              :  * @addtogroup ieee802154_driver
      31              :  * @{
      32              :  *
      33              :  * @name IEEE 802.15.4, section 7.4.2: MAC header information elements
      34              :  * @{
      35              :  */
      36              : 
      37              : /**
      38              :  * @brief Information Element Types.
      39              :  *
      40              :  * @details See sections 7.4.2.1 and 7.4.3.1.
      41              :  */
      42            1 : enum ieee802154_ie_type {
      43              :         IEEE802154_IE_TYPE_HEADER = 0x0, /**< Header type */
      44              :         IEEE802154_IE_TYPE_PAYLOAD,      /**< Payload type */
      45              : };
      46              : 
      47              : /**
      48              :  * @brief Header Information Element IDs.
      49              :  *
      50              :  * @details See section 7.4.2.1, table 7-7, partial list, only IEs actually used
      51              :  * are implemented.
      52              :  */
      53            1 : enum ieee802154_header_ie_element_id {
      54              :         IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE = 0x00,   /**< Vendor specific IE */
      55              :         IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE = 0x1a,               /**< CSL IE */
      56              :         IEEE802154_HEADER_IE_ELEMENT_ID_RIT_IE = 0x1b,               /**< RIT IE */
      57              :         IEEE802154_HEADER_IE_ELEMENT_ID_RENDEZVOUS_TIME_IE = 0x1d,   /**< Rendezvous time IE */
      58              :         IEEE802154_HEADER_IE_ELEMENT_ID_TIME_CORRECTION_IE = 0x1e,   /**< Time correction IE */
      59              :         IEEE802154_HEADER_IE_ELEMENT_ID_HEADER_TERMINATION_1 = 0x7e, /**< Header termination 1 */
      60              :         IEEE802154_HEADER_IE_ELEMENT_ID_HEADER_TERMINATION_2 = 0x7f, /**< Header termination 2 */
      61              :         /* partial list, add additional ids as needed */
      62              : };
      63              : 
      64              : /** @cond INTERNAL_HIDDEN */
      65              : #define IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN 3
      66              : /** INTERNAL_HIDDEN @endcond */
      67              : 
      68              : /** @brief Vendor Specific Header IE, see section 7.4.2.3. */
      69            1 : struct ieee802154_header_ie_vendor_specific {
      70              :         /** Vendor OUI */
      71            1 :         uint8_t vendor_oui[IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN];
      72              :         /** Vendor specific information */
      73            1 :         uint8_t *vendor_specific_info;
      74              : } __packed;
      75              : 
      76              : /** @brief Full CSL IE, see section 7.4.2.3. */
      77            1 : struct ieee802154_header_ie_csl_full {
      78            1 :         uint16_t csl_phase;           /**< CSL phase */
      79            1 :         uint16_t csl_period;          /**< CSL period */
      80            1 :         uint16_t csl_rendezvous_time; /**< Rendezvous time */
      81              : } __packed;
      82              : 
      83              : /** @brief Reduced CSL IE, see section 7.4.2.3. */
      84            1 : struct ieee802154_header_ie_csl_reduced {
      85            1 :         uint16_t csl_phase;  /**< CSL phase */
      86            1 :         uint16_t csl_period; /**< CSL period */
      87              : } __packed;
      88              : 
      89              : /** @brief Generic CSL IE, see section 7.4.2.3. */
      90            1 : struct ieee802154_header_ie_csl {
      91              :         union {
      92              :                 /** CSL full information */
      93            1 :                 struct ieee802154_header_ie_csl_full full;
      94              :                 /** CSL reduced information */
      95            1 :                 struct ieee802154_header_ie_csl_reduced reduced;
      96            0 :         };
      97              : } __packed;
      98              : 
      99              : /** @brief RIT IE, see section 7.4.2.4. */
     100            1 : struct ieee802154_header_ie_rit {
     101            1 :         uint8_t time_to_first_listen;    /**< Time to First Listen */
     102            1 :         uint8_t number_of_repeat_listen; /**< Number of Repeat Listen */
     103            1 :         uint16_t repeat_listen_interval; /**< Repeat listen interval */
     104              : } __packed;
     105              : 
     106              : /**
     107              :  * @brief Full Rendezvous Time IE, see section 7.4.2.6
     108              :  * (macCslInterval is nonzero).
     109              :  */
     110            1 : struct ieee802154_header_ie_rendezvous_time_full {
     111            1 :         uint16_t rendezvous_time; /**< Rendezvous time */
     112            1 :         uint16_t wakeup_interval; /**< Wakeup interval */
     113              : } __packed;
     114              : 
     115              : /**
     116              :  * @brief Reduced Rendezvous Time IE, see section 7.4.2.6
     117              :  * (macCslInterval is zero).
     118              :  */
     119            1 : struct ieee802154_header_ie_rendezvous_time_reduced {
     120            1 :         uint16_t rendezvous_time; /**< Rendezvous time */
     121              : } __packed;
     122              : 
     123              : /** @brief Rendezvous Time IE, see section 7.4.2.6. */
     124            1 : struct ieee802154_header_ie_rendezvous_time {
     125              :         union {
     126              :                 /** Rendezvous time full information */
     127            1 :                 struct ieee802154_header_ie_rendezvous_time_full full;
     128              :                 /** Rendezvous time reduced information */
     129            1 :                 struct ieee802154_header_ie_rendezvous_time_reduced reduced;
     130            0 :         };
     131              : } __packed;
     132              : 
     133              : /** @brief Time Correction IE, see section 7.4.2.7. */
     134            1 : struct ieee802154_header_ie_time_correction {
     135            1 :         uint16_t time_sync_info;  /**< Time synchronization information */
     136              : } __packed;
     137              : 
     138              : /** @cond INTERNAL_HIDDEN */
     139              : 
     140              : /* @brief Generic Header IE, see section 7.4.2.1. */
     141              : struct ieee802154_header_ie {
     142              : #if CONFIG_LITTLE_ENDIAN
     143              :         uint16_t length : 7;
     144              :         uint16_t element_id_low : 1; /* see enum ieee802154_header_ie_element_id */
     145              :         uint16_t element_id_high : 7;
     146              :         uint16_t type : 1; /* always 0 */
     147              : #else
     148              :         uint16_t element_id_low : 1; /* see enum ieee802154_header_ie_element_id */
     149              :         uint16_t length : 7;
     150              :         uint16_t type : 1; /* always 0 */
     151              :         uint16_t element_id_high : 7;
     152              : #endif
     153              :         union {
     154              :                 struct ieee802154_header_ie_vendor_specific vendor_specific;
     155              :                 struct ieee802154_header_ie_csl csl;
     156              :                 struct ieee802154_header_ie_rit rit;
     157              :                 struct ieee802154_header_ie_rendezvous_time rendezvous_time;
     158              :                 struct ieee802154_header_ie_time_correction time_correction;
     159              :                 /* add additional supported header IEs here */
     160              :         } content;
     161              : } __packed;
     162              : 
     163              : /** INTERNAL_HIDDEN @endcond */
     164              : 
     165              : /** @brief The header IE's header length (2 bytes). */
     166            1 : #define IEEE802154_HEADER_IE_HEADER_LENGTH sizeof(uint16_t)
     167              : 
     168              : 
     169              : /** @cond INTERNAL_HIDDEN */
     170              : #define IEEE802154_DEFINE_HEADER_IE(_element_id, _length, _content, _content_type)                 \
     171              :         (struct ieee802154_header_ie) {                                                            \
     172              :                 .length = (_length),                                                               \
     173              :                 .element_id_high = (_element_id) >> 1U, .element_id_low = (_element_id) & 0x01,    \
     174              :                 .type = IEEE802154_IE_TYPE_HEADER,                                                 \
     175              :                 .content._content_type = _content,                                                 \
     176              :         }
     177              : 
     178              : #define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT_LEN(_vendor_specific_info_len)         \
     179              :         (IEEE802154_VENDOR_SPECIFIC_IE_OUI_LEN + (_vendor_specific_info_len))
     180              : 
     181              : #define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT(_vendor_oui, _vendor_specific_info)    \
     182              :         (struct ieee802154_header_ie_vendor_specific) {                                            \
     183              :                 .vendor_oui = _vendor_oui, .vendor_specific_info = (_vendor_specific_info),        \
     184              :         }
     185              : 
     186              : #define IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED_CONTENT(_csl_phase, _csl_period)                   \
     187              :         (struct ieee802154_header_ie_csl_reduced) {                                                \
     188              :                 .csl_phase = sys_cpu_to_le16(_csl_phase),                                          \
     189              :                 .csl_period = sys_cpu_to_le16(_csl_period),                                        \
     190              :         }
     191              : 
     192              : #define IEEE802154_DEFINE_HEADER_IE_CSL_FULL_CONTENT(_csl_phase, _csl_period,                      \
     193              :                                                      _csl_rendezvous_time)                         \
     194              :         (struct ieee802154_header_ie_csl_full) {                                                   \
     195              :                 .csl_phase = sys_cpu_to_le16(_csl_phase),                                          \
     196              :                 .csl_period = sys_cpu_to_le16(_csl_period),                                        \
     197              :                 .csl_rendezvous_time = sys_cpu_to_le16(_csl_rendezvous_time),                      \
     198              :         }
     199              : 
     200              : #define IEEE802154_HEADER_IE_TIME_CORRECTION_NACK          0x8000
     201              : #define IEEE802154_HEADER_IE_TIME_CORRECTION_MASK          0x0fff
     202              : #define IEEE802154_HEADER_IE_TIME_CORRECTION_SIGN_BIT_MASK 0x0800
     203              : 
     204              : #define IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION_CONTENT(_ack, _time_correction_us)             \
     205              :         (struct ieee802154_header_ie_time_correction) {                                            \
     206              :                 .time_sync_info = sys_cpu_to_le16(                                                 \
     207              :                         (!(_ack) * IEEE802154_HEADER_IE_TIME_CORRECTION_NACK) |                    \
     208              :                         ((_time_correction_us) & IEEE802154_HEADER_IE_TIME_CORRECTION_MASK)),      \
     209              :         }
     210              : /** INTERNAL_HIDDEN @endcond */
     211              : 
     212              : /**
     213              :  * @brief Define a vendor specific header IE, see section 7.4.2.3.
     214              :  *
     215              :  * @details Example usage (all parameters in little endian):
     216              :  *
     217              :  * @code{.c}
     218              :  *   uint8_t vendor_specific_info[] = {...some vendor specific IE content...};
     219              :  *   struct ieee802154_header_ie header_ie = IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC(
     220              :  *       {0x9b, 0xb8, 0xea}, vendor_specific_info, sizeof(vendor_specific_info));
     221              :  * @endcode
     222              :  *
     223              :  * @param _vendor_oui an initializer for a 3 byte vendor oui array in little
     224              :  * endian
     225              :  * @param _vendor_specific_info pointer to a variable length uint8_t array with
     226              :  * the vendor specific IE content
     227              :  * @param _vendor_specific_info_len the length of the vendor specific IE content
     228              :  * (in bytes)
     229              :  */
     230              : #define IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC(_vendor_oui, _vendor_specific_info,            \
     231            1 :                                                     _vendor_specific_info_len)                     \
     232              :         IEEE802154_DEFINE_HEADER_IE(IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE,            \
     233              :                                     IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT_LEN(       \
     234              :                                             _vendor_specific_info_len),                            \
     235              :                                     IEEE802154_DEFINE_HEADER_IE_VENDOR_SPECIFIC_CONTENT(           \
     236              :                                             _vendor_oui, _vendor_specific_info),                   \
     237              :                                     vendor_specific)
     238              : 
     239              : /**
     240              :  * @brief Define a reduced CSL IE, see section 7.4.2.3.
     241              :  *
     242              :  * @details Example usage (all parameters in CPU byte order):
     243              :  *
     244              :  * @code{.c}
     245              :  *   uint16_t csl_phase = ...;
     246              :  *   uint16_t csl_period = ...;
     247              :  *   struct ieee802154_header_ie header_ie =
     248              :  *       IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(csl_phase, csl_period);
     249              :  * @endcode
     250              :  *
     251              :  * @param _csl_phase CSL phase in CPU byte order
     252              :  * @param _csl_period CSL period in CPU byte order
     253              :  */
     254            1 : #define IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(_csl_phase, _csl_period)                           \
     255              :         IEEE802154_DEFINE_HEADER_IE(                                                               \
     256              :                 IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE,                                            \
     257              :                 sizeof(struct ieee802154_header_ie_csl_reduced),                                   \
     258              :                 IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED_CONTENT(_csl_phase, _csl_period),          \
     259              :                 csl.reduced)
     260              : 
     261              : /**
     262              :  * @brief Define a full CSL IE, see section 7.4.2.3.
     263              :  *
     264              :  * @details Example usage (all parameters in CPU byte order):
     265              :  *
     266              :  * @code{.c}
     267              :  *   uint16_t csl_phase = ...;
     268              :  *   uint16_t csl_period = ...;
     269              :  *   uint16_t csl_rendezvous_time = ...;
     270              :  *   struct ieee802154_header_ie header_ie =
     271              :  *       IEEE802154_DEFINE_HEADER_IE_CSL_REDUCED(csl_phase, csl_period, csl_rendezvous_time);
     272              :  * @endcode
     273              :  *
     274              :  * @param _csl_phase CSL phase in CPU byte order
     275              :  * @param _csl_period CSL period in CPU byte order
     276              :  * @param _csl_rendezvous_time CSL rendezvous time in CPU byte order
     277              :  */
     278            1 : #define IEEE802154_DEFINE_HEADER_IE_CSL_FULL(_csl_phase, _csl_period, _csl_rendezvous_time)        \
     279              :         IEEE802154_DEFINE_HEADER_IE(IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE,                        \
     280              :                                     sizeof(struct ieee802154_header_ie_csl_full),                  \
     281              :                                     IEEE802154_DEFINE_HEADER_IE_CSL_FULL_CONTENT(                  \
     282              :                                             _csl_phase, _csl_period, _csl_rendezvous_time),        \
     283              :                                     csl.full)
     284              : 
     285              : /**
     286              :  * @brief Define a Time Correction IE, see section 7.4.2.7.
     287              :  *
     288              :  * @details Example usage (parameter in CPU byte order):
     289              :  *
     290              :  * @code{.c}
     291              :  *   uint16_t time_sync_info = ...;
     292              :  *   struct ieee802154_header_ie header_ie =
     293              :  *       IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION(true, time_sync_info);
     294              :  * @endcode
     295              :  *
     296              :  * @param _ack whether or not the enhanced ACK frame that receives this IE is an
     297              :  * ACK (true) or NACK (false)
     298              :  * @param _time_correction_us the positive or negative deviation from expected
     299              :  * RX time in microseconds
     300              :  */
     301            1 : #define IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION(_ack, _time_correction_us)                     \
     302              :         IEEE802154_DEFINE_HEADER_IE(                                                               \
     303              :                 IEEE802154_HEADER_IE_ELEMENT_ID_TIME_CORRECTION_IE,                                \
     304              :                 sizeof(struct ieee802154_header_ie_time_correction),                               \
     305              :                 IEEE802154_DEFINE_HEADER_IE_TIME_CORRECTION_CONTENT(_ack, _time_correction_us),    \
     306              :                 time_correction)
     307              : 
     308              : /**
     309              :  * @brief Retrieve the time correction value in microseconds from a Time Correction IE,
     310              :  * see section 7.4.2.7.
     311              :  *
     312              :  * @param[in] ie pointer to the Time Correction IE structure
     313              :  *
     314              :  * @return The time correction value in microseconds.
     315              :  */
     316              : static inline int16_t
     317            1 : ieee802154_header_ie_get_time_correction_us(struct ieee802154_header_ie_time_correction *ie)
     318              : {
     319              :         if (ie->time_sync_info & IEEE802154_HEADER_IE_TIME_CORRECTION_SIGN_BIT_MASK) {
     320              :                 /* Negative integer */
     321              :                 return (int16_t)ie->time_sync_info | ~IEEE802154_HEADER_IE_TIME_CORRECTION_MASK;
     322              :         }
     323              : 
     324              :         /* Positive integer */
     325              :         return (int16_t)ie->time_sync_info & IEEE802154_HEADER_IE_TIME_CORRECTION_MASK;
     326              : }
     327              : 
     328              : /**
     329              :  * @brief Set the element ID of a header IE.
     330              :  *
     331              :  * @param[in] ie pointer to a header IE
     332              :  * @param[in] element_id IE element id in CPU byte order
     333              :  */
     334            1 : static inline void ieee802154_header_ie_set_element_id(struct ieee802154_header_ie *ie,
     335              :                                                        uint8_t element_id)
     336              : {
     337              :         ie->element_id_high = element_id >> 1U;
     338              :         ie->element_id_low = element_id & 0x01;
     339              : }
     340              : 
     341              : /**
     342              :  * @brief Get the element ID of a header IE.
     343              :  *
     344              :  * @param[in] ie pointer to a header IE
     345              :  *
     346              :  * @return header IE element id in CPU byte order
     347              :  */
     348            1 : static inline uint8_t ieee802154_header_ie_get_element_id(struct ieee802154_header_ie *ie)
     349              : {
     350              :         return (ie->element_id_high << 1U) | ie->element_id_low;
     351              : }
     352              : 
     353              : /** @brief The length in bytes of a "Time Correction" header IE. */
     354            1 : #define IEEE802154_TIME_CORRECTION_HEADER_IE_LEN                                                   \
     355              :         (IEEE802154_HEADER_IE_HEADER_LENGTH + sizeof(struct ieee802154_header_ie_time_correction))
     356              : 
     357              : /** @brief The length in bytes of a "Header Termination 1" header IE. */
     358            1 : #define IEEE802154_HEADER_TERMINATION_1_HEADER_IE_LEN IEEE802154_HEADER_IE_HEADER_LENGTH
     359              : 
     360              : /**
     361              :  * @}
     362              :  *
     363              :  * @}
     364              :  */
     365              : 
     366              : #endif /* ZEPHYR_INCLUDE_NET_IEEE802154_IE_H_ */
        

Generated by: LCOV version 2.0-1