diff --git a/cpu/nrf52/radio/nrf802154/nrf802154.c b/cpu/nrf52/radio/nrf802154/nrf802154.c index 1fb7b96e6260..425a01dc58d7 100644 --- a/cpu/nrf52/radio/nrf802154/nrf802154.c +++ b/cpu/nrf52/radio/nrf802154/nrf802154.c @@ -134,6 +134,16 @@ static void _enable_tx(void) NRF_RADIO->TASKS_START = 1; } +/** + * @brief basic ieee802.15.4 data frame validation + */ +static bool _data_frame_filter(void) +{ + /* Check CRC and data frame filter*/ + return ((NRF_RADIO->CRCSTATUS == 1) && + netdev_ieee802154_data_frame_filter(&nrf802154_dev, &rxbuf[1], rxbuf[0])); +} + static void _set_chan(uint16_t chan) { assert((chan >= IEEE802154_CHANNEL_MIN) && (chan <= IEEE802154_CHANNEL_MAX)); @@ -428,9 +438,7 @@ void isr_radio(void) case RADIO_STATE_STATE_RxIdle: /* only process packet if event callback is set and CRC is valid */ if ((nrf802154_dev.netdev.event_callback) && - (NRF_RADIO->CRCSTATUS == 1) && - (netdev_ieee802154_dst_filter(&nrf802154_dev, - &rxbuf[1]) == 0)) { + _data_frame_filter()) { _state |= RX_COMPLETE; } else { diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h index 70da2a0a5f30..8a7236fa0a8f 100644 --- a/drivers/include/net/netdev/ieee802154.h +++ b/drivers/include/net/netdev/ieee802154.h @@ -192,6 +192,21 @@ int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *va */ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr); +/** + * @brief This function validates a data frame for minimal length and + * destination fields. It includes @ref netdev_ieee802154_dst_filter for + * validating the destination + * + * @param[in] dev network device descriptor + * @param[in] mhr mac header + * @param[in] frame_len Length of the frame as indicated by the phy + * + * @return 0 when the frame is not filtered + * @return 1 when the frame is filtered + */ +int netdev_ieee802154_data_frame_filter(netdev_ieee802154_t *dev, + const uint8_t *mhr, size_t frame_len); + #ifdef __cplusplus } #endif diff --git a/drivers/netdev_ieee802154/netdev_ieee802154.c b/drivers/netdev_ieee802154/netdev_ieee802154.c index 623604f39027..c4ea29404242 100644 --- a/drivers/netdev_ieee802154/netdev_ieee802154.c +++ b/drivers/netdev_ieee802154/netdev_ieee802154.c @@ -279,4 +279,21 @@ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr) return 1; } +int netdev_ieee802154_data_frame_filter(netdev_ieee802154_t *dev, + const uint8_t *mhr, size_t frame_len) +{ + if (frame_len < IEEE802154_FCF_LEN) { + return 1; + } + size_t expected_len = ieee802154_get_frame_hdr_len(mhr); + /* Check lenght data type, length and destination filter */ + if ((expected_len != 0) && + (frame_len > expected_len) && + ((*mhr & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_DATA) && + (netdev_ieee802154_dst_filter(dev, mhr) == 0)) { + return 0; + } + return 1; +} + /** @} */