net: l2: ieee802154: improve inline documentation

Over time, some non-standard concepts and extensions were introduced
into the stack (in KConfig, in drivers, in the internal API and into the
implementation) which makes introduction of additional standard-
compliant extensions like TSCH (and others) unnecessarily difficult.

To introduce extensions like TSCH it is required for the IEEE 802.15.4
stack to become more structurally aligned with the standard again which
will be the focus of some of the upcoming preparatory changes.

One way to check and prove standard compliance is to reference the
standard from within the source code. This change therefore introduces
inline references to the IEEE 802.15.4-2020 standard wherever possible.
Deviations from the standard are documented with TODO or deprecation
labels to be addressed in future changes.

In the future, new code introduced to the IEEE 802.15.4 stack should
be documented and reviewed for standard-compliance to avoid further
divergence. Most importantly:
* MAC/PHY configuration (via net mgmt, radio API, devicetree or
  KConfig) should always be directly linked to well-defined MAC/PHY
  PIB attributes if visible to the MAC API or the end user.
* Net management/shell/radio API commands should have a documented
  reference to the corresponding MLME action from the standard.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
This commit is contained in:
Florian Grandel 2023-05-22 15:23:56 +02:00 committed by Carles Cufí
parent 6b004e267e
commit 32e1213b0c
13 changed files with 210 additions and 118 deletions

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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 <en/de>cryption"

View file

@ -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

View file

@ -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 <zephyr/logging/log.h>
@ -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;

View file

@ -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 <zephyr/logging/log.h>
@ -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;

View file

@ -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 <zephyr/net/net_pkt.h>
#include <zephyr/toolchain.h>
/* 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;

View file

@ -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 <zephyr/logging/log.h>
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;

View file

@ -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__

View file

@ -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);

View file

@ -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 <zephyr/logging/log.h>
@ -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;