[nrf528xx] update radio driver to version 1.3.0 (#3603)

This commit is contained in:
Piotr Szkotak
2019-02-19 08:44:49 -08:00
committed by Jonathan Hui
parent cf7bc35bbe
commit 80c98ac824
34 changed files with 3366 additions and 470 deletions
+2
View File
@@ -51,6 +51,8 @@ COMMONCPPFLAGS
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \
+2
View File
@@ -52,6 +52,8 @@ COMMONCPPFLAGS
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \
+320 -306
View File
@@ -29,17 +29,17 @@
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
if OPENTHREAD_EXAMPLES_NRF52811
lib_LIBRARIES = \
libnordicsemi-nrf52811-sdk.a \
libnordicsemi-nrf52811-radio-driver.a \
lib_LIBRARIES = \
libnordicsemi-nrf52811-sdk.a \
libnordicsemi-nrf52811-radio-driver.a \
$(NULL)
endif
if OPENTHREAD_EXAMPLES_NRF52840
lib_LIBRARIES = \
libnordicsemi-nrf52840-sdk.a \
libnordicsemi-nrf52840-radio-driver.a \
libnordicsemi-nrf52840-radio-driver-softdevice.a \
lib_LIBRARIES = \
libnordicsemi-nrf52840-sdk.a \
libnordicsemi-nrf52840-radio-driver.a \
libnordicsemi-nrf52840-radio-driver-softdevice.a \
$(NULL)
endif
@@ -47,351 +47,365 @@ endif
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DENABLE_FEM=1 \
-I$(srcdir) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/third_party/NordicSemiconductor \
-I$(top_srcdir)/third_party/NordicSemiconductor/cmsis \
-I$(top_srcdir)/third_party/NordicSemiconductor/dependencies \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/delay \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/utf_converter \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52 \
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DENABLE_FEM=1 \
-I$(srcdir) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/third_party/NordicSemiconductor \
-I$(top_srcdir)/third_party/NordicSemiconductor/cmsis \
-I$(top_srcdir)/third_party/NordicSemiconductor/dependencies \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/delay \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/utf_converter \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52 \
$(NULL)
NRF52840_CPPFLAGS = \
-DNRF52840_XXAA \
-DNRF_802154_PROJECT_CONFIG=\"platform-config.h\" \
-I$(top_srcdir)/examples/platforms/nrf52840 \
NRF52840_CPPFLAGS = \
-DNRF52840_XXAA \
-DNRF_802154_PROJECT_CONFIG=\"platform-config.h\" \
-I$(top_srcdir)/examples/platforms/nrf52840 \
$(NULL)
NRF52811_CPPFLAGS = \
-DNRF52811_XXAA \
-DNRF_802154_PROJECT_CONFIG=\"platform-config.h\" \
-D__HEAP_SIZE=0 \
-D__STACK_SIZE=2048 \
-I$(top_srcdir)/examples/platforms/nrf52811 \
NRF52811_CPPFLAGS = \
-DNRF52811_XXAA \
-DNRF_802154_PROJECT_CONFIG=\"platform-config.h\" \
-D__HEAP_SIZE=0 \
-D__STACK_SIZE=2048 \
-I$(top_srcdir)/examples/platforms/nrf52811 \
$(NULL)
NORDICSEMI_COMMON_SOURCES = \
dependencies/app_util_platform.c \
drivers/clock/nrf_drv_clock.c \
drivers/power/nrf_drv_power.c \
libraries/app_error/app_error.c \
libraries/app_error/app_error_weak.c \
libraries/utf_converter/utf.c \
nrfx/drivers/src/nrfx_clock.c \
nrfx/drivers/src/nrfx_power.c \
nrfx/drivers/src/nrfx_systick.c \
nrfx/hal/nrf_nvmc.c \
NORDICSEMI_COMMON_SOURCES = \
dependencies/app_util_platform.c \
drivers/clock/nrf_drv_clock.c \
drivers/power/nrf_drv_power.c \
libraries/app_error/app_error.c \
libraries/app_error/app_error_weak.c \
libraries/utf_converter/utf.c \
nrfx/drivers/src/nrfx_clock.c \
nrfx/drivers/src/nrfx_power.c \
nrfx/drivers/src/nrfx_systick.c \
nrfx/hal/nrf_nvmc.c \
$(NULL)
NORDICSEMI_USB_SOURCES = \
drivers/usbd/nrf_drv_usbd.c \
libraries/atfifo/nrf_atfifo.c \
libraries/atomic/nrf_atomic.c \
libraries/usb/app_usbd.c \
libraries/usb/app_usbd_core.c \
libraries/usb/app_usbd_string_desc.c \
libraries/usb/app_usbd_serial_num.c \
libraries/usb/app_usbd_nrf_dfu_trigger.c \
libraries/usb/nrf_dfu_trigger_usb.c \
libraries/usb/class/cdc/acm/app_usbd_cdc_acm.c \
NORDICSEMI_USB_SOURCES = \
drivers/usbd/nrf_drv_usbd.c \
libraries/atfifo/nrf_atfifo.c \
libraries/atomic/nrf_atomic.c \
libraries/usb/app_usbd.c \
libraries/usb/app_usbd_core.c \
libraries/usb/app_usbd_string_desc.c \
libraries/usb/app_usbd_serial_num.c \
libraries/usb/app_usbd_nrf_dfu_trigger.c \
libraries/usb/nrf_dfu_trigger_usb.c \
libraries/usb/class/cdc/acm/app_usbd_cdc_acm.c \
$(NULL)
NORDICSEMI_NRF52840_SOURCES = \
nrfx/mdk/gcc_startup_nrf52840.S \
nrfx/mdk/system_nrf52840.c \
NORDICSEMI_NRF52840_SOURCES = \
nrfx/mdk/gcc_startup_nrf52840.S \
nrfx/mdk/system_nrf52840.c \
$(NULL)
NORDICSEMI_NRF52811_SOURCES = \
nrfx/mdk/gcc_startup_nrf52811.S \
nrfx/mdk/system_nrf52811.c \
NORDICSEMI_NRF52811_SOURCES = \
nrfx/mdk/gcc_startup_nrf52811.S \
nrfx/mdk/system_nrf52811.c \
$(NULL)
RADIO_DRIVER_SOURCES = \
drivers/radio/nrf_802154.c \
drivers/radio/nrf_802154_ack_pending_bit.c \
drivers/radio/nrf_802154_core.c \
drivers/radio/nrf_802154_core_hooks.c \
drivers/radio/nrf_802154_critical_section.c \
drivers/radio/nrf_802154_debug.c \
drivers/radio/nrf_802154_pib.c \
drivers/radio/nrf_802154_revision.c \
drivers/radio/nrf_802154_rssi.c \
drivers/radio/nrf_802154_rx_buffer.c \
drivers/radio/nrf_802154_timer_coord.c \
drivers/radio/fem/nrf_fem_control.c \
drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c \
drivers/radio/mac_features/nrf_802154_csma_ca.c \
drivers/radio/mac_features/nrf_802154_delayed_trx.c \
drivers/radio/mac_features/nrf_802154_filter.c \
drivers/radio/platform/clock/nrf_802154_clock_sdk.c \
drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c \
drivers/radio/rsch/nrf_802154_rsch.c \
drivers/radio/rsch/nrf_802154_rsch_crit_sect.c \
drivers/radio/timer_scheduler/nrf_802154_timer_sched.c \
RADIO_DRIVER_SOURCES = \
drivers/radio/fem/nrf_fem_control.c \
drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.c \
drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c \
drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c \
drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c \
drivers/radio/mac_features/nrf_802154_csma_ca.c \
drivers/radio/mac_features/nrf_802154_delayed_trx.c \
drivers/radio/mac_features/nrf_802154_filter.c \
drivers/radio/mac_features/nrf_802154_frame_parser.c \
drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c \
drivers/radio/nrf_802154_ack_pending_bit.c \
drivers/radio/nrf_802154_core_hooks.c \
drivers/radio/nrf_802154_core.c \
drivers/radio/nrf_802154_critical_section.c \
drivers/radio/nrf_802154_debug.c \
drivers/radio/nrf_802154_pib.c \
drivers/radio/nrf_802154_revision.c \
drivers/radio/nrf_802154_rssi.c \
drivers/radio/nrf_802154_rx_buffer.c \
drivers/radio/nrf_802154_timer_coord.c \
drivers/radio/nrf_802154.c \
drivers/radio/platform/clock/nrf_802154_clock_sdk.c \
drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c \
drivers/radio/rsch/nrf_802154_rsch_crit_sect.c \
drivers/radio/rsch/nrf_802154_rsch.c \
drivers/radio/timer_scheduler/nrf_802154_timer_sched.c \
$(NULL)
RADIO_DRIVER_SINGLE_PHY_SOURCES = \
drivers/radio/nrf_802154_notification_direct.c \
drivers/radio/nrf_802154_priority_drop_direct.c \
drivers/radio/nrf_802154_request_direct.c \
drivers/radio/rsch/raal/single_phy/single_phy.c \
RADIO_DRIVER_SINGLE_PHY_SOURCES = \
drivers/radio/nrf_802154_notification_direct.c \
drivers/radio/nrf_802154_priority_drop_direct.c \
drivers/radio/nrf_802154_request_direct.c \
drivers/radio/rsch/raal/single_phy/single_phy.c \
$(NULL)
RADIO_DRIVER_SINGLE_PHY_CPPFLAGS = \
-DRAAL_SINGLE_PHY=1 \
RADIO_DRIVER_SINGLE_PHY_CPPFLAGS = \
-DRAAL_SINGLE_PHY=1 \
$(NULL)
RADIO_DRIVER_SOFTDEVICE_SOURCES = \
drivers/radio/nrf_802154_notification_swi.c \
drivers/radio/nrf_802154_priority_drop_swi.c \
drivers/radio/nrf_802154_request_swi.c \
drivers/radio/nrf_802154_swi.c \
drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c \
RADIO_DRIVER_SOFTDEVICE_SOURCES = \
drivers/radio/nrf_802154_notification_swi.c \
drivers/radio/nrf_802154_priority_drop_swi.c \
drivers/radio/nrf_802154_request_swi.c \
drivers/radio/nrf_802154_swi.c \
drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c \
$(NULL)
RADIO_DRIVER_SOFTDEVICE_CPPFLAGS = \
-DRAAL_SOFTDEVICE=1 \
RADIO_DRIVER_SOFTDEVICE_CPPFLAGS = \
-DRAAL_SOFTDEVICE=1 \
$(NULL)
SOFTDEVICE_CPPFLAGS = \
-DSOFTDEVICE_PRESENT \
-DS140 \
-DRAAL_SOFTDEVICE=1 \
SOFTDEVICE_CPPFLAGS = \
-DSOFTDEVICE_PRESENT \
-DS140 \
-DRAAL_SOFTDEVICE=1 \
$(NULL)
libnordicsemi_nrf52840_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
libnordicsemi_nrf52840_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
$(NULL)
libnordicsemi_nrf52840_sdk_a_SOURCES = \
$(NORDICSEMI_COMMON_SOURCES) \
$(NORDICSEMI_USB_SOURCES) \
$(NORDICSEMI_NRF52840_SOURCES) \
libnordicsemi_nrf52840_sdk_a_SOURCES = \
$(NORDICSEMI_COMMON_SOURCES) \
$(NORDICSEMI_USB_SOURCES) \
$(NORDICSEMI_NRF52840_SOURCES) \
$(NULL)
libnordicsemi_nrf52840_radio_driver_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
$(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS) \
libnordicsemi_nrf52840_radio_driver_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
$(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS) \
$(NULL)
libnordicsemi_nrf52840_radio_driver_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SINGLE_PHY_SOURCES) \
libnordicsemi_nrf52840_radio_driver_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SINGLE_PHY_SOURCES) \
$(NULL)
libnordicsemi_nrf52840_radio_driver_softdevice_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
$(SOFTDEVICE_CPPFLAGS) \
$(RADIO_DRIVER_SOFTDEVICE_CPPFLAGS) \
libnordicsemi_nrf52840_radio_driver_softdevice_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52840_CPPFLAGS) \
$(SOFTDEVICE_CPPFLAGS) \
$(RADIO_DRIVER_SOFTDEVICE_CPPFLAGS) \
$(NULL)
libnordicsemi_nrf52840_radio_driver_softdevice_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SOFTDEVICE_SOURCES) \
libnordicsemi_nrf52840_radio_driver_softdevice_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SOFTDEVICE_SOURCES) \
$(NULL)
libnordicsemi_nrf52811_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52811_CPPFLAGS) \
libnordicsemi_nrf52811_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52811_CPPFLAGS) \
$(NULL)
libnordicsemi_nrf52811_sdk_a_SOURCES = \
$(NORDICSEMI_COMMON_SOURCES) \
$(NORDICSEMI_NRF52811_SOURCES) \
libnordicsemi_nrf52811_sdk_a_SOURCES = \
$(NORDICSEMI_COMMON_SOURCES) \
$(NORDICSEMI_NRF52811_SOURCES) \
$(NULL)
libnordicsemi_nrf52811_radio_driver_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52811_CPPFLAGS) \
$(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS) \
libnordicsemi_nrf52811_radio_driver_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(NRF52811_CPPFLAGS) \
$(RADIO_DRIVER_SINGLE_PHY_CPPFLAGS) \
$(NULL)
libnordicsemi_nrf52811_radio_driver_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SINGLE_PHY_SOURCES) \
libnordicsemi_nrf52811_radio_driver_a_SOURCES = \
$(RADIO_DRIVER_SOURCES) \
$(RADIO_DRIVER_SINGLE_PHY_SOURCES) \
$(NULL)
noinst_HEADERS = \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/arm_math.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc_V6.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_gcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cm4.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util_platform.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/apply_old_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nordic_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_instance.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_ctrl.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_ctrl_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_glue.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_macros.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_os.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_resources.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/common/nrf_drv_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/power/nrf_drv_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick/nrf_drv_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error_weak.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/delay/nrf_delay.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_class_base.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_core.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_descriptor.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_langid.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_serial_num.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_string_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config/app_usbd_string_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/utf_converter/utf.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpio.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpiote.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_ppi.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_spis.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52810.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52_to_nrf52810.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52810_to_nrf52811.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_err.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatt.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gattc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatts.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_hci.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_l2cap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_ranges.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_nvic.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_svc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52/nrf_mbr.h \
noinst_HEADERS = \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/arm_math.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc_V6.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_gcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cm4.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util_platform.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/apply_old_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nordic_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_instance.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_ctrl.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_ctrl_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_glue.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_macros.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_os.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_resources.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/common/nrf_drv_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/power/nrf_drv_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick/nrf_drv_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error_weak.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/delay/nrf_delay.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_class_base.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_core.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_descriptor.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_langid.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_serial_num.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_string_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_nrf_dfu_trigger_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config/app_usbd_string_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/utf_converter/utf.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpio.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpiote.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_ppi.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_spis.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52810.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52_to_nrf52810.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52810_to_nrf52811.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52811_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_err.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatt.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gattc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatts.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_hci.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_l2cap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_ranges.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_nvic.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_svc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52/nrf_mbr.h \
$(NULL)
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
@@ -45,15 +45,11 @@ extern "C" {
/** Time in us when LNA GPIO is activated before radio is ready for reception. */
#define NRF_FEM_LNA_TIME_IN_ADVANCE 5
#ifdef NRF52840_XXAA
/** Radio ramp-up time in TX mode, in us. */
#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 40
/** Radio ramp-up time in RX mode, in us. */
#define NRF_FEM_RADIO_RX_STARTUP_LATENCY_US 40
#elif defined NRF52811_XXAA
#if defined(NRF52840_XXAA) || \
defined(NRF52840_AAAA) || \
defined(NRF52840_AABA) || \
defined(NRF52840_AACX) || \
defined(NRF52811_XXAA)
/** Radio ramp-up time in TX mode, in us. */
#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 40
@@ -0,0 +1,603 @@
/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file implements procedures to set pending bit and 802.15.4-2015 information
* elements in nRF 802.15.4 radio driver.
*
*/
#include "nrf_802154_ack_data.h"
#include <assert.h>
#include <string.h>
#include "mac_features/nrf_802154_frame_parser.h"
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_types.h"
/// Maximum number of Short Addresses of nodes for which there is ACK data to set.
#define NUM_SHORT_ADDRESSES NRF_802154_PENDING_SHORT_ADDRESSES
/// Maximum number of Extended Addresses of nodes for which there is ACK data to set.
#define NUM_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES
/// Structure representing pending bit setting variables.
typedef struct
{
bool enabled; /// If setting pending bit is enabled.
uint8_t short_addr[NUM_SHORT_ADDRESSES][SHORT_ADDRESS_SIZE]; /// Array of short addresses of nodes for which there is pending data in the buffer.
uint8_t extended_addr[NUM_EXTENDED_ADDRESSES][EXTENDED_ADDRESS_SIZE]; /// Array of extended addresses of nodes for which there is pending data in the buffer.
uint32_t num_of_short_addr; /// Current number of short addresses of nodes for which there is pending data in the buffer.
uint32_t num_of_ext_addr; /// Current number of extended addresses of nodes for which there is pending data in the buffer.
} pending_bit_arrays_t;
// Structure representing a single IE record.
typedef struct
{
uint8_t p_data[NRF_802154_MAX_ACK_IE_SIZE]; /// Pointer to IE data buffer.
uint8_t len; /// Length of the buffer.
} ie_data_t;
// Structure representing IE records sent in an ACK message to a given short address.
typedef struct
{
uint8_t addr[SHORT_ADDRESS_SIZE]; /// Short address of peer node.
ie_data_t ie_data; /// Pointer to IE records.
} ack_short_ie_data_t;
// Structure representing IE records sent in an ACK message to a given extended address.
typedef struct
{
uint8_t addr[EXTENDED_ADDRESS_SIZE]; /// Extended address of peer node.
ie_data_t ie_data; /// Pointer to IE records.
} ack_ext_ie_data_t;
// Structure representing IE data setting variables.
typedef struct
{
ack_short_ie_data_t short_data[NUM_SHORT_ADDRESSES]; /// Array of short addresses and IE records sent to these addresses.
ack_ext_ie_data_t ext_data[NUM_EXTENDED_ADDRESSES]; /// Array of extended addresses and IE records sent to these addresses.
uint32_t num_of_short_data; /// Current number of short addresses stored in @p short_data.
uint32_t num_of_ext_data; /// Current number of extended addresses stored in @p ext_data.
} ie_arrays_t;
// TODO: Combine below arrays to perform binary search only once per Ack generation.
static pending_bit_arrays_t m_pending_bit;
static ie_arrays_t m_ie;
/***************************************************************************************************
* @section Array handling helper functions
**************************************************************************************************/
/**
* @brief Compare two extended addresses.
*
* @param[in] p_first_addr Pointer to a first address that should be compared.
* @param[in] p_second_addr Pointer to a second address that should be compared.
*
* @retval -1 First address is less than the second address.
* @retval 0 First address is equal to the second address.
* @retval 1 First address is greater than the second address.
*/
static int8_t extended_addr_compare(const uint8_t * p_first_addr, const uint8_t * p_second_addr)
{
uint32_t first_addr;
uint32_t second_addr;
// Compare extended address in two steps to prevent unaligned access error.
for (uint32_t i = 0; i < EXTENDED_ADDRESS_SIZE / sizeof(uint32_t); i++)
{
first_addr = *(uint32_t *)(p_first_addr + (i * sizeof(uint32_t)));
second_addr = *(uint32_t *)(p_second_addr + (i * sizeof(uint32_t)));
if (first_addr < second_addr)
{
return -1;
}
else if (first_addr > second_addr)
{
return 1;
}
}
return 0;
}
/**
* @brief Compare two short addresses.
*
* @param[in] p_first_addr Pointer to a first address that should be compared.
* @param[in] p_second_addr Pointer to a second address that should be compared.
*
* @retval -1 First address is less than the second address.
* @retval 0 First address is equal to the second address.
* @retval 1 First address is greater than the second address.
*/
static int8_t short_addr_compare(const uint8_t * p_first_addr, const uint8_t * p_second_addr)
{
uint16_t first_addr = *(uint16_t *)(p_first_addr);
uint16_t second_addr = *(uint16_t *)(p_second_addr);
if (first_addr < second_addr)
{
return -1;
}
else if (first_addr > second_addr)
{
return 1;
}
else
{
return 0;
}
}
/**
* @brief Compare two addresses.
*
* @param[in] p_first_addr Pointer to a first address that should be compared.
* @param[in] p_second_addr Pointer to a second address that should be compared.
* @param[in] extended Indication if @p p_first_addr and @p p_second_addr are extended or short addresses.
*
* @retval -1 First address is less than the second address.
* @retval 0 First address is equal to the second address.
* @retval 1 First address is greater than the second address.
*/
static int8_t addr_compare(const uint8_t * p_first_addr,
const uint8_t * p_second_addr,
bool extended)
{
if (extended)
{
return extended_addr_compare(p_first_addr, p_second_addr);
}
else
{
return short_addr_compare(p_first_addr, p_second_addr);
}
}
/**
* @brief Perform a binary search for an address in a list of addresses.
*
* @param[in] p_addr Pointer to an address that is searched for.
* @param[in] p_addr_array Pointer to a list of addresses to be searched.
* @param[out] p_location If the address @p p_addr appears in the list, this is its index in the address list.
* Otherwise, it is the index which @p p_addr would have if it was placed in the list
* (ascending order assumed).
* @param[in] extended Indication if @p p_addr is an extended or a short addresses.
*
* @retval true Address @p p_addr is in the list.
* @retval false Address @p p_addr is not in the list.
*/
static bool addr_binary_search(const uint8_t * p_addr,
const uint8_t * p_addr_array,
uint32_t * p_location,
uint8_t data_type,
bool extended)
{
uint32_t addr_array_len = 0;
uint8_t entry_size = 0;
switch (data_type)
{
case NRF_802154_ACK_DATA_PENDING_BIT:
entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE;
addr_array_len = extended ?
m_pending_bit.num_of_ext_addr : m_pending_bit.num_of_short_addr;
break;
case NRF_802154_ACK_DATA_IE:
entry_size = extended ? sizeof(ack_ext_ie_data_t) : sizeof(ack_short_ie_data_t);
addr_array_len = extended ? m_ie.num_of_ext_data : m_ie.num_of_short_data;
break;
default:
assert(false);
break;
}
// The actual algorithm
int32_t low = 0;
int32_t midpoint = 0;
int32_t high = addr_array_len;
while (high >= low)
{
midpoint = low + (high - low) / 2;
if (midpoint >= (int32_t)addr_array_len)
{
break;
}
switch (addr_compare(p_addr, p_addr_array + entry_size * midpoint, extended))
{
case -1:
high = midpoint - 1;
break;
case 0:
*p_location = midpoint;
return true;
case 1:
low = midpoint + 1;
break;
default:
break;
}
}
/* If in the last iteration of the loop the last case was utilized, it means that the midpoint
* found by the algorithm is less than the address to be added. The midpoint should be therefore
* shifted to the next position. As a simplified example, a { 1, 3, 4 } array can be considered.
* Suppose that a number equal to 2 is about to be added to the array. At the beginning of the
* last iteration, midpoint is equal to 1 and low and high are equal to 0. Midpoint is then set
* to 0 and with last case being utilized, low is set to 1. However, midpoint equal to 0 is
* incorrect, as in the last iteration first element of the array proves to be less than the
* element to be added to the array. With the below code, midpoint is then shifted to 1. */
if (low == midpoint + 1)
{
midpoint++;
}
*p_location = midpoint;
return false;
}
/**
* @brief Find an address in a list of addresses.
*
* @param[in] p_addr Pointer to an address that is searched for.
* @param[out] p_location If the address @p p_addr appears in the list, this is its index in the address list.
* Otherwise, it is the index which @p p_addr would have if it was placed in the list
* (ascending order assumed).
* @param[in] extended Indication if @p p_addr is an extended or a short addresses.
*
* @retval true Address @p p_addr is in the list.
* @retval false Address @p p_addr is not in the list.
*/
static bool addr_index_find(const uint8_t * p_addr,
uint32_t * p_location,
uint8_t data_type,
bool extended)
{
uint8_t * p_addr_array;
switch (data_type)
{
case NRF_802154_ACK_DATA_PENDING_BIT:
p_addr_array = extended ? (uint8_t *)m_pending_bit.extended_addr :
(uint8_t *)m_pending_bit.short_addr;
break;
case NRF_802154_ACK_DATA_IE:
p_addr_array = extended ? (uint8_t *)m_ie.ext_data : (uint8_t *)m_ie.short_data;
break;
default:
assert(false);
break;
}
return addr_binary_search(p_addr, p_addr_array, p_location, data_type, extended);
}
/**
* @brief Add an address to the address list in ascending order.
*
* @param[in] p_addr Pointer to the address to be added.
* @param[in] location Index of the location where @p p_addr should be added.
* @param[in] extended Indication if @p p_addr is an extended or a short addresses.
*
* @retval true Address @p p_addr has been added to the list successfully.
* @retval false Address @p p_addr could not be added to the list.
*/
static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_type, bool extended)
{
uint32_t * p_addr_array_len;
uint32_t max_addr_array_len;
uint8_t * p_addr_array;
uint8_t entry_size;
switch (data_type)
{
case NRF_802154_ACK_DATA_PENDING_BIT:
if (extended)
{
p_addr_array = (uint8_t *)m_pending_bit.extended_addr;
max_addr_array_len = NUM_EXTENDED_ADDRESSES;
p_addr_array_len = &m_pending_bit.num_of_ext_addr;
entry_size = EXTENDED_ADDRESS_SIZE;
}
else
{
p_addr_array = (uint8_t *)m_pending_bit.short_addr;
max_addr_array_len = NUM_SHORT_ADDRESSES;
p_addr_array_len = &m_pending_bit.num_of_short_addr;
entry_size = SHORT_ADDRESS_SIZE;
}
break;
case NRF_802154_ACK_DATA_IE:
if (extended)
{
p_addr_array = (uint8_t *)m_ie.ext_data;
max_addr_array_len = NUM_EXTENDED_ADDRESSES;
p_addr_array_len = &m_ie.num_of_ext_data;
entry_size = sizeof(ack_ext_ie_data_t);
}
else
{
p_addr_array = (uint8_t *)m_ie.short_data;
max_addr_array_len = NUM_SHORT_ADDRESSES;
p_addr_array_len = &m_ie.num_of_short_data;
entry_size = sizeof(ack_short_ie_data_t);
}
break;
default:
assert(false);
break;
}
if (*p_addr_array_len == max_addr_array_len)
{
return false;
}
memmove(p_addr_array + entry_size * (location + 1),
p_addr_array + entry_size * (location),
(*p_addr_array_len - location) * entry_size);
memcpy(p_addr_array + entry_size * location,
p_addr,
extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE);
(*p_addr_array_len)++;
return true;
}
/**
* @brief Remove an address from the address list keeping it in ascending order.
*
* @param[in] location Index of the element to be removed from the list.
* @param[in] extended Indication if address to remove is an extended or a short address.
*
* @retval true Address @p p_addr has been removed from the list successfully.
* @retval false Address @p p_addr could not removed from the list.
*/
static bool addr_remove(uint32_t location, uint8_t data_type, bool extended)
{
uint32_t * p_addr_array_len;
uint8_t * p_addr_array;
uint8_t entry_size;
switch (data_type)
{
case NRF_802154_ACK_DATA_PENDING_BIT:
if (extended)
{
p_addr_array = (uint8_t *)m_pending_bit.extended_addr;
p_addr_array_len = &m_pending_bit.num_of_ext_addr;
entry_size = EXTENDED_ADDRESS_SIZE;
}
else
{
p_addr_array = (uint8_t *)m_pending_bit.short_addr;
p_addr_array_len = &m_pending_bit.num_of_short_addr;
entry_size = SHORT_ADDRESS_SIZE;
}
break;
case NRF_802154_ACK_DATA_IE:
if (extended)
{
p_addr_array = (uint8_t *)m_ie.ext_data;
p_addr_array_len = &m_ie.num_of_ext_data;
entry_size = sizeof(ack_ext_ie_data_t);
}
else
{
p_addr_array = (uint8_t *)m_ie.short_data;
p_addr_array_len = &m_ie.num_of_short_data;
entry_size = sizeof(ack_short_ie_data_t);
}
break;
default:
assert(false);
break;
}
if (*p_addr_array_len == 0)
{
return false;
}
memmove(p_addr_array + entry_size * location,
p_addr_array + entry_size * (location + 1),
(*p_addr_array_len - location - 1) * entry_size);
(*p_addr_array_len)--;
return true;
}
static void ie_data_add(uint32_t location, bool extended, const uint8_t * p_data, uint8_t data_len)
{
if (extended)
{
memcpy(m_ie.ext_data[location].ie_data.p_data, p_data, data_len);
m_ie.ext_data[location].ie_data.len = data_len;
}
else
{
memcpy(m_ie.short_data[location].ie_data.p_data, p_data, data_len);
m_ie.short_data[location].ie_data.len = data_len;
}
}
/***************************************************************************************************
* @section Public API
**************************************************************************************************/
void nrf_802154_ack_data_init(void)
{
memset(&m_pending_bit, 0, sizeof(m_pending_bit));
memset(&m_ie, 0, sizeof(m_ie));
m_pending_bit.enabled = true;
}
void nrf_802154_ack_data_enable(bool enabled)
{
m_pending_bit.enabled = enabled;
}
bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr,
bool extended,
const void * p_data,
uint8_t data_len,
uint8_t data_type)
{
uint32_t location = 0;
// Provided address already in the database
if (addr_index_find(p_addr, &location, data_type, extended))
{
return true;
}
bool retval = addr_add(p_addr, location, data_type, extended);
if (data_type == NRF_802154_ACK_DATA_IE && retval)
{
ie_data_add(location, extended, p_data, data_len);
}
return retval;
}
bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, uint8_t data_type)
{
uint32_t location = 0;
if (addr_index_find(p_addr, &location, data_type, extended))
{
return addr_remove(location, data_type, extended);
}
else
{
return false;
}
}
void nrf_802154_ack_data_for_addr_reset(bool extended, uint8_t data_type)
{
switch (data_type)
{
case NRF_802154_ACK_DATA_PENDING_BIT:
if (extended)
{
m_pending_bit.num_of_ext_addr = 0;
}
else
{
m_pending_bit.num_of_short_addr = 0;
}
break;
case NRF_802154_ACK_DATA_IE:
if (extended)
{
m_ie.num_of_ext_data = 0;
}
else
{
m_ie.num_of_short_data = 0;
}
break;
default:
break;
}
}
bool nrf_802154_ack_data_pending_bit_should_be_set(const uint8_t * p_frame)
{
bool extended;
uint32_t location;
const uint8_t * p_src_addr = nrf_802154_frame_parser_src_addr_get(p_frame, &extended);
// The pending bit is set by default.
if (!m_pending_bit.enabled || NULL == p_src_addr)
{
return true;
}
return addr_index_find(p_src_addr, &location, NRF_802154_ACK_DATA_PENDING_BIT, extended);
}
const uint8_t * nrf_802154_ack_data_ie_get(const uint8_t * p_src_addr,
bool src_addr_extended,
uint8_t * p_ie_length)
{
uint32_t location;
if (NULL == p_src_addr)
{
return NULL;
}
if (addr_index_find(p_src_addr, &location, NRF_802154_ACK_DATA_IE, src_addr_extended))
{
if (src_addr_extended)
{
*p_ie_length = m_ie.ext_data[location].ie_data.len;
return m_ie.ext_data[location].ie_data.p_data;
}
else
{
*p_ie_length = m_ie.short_data[location].ie_data.len;
return m_ie.short_data[location].ie_data.p_data;
}
}
else
{
*p_ie_length = 0;
return NULL;
}
}
@@ -0,0 +1,125 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief This module contains an ACK data generator for nRF 802.15.4 radio driver.
*
* @note Current implementation supports setting pending bit and IEs in 802.15.4-2015 Enh-Ack frames.
*/
#ifndef NRF_802154_ACK_DATA_H
#define NRF_802154_ACK_DATA_H
#include <stdbool.h>
#include <stdint.h>
/**
* @brief Initialize this module.
*/
void nrf_802154_ack_data_init(void);
/**
* @brief Enable or disable this module.
*
* @param[in] enabled True if module should be enabled, false otherwise.
*/
void nrf_802154_ack_data_enable(bool enabled);
/**
* @brief Add address to ACK data list.
*
* ACK frames sent in response to frames with source address matching any address from ACK data list
* will have appropriate data set. If source address does not match any of the addresses in the
* list the ACK frame will not have the data set.
*
* @param[in] p_addr Pointer to address that should be added to the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
* @param[in] p_data Pointer to data to set.
* @param[in] data_len Length of @p p_data buffer.
* @param[in] data_type Type of data to set. Please refer to nrf_802154_ack_data_t type.
*
* @retval true Address successfully added to the list.
* @retval false Address was not added to the list (list is full).
*/
bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr,
bool extended,
const void * p_data,
uint8_t data_len,
uint8_t data_type);
/**
* @brief Remove address from ACK data list.
*
* ACK frames sent in response to frames with source address matching any address from ACK data list
* will have appropriate data set. If source address does not match any of the addresses in the
* list the ACK frame will not have the data set.
*
* @param[in] p_addr Pointer to address that should be removed from the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
* @param[in] data_type Type of data that should be cleared for @p p_addr.
*
* @retval true Address successfully removed from the list.
* @retval false Address was not removed from the list (address is missing in the list).
*/
bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, uint8_t data_type);
/**
* @brief Remove all addresses of given length from ACK data list.
*
* @param[in] extended Indication if all extended or all short addresses should be removed
* from the list.
* @param[in] data_type Type of data that should be cleared for all addresses of given length.
*/
void nrf_802154_ack_data_for_addr_reset(bool extended, uint8_t data_type);
/**
* @brief Check if pending bit should be set in ACK sent in response to given frame.
*
* @param[in] p_frame Pointer to a frame to which ACK frame is being prepared.
*
* @retval true Pending bit should be set.
* @retval false Pending bit should be cleared.
*/
bool nrf_802154_ack_data_pending_bit_should_be_set(const uint8_t * p_frame);
/**
* @brief Get IE data stored in the list for source address of provided frame.
*
* @param[in] p_src_addr Pointer to a source address that is searched for in the list.
* @param[in] src_addr_ext If the source address is extended.
* @param[out] p_ie_length Length of the IE data.
*
* @returns Pointer to stored IE data or NULL if IE data should not be set.
*/
const uint8_t * nrf_802154_ack_data_ie_get(const uint8_t * p_src_addr,
bool src_addr_ext,
uint8_t * p_ie_length);
#endif // NRF_802154_ACK_DATA_H
@@ -0,0 +1,93 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This module implements an acknowledgement generator for 802.15.4 radio driver.
*
*/
#include "nrf_802154_ack_generator.h"
#include <assert.h>
#include <stdlib.h>
#include "nrf_802154_const.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_enh_ack_generator.h"
#include "nrf_802154_imm_ack_generator.h"
typedef enum
{
FRAME_VERSION_BELOW_2015,
FRAME_VERSION_2015_OR_ABOVE,
FRAME_VERSION_INVALID
} frame_version_t;
static frame_version_t frame_version_is_2015_or_above(const uint8_t * p_frame)
{
switch (p_frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK)
{
case FRAME_VERSION_0:
case FRAME_VERSION_1:
return FRAME_VERSION_BELOW_2015;
case FRAME_VERSION_2:
return FRAME_VERSION_2015_OR_ABOVE;
default:
return FRAME_VERSION_INVALID;
}
}
void nrf_802154_ack_generator_init(void)
{
// Both generators are initialized to enable sending both Imm-Acks and Enh-Acks.
nrf_802154_imm_ack_generator_init();
nrf_802154_enh_ack_generator_init();
}
const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame)
{
// This function should not be called if ACK is not requested.
assert(p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT);
switch (frame_version_is_2015_or_above(p_frame))
{
case FRAME_VERSION_BELOW_2015:
return nrf_802154_imm_ack_generator_create(p_frame);
case FRAME_VERSION_2015_OR_ABOVE:
return nrf_802154_enh_ack_generator_create(p_frame);
default:
return NULL;
}
}
@@ -0,0 +1,52 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief This module contains an acknowledgement generator for 802.15.4 radio driver.
*
*/
#ifndef NRF_802154_ACK_GENERATOR_H
#define NRF_802154_ACK_GENERATOR_H
#include <stdint.h>
/** Initialize the ACK generator module. */
void nrf_802154_ack_generator_init(void);
/** Create an ACK in response to provided frame and insert it into an appropriate radio buffer.
*
* @param [in] p_frame Pointer to a frame to respond to.
*
* @returns Pointer to constant buffer containing created ACK frame or NULL in case of invalid frame.
*/
const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_ACK_GENERATOR_H
@@ -0,0 +1,380 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file implements an enhanced acknowledgement (Enh-Ack) generator for 802.15.4 radio driver.
*
*/
#include "nrf_802154_enh_ack_generator.h"
#include <assert.h>
#include <string.h>
#include "mac_features/nrf_802154_frame_parser.h"
#include "nrf_802154_ack_data.h"
#include "nrf_802154_ack_pending_bit.h"
#include "nrf_802154_const.h"
#include "nrf_802154_pib.h"
#define ENH_ACK_MAX_SIZE MAX_PACKET_SIZE
static uint8_t m_ack_psdu[ENH_ACK_MAX_SIZE + PHR_SIZE];
static void ack_buffer_clear(void)
{
memset(m_ack_psdu, 0, FCF_SIZE + PHR_SIZE);
}
static void sequence_number_set(const uint8_t * p_frame)
{
if (!nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_frame))
{
m_ack_psdu[DSN_OFFSET] = p_frame[DSN_OFFSET];
}
}
/***************************************************************************************************
* @section Frame control field functions
**************************************************************************************************/
static void fcf_frame_type_set(void)
{
m_ack_psdu[FRAME_TYPE_OFFSET] |= FRAME_TYPE_ACK;
}
static void fcf_security_enabled_set(const uint8_t * p_frame)
{
m_ack_psdu[SECURITY_ENABLED_OFFSET] |=
(p_frame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT);
}
static void fcf_frame_pending_set(const uint8_t * p_frame)
{
if (nrf_802154_ack_pending_bit_should_be_set(p_frame))
{
m_ack_psdu[FRAME_PENDING_OFFSET] |= FRAME_PENDING_BIT;
}
}
static void fcf_panid_compression_set(const uint8_t * p_frame)
{
if (p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK)
{
m_ack_psdu[PAN_ID_COMPR_OFFSET] |= PAN_ID_COMPR_MASK;
}
}
static void fcf_sequence_number_suppression_set(const uint8_t * p_frame)
{
if (nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_frame))
{
m_ack_psdu[DSN_SUPPRESS_OFFSET] |= DSN_SUPPRESS_BIT;
}
}
static void fcf_ie_present_set(const uint8_t * p_frame, const uint8_t * p_ie_data)
{
if (p_ie_data != NULL)
{
m_ack_psdu[IE_PRESENT_OFFSET] |= IE_PRESENT_BIT;
}
}
static void fcf_dst_addressing_mode_set(const uint8_t * p_frame)
{
if (nrf_802154_frame_parser_src_addr_is_extended(p_frame))
{
m_ack_psdu[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_EXTENDED;
}
else if (nrf_802154_frame_parser_src_addr_is_short(p_frame))
{
m_ack_psdu[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_SHORT;
}
else
{
m_ack_psdu[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_NONE;
}
}
static void fcf_src_addressing_mode_set(const uint8_t * p_frame)
{
m_ack_psdu[SRC_ADDR_TYPE_OFFSET] |= SRC_ADDR_TYPE_NONE;
}
static void fcf_frame_version_set(void)
{
m_ack_psdu[FRAME_VERSION_OFFSET] |= FRAME_VERSION_2;
}
static void frame_control_set(const uint8_t * p_frame,
const uint8_t * p_ie_data,
nrf_802154_frame_parser_mhr_data_t * p_ack_offsets)
{
bool parse_results;
fcf_frame_type_set();
fcf_security_enabled_set(p_frame);
fcf_frame_pending_set(p_frame);
fcf_panid_compression_set(p_frame);
fcf_sequence_number_suppression_set(p_frame);
fcf_ie_present_set(p_frame, p_ie_data);
fcf_dst_addressing_mode_set(p_frame);
fcf_frame_version_set();
fcf_src_addressing_mode_set(p_frame);
parse_results = nrf_802154_frame_parser_mhr_parse(m_ack_psdu, p_ack_offsets);
assert(parse_results);
(void)parse_results;
m_ack_psdu[PHR_OFFSET] = p_ack_offsets->addressing_end_offset - PHR_SIZE + FCS_SIZE;
}
/***************************************************************************************************
* @section Addressing fields functions
**************************************************************************************************/
static void destination_set(const nrf_802154_frame_parser_mhr_data_t * p_frame,
const nrf_802154_frame_parser_mhr_data_t * p_ack)
{
// Fill the Ack destination PAN ID field.
if (p_ack->p_dst_panid != NULL)
{
const uint8_t * p_dst_panid;
if (p_frame->p_src_panid != NULL)
{
p_dst_panid = p_frame->p_src_panid;
}
else if (p_frame->p_dst_panid != NULL)
{
p_dst_panid = p_frame->p_dst_panid;
}
else
{
p_dst_panid = nrf_802154_pib_pan_id_get();
}
memcpy((uint8_t *)p_ack->p_dst_panid, p_dst_panid, PAN_ID_SIZE);
}
// Fill the Ack destination address field.
if (p_frame->p_src_addr != NULL)
{
assert(p_ack->p_dst_addr != NULL);
assert(p_ack->dst_addr_size == p_frame->src_addr_size);
memcpy((uint8_t *)p_ack->p_dst_addr, p_frame->p_src_addr, p_frame->src_addr_size);
}
}
static void source_set(const uint8_t * p_frame)
{
// Intentionally empty: source address type is None.
}
/***************************************************************************************************
* @section Auxiliary security header functions
**************************************************************************************************/
static void security_control_set(const nrf_802154_frame_parser_mhr_data_t * p_frame,
const nrf_802154_frame_parser_mhr_data_t * p_ack)
{
assert(p_frame->p_sec_ctrl != NULL);
// All the bits in the security control byte can be copied.
*(uint8_t *)p_ack->p_sec_ctrl = *p_frame->p_sec_ctrl;
m_ack_psdu[PHR_OFFSET] += SECURITY_CONTROL_SIZE;
}
static void security_key_id_set(const nrf_802154_frame_parser_mhr_data_t * p_frame,
const nrf_802154_frame_parser_mhr_data_t * p_ack,
bool fc_suppresed,
const uint8_t ** p_sec_end)
{
const uint8_t * p_frame_key_id;
const uint8_t * p_ack_key_id;
uint8_t key_id_mode_size = 0;
p_frame_key_id = p_frame->p_sec_ctrl + SECURITY_CONTROL_SIZE;
p_ack_key_id = p_ack->p_sec_ctrl + SECURITY_CONTROL_SIZE;
if (!fc_suppresed)
{
p_frame_key_id += FRAME_COUNTER_SIZE;
p_ack_key_id += FRAME_COUNTER_SIZE;
}
switch ((*p_ack->p_sec_ctrl) & KEY_ID_MODE_MASK)
{
case KEY_ID_MODE_1:
key_id_mode_size = KEY_ID_MODE_1_SIZE;
break;
case KEY_ID_MODE_2:
key_id_mode_size = KEY_ID_MODE_2_SIZE;
break;
case KEY_ID_MODE_3:
key_id_mode_size = KEY_ID_MODE_3_SIZE;
break;
default:
break;
}
if (0 != key_id_mode_size)
{
memcpy((uint8_t *)p_ack_key_id, p_frame_key_id, key_id_mode_size);
m_ack_psdu[PHR_OFFSET] += key_id_mode_size;
}
switch (*(p_ack->p_sec_ctrl) & SECURITY_LEVEL_MASK)
{
case SECURITY_LEVEL_MIC_32:
case SECURITY_LEVEL_ENC_MIC_32:
m_ack_psdu[PHR_OFFSET] += MIC_32_SIZE;
break;
case SECURITY_LEVEL_MIC_64:
case SECURITY_LEVEL_ENC_MIC_64:
m_ack_psdu[PHR_OFFSET] += MIC_64_SIZE;
break;
case SECURITY_LEVEL_MIC_128:
case SECURITY_LEVEL_ENC_MIC_128:
m_ack_psdu[PHR_OFFSET] += MIC_128_SIZE;
break;
default:
break;
}
*p_sec_end = p_ack_key_id + key_id_mode_size;
}
static void security_header_set(const nrf_802154_frame_parser_mhr_data_t * p_frame,
const nrf_802154_frame_parser_mhr_data_t * p_ack,
const uint8_t ** p_sec_end)
{
bool fc_suppressed;
if (p_ack->p_sec_ctrl == NULL)
{
*p_sec_end = &m_ack_psdu[p_ack->addressing_end_offset];
return;
}
security_control_set(p_frame, p_ack);
// Frame counter is set by MAC layer when the frame is encrypted.
fc_suppressed = ((*p_ack->p_sec_ctrl) & FRAME_COUNTER_SUPPRESS_BIT);
if (!fc_suppressed)
{
m_ack_psdu[PHR_OFFSET] += FRAME_COUNTER_SIZE;
}
security_key_id_set(p_frame, p_ack, fc_suppressed, p_sec_end);
}
/***************************************************************************************************
* @section Information Elements
**************************************************************************************************/
static void ie_header_set(const uint8_t * p_ie_data, uint8_t ie_data_len, const uint8_t * p_sec_end)
{
uint8_t * p_ack_ie = (uint8_t *)p_sec_end;
if (p_ie_data == NULL)
{
return;
}
assert(p_ack_ie != NULL);
memcpy(p_ack_ie, p_ie_data, ie_data_len);
m_ack_psdu[PHR_OFFSET] += ie_data_len;
}
/***************************************************************************************************
* @section Public API implementation
**************************************************************************************************/
void nrf_802154_enh_ack_generator_init(void)
{
// Intentionally empty.
}
const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame)
{
nrf_802154_frame_parser_mhr_data_t frame_offsets;
nrf_802154_frame_parser_mhr_data_t ack_offsets;
const uint8_t * p_sec_end = NULL;
bool parse_result = nrf_802154_frame_parser_mhr_parse(p_frame,
&frame_offsets);
if (!parse_result)
{
return NULL;
}
uint8_t ie_data_len;
const uint8_t * p_ie_data = nrf_802154_ack_data_ie_get(
frame_offsets.p_src_addr,
frame_offsets.src_addr_size == EXTENDED_ADDRESS_SIZE,
&ie_data_len);
// Clear previously created ACK.
ack_buffer_clear();
// Set Frame Control field bits.
frame_control_set(p_frame, p_ie_data, &ack_offsets);
// Set valid sequence number in ACK frame.
sequence_number_set(p_frame);
// Set destination address and PAN ID.
destination_set(&frame_offsets, &ack_offsets);
// Set source address and PAN ID.
source_set(p_frame);
// Set auxiliary security header.
security_header_set(&frame_offsets, &ack_offsets, &p_sec_end);
// Set IE header.
ie_header_set(p_ie_data, ie_data_len, p_sec_end);
return m_ack_psdu;
}
@@ -0,0 +1,53 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief This module contains an enhanced acknowledgement (Enh-Ack) generator for 802.15.4 radio driver.
*
*/
#ifndef NRF_802154_ENH_ACK_GENERATOR_H
#define NRF_802154_ENH_ACK_GENERATOR_H
#include <stdbool.h>
#include <stdint.h>
/** Initialize the Enhanced ACK generator module. */
void nrf_802154_enh_ack_generator_init(void);
/** Create an Enhanced ACK in response to provided frame and insert it into an appropriate radio buffer.
*
* @param [in] p_frame Pointer to a frame to respond to.
*
* @returns Pointer to constant buffer containing created Enhanced ACK frame.
*/
const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_ENH_ACK_GENERATOR_H
@@ -0,0 +1,72 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file implements an immediate acknowledgement (Imm-Ack) generator for 802.15.4 radio driver.
*
*/
#include "nrf_802154_imm_ack_generator.h"
#include <assert.h>
#include <string.h>
#include "nrf_802154_ack_pending_bit.h"
#include "nrf_802154_const.h"
#define IMM_ACK_INITIALIZER {0x05, ACK_HEADER_WITH_PENDING, 0x00, 0x00, 0x00, 0x00}
static uint8_t m_ack_psdu[IMM_ACK_LENGTH + PHR_SIZE];
void nrf_802154_imm_ack_generator_init(void)
{
const uint8_t ack_psdu[] = IMM_ACK_INITIALIZER;
memcpy(m_ack_psdu, ack_psdu, sizeof(ack_psdu));
}
const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame)
{
// Set valid sequence number in ACK frame.
m_ack_psdu[DSN_OFFSET] = p_frame[DSN_OFFSET];
// Set pending bit in ACK frame.
if (nrf_802154_ack_pending_bit_should_be_set(p_frame))
{
m_ack_psdu[FRAME_PENDING_OFFSET] = ACK_HEADER_WITH_PENDING;
}
else
{
m_ack_psdu[FRAME_PENDING_OFFSET] = ACK_HEADER_WITHOUT_PENDING;
}
return m_ack_psdu;
}
@@ -0,0 +1,53 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief This module contains an immediate acknowledgement (Imm-Ack) generator for 802.15.4 radio driver.
*
*/
#ifndef NRF_802154_IMM_ACK_GENERATOR_H
#define NRF_802154_IMM_ACK_GENERATOR_H
#include <stdbool.h>
#include <stdint.h>
/** Initialize the Immediate ACK generator module. */
void nrf_802154_imm_ack_generator_init(void);
/** Create an Immediate ACK in response to provided frame and insert it into an appropriate radio buffer.
*
* @param [in] p_frame Pointer to a frame to respond to.
*
* @returns Pointer to constant buffer containing created Immediate ACK frame.
*/
const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_IMM_ACK_GENERATOR_H
@@ -0,0 +1,168 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file implements ACK timeout procedure for the 802.15.4 driver.
*
*/
#include "nrf_802154_ack_timeout.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_802154_notification.h"
#include "nrf_802154_request.h"
#include "timer_scheduler/nrf_802154_timer_sched.h"
#define RETRY_DELAY 500 ///< Procedure is delayed by this time if cannot be performed at the moment.
#define MAX_RETRY_DELAY 1000000 ///< Maximal allowed delay of procedure retry.
static void timeout_timer_retry(void);
static uint32_t m_timeout = NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT; ///< ACK timeout in us.
static nrf_802154_timer_t m_timer; ///< Timer used to notify when we are waiting too long for ACK.
static volatile bool m_procedure_is_active;
static const uint8_t * mp_frame;
static void notify_tx_error(bool result)
{
if (result)
{
nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK);
}
}
static void timeout_timer_fired(void * p_context)
{
(void)p_context;
if (m_procedure_is_active)
{
if (nrf_802154_request_receive(NRF_802154_TERM_802154,
REQ_ORIG_ACK_TIMEOUT,
notify_tx_error,
false))
{
m_procedure_is_active = false;
}
else
{
timeout_timer_retry();
}
}
}
static void timeout_timer_retry(void)
{
m_timer.dt += RETRY_DELAY;
assert(m_timer.dt <= MAX_RETRY_DELAY);
nrf_802154_timer_sched_add(&m_timer, true);
}
static void timeout_timer_start(void)
{
m_timer.callback = timeout_timer_fired;
m_timer.p_context = NULL;
m_timer.t0 = nrf_802154_timer_sched_time_get();
m_timer.dt = m_timeout;
m_procedure_is_active = true;
nrf_802154_timer_sched_add(&m_timer, true);
}
static void timeout_timer_stop(void)
{
m_procedure_is_active = false;
// To make sure `timeout_timer_fired()` detects that procedure is being stopped if it preempts
// this function.
__DMB();
nrf_802154_timer_sched_remove(&m_timer);
}
void nrf_802154_ack_timeout_time_set(uint32_t time)
{
m_timeout = time;
}
bool nrf_802154_ack_timeout_tx_started_hook(const uint8_t * p_frame)
{
mp_frame = p_frame;
timeout_timer_start();
return true;
}
bool nrf_802154_ack_timeout_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig)
{
bool result;
if (!m_procedure_is_active || req_orig == REQ_ORIG_ACK_TIMEOUT)
{
// Ignore if procedure is not running or self-request.
result = true;
}
else if (term_lvl >= NRF_802154_TERM_802154)
{
// Stop procedure only if termination level is high enough.
timeout_timer_stop();
result = true;
}
else
{
result = false;
}
return result;
}
void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame)
{
assert((p_frame == mp_frame) || (!m_procedure_is_active));
timeout_timer_stop();
}
bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error)
{
(void)error;
assert((p_frame == mp_frame) || (!m_procedure_is_active));
timeout_timer_stop();
return true;
}
@@ -94,6 +94,12 @@ bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_t
*/
bool nrf_802154_ack_timeout_tx_started_hook(const uint8_t * p_frame);
/**
* @brief Handler of RX ACK started event.
*
*/
void nrf_802154_ack_timeout_rx_ack_started_hook(void);
/**
*@}
**/
@@ -122,7 +122,7 @@ static void frame_transmit(void * p_context)
REQ_ORIG_CSMA_CA,
mp_psdu,
true,
true,
NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT ? false : true,
notify_busy_channel))
{
(void)channel_busy();
@@ -45,9 +45,11 @@
#include <string.h>
#include "nrf_802154_const.h"
#include "nrf_802154_frame_parser.h"
#include "nrf_802154_pib.h"
#define FCF_CHECK_OFFSET (PHR_SIZE + FCF_SIZE)
#define PANID_CHECK_OFFSET (DEST_ADDR_OFFSET)
#define SHORT_ADDR_CHECK_OFFSET (DEST_ADDR_OFFSET + SHORT_ADDRESS_SIZE)
#define EXTENDED_ADDR_CHECK_OFFSET (DEST_ADDR_OFFSET + EXTENDED_ADDRESS_SIZE)
@@ -167,12 +169,8 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(const uint8_t *
switch (p_psdu[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK)
{
case SRC_ADDR_TYPE_SHORT:
*p_num_bytes = SHORT_ADDR_CHECK_OFFSET;
result = NRF_802154_RX_ERROR_NONE;
break;
case SRC_ADDR_TYPE_EXTENDED:
*p_num_bytes = EXTENDED_ADDR_CHECK_OFFSET;
*p_num_bytes = PANID_CHECK_OFFSET;
result = NRF_802154_RX_ERROR_NONE;
break;
@@ -224,9 +222,20 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015(const uint8_t *
case FRAME_TYPE_DATA:
case FRAME_TYPE_ACK:
case FRAME_TYPE_COMMAND:
// TODO: Implement dst addressing filtering according to 2015 spec
result = dst_addressing_end_offset_get_2006(p_psdu, p_num_bytes, frame_type);
break;
{
uint8_t end_offset = nrf_802154_frame_parser_dst_addr_end_offset_get(p_psdu);
if (end_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
result = NRF_802154_RX_ERROR_INVALID_FRAME;
}
else
{
*p_num_bytes = end_offset;
result = NRF_802154_RX_ERROR_NONE;
}
}
break;
case FRAME_TYPE_MULTIPURPOSE:
// TODO: Implement dst addressing filtering according to 2015 spec
@@ -292,21 +301,22 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get(const uint8_t * p_psd
/**
* Verify if destination PAN Id of incoming frame allows processing by this node.
*
* @param[in] p_psdu Pointer of PSDU of incoming frame.
* @param[in] p_panid Pointer of PAN ID of incoming frame.
* @param[in] frame_type Type of the frame being filtered.
*
* @retval true PAN Id of incoming frame allows further processing of the frame.
* @retval false PAN Id of incoming frame does not allow further processing.
*/
static bool dst_pan_id_check(const uint8_t * p_psdu)
static bool dst_pan_id_check(const uint8_t * p_panid, uint8_t frame_type)
{
bool result;
if ((0 == memcmp(&p_psdu[PAN_ID_OFFSET], nrf_802154_pib_pan_id_get(), PAN_ID_SIZE)) ||
(0 == memcmp(&p_psdu[PAN_ID_OFFSET], BROADCAST_ADDRESS, PAN_ID_SIZE)))
if ((0 == memcmp(p_panid, nrf_802154_pib_pan_id_get(), PAN_ID_SIZE)) ||
(0 == memcmp(p_panid, BROADCAST_ADDRESS, PAN_ID_SIZE)))
{
result = true;
}
else if ((FRAME_TYPE_BEACON == (p_psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK)) &&
else if ((FRAME_TYPE_BEACON == frame_type) &&
(0 == memcmp(nrf_802154_pib_pan_id_get(), BROADCAST_ADDRESS, PAN_ID_SIZE)))
{
result = true;
@@ -322,28 +332,18 @@ static bool dst_pan_id_check(const uint8_t * p_psdu)
/**
* Verify if destination short address of incoming frame allows processing by this node.
*
* @param[in] p_psdu Pointer of PSDU of incoming frame.
* @param[in] p_dst_addr Pointer of destination address of incoming frame.
* @param[in] frame_type Type of the frame being filtered.
*
* @retval true Destination address of incoming frame allows further processing of the frame.
* @retval false Destination address of incoming frame does not allow further processing.
*/
static bool dst_short_addr_check(const uint8_t * p_psdu)
static bool dst_short_addr_check(const uint8_t * p_dst_addr, uint8_t frame_type)
{
bool result;
if ((0 == memcmp(&p_psdu[DEST_ADDR_OFFSET],
nrf_802154_pib_short_address_get(),
SHORT_ADDRESS_SIZE)) ||
(0 == memcmp(&p_psdu[DEST_ADDR_OFFSET], BROADCAST_ADDRESS, SHORT_ADDRESS_SIZE)))
{
result = true;
}
else if (FRAME_TYPE_BEACON == (p_psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK))
{
result = true;
}
else if (DEST_ADDR_TYPE_NONE == (p_psdu[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) &&
nrf_802154_pib_pan_coord_get())
if ((0 == memcmp(p_dst_addr, nrf_802154_pib_short_address_get(), SHORT_ADDRESS_SIZE)) ||
(0 == memcmp(p_dst_addr, BROADCAST_ADDRESS, SHORT_ADDRESS_SIZE)))
{
result = true;
}
@@ -358,27 +358,17 @@ static bool dst_short_addr_check(const uint8_t * p_psdu)
/**
* Verify if destination extended address of incoming frame allows processing by this node.
*
* @param[in] p_psdu Pointer of PSDU of incoming frame.
* @param[in] p_dst_addr Pointer of destination address of incoming frame.
* @param[in] frame_type Type of the frame being filtered.
*
* @retval true Destination address of incoming frame allows further processing of the frame.
* @retval false Destination address of incoming frame does not allow further processing.
*/
static bool dst_extended_addr_check(const uint8_t * p_psdu)
static bool dst_extended_addr_check(const uint8_t * p_dst_addr, uint8_t frame_type)
{
bool result;
if (0 == memcmp(&p_psdu[DEST_ADDR_OFFSET],
nrf_802154_pib_extended_address_get(),
EXTENDED_ADDRESS_SIZE))
{
result = true;
}
else if (FRAME_TYPE_BEACON == (p_psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK))
{
result = true;
}
else if (DEST_ADDR_TYPE_NONE == (p_psdu[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) &&
nrf_802154_pib_pan_coord_get())
if (0 == memcmp(p_dst_addr, nrf_802154_pib_extended_address_get(), EXTENDED_ADDRESS_SIZE))
{
result = true;
}
@@ -390,23 +380,78 @@ static bool dst_extended_addr_check(const uint8_t * p_psdu)
return result;
}
/**
* Verify if destination addressing of incoming frame allows processing by this node.
* This function checks addressing according to IEEE 802.15.4-2015.
*
* @param[in] p_psdu Pointer of PSDU of incoming frame.
*
* @retval NRF_802154_RX_ERROR_NONE Destination address of incoming frame allows further processing of the frame.
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Received frame is invalid.
* @retval NRF_802154_RX_ERROR_INVALID_DEST_ADDR Destination address of incoming frame does not allow further processing.
*/
static nrf_802154_rx_error_t dst_addr_check(const uint8_t * p_psdu, uint8_t frame_type)
{
bool result;
nrf_802154_frame_parser_mhr_data_t mhr_data;
result = nrf_802154_frame_parser_mhr_parse(p_psdu, &mhr_data);
if (!result)
{
return NRF_802154_RX_ERROR_INVALID_FRAME;
}
if (mhr_data.p_dst_panid != NULL)
{
if (!dst_pan_id_check(mhr_data.p_dst_panid, frame_type))
{
return NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
}
}
switch (mhr_data.dst_addr_size)
{
case SHORT_ADDRESS_SIZE:
return dst_short_addr_check(mhr_data.p_dst_addr,
frame_type) ? NRF_802154_RX_ERROR_NONE :
NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
case EXTENDED_ADDRESS_SIZE:
return dst_extended_addr_check(mhr_data.p_dst_addr,
frame_type) ? NRF_802154_RX_ERROR_NONE :
NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
case 0:
// Allow frames destined to the Pan Coordinator without destination address or
// beacon frames without destination address
return (nrf_802154_pib_pan_coord_get() ||
(frame_type ==
FRAME_TYPE_BEACON)) ? NRF_802154_RX_ERROR_NONE :
NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
default:
assert(false);
}
return NRF_802154_RX_ERROR_INVALID_FRAME;
}
nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8_t * p_num_bytes)
{
nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_INVALID_FRAME;
nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_INVALID_FRAME;
uint8_t frame_type = p_psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK;
uint8_t frame_version = p_psdu[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK;
switch (*p_num_bytes)
{
case FCF_CHECK_OFFSET:
{
if (p_psdu[0] < IMM_ACK_LENGTH || p_psdu[0] > MAX_PACKET_SIZE)
{
result = NRF_802154_RX_ERROR_INVALID_LENGTH;
break;
}
uint8_t frame_type = p_psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK;
uint8_t frame_version = p_psdu[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK;
if (!frame_type_and_version_filter(frame_type, frame_version))
{
result = NRF_802154_RX_ERROR_INVALID_FRAME;
@@ -421,32 +466,10 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8
result = dst_addressing_end_offset_get(p_psdu, p_num_bytes, frame_type, frame_version);
break;
}
case SHORT_ADDR_CHECK_OFFSET:
if (!dst_pan_id_check(p_psdu))
{
result = NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
break;
}
result = dst_short_addr_check(p_psdu) ? NRF_802154_RX_ERROR_NONE :
NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
break;
case EXTENDED_ADDR_CHECK_OFFSET:
if (!dst_pan_id_check(p_psdu))
{
result = NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
break;
}
result = dst_extended_addr_check(p_psdu) ? NRF_802154_RX_ERROR_NONE :
NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
break;
default:
assert(false);
result = dst_addr_check(p_psdu, frame_type);
break;
}
return result;
@@ -0,0 +1,677 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file implements frame parsing utilities for 802.15.4 radio driver.
*
* @note This module is based on following assumptions:
* a. All received frames contain both source and destination address.
* b. All received frames contain destination PAN ID field.
* Frames that don't meet these assumptions are dropped.
*/
#include "nrf_802154_frame_parser.h"
#include <stdlib.h>
#include "nrf_802154_const.h"
/***************************************************************************************************
* @section Helper functions
**************************************************************************************************/
// Version
static uint8_t frame_version_get(const uint8_t * p_frame)
{
return p_frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK;
}
// Addressing
static uint8_t addressing_offset_get(const uint8_t * p_frame)
{
if ((frame_version_get(p_frame) >= FRAME_VERSION_2) &&
nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_frame))
{
return PHR_SIZE + FCF_SIZE;
}
else
{
return PHR_SIZE + FCF_SIZE + DSN_SIZE;
}
}
static bool src_addr_is_present(const uint8_t * p_frame)
{
return (p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) != SRC_ADDR_TYPE_NONE;
}
static bool dst_addr_is_present(const uint8_t * p_frame)
{
return (p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) != DEST_ADDR_TYPE_NONE;
}
static uint8_t src_addr_size_get(const uint8_t * p_frame)
{
switch (p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK)
{
case SRC_ADDR_TYPE_NONE:
return 0;
case SRC_ADDR_TYPE_SHORT:
return SHORT_ADDRESS_SIZE;
case SRC_ADDR_TYPE_EXTENDED:
return EXTENDED_ADDRESS_SIZE;
default:
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
}
static uint8_t dst_addr_size_get(const uint8_t * p_frame)
{
switch (p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK)
{
case DEST_ADDR_TYPE_NONE:
return 0;
case DEST_ADDR_TYPE_SHORT:
return SHORT_ADDRESS_SIZE;
case DEST_ADDR_TYPE_EXTENDED:
return EXTENDED_ADDRESS_SIZE;
default:
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
}
// PAN ID
static bool dst_panid_is_present(const uint8_t * p_frame)
{
bool panid_compression = (p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK) ? true : false;
switch (frame_version_get(p_frame))
{
case FRAME_VERSION_0:
case FRAME_VERSION_1:
if (!dst_addr_is_present(p_frame))
{
return false;
}
return true;
case FRAME_VERSION_2:
default:
if (nrf_802154_frame_parser_dst_addr_is_extended(p_frame) &&
nrf_802154_frame_parser_src_addr_is_extended(p_frame))
{
return panid_compression ? false : true;
}
if (src_addr_is_present(p_frame) && dst_addr_is_present(p_frame))
{
return true;
}
if (src_addr_is_present(p_frame))
{
return false;
}
if (dst_addr_is_present(p_frame))
{
return panid_compression ? false : true;
}
return panid_compression ? true : false;
}
}
static bool src_panid_is_present(const uint8_t * p_frame)
{
bool panid_compression = (p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK) ? true : false;
switch (frame_version_get(p_frame))
{
case FRAME_VERSION_0:
case FRAME_VERSION_1:
if (!src_addr_is_present(p_frame))
{
return false;
}
return panid_compression ? false : true;
case FRAME_VERSION_2:
default:
if (nrf_802154_frame_parser_dst_addr_is_extended(p_frame) &&
nrf_802154_frame_parser_src_addr_is_extended(p_frame))
{
return false;
}
if (src_addr_is_present(p_frame) && dst_addr_is_present(p_frame))
{
return panid_compression ? false : true;
}
if (src_addr_is_present(p_frame))
{
return panid_compression ? false : true;
}
if (dst_addr_is_present(p_frame))
{
return false;
}
return false;
}
}
static bool src_panid_is_compressed(const uint8_t * p_frame)
{
return dst_panid_is_present(p_frame) && !src_panid_is_present(p_frame);
}
// Security
static bool security_is_enabled(const uint8_t * p_frame)
{
return p_frame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT ? true : false;
}
static uint8_t security_offset_get(const uint8_t * p_frame)
{
uint8_t dst_addr_offset = nrf_802154_frame_parser_dst_addr_offset_get(p_frame);
uint8_t dst_panid_offset = nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
uint8_t dst_addr_size = dst_addr_size_get(p_frame);
uint8_t src_addr_offset = nrf_802154_frame_parser_src_addr_offset_get(p_frame);
uint8_t src_panid_offset = nrf_802154_frame_parser_src_panid_offset_get(p_frame);
uint8_t src_addr_size = src_addr_size_get(p_frame);
if (src_addr_is_present(p_frame))
{
if ((src_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET) ||
(src_addr_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET))
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return src_addr_offset + src_addr_size;
}
else if (src_panid_is_present(p_frame))
{
if (src_panid_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return src_panid_offset + PAN_ID_SIZE;
}
else if (dst_addr_offset)
{
if (dst_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return dst_addr_offset + dst_addr_size;
}
else if (dst_panid_offset)
{
return dst_panid_offset + PAN_ID_SIZE;
}
else
{
return addressing_offset_get(p_frame);
}
}
static uint8_t key_id_size_get(const uint8_t * p_frame)
{
switch (*nrf_802154_frame_parser_sec_ctrl_get(p_frame) & KEY_ID_MODE_MASK)
{
case KEY_ID_MODE_1:
return KEY_ID_MODE_1_SIZE;
case KEY_ID_MODE_2:
return KEY_ID_MODE_2_SIZE;
case KEY_ID_MODE_3:
return KEY_ID_MODE_3_SIZE;
default:
return 0;
}
}
// IEs
static uint8_t ie_offset_get(const uint8_t * p_frame)
{
uint8_t security_offset = security_offset_get(p_frame);
uint8_t key_id_offset = nrf_802154_frame_parser_key_id_offset_get(p_frame);
if (!security_is_enabled(p_frame))
{
if (security_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return security_offset;
}
else
{
if (key_id_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return key_id_offset + key_id_size_get(p_frame);
}
}
/***************************************************************************************************
* @section Frame format functions
**************************************************************************************************/
bool nrf_802154_frame_parser_dst_addr_is_extended(const uint8_t * p_frame)
{
return (p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) == DEST_ADDR_TYPE_EXTENDED;
}
bool nrf_802154_frame_parser_src_addr_is_extended(const uint8_t * p_frame)
{
return (p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == SRC_ADDR_TYPE_EXTENDED;
}
bool nrf_802154_frame_parser_src_addr_is_short(const uint8_t * p_frame)
{
return (p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == SRC_ADDR_TYPE_SHORT;
}
bool nrf_802154_frame_parser_dsn_suppress_bit_is_set(const uint8_t * p_frame)
{
return (p_frame[DSN_SUPPRESS_OFFSET] & DSN_SUPPRESS_BIT) ? true : false;
}
bool nrf_802154_frame_parser_ie_present_bit_is_set(const uint8_t * p_frame)
{
return (p_frame[IE_PRESENT_OFFSET] & IE_PRESENT_BIT) ? true : false;
}
/***************************************************************************************************
* @section Offset functions
**************************************************************************************************/
uint8_t nrf_802154_frame_parser_dst_panid_offset_get(const uint8_t * p_frame)
{
if (dst_panid_is_present(p_frame))
{
return addressing_offset_get(p_frame);
}
else
{
return 0;
}
}
uint8_t nrf_802154_frame_parser_dst_addr_offset_get(const uint8_t * p_frame)
{
uint8_t dst_panid_offset = nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
if (dst_addr_is_present(p_frame))
{
return 0 ==
dst_panid_offset ? addressing_offset_get(p_frame) : dst_panid_offset + PAN_ID_SIZE;
}
else
{
return 0;
}
}
uint8_t nrf_802154_frame_parser_dst_addr_end_offset_get(const uint8_t * p_frame)
{
uint8_t offset = addressing_offset_get(p_frame);
uint8_t dst_addr_size = dst_addr_size_get(p_frame);
if (dst_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
if (dst_panid_is_present(p_frame))
{
offset += PAN_ID_SIZE;
}
offset += dst_addr_size;
return offset;
}
uint8_t nrf_802154_frame_parser_src_panid_offset_get(const uint8_t * p_frame)
{
uint8_t dst_addr_offset = nrf_802154_frame_parser_dst_addr_offset_get(p_frame);
uint8_t dst_panid_offset = nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
uint8_t dst_addr_size = dst_addr_size_get(p_frame);
if (src_panid_is_present(p_frame))
{
if (dst_addr_offset)
{
if (dst_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return dst_addr_offset + dst_addr_size;
}
else if (dst_panid_offset)
{
return dst_panid_offset + PAN_ID_SIZE;
}
else
{
return addressing_offset_get(p_frame);
}
}
else if (src_panid_is_compressed(p_frame))
{
return nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
}
else
{
return 0;
}
}
uint8_t nrf_802154_frame_parser_src_addr_offset_get(const uint8_t * p_frame)
{
uint8_t dst_addr_offset = nrf_802154_frame_parser_dst_addr_offset_get(p_frame);
uint8_t dst_panid_offset = nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
uint8_t dst_addr_size = dst_addr_size_get(p_frame);
uint8_t src_panid_offset = nrf_802154_frame_parser_src_panid_offset_get(p_frame);
if (src_addr_is_present(p_frame))
{
if (src_panid_is_present(p_frame))
{
if (src_panid_offset == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return src_panid_offset + PAN_ID_SIZE;
}
else if (dst_addr_offset)
{
if (dst_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
return dst_addr_offset + dst_addr_size;
}
else if (dst_panid_offset)
{
return dst_panid_offset + PAN_ID_SIZE;
}
else
{
return addressing_offset_get(p_frame);
}
}
else
{
return 0;
}
}
uint8_t nrf_802154_frame_parser_addressing_end_offset_get(const uint8_t * p_frame)
{
return security_offset_get(p_frame);
}
uint8_t nrf_802154_frame_parser_sec_ctrl_offset_get(const uint8_t * p_frame)
{
if (!security_is_enabled(p_frame))
{
return 0;
}
else
{
return security_offset_get(p_frame);
}
}
uint8_t nrf_802154_frame_parser_key_id_offset_get(const uint8_t * p_frame)
{
uint8_t sec_ctrl_offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_frame);
if (0 == sec_ctrl_offset)
{
return 0;
}
if (NRF_802154_FRAME_PARSER_INVALID_OFFSET == sec_ctrl_offset)
{
return NRF_802154_FRAME_PARSER_INVALID_OFFSET;
}
if (p_frame[sec_ctrl_offset] & FRAME_COUNTER_SUPPRESS_BIT)
{
return sec_ctrl_offset + SECURITY_CONTROL_SIZE;
}
else
{
return sec_ctrl_offset + SECURITY_CONTROL_SIZE + FRAME_COUNTER_SIZE;
}
}
uint8_t nrf_802154_frame_parser_ie_header_offset_get(const uint8_t * p_frame)
{
if (!nrf_802154_frame_parser_ie_present_bit_is_set(p_frame))
{
return 0;
}
else
{
return ie_offset_get(p_frame);
}
}
/***************************************************************************************************
* @section Get functions
**************************************************************************************************/
const uint8_t * nrf_802154_frame_parser_dst_addr_get(const uint8_t * p_frame,
bool * p_dst_addr_extended)
{
uint8_t dst_addr_offset = nrf_802154_frame_parser_dst_addr_offset_get(p_frame);
if ((0 == dst_addr_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == dst_addr_offset))
{
*p_dst_addr_extended = false;
return NULL;
}
else
{
*p_dst_addr_extended = nrf_802154_frame_parser_dst_addr_is_extended(p_frame);
return &p_frame[dst_addr_offset];
}
}
const uint8_t * nrf_802154_frame_parser_dst_panid_get(const uint8_t * p_frame)
{
uint8_t dst_panid_offset = nrf_802154_frame_parser_dst_panid_offset_get(p_frame);
return ((0 == dst_panid_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == dst_panid_offset))
? NULL : &p_frame[dst_panid_offset];
}
const uint8_t * nrf_802154_frame_parser_src_panid_get(const uint8_t * p_frame)
{
uint8_t src_panid_offset = nrf_802154_frame_parser_src_panid_offset_get(p_frame);
return ((0 == src_panid_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == src_panid_offset))
? NULL : &p_frame[src_panid_offset];
}
const uint8_t * nrf_802154_frame_parser_src_addr_get(const uint8_t * p_frame,
bool * p_src_addr_extended)
{
uint8_t src_addr_offset = nrf_802154_frame_parser_src_addr_offset_get(p_frame);
if ((0 == src_addr_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == src_addr_offset))
{
*p_src_addr_extended = false;
return NULL;
}
else
{
*p_src_addr_extended = nrf_802154_frame_parser_src_addr_is_extended(p_frame);
return &p_frame[src_addr_offset];
}
}
bool nrf_802154_frame_parser_mhr_parse(const uint8_t * p_frame,
nrf_802154_frame_parser_mhr_data_t * p_fields)
{
uint8_t offset = addressing_offset_get(p_frame);
bool is_dst_panid_present = dst_panid_is_present(p_frame);
bool is_src_panid_present = src_panid_is_present(p_frame);
if (is_dst_panid_present)
{
p_fields->p_dst_panid = &p_frame[offset];
offset += PAN_ID_SIZE;
}
else
{
p_fields->p_dst_panid = NULL;
}
if (dst_addr_is_present(p_frame))
{
p_fields->p_dst_addr = &p_frame[offset];
p_fields->dst_addr_size = dst_addr_size_get(p_frame);
offset += (p_fields->dst_addr_size);
if (p_fields->dst_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return false;
}
}
else
{
p_fields->p_dst_addr = NULL;
p_fields->dst_addr_size = 0;
}
if (is_src_panid_present)
{
p_fields->p_src_panid = &p_frame[offset];
offset += PAN_ID_SIZE;
}
else if (is_dst_panid_present)
{
p_fields->p_src_panid = p_fields->p_dst_panid;
}
else
{
p_fields->p_src_panid = NULL;
}
if (src_addr_is_present(p_frame))
{
p_fields->p_src_addr = &p_frame[offset];
p_fields->src_addr_size = src_addr_size_get(p_frame);
offset += (p_fields->src_addr_size);
if (p_fields->src_addr_size == NRF_802154_FRAME_PARSER_INVALID_OFFSET)
{
return false;
}
}
else
{
p_fields->p_src_addr = NULL;
p_fields->src_addr_size = 0;
}
p_fields->addressing_end_offset = offset;
if (security_is_enabled(p_frame))
{
p_fields->p_sec_ctrl = &p_frame[offset];
// TODO increment offset...
}
else
{
p_fields->p_sec_ctrl = NULL;
}
return true;
}
const uint8_t * nrf_802154_frame_parser_sec_ctrl_get(const uint8_t * p_frame)
{
uint8_t sec_ctrl_offset = nrf_802154_frame_parser_sec_ctrl_offset_get(p_frame);
return ((0 == sec_ctrl_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == sec_ctrl_offset)) ?
NULL : &p_frame[sec_ctrl_offset];
}
const uint8_t * nrf_802154_frame_parser_key_id_get(const uint8_t * p_frame)
{
uint8_t key_id_offset = nrf_802154_frame_parser_key_id_offset_get(p_frame);
return ((0 == key_id_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == key_id_offset)) ?
NULL : &p_frame[key_id_offset];
}
const uint8_t * nrf_802154_frame_parser_ie_header_get(const uint8_t * p_frame)
{
uint8_t ie_header_offset = nrf_802154_frame_parser_ie_header_offset_get(p_frame);
if ((0 == ie_header_offset) || (NRF_802154_FRAME_PARSER_INVALID_OFFSET == ie_header_offset))
{
return NULL;
}
return &p_frame[ie_header_offset];
}
@@ -0,0 +1,285 @@
/* Copyright (c) 2018, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @brief This module contatins frame parsing utilities for 802.15.4 radio driver.
*
*/
#ifndef NRF_802154_FRAME_PARSER_H
#define NRF_802154_FRAME_PARSER_H
#include <stdbool.h>
#include <stdint.h>
#define NRF_802154_FRAME_PARSER_INVALID_OFFSET 0xff
/**
* @biref Structure containing pointers to parts of MHR and details of MHR structure.
*/
typedef struct
{
const uint8_t * p_dst_panid; ///< Pointer to the destination PAN ID field or NULL if missing.
const uint8_t * p_dst_addr; ///< Pointer to the destination address field or NULL if missing.
const uint8_t * p_src_panid; ///< Pointer to the source PAN ID field or NULL if missing.
const uint8_t * p_src_addr; ///< Pointer to the source address field or NULL if missing.
const uint8_t * p_sec_ctrl; ///< Pointer to the security control field or NULL if missing.
uint8_t dst_addr_size; ///< Size of destination address field.
uint8_t src_addr_size; ///< Size of source address field.
uint8_t addressing_end_offset; ///< Offset of the first byte following addressing fields.
} nrf_802154_frame_parser_mhr_data_t;
/**
* @brief Determine if destination address is extended.
*
* @param[in] p_frame Pointer to a frame to check.
*
* @retval true If destination address is extended.
* @retval false Otherwise.
*/
bool nrf_802154_frame_parser_dst_addr_is_extended(const uint8_t * p_frame);
/**
* @brief Get destination address from provided frame.
*
* @param[in] p_frame Pointer to a frame.
* @param[out] p_dst_addr_extended Pointer to a value which is true if destination address is extended.
* Otherwise it is false.
*
* @returns Pointer to the first byte of destination address in @p p_frame.
* NULL if destination address cannot be retrieved.
*/
const uint8_t * nrf_802154_frame_parser_dst_addr_get(const uint8_t * p_frame,
bool * p_dst_addr_extended);
/**
* @brief Get offset of destination address field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of destination address field including one byte of frame length.
* Zero if destination address cannot be retrieved.
*/
uint8_t nrf_802154_frame_parser_dst_addr_offset_get(const uint8_t * p_frame);
/**
* @brief Get destination PAN ID from provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of destination PAN ID in @p p_frame.
* NULL if destination PAN ID cannot be retrieved.
*/
const uint8_t * nrf_802154_frame_parser_dst_panid_get(const uint8_t * p_frame);
/**
* @brief Get offset of destination PAN ID field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of destination PAN ID field including one byte of frame length.
* Zero in case the destination PAN ID cannot be retrieved.
*/
uint8_t nrf_802154_frame_parser_dst_panid_offset_get(const uint8_t * p_frame);
/**
* @brief Get offset of the end of destination address fields.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset of the first byte following destination addressing fields in the MHR.
*/
uint8_t nrf_802154_frame_parser_dst_addr_end_offset_get(const uint8_t * p_frame);
/**
* @brief Determine if source address is extended.
*
* @param[in] p_frame Pointer to a frame to check.
*
* @retval true If source address is extended.
* @retval false Otherwise.
*/
bool nrf_802154_frame_parser_src_addr_is_extended(const uint8_t * p_frame);
/**
* @brief Determine if source address is short.
*
* @param[in] p_frame Pointer to a frame to check.
*
* @retval true If source address is short..
* @retval false Otherwise.
*/
bool nrf_802154_frame_parser_src_addr_is_short(const uint8_t * p_frame);
/**
* @brief Get source address from provided frame.
*
* @param[in] p_frame Pointer to a frame.
* @param[out] p_src_addr_extended Pointer to a value which is true if source address is extended.
* Otherwise it is false.
*
* @returns Pointer to the first byte of source address in @p p_frame.
* NULL if source address cannot be retrieved.
*/
const uint8_t * nrf_802154_frame_parser_src_addr_get(const uint8_t * p_frame,
bool * p_src_addr_extended);
/**
* @brief Get offset of source address field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of source address field including one byte of frame length.
* Zero if source address cannot be retrieved.
*/
uint8_t nrf_802154_frame_parser_src_addr_offset_get(const uint8_t * p_frame);
/**
* @brief Get source PAN ID from provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of source PAN ID in @p p_frame.
* NULL if source PAN ID cannot be retrieved or if it is compressed.
*/
const uint8_t * nrf_802154_frame_parser_src_panid_get(const uint8_t * p_frame);
/**
* @brief Get offset of source PAN ID field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of source PAN ID field including one byte of frame length.
* Zero in case the source PAN ID cannot be retrieved or it is compressed.
*/
uint8_t nrf_802154_frame_parser_src_panid_offset_get(const uint8_t * p_frame);
/**
* @brief Get pointer and details of MHR parts of given frame
*
* @param[in] p_frame Pointer to a frame to parse.
* @param[out] p_fields Pointer to a structure containing pointers and details of the parsed frame.
*
* @retval true Frame parsed correctly.
* @retval false Parse error. @p p_fields values are invalid.
*/
bool nrf_802154_frame_parser_mhr_parse(const uint8_t * p_frame,
nrf_802154_frame_parser_mhr_data_t * p_fields);
/**
* @brief Get security control field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of security control field in @p p_frame.
* NULL if security control cannot be retrieved (security not enabled).
*/
const uint8_t * nrf_802154_frame_parser_sec_ctrl_get(const uint8_t * p_frame);
/**
* @brief Get offset of the first byte after addressing fields in MHR.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of the first byte after addressing fields in MHR.
*/
uint8_t nrf_802154_frame_parser_addressing_end_offset_get(const uint8_t * p_frame);
/**
* @brief Get offset of security control field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of security control field including one byte of frame length.
* Zero if security control cannot be retrieved (security not enabled).
*/
uint8_t nrf_802154_frame_parser_sec_ctrl_offset_get(const uint8_t * p_frame);
/**
* @brief Get key identifier field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of key identifier field in @p p_frame.
* NULL if key identifier cannot be retrieved (security not enabled).
*/
const uint8_t * nrf_802154_frame_parser_key_id_get(const uint8_t * p_frame);
/**
* @brief Get offset of key identifier field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of key identifier field including one byte of frame length.
* Zero if key identifier cannot be retrieved (security not enabled).
*/
uint8_t nrf_802154_frame_parser_key_id_offset_get(const uint8_t * p_frame);
/**
* @brief Determine if sequence number suppression bit is set.
*
* @param[in] p_frame Pointer to a frame.
*
* @retval true If sequence number suppression bit is set.
* @retval false Otherwise.
*/
bool nrf_802154_frame_parser_dsn_suppress_bit_is_set(const uint8_t * p_frame);
/**
* @brief Determine if IE present bit is set.
*
* @param[in] p_frame Pointer to a frame.
*
* @retval true If IE present bit is set.
* @retval false Otherwise.
*/
bool nrf_802154_frame_parser_ie_present_bit_is_set(const uint8_t * p_frame);
/**
* @brief Get IE header field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of IE header field in @p p_frame.
* NULL if IE header cannot be retrieved (IE not present).
*/
const uint8_t * nrf_802154_frame_parser_ie_header_get(const uint8_t * p_frame);
/**
* @brief Get offset of IE header field in provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of IE header field including one byte of frame length.
* Zero if IE header cannot be retrieved (IE not present).
*/
uint8_t nrf_802154_frame_parser_ie_header_offset_get(const uint8_t * p_frame);
#endif // NRF_802154_FRAME_PARSER_H
@@ -160,6 +160,13 @@ void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame)
timeout_timer_stop();
}
void nrf_802154_ack_timeout_rx_ack_started_hook(void)
{
assert(m_procedure_is_active);
timeout_timer_stop();
}
bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error)
{
(void)error;
+12 -2
View File
@@ -67,6 +67,7 @@
#include "mac_features/nrf_802154_ack_timeout.h"
#include "mac_features/nrf_802154_csma_ca.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "mac_features/ack_generator/nrf_802154_ack_data.h"
#if ENABLE_FEM
#include "fem/nrf_fem_control_api.h"
@@ -539,6 +540,15 @@ void nrf_802154_pan_coord_set(bool enabled)
nrf_802154_pib_pan_coord_set(enabled);
}
bool nrf_802154_ack_data_set(const uint8_t * p_addr,
bool extended,
const void * p_data,
uint16_t length,
uint8_t data_type)
{
return nrf_802154_ack_data_for_addr_set(p_addr, extended, p_data, length, data_type);
}
void nrf_802154_auto_pending_bit_set(bool enabled)
{
nrf_802154_ack_pending_bit_set(enabled);
@@ -608,9 +618,9 @@ void nrf_802154_ack_timeout_set(uint32_t time)
#endif // NRF_802154_ACK_TIMEOUT_ENABLED
__WEAK void nrf_802154_tx_ack_started(void)
__WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data)
{
// Intentionally empty
(void)p_data;
}
#if NRF_802154_USE_RAW_API
+24 -4
View File
@@ -400,10 +400,10 @@ bool nrf_802154_transmit(const uint8_t * p_data, uint8_t length, bool cca);
* @note This function is implemented in zero-copy fashion. It passes the given buffer pointer to
* the RADIO peripheral.
*
* This function works as delayed version of the @sref nrf_drv_radio802154_transmit_raw. It is not
* This function works as delayed version of the @sref nrf_802154_transmit_raw. It is not
* blocking, but queues delayed transmission using Radio Scheduler module. If delayed transmission
* cannot be performed (the @ref nrf_drv_radio802154_transmit_raw would return false) or requested
* transmission timeslot is denied, the @ref nrf_drv_radio802154_transmit_failed with the
* cannot be performed (the @ref nrf_802154_transmit_raw would return false) or requested
* transmission timeslot is denied, the @ref nrf_802154_transmit_failed with the
* @ref NRF_802154_TX_ERROR_TIMESLOT_DENIED argument is called.
*
* This function is designed to transmit first symbol of SHR at given time.
@@ -487,8 +487,10 @@ bool nrf_802154_continuous_carrier(void);
* @brief Notify that transmitting the ACK frame has started.
*
* @note This function should be very short to prevent dropping frames by the driver.
*
* @param[in] p_data Pointer to buffer containing ACK data (PHR + PSDU).
*/
extern void nrf_802154_tx_ack_started(void);
extern void nrf_802154_tx_ack_started(const uint8_t * p_data);
#if NRF_802154_USE_RAW_API
@@ -943,6 +945,24 @@ void nrf_802154_pan_coord_set(bool enabled);
*/
bool nrf_802154_pan_coord_get(void);
/**
* @brief Add address of a peer node for which provided ACK data should be set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
* @param[in] p_data Pointer to the buffer containing data to be set.
* @param[in] length Length of @p p_data.
* @param[in] data_type Type of data to be set. Please refer to nrf_802154_ack_data_t type.
*
* @retval True Address successfully added to the list.
* @retval False There is not enough memory to store this address in the list.
*/
bool nrf_802154_ack_data_set(const uint8_t * p_addr,
bool extended,
const void * p_data,
uint16_t length,
uint8_t data_type);
/**
* @brief Enable or disable setting pending bit in automatically transmitted ACK frames.
*
@@ -46,13 +46,9 @@
#include "hal/nrf_radio.h"
/// Maximum number of Short Addresses of nodes for which there is pending data in buffer.
#define NUM_PENDING_SHORT_ADDRESSES NRF_802154_PENDING_SHORT_ADDRESSES
#define NUM_PENDING_SHORT_ADDRESSES NRF_802154_PENDING_SHORT_ADDRESSES
/// Maximum number of Extended Addresses of nodes for which there is pending data in buffer.
#define NUM_PENDING_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES
/// Value used to mark Short Address as unused.
#define UNUSED_PENDING_SHORT_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff})
/// Value used to mark Extended Address as unused.
#define UNUSED_PENDING_EXTENDED_ADDRESS ((uint8_t[EXTENDED_ADDRESS_SIZE]) {0})
#define NUM_PENDING_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES
/// If pending bit in ACK frame should be set to valid or default value.
static bool m_setting_pending_bit_enabled;
@@ -31,6 +31,8 @@
/**
* @brief This file implements procedures to set pending bit in nRF 802.15.4 radio driver.
*
* @deprecated The API provided by this module is deprecated. Please refer to nrf_802154_ack_data module.
*
*/
#ifndef NRF_802154_ACK_PENDING_BIT_H_
@@ -422,6 +422,22 @@ extern "C" {
#define NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS 4
#endif
/**
* @def NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT
*
* Indicates whether the CSMA-CA algorithm waits for an available timeslot before it performs the CCA procedure.
*
* @note When this option is enabled, the CSMA-CA procedure may be synchronized with timeslots of
* other protocols. It decreases robustness of the CSMA-CA procedure and is not recommended.
* This option may be used as a workaround to problems with higher layers that do not correctly handle
* multiple CHANNEL_BUSY errors in a row. This potentially problematic situation may
* happen during activity of other protocols.
*
*/
#ifndef NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT
#define NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT 0
#endif
/**
* @}
* @defgroup nrf_802154_config_timeout ACK timeout feature configuration
@@ -458,6 +474,16 @@ extern "C" {
#define NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT 210
#endif
/**
* @def NRF_802154_MAX_ACK_IE_SIZE
*
* Maximum supported size of 802.15.4-2015 IE header and content fields in an Enh-Ack.
*
*/
#ifndef NRF_802154_MAX_ACK_IE_SIZE
#define NRF_802154_MAX_ACK_IE_SIZE 8
#endif
/**
* @}
* @defgroup nrf_802154_config_transmission Transmission start notification feature configuration
@@ -53,6 +53,10 @@
#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte).
#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte).
#define DSN_SUPPRESS_OFFSET 2 ///< Byte containing DSN suppression field.
#define DSN_SUPPRESS_BIT 0x01 ///< Bits containing DSN suppression field.
#define FRAME_COUNTER_SUPPRESS_BIT 0x20 ///< Bit containing Frame Counter Suppression field.
#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte).
#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit.
@@ -74,11 +78,33 @@
#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10.
#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11.
#define IE_HEADER_LENGTH_MASK 0x3f ///< Mask of bits containing length of an IE header content.
#define IE_PRESENT_OFFSET 2 ///< Byte containing IE Present bit.
#define IE_PRESENT_BIT 0x02 ///< Bits containing IE Present field.
#define KEY_ID_MODE_MASK 0x18 ///< Mask of bits containing Key Identifier Mode in Security Control field.
#define KEY_ID_MODE_0 0 ///< Bits containing 0x00 Key Identifier Mode.
#define KEY_ID_MODE_1 0x08 ///< Bits containing 0x01 Key Identifier Mode.
#define KEY_ID_MODE_2 0x10 ///< Bits containing 0x10 Key Identifier Mode.
#define KEY_ID_MODE_3 0x18 ///< Bits containing 0x11 Key Identifier Mode.
#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte).
#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit.
#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte).
#define PHR_OFFSET 0 ///< Offset of the phy header in a frame
#define SECURITY_ENABLED_OFFSET 1 ///< Byte containing Security enabled bit.
#define SECURITY_ENABLED_BIT 0x08 ///< Bits containing Security enabled field.
#define SECURITY_LEVEL_MASK 0x07 ///< Mask of bits containing Security level field.
#define SECURITY_LEVEL_MIC_32 0x01 ///< Bits containing 32-bit Message Integrity Code (0b001).
#define SECURITY_LEVEL_MIC_64 0x02 ///< Bits containing 64-bit Message Integrity Code (0b010).
#define SECURITY_LEVEL_MIC_128 0x03 ///< Bits containing 128-bit Message Integrity Code (0b011).
#define SECURITY_LEVEL_ENC_MIC_32 0x05 ///< Bits containing 32-bit Encrypted Message Integrity Code (0b101).
#define SECURITY_LEVEL_ENC_MIC_64 0x06 ///< Bits containing 64-bit Encrypted Message Integrity Code (0b110).
#define SECURITY_LEVEL_ENC_MIC_128 0x07 ///< Bits containing 128-bit Encrypted Message Integrity Code (0b111).
#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type.
#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type.
#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type.
@@ -88,14 +114,25 @@
#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short.
#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended.
#define PHR_SIZE 1 ///< Size of PHR field.
#define DSN_SIZE 1 ///< Size of Sequence Number field.
#define FCF_SIZE 2 ///< Size of FCF field.
#define PAN_ID_SIZE 2 ///< Size of Pan Id.
#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address.
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address.
#define FCS_SIZE 2 ///< Size of FCS field.
#define FRAME_COUNTER_SIZE 4 ///< Size of Frame Counter field.
#define IE_HEADER_SIZE 4 ///< Size of obligatory IE Header field elements, including header termination.
#define IMM_ACK_LENGTH 5 ///< Length of ACK frame.
#define KEY_ID_MODE_1_SIZE 1 ///< Size of 0x01 Key Identifier Mode field.
#define KEY_ID_MODE_2_SIZE 5 ///< Size of 0x10 Key Identifier Mode field.
#define KEY_ID_MODE_3_SIZE 9 ///< Size of 0x11 Key Identifier Mode field.
#define MAX_PACKET_SIZE 127 ///< Maximum size of radio packet.
#define MIC_32_SIZE 4 ///< Size of MIC with MIC-32 and ENC-MIC-32 security attributes.
#define MIC_64_SIZE 8 ///< Size of MIC with MIC-64 and ENC-MIC-64 security attributes.
#define MIC_128_SIZE 16 ///< Size of MIC with MIC-128 and ENC-MIC-128 security attributes.
#define PAN_ID_SIZE 2 ///< Size of Pan Id.
#define PHR_SIZE 1 ///< Size of PHR field.
#define SECURITY_CONTROL_SIZE 1 ///< Size of Security Control field.
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address.
#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address.
#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us].
#define CCA_TIME 128UL ///< aCcaTime [us].
@@ -47,6 +47,7 @@
#include "nrf_802154_const.h"
#include "nrf_802154_critical_section.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_frame_parser.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_procedures_duration.h"
@@ -62,6 +63,7 @@
#include "hal/nrf_timer.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "mac_features/nrf_802154_filter.h"
#include "mac_features/ack_generator/nrf_802154_ack_generator.h"
#include "rsch/nrf_802154_rsch.h"
#include "rsch/nrf_802154_rsch_crit_sect.h"
@@ -178,12 +180,12 @@ static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0];
#endif
static uint8_t m_ack_psdu[IMM_ACK_LENGTH + 1]; ///< ACK frame buffer.
static const uint8_t * mp_tx_data; ///< Pointer to the data to transmit.
static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
static uint8_t m_ed_result; ///< Result of the current energy detection procedure.
static const uint8_t * mp_ack; ///< Pointer to Ack frame buffer.
static const uint8_t * mp_tx_data; ///< Pointer to the data to transmit.
static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
static uint8_t m_ed_result; ///< Result of the current energy detection procedure.
static volatile radio_state_t m_state; ///< State of the radio driver.
static volatile radio_state_t m_state; ///< State of the radio driver.
typedef struct
{
@@ -475,24 +477,6 @@ static void channel_set(uint8_t channel)
* @section ACK transmission management
**************************************************************************************************/
/// Set valid sequence number in ACK frame.
static void ack_prepare(void)
{
// Copy sequence number from received frame to ACK frame.
m_ack_psdu[DSN_OFFSET] = mp_current_rx_buffer->psdu[DSN_OFFSET];
}
/// Set pending bit in ACK frame.
static void ack_pending_bit_set(void)
{
m_ack_psdu[FRAME_PENDING_OFFSET] = ACK_HEADER_WITH_PENDING;
if (!nrf_802154_ack_pending_bit_should_be_set(mp_current_rx_buffer->psdu))
{
m_ack_psdu[FRAME_PENDING_OFFSET] = ACK_HEADER_WITHOUT_PENDING;
}
}
/** Check if ACK is requested in given frame.
*
* @param[in] p_frame Pointer to a frame to check.
@@ -1092,6 +1076,8 @@ static void tx_terminate(void)
/** Terminate RX ACK procedure. */
static void rx_ack_terminate(void)
{
uint32_t ints_to_disable;
nrf_ppi_channel_disable(PPI_DISABLED_EGU);
nrf_ppi_channel_disable(PPI_EGU_RAMP_UP);
@@ -1102,7 +1088,10 @@ static void rx_ack_terminate(void)
if (timeslot_is_granted())
{
nrf_radio_int_disable(NRF_RADIO_INT_END_MASK);
ints_to_disable = NRF_RADIO_INT_END_MASK;
ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK;
nrf_radio_int_disable(ints_to_disable);
nrf_radio_shorts_set(SHORTS_IDLE);
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
@@ -1327,9 +1316,9 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
/** Enter Sleep state. */
static void sleep_init(void)
{
nrf_802154_timer_coord_stop();
nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_IDLE);
m_rsch_timeslot_is_granted = false;
nrf_802154_timer_coord_stop();
}
/** Initialize Falling Asleep operation. */
@@ -1828,7 +1817,12 @@ static void irq_address_state_tx_frame(void)
static void irq_address_state_tx_ack(void)
{
nrf_802154_tx_ack_started();
nrf_802154_tx_ack_started(mp_ack);
}
static void irq_address_state_rx_ack(void)
{
nrf_802154_core_hooks_rx_ack_started();
}
#if !NRF_802154_DISABLE_BCC_MATCHING
@@ -1982,15 +1976,24 @@ static void irq_crcok_state_rx(void)
if (m_flags.frame_filtered || nrf_802154_pib_promiscuous_get())
{
bool send_ack = false;
if (m_flags.frame_filtered &&
ack_is_requested(mp_current_rx_buffer->psdu) &&
nrf_802154_pib_auto_ack_get())
{
mp_ack = nrf_802154_ack_generator_create(mp_current_rx_buffer->psdu);
if (NULL != mp_ack)
{
send_ack = true;
}
}
if (send_ack)
{
bool wait_for_phyend;
// Prepare ACK
ack_prepare();
nrf_radio_packet_ptr_set(m_ack_psdu);
nrf_radio_packet_ptr_set(mp_ack);
// Set shorts
nrf_radio_shorts_set(SHORTS_TX_ACK);
@@ -2048,7 +2051,6 @@ static void irq_crcok_state_rx(void)
if (wait_for_phyend)
{
ack_pending_bit_set();
state_set(RADIO_STATE_TX_ACK);
// Set event handlers
@@ -2262,6 +2264,7 @@ static void irq_phyend_state_tx_ack(void)
static void irq_phyend_state_tx_frame(void)
{
uint32_t ints_to_disable = 0;
uint32_t ints_to_enable = 0;
// Ignore PHYEND event if transmission has not started. This event may be triggered by
// previously terminated transmission.
@@ -2290,15 +2293,21 @@ static void irq_phyend_state_tx_frame(void)
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK;
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
nrf_radio_int_disable(ints_to_disable);
if (nrf_802154_revision_has_phyend_event())
{
nrf_radio_int_disable(NRF_RADIO_INT_PHYEND_MASK);
ints_to_disable |= NRF_RADIO_INT_PHYEND_MASK;
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_int_enable(NRF_RADIO_INT_END_MASK);
ints_to_enable |= NRF_RADIO_INT_END_MASK;
}
nrf_radio_int_disable(ints_to_disable);
nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS);
ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK;
nrf_radio_int_enable(ints_to_enable);
// Clear FEM configuration set at the beginning of the transmission
fem_for_tx_reset(false);
// Set PPIs necessary in rx_ack state
@@ -2344,7 +2353,10 @@ static void irq_phyend_state_tx_frame(void)
}
}
ack_matching_enable();
if ((mp_tx_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) != FRAME_VERSION_2)
{
ack_matching_enable();
}
}
else
{
@@ -2360,6 +2372,35 @@ static void irq_end_state_rx_ack(void)
{
bool ack_match = ack_is_matched();
rx_buffer_t * p_ack_buffer = NULL;
uint8_t * p_ack_data = mp_current_rx_buffer->psdu;
if (!ack_match &&
((mp_tx_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) == FRAME_VERSION_2) &&
((p_ack_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) == FRAME_VERSION_2) &&
((p_ack_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) == FRAME_TYPE_ACK) &&
(nrf_radio_crc_status_get() == NRF_RADIO_CRC_STATUS_OK))
{
// For frame version 2 sequence number bit may be suppressed and its check fails.
// Verify ACK frame using its destination address.
nrf_802154_frame_parser_mhr_data_t tx_mhr_data;
nrf_802154_frame_parser_mhr_data_t ack_mhr_data;
bool parse_result;
parse_result = nrf_802154_frame_parser_mhr_parse(mp_tx_data, &tx_mhr_data);
assert(parse_result);
parse_result = nrf_802154_frame_parser_mhr_parse(p_ack_data, &ack_mhr_data);
if (parse_result &&
(tx_mhr_data.p_src_addr != NULL) &&
(ack_mhr_data.p_dst_addr != NULL) &&
(tx_mhr_data.src_addr_size == ack_mhr_data.dst_addr_size) &&
(0 == memcmp(tx_mhr_data.p_src_addr,
ack_mhr_data.p_dst_addr,
tx_mhr_data.src_addr_size)))
{
ack_match = true;
}
}
if (ack_match)
{
@@ -2474,6 +2515,10 @@ static void irq_handler(void)
irq_address_state_tx_ack();
break;
case RADIO_STATE_RX_ACK:
irq_address_state_rx_ack();
break;
default:
assert(false);
}
@@ -2697,14 +2742,11 @@ static void irq_handler(void)
void nrf_802154_core_init(void)
{
const uint8_t ack_psdu[] = {0x05, ACK_HEADER_WITH_PENDING, 0x00, 0x00, 0x00, 0x00};
memcpy(m_ack_psdu, ack_psdu, sizeof(ack_psdu));
m_state = RADIO_STATE_SLEEP;
m_rsch_timeslot_is_granted = false;
nrf_timer_init();
nrf_802154_ack_generator_init();
}
void nrf_802154_core_deinit(void)
@@ -52,6 +52,7 @@ typedef void (* transmitted_hook)(const uint8_t * p_frame);
typedef bool (* tx_failed_hook)(const uint8_t * p_frame, nrf_802154_tx_error_t error);
typedef bool (* tx_started_hook)(const uint8_t * p_frame);
typedef void (* rx_started_hook)(void);
typedef void (* rx_ack_started_hook)(void);
/* Since some compilers do not allow empty initializers for arrays with unspecified bounds,
* NULL pointer is appended to below arrays if the compiler used is not GCC. It is intentionally
@@ -119,6 +120,15 @@ static const rx_started_hook m_rx_started_hooks[] =
NULL,
};
static const rx_ack_started_hook m_rx_ack_started_hooks[] =
{
#if NRF_802154_ACK_TIMEOUT_ENABLED
nrf_802154_ack_timeout_rx_ack_started_hook,
#endif
NULL,
};
bool nrf_802154_core_hooks_terminate(nrf_802154_term_t term_lvl, req_originator_t req_orig)
{
bool result = true;
@@ -210,3 +220,17 @@ void nrf_802154_core_hooks_rx_started(void)
m_rx_started_hooks[i]();
}
}
void nrf_802154_core_hooks_rx_ack_started(void)
{
for (uint32_t i = 0; i < sizeof(m_rx_ack_started_hooks) / sizeof(m_rx_ack_started_hooks[0]);
i++)
{
if (m_rx_ack_started_hooks[i] == NULL)
{
break;
}
m_rx_ack_started_hooks[i]();
}
}
@@ -93,6 +93,11 @@ bool nrf_802154_core_hooks_tx_started(const uint8_t * p_frame);
*/
void nrf_802154_core_hooks_rx_started(void);
/**
* @brief Process hooks for the RX ACK started event.
*/
void nrf_802154_core_hooks_rx_ack_started(void);
/**
*@}
**/
@@ -189,4 +189,16 @@ void __assert_func(const char * file, int line, const char * func, const char *
;
}
void __aeabi_assert(const char * expr, const char * file, int line)
{
(void)expr;
(void)file;
(void)line;
__disable_irq();
while (1)
;
}
#endif // ENABLE_DEBUG_ASSERT
@@ -123,6 +123,12 @@ extern "C" {
#define FUNCTION_TSCH_ADD 0x0600UL
#define FUNCTION_TSCH_FIRED 0x0601UL
#define FUNCTION_TCOOR_START 0x0700UL
#define FUNCTION_TCOOR_STOP 0x0701UL
#define FUNCTION_TCOOR_TIMESTAMP_PREPARE 0x0702UL
#define FUNCTION_TCOOR_TIMESTAMP_GET 0x0703UL
#define FUNCTION_TCOOR_SYNCHRONIZED 0x0704UL
#define PIN_DBG_RADIO_EVT_END 11
#define PIN_DBG_RADIO_EVT_DISABLED 12
#define PIN_DBG_RADIO_EVT_READY 13
@@ -38,15 +38,17 @@
#include <assert.h>
/** @breif Types of nRF52840 revisions. */
/** @breif Types of nRF revisions. */
typedef enum
{
NRF52840_REVISION_AAAA,
NRF52840_REVISION_AABA,
NRF52840_REVISION_UNKNOWN,
NRF52840_REVISION_AACX,
NRF52811_REVISION,
NRF_REVISION_UNKNOWN,
} nrf_802154_chip_revision;
static nrf_802154_chip_revision m_nrf52840_revision = NRF52840_REVISION_UNKNOWN;
static nrf_802154_chip_revision m_nrf_revision = NRF_REVISION_UNKNOWN;
/**
* @brief Internal auxiliary function to check if the program is running on NRF52840 chip.
@@ -78,7 +80,7 @@ static inline bool nrf_revision_type_52840_aaaa(void)
* @brief Internal auxiliary function to check if the program is running
* on the AABA revision of the nRF52840 chip.
*
* @retval true If it is NRF52480_AAAA chip revision.
* @retval true If it is NRF52480_AABA chip revision.
* @retval false It is other chip revision.
*/
static inline bool nrf_revision_type_52840_aaba(void)
@@ -88,39 +90,82 @@ static inline bool nrf_revision_type_52840_aaba(void)
(((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00)); // sub-revision
}
/**
* @brief Internal auxiliary function to check if the program is running
* on the AACx revision of the nRF52840 chip.
*
* @retval true If it is NRF52480_AACx chip revision.
* @retval false It is other chip revision.
*/
static inline bool nrf_revision_type_52840_aacx(void)
{
return (nrf_revision_type_52840() &&
(((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x20) && // revision
(((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00)); // sub-revision
}
/**
* @brief Internal auxiliary function to check if the program is running on NRF52811 chip.
*
* @retval true If it is NRF52411 chip.
* @retval false If it is other chip.
*/
static inline bool nrf_revision_type_52811(void)
{
return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x0E) &&
(((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x00));
}
void nrf_802154_revision_init(void)
{
if (nrf_revision_type_52840_aaaa())
{
m_nrf52840_revision = NRF52840_REVISION_AAAA;
m_nrf_revision = NRF52840_REVISION_AAAA;
}
else if (nrf_revision_type_52840_aaba())
{
m_nrf52840_revision = NRF52840_REVISION_AABA;
m_nrf_revision = NRF52840_REVISION_AABA;
}
else if (nrf_revision_type_52840_aacx())
{
m_nrf_revision = NRF52840_REVISION_AACX;
}
else if (nrf_revision_type_52811())
{
m_nrf_revision = NRF52811_REVISION;
}
else
{
m_nrf52840_revision = NRF52840_REVISION_UNKNOWN;
m_nrf_revision = NRF_REVISION_UNKNOWN;
}
// This variable may be unused if revision is defined by the compiler.
(void)m_nrf_revision;
}
bool nrf_802154_revision_has_phyend_event(void)
{
#if NRF52840_AAAA
#if defined(NRF52840_XXAA) || defined(NRF52840_AAAA)
return false;
#elif NRF52840_AABA
#elif defined(NRF52840_AABA)
return true;
#elif defined(NRF52840_AACX)
return true;
#elif defined(NRF52811_XXAA)
return true;
#else
bool result = false;
switch (m_nrf52840_revision)
switch (m_nrf_revision)
{
case NRF52840_REVISION_AAAA:
result = false;
break;
case NRF52840_REVISION_AABA:
case NRF52840_REVISION_UNKNOWN:
case NRF52840_REVISION_AACX:
case NRF52811_REVISION:
case NRF_REVISION_UNKNOWN:
result = true;
break;
@@ -41,6 +41,7 @@
#include <stdint.h>
#include "nrf_802154_config.h"
#include "nrf_802154_debug.h"
#include "hal/nrf_ppi.h"
#include "platform/hp_timer/nrf_802154_hp_timer.h"
#include "platform/lp_timer/nrf_802154_lp_timer.h"
@@ -110,20 +111,30 @@ void nrf_802154_timer_coord_uninit(void)
void nrf_802154_timer_coord_start(void)
{
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_START);
m_synchronized = false;
nrf_802154_hp_timer_start();
nrf_802154_hp_timer_sync_prepare();
nrf_802154_lp_timer_sync_start_now();
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_START);
}
void nrf_802154_timer_coord_stop(void)
{
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_STOP);
nrf_802154_hp_timer_stop();
nrf_802154_lp_timer_sync_stop();
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_STOP);
}
void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr)
{
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_TIMESTAMP_PREPARE);
nrf_ppi_channel_and_fork_endpoint_setup(PPI_TIMESTAMP,
event_addr,
nrf_802154_hp_timer_timestamp_task_get(),
@@ -131,6 +142,8 @@ void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr)
PPI_TIMESTAMP_GROUP));
nrf_ppi_group_enable(PPI_TIMESTAMP_GROUP);
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_TIMESTAMP_PREPARE);
}
bool nrf_802154_timer_coord_timestamp_get(uint32_t * p_timestamp)
@@ -138,21 +151,24 @@ bool nrf_802154_timer_coord_timestamp_get(uint32_t * p_timestamp)
uint32_t hp_timestamp;
uint32_t hp_delta;
int32_t drift;
bool result = false;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_TIMESTAMP_GET);
assert(p_timestamp != NULL);
if (!m_synchronized)
if (m_synchronized)
{
return false;
hp_timestamp = nrf_802154_hp_timer_timestamp_get();
hp_delta = hp_timestamp - m_last_sync.hp_timer_time;
drift = m_drift_known ?
(DIV_ROUND(((int64_t)m_drift * hp_delta), ((int64_t)TIME_BASE + m_drift))) :
0;
*p_timestamp = m_last_sync.lp_timer_time + hp_delta - drift;
result = true;
}
hp_timestamp = nrf_802154_hp_timer_timestamp_get();
hp_delta = hp_timestamp - m_last_sync.hp_timer_time;
drift = m_drift_known ?
(DIV_ROUND(((int64_t)m_drift * hp_delta), ((int64_t)TIME_BASE + m_drift))) : 0;
*p_timestamp = m_last_sync.lp_timer_time + hp_delta - drift;
return true;
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_TIMESTAMP_GET);
return result;
}
void nrf_802154_lp_timer_synchronized(void)
@@ -164,6 +180,8 @@ void nrf_802154_lp_timer_synchronized(void)
int32_t drift;
int32_t tb_fraction_of_lp_delta;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_SYNCHRONIZED);
if (nrf_802154_hp_timer_sync_time_get(&sync_time.hp_timer_time))
{
sync_time.lp_timer_time = nrf_802154_lp_timer_sync_time_get();
@@ -209,6 +227,8 @@ void nrf_802154_lp_timer_synchronized(void)
nrf_802154_hp_timer_sync_prepare();
nrf_802154_lp_timer_sync_start_now();
}
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_SYNCHRONIZED);
}
#else // NRF_802154_FRAME_TIMESTAMP_ENABLED
@@ -129,6 +129,14 @@ typedef struct
uint8_t corr_limit; // !< Limit of occurrences above CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED.
} nrf_802154_cca_cfg_t;
/**
* @brief Types of data that can be set in an Ack message.
*/
typedef uint8_t nrf_802154_ack_data_t;
#define NRF_802154_ACK_DATA_PENDING_BIT 0x00
#define NRF_802154_ACK_DATA_IE 0x01
/**
*@}
**/
@@ -82,6 +82,17 @@ _Pragma("GCC diagnostic pop")
*/
#define BLE_ADV_SCHED_CFG_SUPPORT_MIN_SD_VERSION (6001001)
/*
* @brief Defines the minimum version of the SoftDevice that correctly handles timeslot releasing.
*
* The first SoftDevice that supports this option is S140 6.1.0 (6001000). The full version
* number for the SoftDevice binary is a decimal number in the form Mmmmbbb, where:
* - M is major version (one or more digits)
* - mmm is minor version (three digits)
* - bbb is bugfix version (three digits).
*/
#define TIMESLOT_RELEASE_SUPPORT_MIN_SD_VERSION (6001000)
/**@brief Enable Request and End on timeslot safety interrupt. */
#define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0
@@ -161,6 +172,9 @@ static uint16_t m_extension_interval;
/**@brief Number of already performed extentions tries on failed event. */
static volatile uint16_t m_timeslot_extend_tries;
/**@brief Defines if timeslot releasing works correctly on given SoftDevice version. */
static bool m_timeslot_releasing;
/***************************************************************************************************
* @section Drift calculations
**************************************************************************************************/
@@ -197,9 +211,12 @@ static void timer_start(void)
/**@brief Reset timer. */
static void timer_reset(void)
{
NVIC_DisableIRQ(RAAL_TIMER_IRQn);
__DSB();
__ISB();
nrf_timer_task_trigger(RAAL_TIMER, NRF_TIMER_TASK_STOP);
nrf_timer_event_clear(RAAL_TIMER, TIMER_CC_ACTION_EVENT);
NVIC_ClearPendingIRQ(RAAL_TIMER_IRQn);
}
/**@brief Get current time on RAAL Timer. */
@@ -486,9 +503,8 @@ static nrf_radio_signal_callback_return_param_t * signal_handler(uint8_t signal_
m_timeslot_state = TIMESLOT_STATE_IDLE;
// TODO: Change to NRF_RADIO_SIGNAL_CALLBACK_ACTION_END (KRKNWK-937)
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
timer_reset();
m_ret_param.callback_action = m_timeslot_releasing ? NRF_RADIO_SIGNAL_CALLBACK_ACTION_END :
NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_ENDED);
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER);
@@ -714,6 +730,12 @@ void nrf_raal_init(void)
}
#endif
// Ensure that correct SoftDevice version is flashed.
if (SD_VERSION_GET(MBR_SIZE) >= TIMESLOT_RELEASE_SUPPORT_MIN_SD_VERSION)
{
m_timeslot_releasing = true;
}
m_initialized = true;
}
@@ -757,12 +779,22 @@ void nrf_raal_continuous_mode_exit(void)
assert(m_initialized);
assert(m_continuous);
m_continuous = false;
// Emulate signal interrupt to inform SD about end of continuous mode.
if (timeslot_is_granted())
{
NVIC_SetPendingIRQ(RAAL_TIMER_IRQn);
// Reset timer prior marking exiting continuous mode to prevent timeslot release caused by
// the timer
timer_reset();
m_continuous = false;
__DMB();
// Emulate signal interrupt to inform SD about end of continuous mode.
NVIC_SetPendingIRQ(RADIO_IRQn);
NVIC_EnableIRQ(RADIO_IRQn);
}
else
{
m_continuous = false;
}
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT);
@@ -792,5 +824,5 @@ bool nrf_raal_timeslot_request(uint32_t length_us)
uint32_t nrf_raal_timeslot_us_left_get(void)
{
return safe_time_to_timeslot_end_get();
return timeslot_is_granted() ? safe_time_to_timeslot_end_get() : 0;
}