From 21a8603890ccb0078001024f6d4fddd3ee6cf400 Mon Sep 17 00:00:00 2001 From: Simon Piriou Date: Sat, 5 Jul 2025 16:57:00 +0200 Subject: [PATCH] net: l2: ieee802154: add support for IEEE802154_CFI_DATA_REQUEST 802.15.4 specifies that a device may send a DATA_REQUEST command to the coordinator after waiting for "macResponseWaitTime", starting after the acknowledgment to the association request command. This change adds support to generate DATA_REQUEST frames and sends one for the association usecase only. The two other usecases, for MLME-POLL or for beacon-enabled PAN, are not yet supported. Signed-off-by: Simon Piriou --- subsys/net/l2/ieee802154/ieee802154_frame.c | 31 ++++++++++++++++++++- subsys/net/l2/ieee802154/ieee802154_mgmt.c | 26 ++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.c b/subsys/net/l2/ieee802154/ieee802154_frame.c index a4a3793081159..b561498538130 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/l2/ieee802154/ieee802154_frame.c @@ -792,8 +792,37 @@ static inline bool cfi_to_fs_settings(enum ieee802154_cfi cfi, struct ieee802154 break; case IEEE802154_CFI_DATA_REQUEST: + if (params->dst.len == 0) { + /* If the Destination Addressing Mode subfield is set to zero (i.e., + * destination addressing information not present), the PAN ID + * Compression subfield of the Frame Control field shall be set to zero + * and the source PAN identifier shall contain the value of macPANId. + * + * This is the case only if the data request command is being + * sent in response to the receipt of a beacon frame indicating that + * data are pending for that device. + */ + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_NONE; + } else { + /* Both short and extended dest addresses are supported. + * It's up to the caller to configure it correctly. + */ + if (params->dst.len == IEEE802154_SHORT_ADDR_LENGTH) { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_SHORT; + } else { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_EXTENDED; + } + fs->fc.pan_id_comp = 1U; + } + + if (params->short_addr == IEEE802154_NO_SHORT_ADDRESS_ASSIGNED) { + fs->fc.src_addr_mode = IEEE802154_ADDR_MODE_EXTENDED; + } else { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_SHORT; + } + + /* the Acknowledgment Request subfield is always set */ fs->fc.ar = 1U; - /* TODO: src/dst addr mode: see section 7.5.5 */ break; case IEEE802154_CFI_ORPHAN_NOTIFICATION: diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index cfd8cae625044..da4e64a900993 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -574,7 +574,30 @@ static int ieee802154_associate(uint64_t mgmt_request, struct net_if *iface, * TODO: The Association Response command shall be sent to the device * requesting association using indirect transmission. */ - k_sem_take(&ctx->scan_ctx_lock, K_USEC(ieee802154_get_response_wait_time_us(iface))); + ret = k_sem_take(&ctx->scan_ctx_lock, K_USEC(ieee802154_get_response_wait_time_us(iface))); + + if (ret == -EAGAIN) { + /* Timeout, send DATA_REQUEST */ + net_pkt_unref(pkt); + pkt = ieee802154_create_mac_cmd_frame(iface, IEEE802154_CFI_DATA_REQUEST, ¶ms); + if (pkt == NULL) { + ret = -ENOBUFS; + k_sem_give(&ctx->scan_ctx_lock); + NET_ERR("Could not associate: cannot allocate DATA request frame"); + goto out; + } + ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_DATA_REQUEST); + + if (ieee802154_radio_send(iface, pkt, pkt->buffer)) { + ret = -EIO; + k_sem_give(&ctx->scan_ctx_lock); + NET_ERR("Could not associate: cannot send DATA request"); + goto out; + } + + k_sem_take(&ctx->scan_ctx_lock, + K_USEC(ieee802154_get_response_wait_time_us(iface))); + } /* Release the scan lock in case an association response was not received * within macResponseWaitTime and we got a timeout instead. @@ -607,6 +630,7 @@ static int ieee802154_associate(uint64_t mgmt_request, struct net_if *iface, } ctx->channel = req->channel; + ret = 0; } else { ret = -EACCES; }