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:
parent
2624d65b60
commit
4fe1da9f58
2 changed files with 53 additions and 24 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue