drivers: ieee802154_nrf5: Add ACK handling
nRF5 driver did not utilize `ieee802154_radio_handle_ack` API, therefore did not provide ACK frames to the upper layer. This commit fixes this problem. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
e86ec977fb
commit
2624d65b60
2 changed files with 54 additions and 10 deletions
|
@ -256,6 +256,49 @@ static int nrf5_set_txpower(struct device *dev, s16_t dbm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int handle_ack(struct nrf5_802154_data *nrf5_radio)
|
||||
{
|
||||
u8_t ack_len = nrf5_radio->ack_frame.psdu[0] - NRF5_FCS_LENGTH;
|
||||
struct net_pkt *ack_pkt;
|
||||
int err = 0;
|
||||
|
||||
ack_pkt = net_pkt_alloc_with_buffer(nrf5_radio->iface, ack_len,
|
||||
AF_UNSPEC, 0, K_NO_WAIT);
|
||||
if (!ack_pkt) {
|
||||
LOG_ERR("No free packet available.");
|
||||
err = -ENOMEM;
|
||||
goto free_nrf_ack;
|
||||
}
|
||||
|
||||
/* Upper layers expect the frame to start at the MAC header, skip the
|
||||
* PHY header (1 byte).
|
||||
*/
|
||||
if (net_pkt_write(ack_pkt, nrf5_radio->ack_frame.psdu + 1,
|
||||
ack_len) < 0) {
|
||||
LOG_ERR("Failed to write to a packet.");
|
||||
err = -ENOMEM;
|
||||
goto free_net_ack;
|
||||
}
|
||||
|
||||
net_pkt_set_ieee802154_lqi(ack_pkt, nrf5_radio->ack_frame.lqi);
|
||||
net_pkt_set_ieee802154_rssi(ack_pkt, nrf5_radio->ack_frame.rssi);
|
||||
|
||||
net_pkt_cursor_init(ack_pkt);
|
||||
|
||||
if (ieee802154_radio_handle_ack(nrf5_radio->iface, ack_pkt) != NET_OK) {
|
||||
LOG_INF("ACK packet not handled - releasing.");
|
||||
}
|
||||
|
||||
free_net_ack:
|
||||
net_pkt_unref(ack_pkt);
|
||||
|
||||
free_nrf_ack:
|
||||
nrf_802154_buffer_free_raw(nrf5_radio->ack_frame.psdu);
|
||||
nrf5_radio->ack_frame.psdu = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nrf5_tx(struct device *dev,
|
||||
struct net_pkt *pkt,
|
||||
struct net_buf *frag)
|
||||
|
@ -294,14 +337,13 @@ static int nrf5_tx(struct device *dev,
|
|||
LOG_DBG("Result: %d", nrf5_data.tx_result);
|
||||
|
||||
if (nrf5_radio->tx_result == NRF_802154_TX_ERROR_NONE) {
|
||||
/* ACK frame not used currently. */
|
||||
if (nrf5_radio->ack != NULL) {
|
||||
nrf_802154_buffer_free_raw(nrf5_radio->ack);
|
||||
if (nrf5_radio->ack_frame.psdu == NULL) {
|
||||
/* No ACK was requested. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
nrf5_radio->ack = NULL;
|
||||
|
||||
return 0;
|
||||
/* Handle ACK packet. */
|
||||
return handle_ack(nrf5_radio);
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
|
@ -466,7 +508,9 @@ void nrf_802154_transmitted_raw(const uint8_t *frame, uint8_t *ack,
|
|||
ARG_UNUSED(lqi);
|
||||
|
||||
nrf5_data.tx_result = NRF_802154_TX_ERROR_NONE;
|
||||
nrf5_data.ack = ack;
|
||||
nrf5_data.ack_frame.psdu = ack;
|
||||
nrf5_data.ack_frame.rssi = power;
|
||||
nrf5_data.ack_frame.lqi = lqi;
|
||||
|
||||
k_sem_give(&nrf5_data.tx_wait);
|
||||
}
|
||||
|
|
|
@ -61,10 +61,10 @@ struct nrf5_802154_data {
|
|||
/* TX result, updated in radio transmit callbacks. */
|
||||
u8_t tx_result;
|
||||
|
||||
/* A pointer to the received ACK frame. May be NULL if no ACK was
|
||||
* requested/received.
|
||||
/* A buffer for the received ACK frame. psdu pointer be NULL if no
|
||||
* ACK was requested/received.
|
||||
*/
|
||||
u8_t *ack;
|
||||
struct nrf5_802154_rx_frame ack_frame;
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue