diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index d5673ff282..a1b2d8c5ff 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -88,7 +88,8 @@ config IEEE802154_2015 config IEEE802154_CSL_ENDPOINT bool "Support for CSL Endpoint" help - Enable support for CSL Endpoint with delayed reception handling and CSL IE injection. + Make this device a CSL (coordinated sampled listening) endpoint with delayed + reception handling and CSL IE injection. config IEEE802154_SELECTIVE_TXPOWER bool "Support selective TX power setting" diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index 536dbfba70..d1b49c3c88 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -28,11 +28,11 @@ extern "C" { * @{ */ -/* See IEEE 802.15.4-2006, sections 5.5.3.2, 6.4.1 and 7.2.1.9 */ -#define IEEE802154_MAX_PHY_PACKET_SIZE 127 -#define IEEE802154_FCS_LENGTH 2 +/* References are to the IEEE 802.15.4-2020 standard */ +#define IEEE802154_MAX_PHY_PACKET_SIZE 127 /* see section 11.3, aMaxPhyPacketSize */ +#define IEEE802154_FCS_LENGTH 2 /* see section 7.2.1.1 */ #define IEEE802154_MTU (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_FCS_LENGTH) -/* TODO: Support flexible MTU for IEEE 802.15.4-2015 */ +/* TODO: Support flexible MTU and FCS lengths for IEEE 802.15.4-2015ff */ #define IEEE802154_SHORT_ADDR_LENGTH 2 #define IEEE802154_EXT_ADDR_LENGTH 8 @@ -40,11 +40,15 @@ extern "C" { #define IEEE802154_NO_CHANNEL USHRT_MAX -/* See IEEE 802.15.4-2006, section 7.2.1.4 */ -#define IEEE802154_BROADCAST_ADDRESS 0xFFFF -#define IEEE802154_NO_SHORT_ADDRESS_ASSIGNED 0xFFFE -#define IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED 0x0000 -#define IEEE802154_BROADCAST_PAN_ID 0xFFFF +/* See IEEE 802.15.4-2020, sections 6.1 and 7.3.5 */ +#define IEEE802154_BROADCAST_ADDRESS 0xffff +#define IEEE802154_NO_SHORT_ADDRESS_ASSIGNED 0xfffe + +/* See IEEE 802.15.4-2020, section 6.1 */ +#define IEEE802154_BROADCAST_PAN_ID 0xffff + +/* See IEEE 802.15.4-2020, section 7.3.5 */ +#define IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED IEEE802154_BROADCAST_ADDRESS struct ieee802154_security_ctx { uint32_t frame_counter; @@ -60,7 +64,7 @@ struct ieee802154_security_ctx { /* This not meant to be used by any code but 802.15.4 L2 stack */ struct ieee802154_context { uint16_t pan_id; /* in CPU byte order */ - uint16_t channel; + uint16_t channel; /* in CPU byte order */ /* short address: * 0 == not associated, * 0xfffe == associated but no short address assigned diff --git a/include/zephyr/net/ieee802154_mgmt.h b/include/zephyr/net/ieee802154_mgmt.h index 8a4fb67027..991f1099e4 100644 --- a/include/zephyr/net/ieee802154_mgmt.h +++ b/include/zephyr/net/ieee802154_mgmt.h @@ -7,6 +7,8 @@ /** * @file * @brief IEEE 802.15.4 Management interface public header + * + * All references to the standard in this file cite IEEE 802.15.4-2020. */ #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_MGMT_H_ @@ -34,26 +36,63 @@ extern "C" { NET_MGMT_LAYER_CODE(_NET_IEEE802154_CODE)) #define _NET_IEEE802154_EVENT (_NET_IEEE802154_BASE | NET_MGMT_EVENT_BIT) +/* All attributes and parameters are given in CPU byte order + * (scalars) or big endian (byte arrays) unless otherwise + * specified. + * + * The following IEEE 802.15.4 MAC management service primitives + * are referenced below: + * - MLME-ASSOCIATE.request, see section 8.2.3 + * - MLME-DISASSOCIATE.request, see section 8.2.4 + * - MLME-SET/GET.request, see section 8.2.6 + * - MLME-SCAN.request, see section 8.2.11 + * + * The following IEEE 802.15.4 MAC data service primitives + * are referenced below: + * - MLME-DATA.request, see section 8.3.2 + * + * MAC PIB attributes (mac.../sec...): see sections 8.4.3 and 9.5. + * PHY PIB attributes (phy...): see section 11.3. + * Both are accessed through MLME-SET/GET primitives. + */ enum net_request_ieee802154_cmd { - NET_REQUEST_IEEE802154_CMD_SET_ACK = 1, - NET_REQUEST_IEEE802154_CMD_UNSET_ACK, - NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN, - NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN, - NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN, - NET_REQUEST_IEEE802154_CMD_ASSOCIATE, - NET_REQUEST_IEEE802154_CMD_DISASSOCIATE, - NET_REQUEST_IEEE802154_CMD_SET_CHANNEL, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_GET_CHANNEL, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_SET_PAN_ID, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_GET_PAN_ID, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR, /* in big endian byte order */ - NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR, /* in big endian byte order */ - NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR, /* in CPU byte order */ - NET_REQUEST_IEEE802154_CMD_GET_TX_POWER, - NET_REQUEST_IEEE802154_CMD_SET_TX_POWER, - NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS, - NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS, + NET_REQUEST_IEEE802154_CMD_SET_ACK = 1, /* sets AckTx for all subsequent + * MLME-DATA (aka TX) requests + */ + NET_REQUEST_IEEE802154_CMD_UNSET_ACK, /* unsets AckTx for all subsequent + * MLME-DATA requests + */ + NET_REQUEST_IEEE802154_CMD_PASSIVE_SCAN, /* MLME-SCAN(PASSIVE, ...) request */ + NET_REQUEST_IEEE802154_CMD_ACTIVE_SCAN, /* MLME-SCAN(ACTIVE, ...) request */ + NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN, /* not-standard */ + NET_REQUEST_IEEE802154_CMD_ASSOCIATE, /* MLME-ASSOCIATE(...) request */ + NET_REQUEST_IEEE802154_CMD_DISASSOCIATE, /* MLME-DISASSOCIATE(...) request */ + NET_REQUEST_IEEE802154_CMD_SET_CHANNEL, /* MLME-SET(phyCurrentChannel) request */ + NET_REQUEST_IEEE802154_CMD_GET_CHANNEL, /* MLME-GET(phyCurrentChannel) request */ + NET_REQUEST_IEEE802154_CMD_SET_PAN_ID, /* MLME-SET(macPanId) request */ + NET_REQUEST_IEEE802154_CMD_GET_PAN_ID, /* MLME-GET(macPanId) request */ + NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR, /* non-standard, see chapters 7.1 and 8.4.3.1, in + * big endian byte order + */ + NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR, /* like MLME-GET(macExtendedAddress) but in big + * endian byte order + */ + NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR, /* MLME-SET(macShortAddress) request, only + * allowed for co-ordinators + */ + NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR, /* MLME-GET(macShortAddress) request */ + NET_REQUEST_IEEE802154_CMD_GET_TX_POWER, /* MLME-SET(phyUnicastTxPower/phyBroadcastTxPower) + * request (currently not distinguished) + */ + NET_REQUEST_IEEE802154_CMD_SET_TX_POWER, /* MLME-GET(phyUnicastTxPower/phyBroadcastTxPower) + * request + */ + + NET_REQUEST_IEEE802154_CMD_SET_SECURITY_SETTINGS, /* implies macSecurityEnabled=true, + * configures basic sec* MAC PIB + * attributes + */ + NET_REQUEST_IEEE802154_CMD_GET_SECURITY_SETTINGS, /* gets the configured sec* attributes */ }; @@ -173,15 +212,15 @@ enum net_event_ieee802154_cmd { #define IEEE802154_IS_CHAN_UNSCANNED(_channel_set, _chan) \ (!IEEE802154_IS_CHAN_SCANNED(_channel_set, _chan)) -/* Useful define to request all channels to be scanned, - * from 11 to 26 included. +/* Useful define to request all 16 channels of channel page zero + * in the 2450 MHz band to be scanned, from 11 to 26 included. */ #define IEEE802154_ALL_CHANNELS (0x03FFFC00) /** * @brief Scanning parameters * - * Used to request a scan and get results as well + * Used to request a scan and get results as well, see section 8.2.11.2 */ struct ieee802154_req_params { /** The set of channels to scan, use above macros to manage it */ @@ -210,14 +249,17 @@ struct ieee802154_req_params { /** * @brief Security parameters * - * Used to setup the link-layer security settings + * Used to setup the link-layer security settings, + * see tables 9-9 and 9-10 in section 9.5. */ struct ieee802154_security_params { - uint8_t key[16]; - uint8_t key_len; - uint8_t key_mode : 2; - uint8_t level : 3; - uint8_t _unused : 3; + uint8_t key[16]; /* secKeyDescriptor.secKey */ + uint8_t key_len; /* a key length of 16 bytes is mandatory for standards conformance */ + uint8_t key_mode : 2; /* secKeyIdMode */ + uint8_t level : 3; /* Used instead of a frame-specific SecurityLevel parameter when + * constructing the auxiliary security header + */ + uint8_t _unused : 3; }; #ifdef __cplusplus diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 3fa75f0a99..41a906112e 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -29,7 +29,7 @@ extern "C" { /** * @brief IEEE 802.15.4 Channel assignments * - * Channel numbering for 868 MHz, 915 MHz, and 2450 MHz bands. + * Channel numbering for 868 MHz, 915 MHz, and 2450 MHz bands (channel page zero). * * - Channel 0 is for 868.3 MHz. * - Channels 1-10 are for 906 to 924 MHz with 2 MHz channel spacing. @@ -177,6 +177,10 @@ enum ieee802154_config_type { /** Configure a radio reception slot. This can be used for any scheduler reception, e.g.: * Zigbee GP device, CSL, TSCH, etc. + */ + IEEE802154_CONFIG_RX_SLOT, + + /** Configure CSL receiver (Endpoint) period * * In order to configure a CSL receiver the upper layer should combine several * configuration options in the following way: @@ -210,9 +214,6 @@ enum ieee802154_config_type { * | | * +--------------------- loop ---------+ */ - IEEE802154_CONFIG_RX_SLOT, - - /** Configure CSL receiver (Endpoint) period */ IEEE802154_CONFIG_CSL_PERIOD, /** Configure the next CSL receive window center, in units of microseconds, diff --git a/subsys/net/l2/ieee802154/Kconfig b/subsys/net/l2/ieee802154/Kconfig index d5b5eaefff..7a85597f16 100644 --- a/subsys/net/l2/ieee802154/Kconfig +++ b/subsys/net/l2/ieee802154/Kconfig @@ -59,8 +59,9 @@ endchoice config NET_L2_IEEE802154_ACK_REPLY bool "IEEE 802.15.4 ACK reply logic" help - Enable inner stack's logic on handling ACK request. Note that - if the hw driver has an AUTOACK feature, this is then unnecessary. + Enable sending of ACK replies when receiving packages that request + ACK. Note that if the HW driver has an AUTOACK feature, this should be + disabled to avoid duplicate ACK packages. choice prompt "Device features level support" @@ -119,7 +120,11 @@ config NET_L2_IEEE802154_SECURITY select EXPERIMENTAL help Enable 802.15.4 frame security handling, in order to bring data - confidentiality and authenticity. + confidentiality and authenticity. The implementation is incomplete + (only implicit key mode, no key/device specific state, incoming + and outgoing security procedures only partially implemented, etc.). + Therefore the feature is to be considered EXPERIMENTAL work in + progress. config NET_L2_IEEE802154_SECURITY_CRYPTO_DEV_NAME string "Crypto device name used for cryption" diff --git a/subsys/net/l2/ieee802154/Kconfig.radio b/subsys/net/l2/ieee802154/Kconfig.radio index ed662a46fd..180e873778 100644 --- a/subsys/net/l2/ieee802154/Kconfig.radio +++ b/subsys/net/l2/ieee802154/Kconfig.radio @@ -16,7 +16,8 @@ config NET_L2_IEEE802154_RADIO_TX_RETRIES range 1 7 help Number of transmission attempts radio driver should do, before - replying it could not send the packet. + replying it could not send the packet (MAC PIB attribute: + macMaxFrameRetries). choice prompt "Radio protocol" @@ -47,7 +48,8 @@ config NET_L2_IEEE802154_RADIO_CSMA_CA_MAX_BO range 1 5 help The maximum number of backoffs the CSMA-CA algorithm will attempt - before declaring a channel access failure. + before declaring a channel access failure (MAC PIB attribute: + maxMaxCSMABackoffs). config NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE int "CSMA MAC minimum backoff exponent" @@ -55,7 +57,7 @@ config NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE range 1 8 help The minimum value of the backoff exponent (BE) in the CSMA-CA - algorithm. + algorithm (MAC PIB attribute: macMinBe). config NET_L2_IEEE802154_RADIO_CSMA_CA_MAX_BE int "CSMA MAC maximum backoff exponent" @@ -63,7 +65,7 @@ config NET_L2_IEEE802154_RADIO_CSMA_CA_MAX_BE range 1 8 help The maximum value of the backoff exponent (BE) in the CSMA-CA - algorithm. + algorithm (MAC PIB attribute: macMaxBe). endif # NET_L2_IEEE802154_RADIO_CSMA_CA diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index 1d4e89d46c..9391e14666 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -7,6 +7,8 @@ /** * @file * @brief IEEE 802.15.4 MAC layer implementation + * + * All references to the spec refer to IEEE 802.15.4-2020. */ #include @@ -139,8 +141,9 @@ static inline void swap_and_set_pkt_ll_addr(struct net_linkaddr *addr, bool comp } /** - * Filters the destination address of the frame (used when IEEE802154_HW_FILTER - * is not available). + * Filters the destination address of the frame. + * + * This is done before deciphering and authenticating encrypted frames. */ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_mhr *mhr) { @@ -148,9 +151,8 @@ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_m struct ieee802154_context *ctx = net_if_l2_data(iface); bool ret = false; - /* - * Apply filtering requirements from chapter 6.7.2 of the IEEE - * 802.15.4-2015 standard: + /* Apply filtering requirements from section 6.7.2 c)-e). For a)-b), + * see ieee802154_parse_fcf_seq() */ if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_NONE) { @@ -167,9 +169,8 @@ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_m k_sem_take(&ctx->ctx_lock, K_FOREVER); - /* - * c. If a destination PAN ID is included in the frame, it shall match - * macPanId or shall be the broadcastPAN ID + /* c) If a destination PAN ID is included in the frame, it shall match + * macPanId or shall be the broadcast PAN ID. */ if (!(dst_plain->pan_id == IEEE802154_BROADCAST_PAN_ID || dst_plain->pan_id == ctx->pan_id)) { @@ -178,8 +179,7 @@ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_m } if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_SHORT) { - /* - * d.1. A short destination address is included in the frame, + /* d.1) A short destination address is included in the frame, * and it matches either macShortAddress or the broadcast * address. */ @@ -190,17 +190,23 @@ static bool ieeee802154_check_dst_addr(struct net_if *iface, struct ieee802154_m } } else if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_EXTENDED) { - /* - * An extended destination address is included in the frame and - * matches either macExtendedAddress or, if macGroupRxMode is - * set to TRUE, an 64-bit extended unique identifier (EUI-64) - * group address. + /* d.2) An extended destination address is included in the frame and + * matches [...] macExtendedAddress [...]. */ if (memcmp(dst_plain->addr.ext_addr, ctx->ext_addr, IEEE802154_EXT_ADDR_LENGTH) != 0) { LOG_DBG("Frame dst address (ext) does not match!"); goto out; } + + /* TODO: d.3) The Destination Address field and the Destination PAN ID + * field are not included in the frame and macImplicitBroadcast is TRUE. + */ + + /* TODO: d.4) The device is the PAN coordinator, only source addressing fields + * are included in a Data frame or MAC command and the source PAN ID + * matches macPanId. + */ } ret = true; @@ -253,7 +259,7 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk return verdict; } - /* At this point the frame has to be a DATA one */ + /* At this point the frame has to be a data frame. */ ieee802154_acknowledge(iface, &mpdu); @@ -286,8 +292,15 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk #else return NET_CONTINUE; #endif /* CONFIG_NET_6LO */ + + /* At this point the call amounts to (part of) an + * MCPS-DATA.indication primitive, see section 8.3.3. + */ } +/** + * Implements (part of) the MCPS-DATA.request/confirm primitives, see sections 8.3.2/3. + */ static int ieee802154_send(struct net_if *iface, struct net_pkt *pkt) { static struct net_buf *frame_buf; diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.c b/subsys/net/l2/ieee802154/ieee802154_frame.c index 83b022dae6..2374e1f027 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/l2/ieee802154/ieee802154_frame.c @@ -7,6 +7,8 @@ /** * @file * @brief IEEE 802.15.4 MAC frame related functions implementation + * + * All references to the spec refer to IEEE 802.15.4-2020. */ #include @@ -146,7 +148,7 @@ ieee802154_validate_aux_security_hdr(uint8_t *buf, uint8_t **p_buf, uint8_t *len return NULL; } - /* Explicit key must have a key index != 0x00, see section 7.6.2.4.2 */ + /* Explicit key must have a key index != 0x00, see section 9.4.2.3 */ switch (ash->control.key_id_mode) { case IEEE802154_KEY_ID_MODE_IMPLICIT: break; @@ -654,7 +656,7 @@ static uint8_t *generate_aux_security_hdr(struct ieee802154_security_ctx *sec_ct } if (sec_ctx->key_mode != IEEE802154_KEY_ID_MODE_IMPLICIT) { - /* TODO: it supports implicit mode only, for now */ + /* TODO: Support other key ID modes. */ return NULL; } @@ -802,7 +804,7 @@ static inline bool cfi_to_fs_settings(enum ieee802154_cfi cfi, struct ieee802154 break; case IEEE802154_CFI_DATA_REQUEST: fs->fc.ar = 1U; - /* TODO: src/dst addr mode: see section 7.3.4 */ + /* TODO: src/dst addr mode: see section 7.5.5 */ break; case IEEE802154_CFI_ORPHAN_NOTIFICATION: @@ -817,7 +819,7 @@ static inline bool cfi_to_fs_settings(enum ieee802154_cfi cfi, struct ieee802154 break; case IEEE802154_CFI_COORDINATOR_REALIGNEMENT: fs->fc.src_addr_mode = IEEE802154_ADDR_MODE_EXTENDED; - /* TODO: ar and dst addr mode: see section 7.3.8 */ + /* TODO: ar and dst addr mode: see section 7.5.10 */ break; case IEEE802154_CFI_GTS_REQUEST: @@ -866,8 +868,9 @@ struct net_pkt *ieee802154_create_mac_cmd_frame(struct net_if *iface, enum ieee8 k_sem_take(&ctx->ctx_lock, K_FOREVER); - /* It would be costly to compute the size when actual frame are never - * bigger than 125 bytes, so let's allocate that size as buffer. + /* It would be costly to compute the size when actual frames are never + * bigger than IEEE802154_MTU bytes less the FCS size, so let's allocate that + * size as buffer. */ pkt = net_pkt_alloc_with_buffer(iface, IEEE802154_MTU, AF_UNSPEC, 0, BUF_TIMEOUT); if (!pkt) { @@ -954,9 +957,12 @@ bool ieee802154_decipher_data_frame(struct net_if *iface, struct net_pkt *pkt, goto out; } - /* Section 7.2.3 (i) talks about "security level policy" conformance - * but such policy does not seem to be detailed. So let's assume both - * ends should have same security level. + /* Section 9.2.4: Incoming frame security procedure, Security Enabled field is set to one + * + * [...] + * + * a) Legacy security. If the Frame Version field of the frame to be unsecured is set to + * zero, the procedure shall return with a Status of UNSUPPORTED_LEGACY. */ if (mpdu->mhr.aux_sec->control.security_level != level) { goto out; diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.h b/subsys/net/l2/ieee802154/ieee802154_frame.h index af2e42070f..99e5f38a7f 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.h +++ b/subsys/net/l2/ieee802154/ieee802154_frame.h @@ -9,6 +9,12 @@ * @brief IEEE 802.15.4 MAC frame related functions * * This is not to be included by the application. + * + * All specification references in this file refer to IEEE 802.15.4-2020. + * + * Note: All structs and attributes (e.g. PAN id, ext address and short + * address) in this file that directly represent IEEE 802.15.4 frames + * are in LITTLE ENDIAN, see section 4, especially section 4.3. */ #ifndef __IEEE802154_FRAME_H__ @@ -19,17 +25,8 @@ #include #include -/* All specification references in this file refer to IEEE 802.15.4-2006 - * unless otherwise noted. - * - * Note: All structs and attributes (e.g. PAN id, ext address and short - * address) in this file that directly represent IEEE 802.15.4 frames - * are in LITTLE ENDIAN, see section 4, especially section 4.3. - */ - -#define IEEE802154_MIN_LENGTH 3 -/* ACK packet size is the minimum size, see section 7.2.2.3 */ -#define IEEE802154_ACK_PKT_LENGTH IEEE802154_MIN_LENGTH +#define IEEE802154_ACK_PKT_LENGTH 3 /* Imm-Ack length, see section 7.3.3 */ +#define IEEE802154_MIN_LENGTH IEEE802154_ACK_PKT_LENGTH #define IEEE802154_FCF_SEQ_LENGTH 3 #define IEEE802154_SIMPLE_ADDR_LENGTH 1 @@ -46,7 +43,7 @@ #define IEEE802154_BEACON_GTS_RX 1 #define IEEE802154_BEACON_GTS_TX 0 -/* See section 7.2.1.1.1 and IEEE 802.15.4-2020, section 7.2.2.2 */ +/* See section 7.2.2.2 */ enum ieee802154_frame_type { IEEE802154_FRAME_TYPE_BEACON = 0x0, IEEE802154_FRAME_TYPE_DATA = 0x1, @@ -58,7 +55,7 @@ enum ieee802154_frame_type { IEEE802154_FRAME_TYPE_EXTENDED = 0x7, }; -/* See section 7.2.1.1.6 */ +/* See section 7.2.2.9, table 7-3 */ enum ieee802154_addressing_mode { IEEE802154_ADDR_MODE_NONE = 0x0, IEEE802154_ADDR_MODE_SIMPLE = 0x1, @@ -69,10 +66,7 @@ enum ieee802154_addressing_mode { /* Version 2006 (and before) do no support simple addressing mode */ #define IEEE802154_ADDR_MODE_RESERVED IEEE802154_ADDR_MODE_SIMPLE -/* - * See IEEE 802.15.4-2006 section 7.2.1.1.7 and - * IEEE 802.15.4-2015, section 7.2.1.9 - */ +/* See section 7.2.2.10 */ enum ieee802154_version { IEEE802154_VERSION_802154_2003 = 0x0, IEEE802154_VERSION_802154_2006 = 0x1, @@ -81,8 +75,7 @@ enum ieee802154_version { }; /* - * Frame Control Field and sequence number, - * see section 7.2.1.1 + * Frame Control Field, see section 7.2.2 */ struct ieee802154_fcf_seq { struct { @@ -140,7 +133,7 @@ struct ieee802154_address_field { }; } __packed; -/* See section 7.6.2.2.1 */ +/* See section 9.4.2.2, table 9-6 */ enum ieee802154_security_level { IEEE802154_SECURITY_LEVEL_NONE = 0x0, IEEE802154_SECURITY_LEVEL_MIC_32 = 0x1, @@ -157,7 +150,7 @@ enum ieee802154_security_level { #define IEEE8021254_AUTH_TAG_LENGTH_64 8 #define IEEE8021254_AUTH_TAG_LENGTH_128 16 -/* See section 7.6.2.2.2 */ +/* See section 9.4.2.3, table 9-7 */ enum ieee802154_key_id_mode { IEEE802154_KEY_ID_MODE_IMPLICIT = 0x0, IEEE802154_KEY_ID_MODE_INDEX = 0x1, @@ -171,7 +164,7 @@ enum ieee802154_key_id_mode { #define IEEE802154_KEY_MAX_LEN 16 -/* See section 7.6.2.2 */ +/* See section 9.4.2 */ struct ieee802154_security_control_field { #ifdef CONFIG_LITTLE_ENDIAN uint8_t security_level : 3; @@ -186,7 +179,7 @@ struct ieee802154_security_control_field { #define IEEE802154_SECURITY_CF_LENGTH 1 -/* See section 7.6.2.4 */ +/* see section 9.4.4 */ struct ieee802154_key_identifier_field { union { /* mode_0 being implicit, it holds no info here */ @@ -208,7 +201,7 @@ struct ieee802154_key_identifier_field { /* * Auxiliary Security Header - * See section 7.6.2 + * see section 9.4 */ struct ieee802154_aux_security_hdr { struct ieee802154_security_control_field control; @@ -228,6 +221,7 @@ struct ieee802154_mhr { #endif }; +/* see section 7.3.1.5, figure 7-10 */ struct ieee802154_gts_dir { #ifdef CONFIG_LITTLE_ENDIAN uint8_t mask : 7; @@ -238,6 +232,7 @@ struct ieee802154_gts_dir { #endif } __packed; +/* see section 7.3.1.5, figure 7-11 */ struct ieee802154_gts { uint16_t short_address; #ifdef CONFIG_LITTLE_ENDIAN @@ -249,6 +244,7 @@ struct ieee802154_gts { #endif } __packed; +/* see section 7.3.1.5, figure 7-9 */ struct ieee802154_gts_spec { #ifdef CONFIG_LITTLE_ENDIAN /* Descriptor Count */ @@ -265,6 +261,7 @@ struct ieee802154_gts_spec { #endif } __packed; +/* see section 7.3.1.6, figure 7-13 */ struct ieee802154_pas_spec { #ifdef CONFIG_LITTLE_ENDIAN /* Number of Short Addresses Pending */ @@ -283,6 +280,7 @@ struct ieee802154_pas_spec { #endif } __packed; +/* see section 7.3.1.4, figure 7-7 */ struct ieee802154_beacon_sf { #ifdef CONFIG_LITTLE_ENDIAN /* Beacon Order*/ @@ -315,6 +313,7 @@ struct ieee802154_beacon_sf { #endif } __packed; +/* see section 7.3.1.1, figure 7-5 */ struct ieee802154_beacon { struct ieee802154_beacon_sf sf; @@ -322,7 +321,7 @@ struct ieee802154_beacon { struct ieee802154_gts_spec gts; } __packed; -/* See section 7.3.1 */ +/* see section 7.5.2 */ struct ieee802154_cmd_assoc_req { struct { #ifdef CONFIG_LITTLE_ENDIAN @@ -347,7 +346,7 @@ struct ieee802154_cmd_assoc_req { #define IEEE802154_CMD_ASSOC_REQ_LENGTH 1 -/* See section 7.3.2 */ +/* See section 7.5.3 */ enum ieee802154_association_status_field { IEEE802154_ASF_SUCCESSFUL = 0x00, IEEE802154_ASF_PAN_AT_CAPACITY = 0x01, @@ -363,7 +362,7 @@ struct ieee802154_cmd_assoc_res { #define IEEE802154_CMD_ASSOC_RES_LENGTH 3 -/* See section 7.3.3.2 */ +/* See section 7.5.4 */ enum ieee802154_disassociation_reason_field { IEEE802154_DRF_RESERVED_1 = 0x00, IEEE802154_DRF_COORDINATOR_WISH = 0x01, @@ -378,7 +377,7 @@ struct ieee802154_cmd_disassoc_note { #define IEEE802154_CMD_DISASSOC_NOTE_LENGTH 1 -/* Coordinator realignment, see section 7.3.8 */ +/* Coordinator realignment, see section 7.5.10 */ struct ieee802154_cmd_coord_realign { uint16_t pan_id; uint16_t coordinator_short_addr; @@ -389,7 +388,7 @@ struct ieee802154_cmd_coord_realign { #define IEEE802154_CMD_COORD_REALIGN_LENGTH 3 -/* GTS request, see section 7.3.9 */ +/* GTS request, see section 7.5.11 */ struct ieee802154_gts_request { struct { #ifdef CONFIG_LITTLE_ENDIAN @@ -408,7 +407,7 @@ struct ieee802154_gts_request { #define IEEE802154_GTS_REQUEST_LENGTH 1 -/* Command Frame Identifiers (CFI), see Section 7.3 */ +/* Command Frame Identifiers (CFI), see section 7.5.1 */ enum ieee802154_cfi { IEEE802154_CFI_UNKNOWN = 0x00, IEEE802154_CFI_ASSOCIATION_REQUEST = 0x01, @@ -431,8 +430,8 @@ struct ieee802154_command { struct ieee802154_cmd_disassoc_note disassoc_note; struct ieee802154_cmd_coord_realign coord_realign; struct ieee802154_gts_request gts_request; - /* Data request, PAN ID conflict, Orphan notification - * or Beacon request do not provide more than the CIF. + /* Data request, PAN ID conflict, orphan notification + * or beacon request just provide the CFI. */ }; } __packed; diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index a11996d9f5..69296f411d 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -4,6 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief IEEE 802.15.4 Net Management Implementation + * + * All references to the spec refer to IEEE 802.15.4-2020. + */ + #include LOG_MODULE_REGISTER(net_ieee802154_mgmt, CONFIG_NET_L2_IEEE802154_LOG_LEVEL); @@ -22,6 +29,9 @@ LOG_MODULE_REGISTER(net_ieee802154_mgmt, CONFIG_NET_L2_IEEE802154_LOG_LEVEL); #include "ieee802154_utils.h" #include "ieee802154_radio_utils.h" +/** + * Implements (part of) the MLME-BEACON.notify primitive, see section 8.2.5.2. + */ enum net_verdict ieee802154_handle_beacon(struct net_if *iface, struct ieee802154_mpdu *mpdu, uint8_t lqi) @@ -304,7 +314,7 @@ enum net_verdict ieee802154_handle_mac_command(struct net_if *iface, goto out; } - /* validation of the disassociation request, see section 7.3.3.1 */ + /* validation of the disassociation notification, see section 7.5.4 */ if (mpdu->mhr.fs->fc.src_addr_mode != IEEE802154_ADDR_MODE_EXTENDED || @@ -386,7 +396,9 @@ static int ieee802154_associate(uint32_t mgmt_request, struct net_if *iface, /* acquire the lock so that the next k_sem_take() blocks */ k_sem_take(&ctx->scan_ctx_lock, K_FOREVER); - /* TODO: current timeout is arbitrary, see IEEE 802.15.4-2015, 8.4.2, macResponseWaitTime */ + /* TODO: current timeout is arbitrary, + * see section 8.4.3.1, table 8-94, macResponseWaitTime + */ k_sem_take(&ctx->scan_ctx_lock, K_SECONDS(1)); /* release the lock */ @@ -455,7 +467,7 @@ static int ieee802154_disassociate(uint32_t mgmt_request, struct net_if *iface, goto out; } - /* See section 7.3.3 */ + /* See section 7.5.4 */ params.dst.pan_id = ctx->pan_id; diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h b/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h index 31d61eeaa7..2e8b53693a 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt_priv.h @@ -6,7 +6,7 @@ /** * @file - * @brief IEEE 802.15.4 Private Management + * @brief IEEE 802.15.4 Net Management Private API */ #ifndef __IEEE802154_MGMT_PRIV_H__ diff --git a/subsys/net/l2/ieee802154/ieee802154_radio_utils.h b/subsys/net/l2/ieee802154/ieee802154_radio_utils.h index 0178dc310f..1c1b4a12de 100644 --- a/subsys/net/l2/ieee802154/ieee802154_radio_utils.h +++ b/subsys/net/l2/ieee802154/ieee802154_radio_utils.h @@ -4,6 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief IEEE 802.15.4 low level radio helper utilities + * + * All references to the spec refer to IEEE 802.15.4-2020. + */ + #ifndef __IEEE802154_RADIO_UTILS_H__ #define __IEEE802154_RADIO_UTILS_H__ @@ -53,7 +60,7 @@ static inline int wait_for_ack(struct net_if *iface, if (k_sem_take(&ctx->ack_lock, K_MSEC(10)) == 0) { /* - * We reinit the semaphore in case handle_ack + * We reinit the semaphore in case handle_ack() * got called multiple times. */ k_sem_init(&ctx->ack_lock, 0, K_SEM_MAX_LIMIT); diff --git a/subsys/net/l2/ieee802154/ieee802154_security.c b/subsys/net/l2/ieee802154/ieee802154_security.c index 9a58ac3a7f..4626eaf8f5 100644 --- a/subsys/net/l2/ieee802154/ieee802154_security.c +++ b/subsys/net/l2/ieee802154/ieee802154_security.c @@ -7,6 +7,8 @@ /** * @file * @brief 802.15.4 6LoWPAN authentication and encryption implementation + * + * All references to the spec refer to IEEE 802.15.4-2020. */ #include @@ -101,15 +103,14 @@ static void prepare_cipher_aead_pkt(uint8_t *frame, uint8_t level, uint8_t hdr_l bool is_authenticated = level != IEEE802154_SECURITY_LEVEL_NONE && level != IEEE802154_SECURITY_LEVEL_ENC; - /* See section 7.6.3.4.2 */ + /* See section 9.3.5.3 */ pkt->in_buf = is_encrypted && payload_len ? frame + hdr_len : NULL; pkt->in_len = is_encrypted ? payload_len : 0; - /* See section 7.6.3.4.2 */ + /* See section 9.3.5.4 */ uint8_t out_buf_offset = is_encrypted ? hdr_len : hdr_len + payload_len; uint8_t auth_len = is_authenticated ? out_buf_offset : 0; - /* See section 7.5.8.2.1 i) 1) */ pkt->out_buf = frame + out_buf_offset; pkt->out_buf_max = (is_encrypted ? payload_len : 0) + tag_size; @@ -141,7 +142,7 @@ bool ieee802154_decrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *f return false; } - /* See section 7.6.3.2 */ + /* See section 9.3.3.1 */ memcpy(nonce, src_ext_addr, IEEE802154_EXT_ADDR_LENGTH); sys_put_be32(frame_counter, &nonce[8]); nonce[12] = level; @@ -184,13 +185,12 @@ bool ieee802154_encrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *f return false; } - /* See section 7.5.8.2.1 f) */ if (sec_ctx->frame_counter == 0xffffffff) { NET_ERR("Max frame counter reached. Update key material to reset the counter."); return false; } - /* See section 7.6.3.2 */ + /* See section 9.3.3.1 */ memcpy(nonce, src_ext_addr, IEEE802154_EXT_ADDR_LENGTH); sys_put_be32(sec_ctx->frame_counter, &nonce[8]); nonce[12] = level;