| /* |
| * Copyright (c) 2016 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef __IEEE802154_RADIO_UTILS_H__ |
| #define __IEEE802154_RADIO_UTILS_H__ |
| |
| typedef int (ieee802154_radio_tx_frag_t)(struct net_if *iface, |
| struct net_pkt *pkt, |
| struct net_buf *frag); |
| |
| static inline bool prepare_for_ack(struct ieee802154_context *ctx, |
| struct net_pkt *pkt) |
| { |
| if (ieee802154_ack_required(pkt)) { |
| ctx->ack_received = false; |
| k_sem_init(&ctx->ack_lock, 0, UINT_MAX); |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| static inline int wait_for_ack(struct ieee802154_context *ctx, |
| bool ack_required) |
| { |
| if (!ack_required) { |
| return 0; |
| } |
| |
| if (k_sem_take(&ctx->ack_lock, 10) == 0) { |
| /* |
| * We reinit the semaphore in case handle_ack |
| * got called multiple times. |
| */ |
| k_sem_init(&ctx->ack_lock, 0, UINT_MAX); |
| } |
| |
| return ctx->ack_received ? 0 : -EIO; |
| } |
| |
| static inline int handle_ack(struct ieee802154_context *ctx, |
| struct net_pkt *pkt) |
| { |
| if (pkt->frags->len == IEEE802154_ACK_PKT_LENGTH) { |
| ctx->ack_received = true; |
| k_sem_give(&ctx->ack_lock); |
| |
| return NET_OK; |
| } |
| |
| return NET_CONTINUE; |
| } |
| |
| static inline int tx_packet_fragments(struct net_if *iface, |
| struct net_pkt *pkt, |
| ieee802154_radio_tx_frag_t *tx_func) |
| { |
| int ret = 0; |
| struct net_buf *frag; |
| |
| frag = pkt->frags; |
| while (frag) { |
| ret = tx_func(iface, pkt, frag); |
| if (ret) { |
| break; |
| } |
| |
| frag = frag->frags; |
| } |
| |
| if (!ret) { |
| net_pkt_unref(pkt); |
| } |
| |
| return ret; |
| } |
| |
| #endif /* __IEEE802154_RADIO_UTILS_H__ */ |