diff --git a/subsys/net/l2/openthread/openthread.c b/subsys/net/l2/openthread/openthread.c index 02a917260ff..c9882cb49c6 100644 --- a/subsys/net/l2/openthread/openthread.c +++ b/subsys/net/l2/openthread/openthread.c @@ -313,16 +313,6 @@ exit: return len; } -enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface, - struct net_buf *buf) -{ - ARG_UNUSED(iface); - ARG_UNUSED(buf); - NET_DBG(""); - - return NET_CONTINUE; -} - static void openthread_start(struct openthread_context *ot_context) { otInstance *ot_instance = ot_context->instance; diff --git a/subsys/net/lib/openthread/platform/radio.c b/subsys/net/lib/openthread/platform/radio.c index 8bef7f01c01..2e2ed2e8029 100644 --- a/subsys/net/lib/openthread/platform/radio.c +++ b/subsys/net/lib/openthread/platform/radio.c @@ -38,10 +38,16 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define SHORT_ADDRESS_SIZE 2 #define FCS_SIZE 2 +#define ACK_PKT_LENGTH 3 + +#define FRAME_TYPE_MASK 0x07 +#define FRAME_TYPE_ACK 0x02 static otRadioState sState = OT_RADIO_STATE_DISABLED; static otRadioFrame sTransmitFrame; +static otRadioFrame ack_frame; +static u8_t ack_psdu[ACK_PKT_LENGTH]; static struct net_pkt *tx_pkt; static struct net_buf *tx_payload; @@ -52,6 +58,38 @@ static struct ieee802154_radio_api *radio_api; static s8_t tx_power; static u16_t channel; +enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface, + struct net_pkt *pkt) +{ + ARG_UNUSED(iface); + + size_t ack_len = net_pkt_get_len(pkt); + + if (ack_len != ACK_PKT_LENGTH) { + return NET_CONTINUE; + } + + if ((*net_pkt_data(pkt) & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) { + return NET_CONTINUE; + } + + if (ack_frame.mLength != 0) { + LOG_ERR("Overwriting unhandled ACK frame."); + } + + if (net_pkt_read(pkt, ack_psdu, ack_len) < 0) { + LOG_ERR("Failed to read ACK frame."); + return NET_CONTINUE; + } + + ack_frame.mPsdu = ack_psdu; + ack_frame.mLength = ack_len; + ack_frame.mInfo.mRxInfo.mLqi = net_pkt_ieee802154_lqi(pkt); + ack_frame.mInfo.mRxInfo.mRssi = net_pkt_ieee802154_rssi(pkt); + + return NET_OK; +} + static void dataInit(void) { tx_pkt = net_pkt_alloc(K_NO_WAIT); @@ -123,25 +161,26 @@ void platformRadioProcess(otInstance *aInstance) } else #endif { - if (sTransmitFrame.mPsdu[0] & 0x20) { - /* - * TODO: Get real ACK frame - * instead of making a spoofed one - */ - otRadioFrame ackFrame; - u8_t ackPsdu[] = {0x02, 0x00, 0x00, 0x00, 0x00}; + if (sTransmitFrame.mPsdu[0] & IEEE802154_AR_FLAG_SET) { + if (ack_frame.mLength == 0) { + LOG_DBG("No ACK received."); - ackPsdu[2] = sTransmitFrame.mPsdu[2]; - ackFrame.mPsdu = ackPsdu; - ackFrame.mInfo.mRxInfo.mLqi = 80; - ackFrame.mInfo.mRxInfo.mRssi = -40; - ackFrame.mLength = 5; + result = OT_ERROR_NO_ACK; + + otPlatRadioTxDone(aInstance, + &sTransmitFrame, + NULL, result); + + return; + } otPlatRadioTxDone(aInstance, &sTransmitFrame, - &ackFrame, result); + &ack_frame, result); + + ack_frame.mLength = 0; } else { otPlatRadioTxDone(aInstance, &sTransmitFrame, - NULL, result); + NULL, result); } } }