net: openthread: Process real ACK frame instead of fake one

OpenThread radio layer did not implement `ieee802154_radio_handle_ack`
API and provided fake ACK frame to the OpenThread.

This prevented proper Sleepy End Device operation, as it expects to
receive information in the ACK whether it should wait for more data to
come or should it put the radio to sleep.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2019-04-11 15:32:41 +02:00 committed by Anas Nashif
commit 4fe1da9f58
2 changed files with 53 additions and 24 deletions

View file

@ -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;

View file

@ -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);
}
}
}