Skip to content

Commit

Permalink
net: l2: ieee802154: simplify/fix ACK procedure
Browse files Browse the repository at this point in the history
Removes redundant ACK state from `struct ieee802154_context` and
simplifies the ACK procedure.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
  • Loading branch information
fgrandel committed Jul 6, 2023
1 parent a7612f7 commit 3724f46
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 14 deletions.
3 changes: 1 addition & 2 deletions include/zephyr/net/ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ struct ieee802154_context {
*/
uint8_t sequence;

uint8_t _unused : 6;
uint8_t _unused : 7;

uint8_t ack_received : 1; /* guarded by ack_lock */
uint8_t ack_requested : 1; /* guarded by ack_lock */
uint8_t ack_seq; /* guarded by ack_lock */
struct k_sem ack_lock;
Expand Down
24 changes: 14 additions & 10 deletions subsys/net/l2/ieee802154/ieee802154.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ inline bool ieee802154_prepare_for_ack(struct net_if *iface, struct net_pkt *pkt
struct ieee802154_context *ctx = net_if_l2_data(iface);

ctx->ack_seq = fs->sequence;
ctx->ack_received = false;
k_sem_init(&ctx->ack_lock, 0, K_SEM_MAX_LIMIT);
if (k_sem_count_get(&ctx->ack_lock) == 1U) {
k_sem_take(&ctx->ack_lock, K_NO_WAIT);
}

return true;
}
Expand Down Expand Up @@ -139,7 +140,6 @@ enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt
return NET_CONTINUE;
}

ctx->ack_received = true;
k_sem_give(&ctx->ack_lock);

/* TODO: Release packet in L2 as we're taking ownership. */
Expand All @@ -152,23 +152,26 @@ enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt
inline int ieee802154_wait_for_ack(struct net_if *iface, bool ack_required)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
int ret;

if (!ack_required ||
(ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_TX_RX_ACK)) {
__ASSERT_NO_MSG(ctx->ack_seq == 0U);
return 0;
}

if (k_sem_take(&ctx->ack_lock, K_MSEC(10)) == 0) {
/* We reinit the semaphore in case ieee802154_handle_ack()
* got called multiple times.
*/
k_sem_init(&ctx->ack_lock, 0, K_SEM_MAX_LIMIT);
ret = k_sem_take(&ctx->ack_lock, K_MSEC(10));
if (ret == 0) {
/* no-op */
} else if (ret == -EAGAIN) {
ret = -ETIME;
} else {
NET_ERR("Error while waiting for ACK.");
ret = -EFAULT;
}

ctx->ack_seq = 0U;

return ctx->ack_received ? 0 : -ETIME;
return ret;
}

int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt, struct net_buf *frag)
Expand Down Expand Up @@ -619,6 +622,7 @@ void ieee802154_init(struct net_if *iface)
NET_DBG("Initializing IEEE 802.15.4 stack on iface %p", iface);

k_sem_init(&ctx->ctx_lock, 1, 1);
k_sem_init(&ctx->ack_lock, 0, 1);

/* no need to lock the context here as it has
* not been published yet.
Expand Down
4 changes: 2 additions & 2 deletions subsys/net/l2/ieee802154/ieee802154_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,8 +914,8 @@ bool ieee802154_create_ack_frame(struct net_if *iface, struct net_pkt *pkt, uint

fs = generate_fcf_grounds(&p_buf, false);

fs->fc.dst_addr_mode = 0U;
fs->fc.src_addr_mode = 0U;
fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_NONE;
fs->fc.src_addr_mode = IEEE802154_ADDR_MODE_NONE;

fs->fc.frame_type = IEEE802154_FRAME_TYPE_ACK;
fs->sequence = seq;
Expand Down

0 comments on commit 3724f46

Please sign in to comment.