diff --git a/examples/platforms/nrf52811/Makefile.am b/examples/platforms/nrf52811/Makefile.am index 469825023..a1a003196 100644 --- a/examples/platforms/nrf52811/Makefile.am +++ b/examples/platforms/nrf52811/Makefile.am @@ -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 \ diff --git a/examples/platforms/nrf52840/Makefile.am b/examples/platforms/nrf52840/Makefile.am index 1ae03dc34..c7cd6a015 100644 --- a/examples/platforms/nrf52840/Makefile.am +++ b/examples/platforms/nrf52840/Makefile.am @@ -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 \ diff --git a/third_party/NordicSemiconductor/Makefile.am b/third_party/NordicSemiconductor/Makefile.am index d15719a62..397028c91 100644 --- a/third_party/NordicSemiconductor/Makefile.am +++ b/third_party/NordicSemiconductor/Makefile.am @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h index 0b3a30577..6183501e1 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.c new file mode 100644 index 000000000..01ecab203 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.c @@ -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 +#include + +#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; + } +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.h new file mode 100644 index 000000000..35e39f485 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_data.h @@ -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 +#include + +/** + * @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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c new file mode 100644 index 000000000..41b4cf303 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c @@ -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 +#include + +#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; + } +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h new file mode 100644 index 000000000..08aaffc40 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h @@ -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 + +/** 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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c new file mode 100644 index 000000000..d7c5fffe3 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c @@ -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 +#include + +#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; +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h new file mode 100644 index 000000000..7e46cf0d7 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h @@ -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 +#include + +/** 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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c new file mode 100644 index 000000000..06a35deff --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c @@ -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 +#include + +#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; +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h new file mode 100644 index 000000000..4aad1f2ca --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h @@ -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 +#include + +/** 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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c new file mode 100644 index 000000000..4ca4a1d71 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c @@ -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 +#include +#include + +#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; +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h index 95102fc8a..a42b39be4 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h @@ -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); + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c index 4c0f5a6f9..1a47c0e6e 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c @@ -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(); diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c index 5fc56d1d5..896d61c51 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c @@ -45,9 +45,11 @@ #include #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; diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.c new file mode 100644 index 000000000..83a6f80ed --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.c @@ -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 + +#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]; +} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.h new file mode 100644 index 000000000..cefcd8fe5 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_frame_parser.h @@ -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 +#include + +#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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c index ca7383db7..f8ccd06b4 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c @@ -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; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c index 4cc86b40a..86192e9e4 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h index 691f4488b..3ff28b06a 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h @@ -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. * diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c index 79d20b787..b46d13438 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c @@ -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; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h index a773a7553..3b40730e5 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h @@ -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_ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h index 8a81452f9..54c1654ec 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h index 7d59a6419..31d0c617d 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h @@ -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]. diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c index e9306418e..0306db8b9 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c @@ -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) diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c index 325cc3aa4..a5678b852 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c @@ -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](); + } +} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h index 8a14fdecd..1b5c3fa30 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h @@ -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); + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c index aa6c6ebfb..94b9ed0b5 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h index 33a503669..c469397dc 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c index 733739937..33a8fad2b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c @@ -38,15 +38,17 @@ #include -/** @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; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c index 7b636a423..3d8b4a1fc 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c @@ -41,6 +41,7 @@ #include #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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h index 93f566b86..a2c8f6e80 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h @@ -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 + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c index 14fec32f6..cc606caa6 100644 --- a/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c @@ -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; }