Commit 34999a8b authored by Florian Grandel's avatar Florian Grandel Committed by Carles Cufi
Browse files

net: l2: ieee802154: document endianness



The IEEE 802.15.4 L2 code stores representation of attributes like
PAN id, short address and extended address in different encodings:

* big endian for extended address and CPU byte order for everything
  else whenever such attributes enter user space (except for IP/socket
  link layer addresses which are always big endian - even in case of
  short addresses - to maintain POSIX compatibility).

* little endian for everything that is close to the radio driver as
  IEEE 802.15.4 frames are little endian encoded.

Endianness was almost nowhere documented which led to several bugs and
inconsistencies where assignments of different byte order were not
converted (or sometimes converted, sometimes not).

This change documents endianness wherever possible within the realm of
the IEEE 802.15.4 L2 code. Conversion bugs and inconsistencies that were
revealed by the improved documentation will be fixed in a separate
commit.

Signed-off-by: default avatarFlorian Grandel <jerico.dev@gmail.com>
parent a05f0f3f
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -58,11 +58,11 @@ struct ieee802154_security_ctx {
/* This not meant to be used by any code but 802.15.4 L2 stack */
struct ieee802154_context {
	enum net_l2_flags flags;
	uint16_t pan_id;
	uint16_t pan_id; /* in CPU byte order */
	uint16_t channel;
	struct k_sem ack_lock;
	uint16_t short_addr;
	uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH];
	uint16_t short_addr; /* in CPU byte order */
	uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH]; /* in little endian */
#ifdef CONFIG_NET_L2_IEEE802154_MGMT
	struct ieee802154_req_params *scan_ctx;
	union {
@@ -70,8 +70,8 @@ struct ieee802154_context {
		struct k_sem req_lock;
	};
	union {
		uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH];
		uint16_t short_addr;
		uint8_t ext_addr[IEEE802154_MAX_ADDR_LENGTH]; /* in little endian */
		uint16_t short_addr; /* in CPU byte order */
	} coord;
	uint8_t coord_addr_len;
#endif
+12 −12
Original line number Diff line number Diff line
@@ -42,14 +42,14 @@ enum net_request_ieee802154_cmd {
	NET_REQUEST_IEEE802154_CMD_CANCEL_SCAN,
	NET_REQUEST_IEEE802154_CMD_ASSOCIATE,
	NET_REQUEST_IEEE802154_CMD_DISASSOCIATE,
	NET_REQUEST_IEEE802154_CMD_SET_CHANNEL,
	NET_REQUEST_IEEE802154_CMD_GET_CHANNEL,
	NET_REQUEST_IEEE802154_CMD_SET_PAN_ID,
	NET_REQUEST_IEEE802154_CMD_GET_PAN_ID,
	NET_REQUEST_IEEE802154_CMD_SET_EXT_ADDR,
	NET_REQUEST_IEEE802154_CMD_GET_EXT_ADDR,
	NET_REQUEST_IEEE802154_CMD_SET_SHORT_ADDR,
	NET_REQUEST_IEEE802154_CMD_GET_SHORT_ADDR,
	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,
@@ -191,14 +191,14 @@ struct ieee802154_req_params {
	uint32_t duration;

	/** Current channel in use as a result */
	uint16_t channel;
	uint16_t channel; /* in CPU byte order */
	/** Current pan_id in use as a result */
	uint16_t pan_id;
	uint16_t pan_id; /* in CPU byte order */

	/** Result address */
	union {
		uint8_t addr[IEEE802154_MAX_ADDR_LENGTH];
		uint16_t short_addr;
		uint8_t addr[IEEE802154_MAX_ADDR_LENGTH]; /* in big endian */
		uint16_t short_addr; /* in CPU byte order */
	};

	/** length of address */
+2 −2
Original line number Diff line number Diff line
@@ -384,9 +384,9 @@ NET_L2_INIT(IEEE802154_L2, ieee802154_recv, ieee802154_send, ieee802154_enable,
void ieee802154_init(struct net_if *iface)
{
	struct ieee802154_context *ctx = net_if_l2_data(iface);
	const uint8_t *mac = net_if_get_link_addr(iface)->addr;
	const uint8_t *mac = net_if_get_link_addr(iface)->addr; /* in big endian */
	int16_t tx_power = CONFIG_NET_L2_IEEE802154_RADIO_DFLT_TX_POWER;
	uint8_t long_addr[8];
	uint8_t long_addr[8]; /* in little endian */

	NET_DBG("Initializing IEEE 802.15.4 stack on iface %p", iface);

+10 −6
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@

/* 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
@@ -383,7 +387,7 @@ struct ieee802154_cmd_coord_realign {
	uint16_t coordinator_short_addr;
	uint8_t channel;
	uint16_t short_addr;
	uint8_t channel_page; /* Optional */
	uint8_t channel_page; /* optional */
} __packed;

#define IEEE802154_CMD_COORD_REALIGN_LENGTH 3
@@ -453,16 +457,16 @@ struct ieee802154_mpdu {
struct ieee802154_frame_params {
	struct {
		union {
			uint8_t *ext_addr;
			uint16_t short_addr;
			uint8_t *ext_addr; /* in big endian */
			uint16_t short_addr; /* in CPU byte order */
		};

		uint16_t len;
		uint16_t pan_id;
		uint16_t pan_id; /* in CPU byte order */
	} dst;

	uint16_t short_addr;
	uint16_t pan_id;
	uint16_t short_addr; /* in CPU byte order */
	uint16_t pan_id; /* in CPU byte order */
} __packed;

#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
+23 −0
Original line number Diff line number Diff line
@@ -18,10 +18,33 @@
int ieee802154_security_setup_session(struct ieee802154_security_ctx *sec_ctx, uint8_t level,
				      uint8_t key_mode, uint8_t *key, uint8_t key_len);

/**
 * @brief Decrypt an authenticated payload.
 *
 * @param sec_ctx Pointer to an IEEE 802.15.4 security context.
 * @param frame Pointer to the frame data in original (little endian) byte order.
 * @param hdr_len Length of the MHR.
 * @param payload_len Length of the MAC payload.
 * @param tag_size Length of the authentication tag.
 * @param src_ext_addr Pointer to the extended source address of the frame (in little endian byte
 *                     order).
 * @param frame_counter Frame counter in CPU byte order.
 */
bool ieee802154_decrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *frame,
			     uint8_t hdr_len, uint8_t payload_len, uint8_t tag_size,
			     uint8_t *src_ext_addr, uint32_t frame_counter);

/**
 * @brief Encrypt an authenticated payload.
 *
 * @param sec_ctx Pointer to an IEEE 802.15.4 security context.
 * @param frame Pointer to the frame data in original (little endian) byte order.
 * @param hdr_len Length of the MHR.
 * @param payload_len Length of the MAC payload.
 * @param tag_size Length of the authentication tag.
 * @param src_ext_addr Pointer to the extended source address of the frame (in little endian byte
 *                     order).
 */
bool ieee802154_encrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *frame,
			     uint8_t hdr_len, uint8_t payload_len,
			     uint8_t tag_size, uint8_t *src_ext_addr);
Loading