drivers: ieee802154: fix ACK header IE implementation

- In `set_vendor_ie_header_lm`, case when
`link_metrics_data_len == 0` has been ignored.
This commit fixes that by setting `header_ie->length = 0`
before returning.
- current implementation of enh ACK header IE returns
`-ENOTSUP` when `ack_ie.header_ie == NULL` or
`ack_ie.header_ie->length == 0`. This commit fixes that by
refactoring checks in `nrf5_configure`.

Co-authored-by: Przemyslaw Bida <przemyslaw.bida@nordicsemi.no>

Signed-off-by: Maciej Baczmanski <maciej.baczmanski@nordicsemi.no>
This commit is contained in:
Maciej Baczmanski 2024-01-23 14:36:55 +01:00 committed by Carles Cufí
parent 8ff447700b
commit d76bcd346c
2 changed files with 28 additions and 31 deletions

View file

@ -899,35 +899,38 @@ static int nrf5_configure(const struct device *dev,
uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE];
uint8_t short_addr_le[SHORT_ADDRESS_SIZE];
uint8_t element_id;
bool valid_vendor_specific_ie = false;
if (config->ack_ie.short_addr == IEEE802154_BROADCAST_ADDRESS ||
config->ack_ie.ext_addr == NULL) {
return -ENOTSUP;
}
element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie);
if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE &&
(!IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) ||
element_id != IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE)) {
return -ENOTSUP;
}
#if defined(CONFIG_NET_L2_OPENTHREAD)
uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] =
IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI;
if (element_id == IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE &&
memcmp(config->ack_ie.header_ie->content.vendor_specific.vendor_oui,
vendor_oui_le, sizeof(vendor_oui_le))) {
return -ENOTSUP;
}
#endif
sys_put_le16(config->ack_ie.short_addr, short_addr_le);
sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
if (config->ack_ie.header_ie && config->ack_ie.header_ie->length > 0) {
if (config->ack_ie.header_ie == NULL || config->ack_ie.header_ie->length == 0) {
nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE);
nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE);
} else {
element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie);
#if defined(CONFIG_NET_L2_OPENTHREAD)
uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] =
IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI;
if (element_id == IEEE802154_HEADER_IE_ELEMENT_ID_VENDOR_SPECIFIC_IE &&
memcmp(config->ack_ie.header_ie->content.vendor_specific.vendor_oui,
vendor_oui_le, sizeof(vendor_oui_le)) == 0) {
valid_vendor_specific_ie = true;
}
#endif
if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE &&
!valid_vendor_specific_ie) {
return -ENOTSUP;
}
nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.header_ie,
config->ack_ie.header_ie->length +
IEEE802154_HEADER_IE_HEADER_LENGTH,
@ -936,9 +939,6 @@ static int nrf5_configure(const struct device *dev,
config->ack_ie.header_ie->length +
IEEE802154_HEADER_IE_HEADER_LENGTH,
NRF_802154_ACK_DATA_IE);
} else {
nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE);
nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE);
}
} break;

View file

@ -1350,7 +1350,7 @@ uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance)
* | IE_VENDOR_THREAD_ACK_PROBING_ID | LINK_METRIC_TOKEN | LINK_METRIC_TOKEN|
* |---------------------------------|-------------------|------------------|
*/
static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header)
static void set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header)
{
/* Vendor-specific IE identifier */
const uint8_t ie_vendor_id = 0x00;
@ -1364,7 +1364,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui
const uint8_t ie_vendor_thread_margin_token = 0x02;
/* Thread Vendor-specific ACK Probing IE LQI value placeholder */
const uint8_t ie_vendor_thread_lqi_token = 0x03;
const uint8_t ie_header_size = 2;
const uint8_t oui_size = 3;
const uint8_t sub_type = 1;
const uint8_t id_offset = 7;
@ -1382,7 +1381,8 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui
__ASSERT(ie_header, "Invalid argument");
if (link_metrics_data_len == 0) {
return 0;
ie_header[0] = 0;
return;
}
/* Set Element ID */
@ -1417,8 +1417,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui
if (rssi) {
ie_header[link_metrics_idx++] = ie_vendor_thread_rssi_token;
}
return ie_header_size + content_len;
}
otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics aLinkMetrics,
@ -1430,13 +1428,12 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a
.ack_ie.ext_addr = aExtAddress->m8,
};
uint8_t header_ie_buf[OT_ACK_IE_MAX_SIZE];
uint16_t header_ie_len;
int result;
ARG_UNUSED(aInstance);
header_ie_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin,
aLinkMetrics.mRssi, header_ie_buf);
set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin,
aLinkMetrics.mRssi, header_ie_buf);
config.ack_ie.header_ie = (struct ieee802154_header_ie *)header_ie_buf;
result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);