net: l2: ieee802154: mgmt: allow beacon payload
The standard does allow for a optional beacon payload, which gets lost during scan, that could be interesting for the application to access in the NET_EVENT_IEEE802154_SCAN_RESULT callback. See section 7.3.1.6 in IEEE Std 802.15.4 for more information about the beacon payload field. And section 7.3.1 and figure 7-5 about general beacon frame format. Signed-off-by: Fabian Pflug <fabian.pflug@grandcentrix.net>
This commit is contained in:
parent
293fa118df
commit
ca53d2bf80
5 changed files with 42 additions and 10 deletions
|
@ -330,6 +330,11 @@ struct ieee802154_req_params {
|
|||
uint8_t len;
|
||||
/** Link quality information, between 0 and 255 */
|
||||
uint8_t lqi;
|
||||
|
||||
/** Additional payload of the beacon if any.*/
|
||||
uint8_t *beacon_payload;
|
||||
/** Length of the additional payload. */
|
||||
size_t beacon_payload_len;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -194,30 +194,32 @@ ieee802154_validate_aux_security_hdr(uint8_t *buf, uint8_t **p_buf, uint8_t *len
|
|||
}
|
||||
#endif /* CONFIG_NET_L2_IEEE802154_SECURITY */
|
||||
|
||||
static inline bool validate_beacon(struct ieee802154_mpdu *mpdu, uint8_t *buf, uint8_t length)
|
||||
int ieee802514_beacon_header_length(uint8_t *buf, uint8_t length)
|
||||
{
|
||||
struct ieee802154_beacon *beacon = (struct ieee802154_beacon *)buf;
|
||||
struct ieee802154_pas_spec *pas;
|
||||
uint8_t len = IEEE802154_BEACON_SF_SIZE + IEEE802154_BEACON_GTS_SPEC_SIZE;
|
||||
|
||||
if (length < len) {
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* see section 7.3.1.5 on how to calculate GTS length */
|
||||
if (beacon->gts.desc_count) {
|
||||
len += IEEE802154_BEACON_GTS_DIR_SIZE +
|
||||
beacon->gts.desc_count * IEEE802154_BEACON_GTS_SIZE;
|
||||
}
|
||||
|
||||
if (length < len) {
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* see section 7.3.1.6 on how to calculate pending address length */
|
||||
pas = (struct ieee802154_pas_spec *)buf + len;
|
||||
|
||||
len += IEEE802154_BEACON_PAS_SPEC_SIZE;
|
||||
if (length < len) {
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pas->nb_sap || pas->nb_eap) {
|
||||
|
@ -226,12 +228,10 @@ static inline bool validate_beacon(struct ieee802154_mpdu *mpdu, uint8_t *buf, u
|
|||
}
|
||||
|
||||
if (length < len) {
|
||||
return false;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mpdu->beacon = beacon;
|
||||
|
||||
return true;
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline bool validate_mac_command_cfi_to_mhr(struct ieee802154_mhr *mhr,
|
||||
|
@ -376,7 +376,7 @@ static inline bool validate_payload_and_mfr(struct ieee802154_mpdu *mpdu, uint8_
|
|||
NET_DBG("Header size: %u, payload size %u", (uint32_t)(p_buf - buf), length);
|
||||
|
||||
if (type == IEEE802154_FRAME_TYPE_BEACON) {
|
||||
if (!validate_beacon(mpdu, p_buf, length)) {
|
||||
if (ieee802514_beacon_header_length(p_buf, length) < 0) {
|
||||
return false;
|
||||
}
|
||||
} else if (type == IEEE802154_FRAME_TYPE_DATA) {
|
||||
|
|
|
@ -472,6 +472,20 @@ ieee802154_validate_aux_security_hdr(uint8_t *buf, uint8_t **p_buf, uint8_t *len
|
|||
struct ieee802154_fcf_seq *ieee802154_validate_fc_seq(uint8_t *buf, uint8_t **p_buf,
|
||||
uint8_t *length);
|
||||
|
||||
/**
|
||||
* @brief Calculate the beacon header length.
|
||||
*
|
||||
* @details Returns the length of the MAC payload without the beacon payload,
|
||||
* see section 7.3.1.1, figure 7-5.
|
||||
*
|
||||
* @param buf pointer to the MAC payload
|
||||
* @param length buffer length
|
||||
*
|
||||
* @retval -EINVAL The header is invalid.
|
||||
* @return the length of the beacon header
|
||||
*/
|
||||
int ieee802514_beacon_header_length(uint8_t *buf, uint8_t length);
|
||||
|
||||
bool ieee802154_validate_frame(uint8_t *buf, uint8_t length, struct ieee802154_mpdu *mpdu);
|
||||
|
||||
void ieee802154_compute_header_and_authtag_len(struct net_if *iface, struct net_linkaddr *dst,
|
||||
|
|
|
@ -37,6 +37,7 @@ enum net_verdict ieee802154_handle_beacon(struct net_if *iface,
|
|||
uint8_t lqi)
|
||||
{
|
||||
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
||||
int beacon_hdr_len;
|
||||
|
||||
NET_DBG("Beacon received");
|
||||
|
||||
|
@ -64,6 +65,10 @@ enum net_verdict ieee802154_handle_beacon(struct net_if *iface,
|
|||
IEEE802154_EXT_ADDR_LENGTH);
|
||||
}
|
||||
|
||||
beacon_hdr_len = ieee802514_beacon_header_length(mpdu->payload, mpdu->payload_length);
|
||||
ctx->scan_ctx->beacon_payload_len = mpdu->payload_length - beacon_hdr_len;
|
||||
ctx->scan_ctx->beacon_payload = (uint8_t *)mpdu->payload + beacon_hdr_len;
|
||||
|
||||
net_mgmt_event_notify(NET_EVENT_IEEE802154_SCAN_RESULT, iface);
|
||||
|
||||
k_sem_give(&ctx->scan_ctx_lock);
|
||||
|
|
|
@ -45,12 +45,16 @@ K_SEM_DEFINE(scan_lock, 0, 1);
|
|||
#define EXPECTED_ENDDEVICE_EXT_ADDR_STR "08:07:06:05:04:03:02:01"
|
||||
#define EXPECTED_ENDDEVICE_SHORT_ADDR 0xaaaa
|
||||
|
||||
#define EXPECTED_PAYLOAD_DATA EXPECTED_ENDDEVICE_EXT_ADDR_LE
|
||||
#define EXPECTED_PAYLOAD_LEN 8
|
||||
|
||||
static void scan_result_cb(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
|
||||
struct net_if *iface)
|
||||
{
|
||||
struct ieee802154_context *ctx = net_if_l2_data(iface);
|
||||
struct ieee802154_req_params *scan_ctx = ctx->scan_ctx;
|
||||
uint8_t expected_coordinator_address[] = {EXPECTED_COORDINATOR_ADDR_BE};
|
||||
uint8_t expected_payload_data[] = {EXPECTED_PAYLOAD_DATA};
|
||||
|
||||
/* No need for scan_ctx locking as we should execute exclusively. */
|
||||
|
||||
|
@ -63,6 +67,10 @@ static void scan_result_cb(struct net_mgmt_event_callback *cb, uint32_t mgmt_eve
|
|||
zassert_equal(scan_ctx->lqi, EXPECTED_COORDINATOR_LQI,
|
||||
"Scan did not receive correct link quality indicator.");
|
||||
|
||||
zassert_equal(scan_ctx->beacon_payload_len, EXPECTED_PAYLOAD_LEN,
|
||||
"Scan did not include the payload");
|
||||
zassert_mem_equal(scan_ctx->beacon_payload, expected_payload_data, EXPECTED_PAYLOAD_LEN);
|
||||
|
||||
k_sem_give(&scan_lock);
|
||||
}
|
||||
|
||||
|
@ -201,7 +209,7 @@ ZTEST(ieee802154_l2_shell, test_active_scan)
|
|||
0x00, 0xc0, /* Superframe Specification: PAN coordinator + association permitted */
|
||||
0x00, /* GTS */
|
||||
0x00, /* Pending Addresses */
|
||||
0x00, 0x00 /* Payload */
|
||||
EXPECTED_PAYLOAD_DATA /* Layer 3 payload */
|
||||
};
|
||||
struct net_pkt *pkt;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue